From 4d30d025a1611326fd07c2b084fb37283e74d1e3 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Mon, 18 Jul 2022 18:03:24 +0200 Subject: [PATCH 1/3] DummyLoader: Skip registering the Image3dApi interfaces as part of the loader Done to prevent the loader from "hijacking" the registration of the IImage3dSource and IImage3dFileLoader interfaces that should really be the responsibility of the "host" SW to register. --- DummyLoader/Main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DummyLoader/Main.cpp b/DummyLoader/Main.cpp index 48f8751..a5715d9 100644 --- a/DummyLoader/Main.cpp +++ b/DummyLoader/Main.cpp @@ -41,7 +41,7 @@ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID STDAPI DllRegisterServer() { // registers object, typelib and all interfaces in typelib - return _AtlModule.DllRegisterServer(); + return _AtlModule.DllRegisterServer(false); // skip TypeLib registration since that is the responsibility of the host } // DllUnregisterServer - Removes entries from the system registry. From feca4a266e83dec569f5ef67937b69e62d0a8eb6 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Tue, 19 Jul 2022 00:28:45 +0200 Subject: [PATCH 2/3] Python: Switch to loading Image3dAPI types from Image3dAPI.tlb instead of the loader. This depends on Image3dAPI.tlb being found in the system PATH. --- TestPython/TestPython.py | 4 +--- TestPython/TestPython.pyproj | 1 + TestPython/utils.py | 22 ---------------------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/TestPython/TestPython.py b/TestPython/TestPython.py index d48fcff..11021a6 100644 --- a/TestPython/TestPython.py +++ b/TestPython/TestPython.py @@ -1,18 +1,16 @@ ## Sample code to demonstrate how to access Image3dAPI from a python script -import platform import comtypes import comtypes.client import numpy as np from utils import SafeArrayToNumpy from utils import FrameTo3dArray -from utils import TypeLibFromObject if __name__=="__main__": # create loader object loader = comtypes.client.CreateObject("DummyLoader.Image3dFileLoader") # cast to IImage3dFileLoader interface - Image3dAPI = TypeLibFromObject(loader) + Image3dAPI = comtypes.client.GetModule("Image3dAPI.tlb") loader = loader.QueryInterface(Image3dAPI.IImage3dFileLoader) # load file diff --git a/TestPython/TestPython.pyproj b/TestPython/TestPython.pyproj index 1b32374..55b901a 100644 --- a/TestPython/TestPython.pyproj +++ b/TestPython/TestPython.pyproj @@ -14,6 +14,7 @@ TestPython Standard Python launcher False + PATH=$(SolutionDir)x64 true diff --git a/TestPython/utils.py b/TestPython/utils.py index 2325783..0466198 100644 --- a/TestPython/utils.py +++ b/TestPython/utils.py @@ -1,30 +1,8 @@ ## Sample code to demonstrate how to access Image3dAPI from a python script -import platform import comtypes -import comtypes.client import numpy as np -def TypeLibFromObject (object): - """Loads the type library associated with a COM class instance""" - import winreg - - with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, "CLSID\\"+object.__clsid+"\\TypeLib", 0, winreg.KEY_READ) as key: - typelib = winreg.EnumValue(key, 0)[1] - with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, "CLSID\\"+object.__clsid+"\\Version", 0, winreg.KEY_READ) as key: - version = winreg.EnumValue(key, 0)[1] - - try: - major_ver, minor_ver = version.split(".") - return comtypes.client.GetModule([typelib, int(major_ver), int(minor_ver)]) - except OSError as err: - # API 1.2-only compatibility fallback to avoid breaking existing loaders - if (version != "1.2") or (err.winerror != -2147319779): # Library not registered - raise # rethrow - # Fallback to TypeLib version 1.0 - return comtypes.client.GetModule([typelib, 1, 0]) - - def SafeArrayToNumpy (safearr_ptr, copy=True): """Convert a SAFEARRAY buffer to its numpy equivalent""" import ctypes From 78e189019548a67720fd0accc1b0a853aa986852 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Tue, 19 Jul 2022 00:40:29 +0200 Subject: [PATCH 3/3] SandboxTest: Also load and register the Image3dAPI type library to enable marshsaling of the corresponding interfaces. --- DummyLoader/Main.cpp | 5 ++--- SandboxTest/Main.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/DummyLoader/Main.cpp b/DummyLoader/Main.cpp index a5715d9..def6e71 100644 --- a/DummyLoader/Main.cpp +++ b/DummyLoader/Main.cpp @@ -40,14 +40,13 @@ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID // DllRegisterServer - Adds entries to the system registry. STDAPI DllRegisterServer() { - // registers object, typelib and all interfaces in typelib - return _AtlModule.DllRegisterServer(false); // skip TypeLib registration since that is the responsibility of the host + return _AtlModule.DllRegisterServer(FALSE); // skip TypeLib registration since that is the responsibility of the host } // DllUnregisterServer - Removes entries from the system registry. STDAPI DllUnregisterServer() { - return _AtlModule.DllUnregisterServer(); + return _AtlModule.DllUnregisterServer(FALSE); // skip TypeLib unregistration for consistency with DllRegisterServer } // DllInstall - Adds/Removes entries to the system registry per user per machine. diff --git a/SandboxTest/Main.cpp b/SandboxTest/Main.cpp index 5e88c3d..627ca7a 100644 --- a/SandboxTest/Main.cpp +++ b/SandboxTest/Main.cpp @@ -198,6 +198,21 @@ int wmain(int argc, wchar_t *argv[]) { } } + // register type library to enable out-of-proc Image3dAPI calls + // only works if running as admin + CComPtr typelib; + HRESULT hr = LoadTypeLibEx(L"Image3dAPI.tlb", REGKIND_REGISTER, &typelib); + CHECK(hr); + +#if 0 + // unregister type library + TLIBATTR * tlb_attr = nullptr; + CHECK(typelib->GetLibAttr(&tlb_attr)); + hr = UnRegisterTypeLib(tlb_attr->guid, tlb_attr->wMajorVerNum, tlb_attr->wMinorVerNum, tlb_attr->lcid, tlb_attr->syskind); + CHECK(hr); + typelib->ReleaseTLibAttr(tlb_attr); +#endif + // create loader in a separate "low integrity" dllhost.exe process CComPtr loader; CComPtr source;