Merge nucleic/lucid-river-toad-6efj into dev
This commit is contained in:
@@ -82,11 +82,35 @@ internal static class InternalComProbe
|
||||
Console.WriteLine($" {name} {{{clsid}}}");
|
||||
Console.WriteLine($" ({source})");
|
||||
|
||||
var iunknown = typeof(object).GUID; // IID_IUnknown
|
||||
var hr = CoCreateInstance(in clsid, IntPtr.Zero, ClsctxAll, in iunknown, out var unknown);
|
||||
var hr = CoCreateInstance(in clsid, IntPtr.Zero, ClsctxAll, in IidIUnknown, out var unknown);
|
||||
if (hr < 0)
|
||||
{
|
||||
Console.WriteLine($" activation failed: {Hresult(hr)}");
|
||||
if ((uint)hr == ENoInterface)
|
||||
// Every COM object implements IUnknown, so this combination is impossible
|
||||
// unless the IID being passed is not IID_IUnknown. Say so loudly: the first
|
||||
// version of this probe did exactly that and reported a confident false
|
||||
// negative that read like a real finding about WSL.
|
||||
Console.WriteLine(" !! E_NOINTERFACE on an IUnknown activation is IMPOSSIBLE — "
|
||||
+ "every COM object implements IUnknown. This probe is passing a wrong IID; "
|
||||
+ "treat the whole run as void and fix it, do NOT record a finding.");
|
||||
// A class factory is allowed to refuse IUnknown-first activation, so a failure
|
||||
// here is not yet an answer: ask for each internal interface directly before
|
||||
// concluding anything.
|
||||
foreach (var (interfaceName, iid, _) in Interfaces)
|
||||
{
|
||||
var direct = iid;
|
||||
var dhr = CoCreateInstance(in clsid, IntPtr.Zero, ClsctxAll, in direct, out var instance);
|
||||
Console.WriteLine($" direct activation as {interfaceName}: "
|
||||
+ (dhr >= 0 ? "**YES**" : Hresult(dhr)));
|
||||
if (dhr < 0) continue;
|
||||
if (interfaceName == "IWSLCSessionManager")
|
||||
{
|
||||
bound = true;
|
||||
if (callThrough) CallThrough(instance);
|
||||
}
|
||||
Marshal.Release(instance);
|
||||
}
|
||||
Console.WriteLine();
|
||||
continue;
|
||||
}
|
||||
@@ -227,9 +251,20 @@ internal static class InternalComProbe
|
||||
|
||||
// MARK: - Interop
|
||||
|
||||
/// <summary>
|
||||
/// `IID_IUnknown`, spelled out. **Do not** reach for `typeof(object).GUID` here — that is the
|
||||
/// CLR's type GUID for `System.Object`, not `IID_IUnknown`, and activating with it asks every
|
||||
/// class factory for an interface nothing implements. The failure is maximally misleading:
|
||||
/// each registered class answers `E_NOINTERFACE` *at activation*, which reads exactly like
|
||||
/// "this class does not expose the interface you wanted" and is really "you asked for
|
||||
/// gibberish". That mistake produced a false negative on this very probe.
|
||||
/// </summary>
|
||||
private static readonly Guid IidIUnknown = new("00000000-0000-0000-C000-000000000046");
|
||||
|
||||
private const uint ClsctxAll = 0x17; // INPROC_SERVER|HANDLER|LOCAL_SERVER|REMOTE_SERVER
|
||||
private const uint CoinitMultithreaded = 0;
|
||||
private const uint RpcEChangedMode = 0x80010106;
|
||||
private const uint ENoInterface = 0x80004002;
|
||||
|
||||
[DllImport("ole32.dll")]
|
||||
private static extern int CoInitializeEx(IntPtr reserved, uint coInit);
|
||||
|
||||
Reference in New Issue
Block a user