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($" {name} {{{clsid}}}");
|
||||||
Console.WriteLine($" ({source})");
|
Console.WriteLine($" ({source})");
|
||||||
|
|
||||||
var iunknown = typeof(object).GUID; // IID_IUnknown
|
var hr = CoCreateInstance(in clsid, IntPtr.Zero, ClsctxAll, in IidIUnknown, out var unknown);
|
||||||
var hr = CoCreateInstance(in clsid, IntPtr.Zero, ClsctxAll, in iunknown, out var unknown);
|
|
||||||
if (hr < 0)
|
if (hr < 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine($" activation failed: {Hresult(hr)}");
|
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();
|
Console.WriteLine();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -227,9 +251,20 @@ internal static class InternalComProbe
|
|||||||
|
|
||||||
// MARK: - Interop
|
// 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 ClsctxAll = 0x17; // INPROC_SERVER|HANDLER|LOCAL_SERVER|REMOTE_SERVER
|
||||||
private const uint CoinitMultithreaded = 0;
|
private const uint CoinitMultithreaded = 0;
|
||||||
private const uint RpcEChangedMode = 0x80010106;
|
private const uint RpcEChangedMode = 0x80010106;
|
||||||
|
private const uint ENoInterface = 0x80004002;
|
||||||
|
|
||||||
[DllImport("ole32.dll")]
|
[DllImport("ole32.dll")]
|
||||||
private static extern int CoInitializeEx(IntPtr reserved, uint coInit);
|
private static extern int CoInitializeEx(IntPtr reserved, uint coInit);
|
||||||
|
|||||||
Reference in New Issue
Block a user