mirror of
https://github.com/ZuneDev/ZuneShell.dll.git
synced 2026-07-27 13:11:51 -07:00
Fill in more gaps in ZuneDBApi
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
public enum ELibraryFilter
|
||||||
|
{
|
||||||
|
eLibraryFilterAll = -1,
|
||||||
|
eLibraryFilterInLibraryOnly = 1,
|
||||||
|
eLibraryFilterNotInLibrary = 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
public enum EQuickMixState
|
||||||
|
{
|
||||||
|
eQuickMixStateNotFound = 2,
|
||||||
|
eQuickMixStateReady = 1,
|
||||||
|
eQuickMixStateUnknown = 0,
|
||||||
|
eQuickMixStateInvalid = -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
public enum EWatchType
|
||||||
|
{
|
||||||
|
eWatchCount = 3,
|
||||||
|
eWatching = 2,
|
||||||
|
eWatched = 1,
|
||||||
|
eUnWatched = 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Microsoft.Zune.Service;
|
||||||
|
|
||||||
|
public class PointsPayment : PaymentInstrument
|
||||||
|
{
|
||||||
|
public PointsPayment()
|
||||||
|
: base(null, PaymentType.Points)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Microsoft.Zune.Util;
|
||||||
|
|
||||||
|
public class Point
|
||||||
|
{
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
public int X { get; set; }
|
||||||
|
|
||||||
|
public Point(int x, int y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point() : this(0, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Microsoft.Zune.Util;
|
||||||
|
|
||||||
|
public class Size
|
||||||
|
{
|
||||||
|
public int Height { get; set; }
|
||||||
|
|
||||||
|
public int Width { get; set; }
|
||||||
|
|
||||||
|
public Size(int width, int height)
|
||||||
|
{
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Size() : this(0, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using Microsoft.Iris;
|
using Microsoft.Iris;
|
||||||
|
|
||||||
namespace Microsoft.Zune.Util;
|
namespace Microsoft.Zune.Util;
|
||||||
@@ -7,7 +5,9 @@ namespace Microsoft.Zune.Util;
|
|||||||
// Original wraps native Windows 7 taskbar integration (thumbnail preview window, jump
|
// Original wraps native Windows 7 taskbar integration (thumbnail preview window, jump
|
||||||
// list command dispatch via window messages). Not reverse engineered — see
|
// list command dispatch via window messages). Not reverse engineered — see
|
||||||
// logs/Microsoft.Zune/Util/DownloadManager.md.
|
// logs/Microsoft.Zune/Util/DownloadManager.md.
|
||||||
public class TaskbarPlayer : IDisposable
|
// Original derives from Microsoft.Iris.ModelItem, which is where INotifyPropertyChanged
|
||||||
|
// (PropertyChanged event, FirePropertyChanged) comes from.
|
||||||
|
public class TaskbarPlayer : ModelItem, IDisposable
|
||||||
{
|
{
|
||||||
private static TaskbarPlayer sm_taskbarPlayer;
|
private static TaskbarPlayer sm_taskbarPlayer;
|
||||||
|
|
||||||
@@ -17,19 +17,65 @@ public class TaskbarPlayer : IDisposable
|
|||||||
|
|
||||||
public Point RestorePosition { get; private set; }
|
public Point RestorePosition { get; private set; }
|
||||||
|
|
||||||
public WindowState RestoreState { get; set; }
|
private WindowState m_restoreState = WindowState.Maximized;
|
||||||
|
|
||||||
|
public WindowState RestoreState
|
||||||
|
{
|
||||||
|
get => m_restoreState;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (m_restoreState != value)
|
||||||
|
{
|
||||||
|
m_restoreState = value;
|
||||||
|
FirePropertyChanged(nameof(RestoreState));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Size PopupSize { get; private set; }
|
public Size PopupSize { get; private set; }
|
||||||
|
|
||||||
public Point PopupPosition { get; private set; }
|
public Point PopupPosition { get; private set; }
|
||||||
|
|
||||||
public bool PopupVisible { get; set; }
|
private bool m_fPopupVisible;
|
||||||
|
|
||||||
public bool ToolbarVisible { get; set; }
|
public bool PopupVisible
|
||||||
|
{
|
||||||
|
get => m_fPopupVisible;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (m_fPopupVisible == value) return;
|
||||||
|
m_fPopupVisible = value;
|
||||||
|
FirePropertyChanged(nameof(PopupVisible));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool m_fToolbarVisible;
|
||||||
|
|
||||||
|
public bool ToolbarVisible
|
||||||
|
{
|
||||||
|
get => m_fToolbarVisible;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (m_fToolbarVisible == value) return;
|
||||||
|
m_fToolbarVisible = value;
|
||||||
|
FirePropertyChanged(nameof(ToolbarVisible));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool EnableToolbar { get; set; }
|
public bool EnableToolbar { get; set; }
|
||||||
|
|
||||||
public bool ShowToolbar { get; set; }
|
private bool m_fShowToolbar;
|
||||||
|
|
||||||
|
public bool ShowToolbar
|
||||||
|
{
|
||||||
|
get => m_fShowToolbar;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (m_fShowToolbar == value) return;
|
||||||
|
m_fShowToolbar = value;
|
||||||
|
FirePropertyChanged(nameof(ShowToolbar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Command Restore { get; } = new();
|
public Command Restore { get; } = new();
|
||||||
|
|
||||||
@@ -45,9 +91,11 @@ public class TaskbarPlayer : IDisposable
|
|||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
|
if (disposing)
|
||||||
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public new void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using Microsoft.Iris;
|
||||||
|
|
||||||
|
namespace MicrosoftZuneLibrary;
|
||||||
|
|
||||||
|
public class AsyncQueryParams
|
||||||
|
{
|
||||||
|
public Guid ArtistId { get; }
|
||||||
|
|
||||||
|
public bool GetFriends { get; }
|
||||||
|
|
||||||
|
public int UserId { get; }
|
||||||
|
|
||||||
|
public DeferredInvokeHandler SetResultsHandler { get; }
|
||||||
|
|
||||||
|
public bool ResolveZuneTags { get; }
|
||||||
|
|
||||||
|
public AsyncQueryParams(Guid artistId, bool getFriends, int userId, DeferredInvokeHandler setResultsHandler, bool resolveZuneTags)
|
||||||
|
{
|
||||||
|
ArtistId = artistId;
|
||||||
|
GetFriends = getFriends;
|
||||||
|
UserId = userId;
|
||||||
|
SetResultsHandler = setResultsHandler;
|
||||||
|
ResolveZuneTags = resolveZuneTags;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace MicrosoftZuneLibrary;
|
||||||
|
|
||||||
|
public class FriendOfArtist
|
||||||
|
{
|
||||||
|
public string ZuneTag { get; set; }
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Threading;
|
||||||
|
using Microsoft.Iris;
|
||||||
|
|
||||||
|
namespace MicrosoftZuneLibrary;
|
||||||
|
|
||||||
|
public class FriendsOfArtistQuery : ModelItem, IDisposable
|
||||||
|
{
|
||||||
|
private Guid m_artistId;
|
||||||
|
|
||||||
|
private bool m_getFriends;
|
||||||
|
|
||||||
|
private int m_userId;
|
||||||
|
|
||||||
|
private bool m_resolveZuneTags;
|
||||||
|
|
||||||
|
private bool m_hasFriends;
|
||||||
|
|
||||||
|
private bool m_queryComplete;
|
||||||
|
|
||||||
|
private IList m_friends;
|
||||||
|
|
||||||
|
private IList m_friendsWithFavs;
|
||||||
|
|
||||||
|
private IList m_friendsWithMostPlayedSongs;
|
||||||
|
|
||||||
|
private IList m_friendsWithMostPlayedArtists;
|
||||||
|
|
||||||
|
private static FriendsOfArtistQuery m_singletonInstance;
|
||||||
|
|
||||||
|
public IList FriendsWithMostPlayedArtists => m_friendsWithMostPlayedArtists;
|
||||||
|
|
||||||
|
public IList FriendsWithMostPlayedSongs => m_friendsWithMostPlayedSongs;
|
||||||
|
|
||||||
|
public IList FriendsWithFavs => m_friendsWithFavs;
|
||||||
|
|
||||||
|
public IList Friends => m_friends;
|
||||||
|
|
||||||
|
public bool HasFriends => m_hasFriends;
|
||||||
|
|
||||||
|
public bool QueryComplete
|
||||||
|
{
|
||||||
|
get => m_queryComplete;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != m_queryComplete)
|
||||||
|
{
|
||||||
|
m_queryComplete = value;
|
||||||
|
FirePropertyChanged(nameof(QueryComplete));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FriendsOfArtistQuery Instance => m_singletonInstance ??= new FriendsOfArtistQuery();
|
||||||
|
|
||||||
|
private FriendsOfArtistQuery()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Query(Guid artistId, bool getFriends, int userId) => Query(artistId, getFriends, userId, resolveZuneTags: true);
|
||||||
|
|
||||||
|
public void Query(Guid artistId, bool getFriends, int userId, bool resolveZuneTags)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Monitor.Enter(m_singletonInstance);
|
||||||
|
|
||||||
|
QueryComplete = false;
|
||||||
|
|
||||||
|
if (artistId == m_artistId && (!getFriends || m_getFriends) && userId == m_userId)
|
||||||
|
{
|
||||||
|
QueryComplete = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_artistId = artistId;
|
||||||
|
m_getFriends = getFriends;
|
||||||
|
m_userId = userId;
|
||||||
|
m_resolveZuneTags = resolveZuneTags;
|
||||||
|
|
||||||
|
SetResults(hasFriends: false, null, null, null, null);
|
||||||
|
|
||||||
|
if (artistId != Guid.Empty)
|
||||||
|
{
|
||||||
|
AsyncQueryParams state = new(artistId, getFriends, userId, DeferredSetResults, m_resolveZuneTags);
|
||||||
|
ThreadPool.QueueUserWorkItem(AsyncQuery, state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QueryComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Monitor.Exit(m_singletonInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The original resolves the artist's user cards (and, per card, the ZuneTag) via the native
|
||||||
|
// ZuneLibraryExports.UserCardsForMedia/GetFieldValues exports. Those resolve through the same
|
||||||
|
// opaque native singleton/factory table documented as unreachable via static analysis in
|
||||||
|
// logs/MicrosoftZuneInterop/IQueryPropertyBag.md (no recoverable RTTI/symbol for the concrete
|
||||||
|
// implementation, would need dynamic tracing) — see logs/MicrosoftZuneLibrary/FriendsOfArtistQuery.md.
|
||||||
|
// Until that native database exists, every query completes with "no friends found," matching
|
||||||
|
// the same treatment as MicrosoftZuneLibrary/LibraryDataProviderItemBase.GetFieldValue/SetFieldValue.
|
||||||
|
private static void AsyncQuery(object obj)
|
||||||
|
{
|
||||||
|
AsyncQueryParams asyncQueryParams = (AsyncQueryParams)obj;
|
||||||
|
SetResultsParams args = new(hasFriends: false, null, null, null, null);
|
||||||
|
Application.DeferredInvoke(asyncQueryParams.SetResultsHandler, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetResults(bool hasFriends, IList friends, IList friendsWithFavs, IList friendsWithMostPlayedSongs, IList friendsWithMostPlayedArtists)
|
||||||
|
{
|
||||||
|
if (m_friends != friends)
|
||||||
|
{
|
||||||
|
m_friends = friends;
|
||||||
|
FirePropertyChanged(nameof(Friends));
|
||||||
|
}
|
||||||
|
if (m_friendsWithFavs != friendsWithFavs)
|
||||||
|
{
|
||||||
|
m_friendsWithFavs = friendsWithFavs;
|
||||||
|
FirePropertyChanged(nameof(FriendsWithFavs));
|
||||||
|
}
|
||||||
|
if (m_friendsWithMostPlayedSongs != friendsWithMostPlayedSongs)
|
||||||
|
{
|
||||||
|
m_friendsWithMostPlayedSongs = friendsWithMostPlayedSongs;
|
||||||
|
FirePropertyChanged(nameof(FriendsWithMostPlayedSongs));
|
||||||
|
}
|
||||||
|
if (m_friendsWithMostPlayedArtists != friendsWithMostPlayedArtists)
|
||||||
|
{
|
||||||
|
m_friendsWithMostPlayedArtists = friendsWithMostPlayedArtists;
|
||||||
|
FirePropertyChanged(nameof(FriendsWithMostPlayedArtists));
|
||||||
|
}
|
||||||
|
if (m_hasFriends != hasFriends)
|
||||||
|
{
|
||||||
|
m_hasFriends = hasFriends;
|
||||||
|
FirePropertyChanged(nameof(HasFriends));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeferredSetResults(object obj)
|
||||||
|
{
|
||||||
|
QueryComplete = true;
|
||||||
|
SetResultsParams setResultsParams = (SetResultsParams)obj;
|
||||||
|
SetResults(setResultsParams.HasFriends, setResultsParams.Friends, setResultsParams.FriendsWithFavs, setResultsParams.FriendsWithMostPlayedSongs, setResultsParams.FriendsWithMostPlayedArtists);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~FriendsOfArtistQuery()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace MicrosoftZuneLibrary;
|
||||||
|
|
||||||
|
public class SetResultsParams
|
||||||
|
{
|
||||||
|
public bool HasFriends { get; }
|
||||||
|
|
||||||
|
public IList Friends { get; }
|
||||||
|
|
||||||
|
public IList FriendsWithFavs { get; }
|
||||||
|
|
||||||
|
public IList FriendsWithMostPlayedSongs { get; }
|
||||||
|
|
||||||
|
public IList FriendsWithMostPlayedArtists { get; }
|
||||||
|
|
||||||
|
public SetResultsParams(bool hasFriends, IList friends, IList friendsWithFavs, IList friendsWithMostPlayedSongs, IList friendsWithMostPlayedArtists)
|
||||||
|
{
|
||||||
|
HasFriends = hasFriends;
|
||||||
|
Friends = friends;
|
||||||
|
FriendsWithFavs = friendsWithFavs;
|
||||||
|
FriendsWithMostPlayedSongs = friendsWithMostPlayedSongs;
|
||||||
|
FriendsWithMostPlayedArtists = friendsWithMostPlayedArtists;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -551,8 +551,7 @@ namespace Microsoft.Zune.Shell
|
|||||||
|
|
||||||
if (num > 0)
|
if (num > 0)
|
||||||
{
|
{
|
||||||
Debug.WriteLine(str);
|
throw new ZuneShellException("Internal Zune Shell error", $"Scripting errors encountered (Process ID) = {Environment.ProcessId.ToString(CultureInfo.InvariantCulture)}\n\n{str}");
|
||||||
throw new ZuneShellException("Internal Zune Shell error", $"Scripting errors encountered (Process ID) = {Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture)}\n\n{str}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
|
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
|
||||||
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
||||||
|
|
||||||
using Microsoft.Zune.Util;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace ZuneUI
|
namespace ZuneUI
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
|
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
|
||||||
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
||||||
|
|
||||||
using Microsoft.Zune.Util;
|
|
||||||
using MicrosoftZuneLibrary;
|
using MicrosoftZuneLibrary;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using UIXControls;
|
using UIXControls;
|
||||||
using ZuneDBApi.Abstractions;
|
using ZuneDBApi.Abstractions;
|
||||||
|
using Point = Microsoft.Zune.Util.Point;
|
||||||
|
using Size = Microsoft.Zune.Util.Size;
|
||||||
|
|
||||||
namespace ZuneUI
|
namespace ZuneUI
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
||||||
|
|
||||||
using Microsoft.Zune.Service;
|
using Microsoft.Zune.Service;
|
||||||
using Microsoft.Zune.Util;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|||||||
@@ -5,11 +5,10 @@
|
|||||||
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
||||||
|
|
||||||
using Microsoft.Iris;
|
using Microsoft.Iris;
|
||||||
using Microsoft.Zune.Util;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using Microsoft.Zune.Util;
|
||||||
|
|
||||||
namespace ZuneUI
|
namespace ZuneUI
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
Submodule libs/ZuneUIXTools updated: 7c12de65bd...b3726931db
@@ -0,0 +1,75 @@
|
|||||||
|
# MicrosoftZuneLibrary.FriendsOfArtistQuery — decompilation log
|
||||||
|
|
||||||
|
Append-only. Do not edit previous entries.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-07-26 — Stage 1 + 2 for FriendsOfArtistQuery, AsyncQueryParams, SetResultsParams
|
||||||
|
|
||||||
|
**Trigger:** explicit request to complete stages 1 and 2 for
|
||||||
|
`MicrosoftZuneLibrary.FriendsOfArtistQuery`. The user pointed out the type lives in
|
||||||
|
`ZuneDBApi.dll` (the original mixed-mode C++/CLI assembly at
|
||||||
|
`/home/yoshiask/repos/ZuneDev/windows/shared/zune-x64/Zune/ZuneDBApi.dll`), not in the
|
||||||
|
pure-managed `ZuneShell.dll` this session initially checked (which only carries the
|
||||||
|
`Microsoft.Zune.Shell`/`ZuneUI`/`ZuneXml` layer — the `MicrosoftZuneLibrary` namespace is
|
||||||
|
merged into `ZuneDBApi.dll`, confirmed via `ilspy_list_assembly_types` returning 0 hits
|
||||||
|
for that namespace in `ZuneShell.dll` and 160 hits in `ZuneDBApi.dll`).
|
||||||
|
|
||||||
|
**Source:** `mcp__ilspy__decompile_type` on `MicrosoftZuneLibrary.FriendsOfArtistQuery`,
|
||||||
|
`MicrosoftZuneLibrary.AsyncQueryParams`, and `MicrosoftZuneLibrary.SetResultsParams` (all
|
||||||
|
three are top-level types in that namespace, not nested — confirmed via
|
||||||
|
`list_assembly_types`).
|
||||||
|
|
||||||
|
**`AsyncQueryParams`/`SetResultsParams`**: plain immutable data-carrier classes with no
|
||||||
|
native dependency at all (just `Guid`/`bool`/`int`/`IList`/`Microsoft.Iris.DeferredInvokeHandler`
|
||||||
|
fields exposed as read-only properties). Transcribed as real logic — auto-properties set
|
||||||
|
from the constructor, matching CLAUDE.md's "prefer auto-properties" guidance rather than
|
||||||
|
the original's explicit backing-field get-only pattern (behaviorally identical).
|
||||||
|
|
||||||
|
**`FriendsOfArtistQuery`**: extends `Microsoft.Iris.ModelItem` (already present in this
|
||||||
|
repo via the `UIX.csproj` reference — real, not reimplemented this session) and is a
|
||||||
|
lazy, non-thread-safe singleton (`Instance` property), matching the original exactly
|
||||||
|
(no double-checked locking in the original either).
|
||||||
|
|
||||||
|
Real logic kept for:
|
||||||
|
- `Query(Guid, bool, int[, bool])`: the cache-hit short-circuit
|
||||||
|
(`artistId == m_artistId && (!getFriends || m_getFriends) && userId == m_userId`),
|
||||||
|
field assignment, `Guid.Empty` fast path, and `ThreadPool.QueueUserWorkItem` dispatch —
|
||||||
|
none of this touches native code.
|
||||||
|
- `SetResults`/`DeferredSetResults`: pure change-tracking + `FirePropertyChanged` calls
|
||||||
|
(`FirePropertyChanged` is `protected` on the real `ModelItem` base, so no reimplementation
|
||||||
|
needed).
|
||||||
|
- The `Application.DeferredInvoke(DeferredInvokeHandler, object)` completion hop: this is
|
||||||
|
real `Microsoft.Iris` framework machinery already implemented in `UIX.csproj`
|
||||||
|
(`libs/ZuneUIXTools/libs/MicrosoftIris/UIX/Microsoft/Iris/Application.cs:324`), not a
|
||||||
|
native call — confirmed by reading it before assuming it needed stubbing.
|
||||||
|
|
||||||
|
Stubbed (native-dependent):
|
||||||
|
- `AsyncQuery`'s body originally calls `global::<Module>.ZuneLibraryExports.UserCardsForMedia`
|
||||||
|
and `.GetFieldValues` — native module-level exports of `ZuneDBApi.dll`, resolved through
|
||||||
|
the same opaque native singleton/factory table documented as a dead end (no recoverable
|
||||||
|
RTTI or symbol for the concrete implementation, would require dynamic tracing of a running
|
||||||
|
process) in `logs/MicrosoftZuneInterop/IQueryPropertyBag.md`'s 2026-07-21 entry for
|
||||||
|
`ZuneLibraryExports.CreatePropertyBag`/`CreateMultiSortAttributes`. Per CLAUDE.md's
|
||||||
|
*Dealing with unknowns* step 4, this was not re-attempted from scratch — same native
|
||||||
|
export family, same already-documented dead end. ILSpy's decompilation of `AsyncQuery`
|
||||||
|
also emits unreadable `$ArrayType$...` struct spam for the native `DBPropertyRequestStruct`
|
||||||
|
stack-allocated array, consistent with CLAUDE.md's warning that native/mixed-mode
|
||||||
|
decompiler output is low quality and shouldn't be transcribed verbatim.
|
||||||
|
- Kept the surrounding framework intact (still runs on the thread pool, still completes via
|
||||||
|
`Application.DeferredInvoke` so `QueryComplete` flips to `true` and `HasFriends`/`Friends`
|
||||||
|
etc. fire their property-changed notifications) — every query now completes with "no
|
||||||
|
friends found," the same treatment as `MicrosoftZuneLibrary.LibraryDataProviderItemBase`'s
|
||||||
|
`GetFieldValue`/`SetFieldValue` stubs and `Microsoft.Zune.Util.DRMCanDoQuery`'s "every
|
||||||
|
query answers no" convention.
|
||||||
|
|
||||||
|
**Dispose/finalizer note:** ILSpy's decompilation of the original showed invalid C# —
|
||||||
|
`private void ~FriendsOfArtistQuery() {}` as an ordinary method with an empty body, and
|
||||||
|
`Dispose(bool P_0)` calling `Finalize()` directly in the non-disposing branch. Per
|
||||||
|
CLAUDE.md's *COM objects* rule (rewrite invalid C++-style destructor syntax as a proper
|
||||||
|
C# `~Type()` finalizer), this was rewritten as the standard `Dispose(bool)`/`~Type()`
|
||||||
|
pattern with identical externally-observable behavior (disposing calls `base.Dispose()`;
|
||||||
|
the finalizer path is a no-op, matching the original's empty destructor body) rather than
|
||||||
|
transcribing the decompiler artifact verbatim.
|
||||||
|
|
||||||
|
**Result:** `ZuneDBApi.csproj` builds with 0 errors (1351 pre-existing warnings, none new).
|
||||||
Reference in New Issue
Block a user