Windows / C ++: how to use a COM DLL that is not registered

In our application, we need to use COM-dll (namely msdia100.dll), which was not previously registered in the system.

Earler, we just named the DLL by calling it DllRegisterServer through this code:

// Register DIA DLL required by Breakpad std::string diaLibPath = "msdia100"; HMODULE diaLib = LoadLibrary(diaLibPath.c_str()); if( diaLib == NULL ) { errors << "Cannot load DLL " << diaLibPath << endl; return; } typedef HRESULT ( __stdcall * regServer_t )(void); regServer_t regServer = (regServer_t)GetProcAddress(diaLib, "DllRegisterServer"); if( regServer == NULL ) { errors << "Cannot get method DllRegisterServer from " << diaLibPath << endl; FreeLibrary(diaLib); return; } if( regServer() != S_OK ) { errors << "Cannot call DllRegisterServer from " << diaLibPath << endl; } FreeLibrary(diaLib); 

This no longer works on Windows 7 (Vista may not have tried it either) because it needs administrator privileges to call this function.

I found all solutions to this problem, where about obtaining these administrator rights. This is not a possible solution for us, because our application should also work if the user cannot obtain these administrator rights.

For us, we also donโ€™t need to suddenly need an installer for our application that registers this DLL.

So what are the possibilities? How can I use this DLL without administrator privileges? Should I recode a COM that works without having to register the DLL first?


The code in which I use this library is as follows:

 CComPtr<IDiaDataSource> data_source; if (FAILED(data_source.CoCreateInstance(CLSID_DiaSource))) { fprintf(stderr, "CoCreateInstance CLSID_DiaSource failed " "(msdia80.dll unregistered?)\n"); return false; } 

(Btw., For those interested: it's part of the Google Breakpad.)

+4
source share
2 answers

A simple approach is to use LoadLibrary ("msdia100.dll") to directly load the DLL. Then use GetProcAddress ("DllGetClassObject"). You can then use IClassFactory to execute the CoCreateInstance equivalent.

So, something like the following. (Disclaimer: I did not compile this ...)

 HRESULT CoCreateDiaDataSource(CComPtr<IDiaDataSource>& data_source) { HMODULE hmodule = LoadLibrary("MSDIA100"); if (!hmodule) return HRESULT_FROM_WIN32(GetLastError()); // library not found BOOL (WINAPI*DllGetClassObject)(REFCLSID,REFIID,LPVOID*) = (BOOL(WINAPI*)(REFCLSID,REFIID,LPVOID*))GetProcAddress(hmodule, "DllGetClassObject"); if (!DllGetClassObject) return HRESULT_FROM_WIN32(GetLastError()); CComPtr<IClassFactory> pClassFactory; HRESULT hr = DllGetClassObject(CLSID_DiaSource, IID_IClassFactory, &pClassFactory); if (FAILED(hr)) return hr; hr = pClassFactory->CreateInstance(NULL, IID_IDiaDataSource, (void**)&data_source); if (FAILED(hr)) return hr; return S_OK; } 

Notes:

  • In a LoadLibrary call, you may need to specify a path. I do not know where MSDIA100.DLL usually resides.

  • I do not know what MSDIA100.DLL does. Not all COM DLLs will work with this method, especially if they rely on COM for free flow and sorts and terrible things like this. However, most COM libraries are simply simple in the apartment and work great in my experience.

+8
source

I think you should try registering for free COM. See: http://msdn.microsoft.com/en-us/library/ms973913.aspx

[edit] In addition, I found a link to a discussion stating that only LoadLibrary will be executed. I canโ€™t confirm that this works from my own experience. See: http://www.eggheadcafe.com/forumarchives/win32programmerole/Dec2005/post25120399.asp

+5
source

Source: https://habr.com/ru/post/1304413/


All Articles