CoInitialize() has not been called exceptions in C++ - c++

-My problem
I got CoInitialize has not been called exption.
-My project structure
Here is my porblem. I have a COM dll, MCLWrapper.dll developped with C#; I have a nother native C++ dll, ThorDetectorSwitch.dll that calls MCLWrapper.dll; And finally, I have a console application TDSTest.exe that calls ThorDetectorSwitch.dll. Basically, something like this:
TDSTest.exe (C++ console) -> ThorDetectorSwitch.dll (C++ native) -> MCLWrapper.dll (C#)
Code in TDSTest.exe that loads the ThorDetectorSwitch.dll:
HINSTANCE hInst = LoadLibrary(_T("C:\\TIS_Nick\\Hardware\\Devices\\ThorDetectorSwitch\\TDSTest\\TDSTest\\Debug\\Modules_Native\\ThorDetectorSwitch.dll"));
Constructor in ThorDetectorSwitch.cpp
ThorDetectorSwitch::ThorDetectorSwitch() : _mcSwitch(__uuidof(MCLControlClass))
{
_A = WstringToBSTR(L"A");
_B = WstringToBSTR(L"B");
_C = WstringToBSTR(L"C");
_D = WstringToBSTR(L"D");
_deviceDetected = FALSE;
}
The break point hits the first parenthesis of the constructor of the ThorDetectorSwitch.dll above, but the exception occurred immediately if I hit F10 (one more step)
It jumps to
hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
in the comip.h. The hr is simply "CoInitialize has not been called".
I have been thinking abou this porblem for days, and cannot figure out a solution. Anyone here can sharing any thoughts? Really appreciate it.

Your COM dll requires you to be in Single-Threaded Apartment mode. You need to call CoInitialize prior to using it.
Add this to your .exe:
CoInitialize(nullptr); // NULL if using older VC++
HINSTANCE hInst = LoadLibrary(_T("C:\\TIS_Nick\\...

Related

MFC assertion failed when debugging

I'm not familiar with MFC but currently I must continue a project that was written in MFC. Now I'm having trouble with the following line when debugging
m_hIcon = AfxGetApp()->LoadIcon (IDR_MAINFRAME);
It always stops after the error "Assertion Failed: at afxwin1.inl". If I put a breakpoint there I saw a NULL icon handle. I tried running in release mode and it worked just fine although the handle is still NULL. I've read this question but my program is not a static library. It's a program that use a dll to connect to a CAN bus device. And the resource IDR_MAINFRAME is already in the project. It contains the default MFC icons. How can I solve this problem?
I've tried debugging and see that pModuleState changes between the first load program name call and the second load icon call. The first call returns successfully because pModuleState points to an object that has valid handle. But in the icon load call, pModuleState points to some object contains NULL handle. I also tried putting AFX_MANAGE_STATE(AfxGetStaticModuleState( )); right above the LoadIcon() call but the problem still arises
I've known the cause of this problem
UINT __cdecl RunCPRead(LPVOID pParam)
{
CMyDlg *thisclass = (CMyDlg *)pParam;
while (thisclass->m_Start)
{
thisclass->GetData();
}
return 0;
}
AfxBeginThread(&RunCPRead, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
After the GetData() call in RunCPRead, the control flows directly to CMyDlg's contructor although there's no object being created or copied
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
and then fails at the assignment to m_hIcon with the error "access violation while reading". I've seen the disassembly, it was the line mov dword ptr [esi+90h], eax and it's inherently a write to memory.
I don't know why. How can I solve this?
The MFC code need the correct module handle to load the resource.
Please try to read Afx*G/S*etResourceHandle.
By default MFC uses the resource handle of the main application, not of the DLL. If you are making the call in the DLL then add this line at the start of the exported DLL function:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
There is more information about this here:
http://msdn.microsoft.com/en-us/library/ba9d5yh5(v=vs.110).aspx
Assertion Errors in MFC usually happens when wrong settings are set.
go to project settings > linker > System and change subsystem to (/SUBSYSTEM:WINDOWS) this solution solved my own problem.

MFC app Assert fail at CRecentFileList::Add on Command line FileOpen

I'm using VS2010 and Windows 7, and my app is SDI shared DLL, upgraded from VC6. After installing my application, if the user double-clicks the registered file type, the application crashes at the MFC function:
void CRecentFileList::Add(LPCTSTR lpszPathName, LPCTSTR lpszAppID)
{
// ...
#if (WINVER >= 0x0601)
// ...
#ifdef UNICODE
// ...
#endif
ENSURE(SUCCEEDED(hr)); // Crash here: "hr = 0x800401f0 CoInitialize has not been called."
This is called from the InitInstance() function:
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
//CString str = cmdInfo.m_strFileName + '\n';
//MessageBox(NULL,str, "MyApp", MB_OK|MB_ICONWARNING);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
The user's chosen file is correctly passed through (as I checked with the MessageBox).
The hr = 0x800401f0 seems to be a COM problem (here), but I'm not using COM or ATL. The assertion is the same as this, but from a different cause. The Germans had the same problem as me (here), but I can't understand the google translation (here)!! I don't think it's a WINVER issue (here) and I don't want to parse my own stuff (like this), just have the application open when a user double clicks a file.
Thanks for any help you can offer :)
The comment you inserted in your code contains the answer:
// Crash here: "hr = 0x800401f0 CoInitialize has not been called."
The HRESULT value is telling you that you need to call the CoInitialize function in order to initialize the COM library for your application's thread.
Of course, the message is a little bit outdated. As you'll see in the above-linked documentation, all new applications should call the CoInitializeEx function instead. No worries, though: it does essentially the same thing as its older brother.
As the "Remarks" section of the documentation indicates:
CoInitializeEx must be called at least once, and is usually called only once, for each thread that uses the COM library. [. . . ] You need to initialize the COM library on a thread before you call any of the library functions except CoGetMalloc, to get a pointer to the standard allocator, and the memory allocation functions. Otherwise, the COM function will return CO_E_NOTINITIALIZED.
You say that you're not using COM, but this is incorrect. You may not be using it explicitly, but Windows and the MFC framework are definitely using it "behind the scenes". All of the file type registration functions rely on COM. The skeleton code produced by the MFC project wizard in Visual Studio 2010 would have automatically inserted the appropriate COM registration code, but since you upgraded an existing project from VC++ 6, you appear to be missing this vital step.
In MFC, the AfxOleInit function also initializes COM for the current apartment of the calling app, just as the OleInitialize function does internally. Make sure that your overridden InitInstance function contains a call to one of these functions.
For example, in a fresh new MFC project created by the VS 2010 wizard, the InitInstance function looks something like this:
BOOL CTestApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
// Initialize OLE libraries
if (!AfxOleInit()) // ** MAKE SURE THAT YOU CALL THIS!! **
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// . . .
// a bunch more boring initialization stuff...
// The one and only window has been initialized, so show and update it
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
}

In MFC APP, if I call "LoadLibraryA" from "InitInstance", it calls "InitInstance" again and again

I have created an MFCApp using VS2008 wizard. Inside my application's "InitInstance()" I'm calling "LoadLibraryA()" method as I need to load a few dll files. But as soon as I call "LoadLibraryA()", it again calls "InitInstance()" of my application and hence it becomes a infinite recursion stuff. Is there something I'm doing wrong?
// CLoader_MFCApp initialization
BOOL CLoader_MFCApp::InitInstance()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance();
SetRegistryKey(_T("MyApp"));
HMODULE hm = LoadLibraryA("./abc/def.dll");
// after above line InitInstance() gets called again
// more code
return FALSE;
}
Call Stack:
MyApp.exe!CLoader_MFCApp::InitInstance() C++
CORE.dll!InternalDllMain(HINSTANCE__ *, unsigned long, void *) C++
CORE.dll!__DllMainCRTStartup(void *, unsigned long, void *) C
CORE.dll!_DllMainCRTStartup(void *, unsigned long, void *) C
ntdll.dll!_LdrpCallInitRoutine#16()
ntdll.dll!_LdrpRunInitializeRoutines#4()
ntdll.dll!_LdrpLoadDll#24()
ntdll.dll!_LdrLoadDll#16()
kernel32.dll!_LoadLibraryExW#12()
kernel32.dll!_LoadLibraryExA#12()
kernel32.dll!_LoadLibraryA#4()
MyApp.exe!CLoader_MFCApp::InitInstance() C++
mfc90.dll!AfxWinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int) C++
MyApp.exe!__tmainCRTStartup() C
kernel32.dll!_BaseProcessStart#4()
"Def.dll" is any other dll and completely unrelated from MyApp. In this case, I'm trying to load another dll "CORE.dll"
All I can figure out is that I'm calling LoadLibrary before InitInstance routine is over. Is there any other (overridable) method which is called after InitInstance??? If so, I can try moving LoadLibrary calls to that method...
Yes, you are doing something wrong.
You are in mfc90.dll's DllMain and it is not safe to call LoadLibrary from DllMain, says so right here:
http://msdn.microsoft.com/en-us/library/ms684175%28v=vs.85%29.aspx
This is more of a workaround than a true solution (i.e. I don't know the rules for LoadLibrary in MFC, as I've never read anything to say you can't, nor do I happen to use this technique in our MFC code).
However, Generally speaking, if windows coughs up a hairball due to order of operations, I just move the calls out to another message handler. You can even post a thread message to your application, and write a handler for that message.
Something like:
// in InitInstance - post a message to our main thread to handle after init instance...
PostMessage(NULL, WM_PostInit);
// in your message table
ON_THREAD_MESSAGE(WM_PostInit, OnPostInit)
// in your app
void MyApp::OnPostInit(WPARAM,LPARAM) // both args unused
{
// try load library now...!
}
NOTE: The above is "brain code" - untested. Details undoubtedly need to be massaged for full compilability.
References:
http://msdn.microsoft.com/en-us/library/ms644944%28v=VS.85%29.aspx
I've just had the same issue, caused by the Configuration type being incorrectly set to exe not dll for the dll to be loaded.
Fix: Project -> Configuration Properties -> General -> Configuration Type = Dynamic Library (.dll) (was incorrectly set to Application (.exe))

Hooking DirectX EndScene from an injected DLL

I want to detour EndScene from an arbitrary DirectX 9 application to create a small overlay. As an example, you could take the frame counter overlay of FRAPS, which is shown in games when activated.
I know the following methods to do this:
Creating a new d3d9.dll, which is then copied to the games path. Since the current folder is searched first, before going to system32 etc., my modified DLL gets loaded, executing my additional code.
Downside: You have to put it there before you start the game.
Same as the first method, but replacing the DLL in system32 directly.
Downside: You cannot add game specific code. You cannot exclude applications where you don't want your DLL to be loaded.
Getting the EndScene offset directly from the DLL using tools like IDA Pro 4.9 Free. Since the DLL gets loaded as is, you can just add this offset to the DLL starting address, when it is mapped to the game, to get the actual offset, and then hook it.
Downside: The offset is not the same on every system.
Hooking Direct3DCreate9 to get the D3D9, then hooking D3D9->CreateDevice to get the device pointer, and then hooking Device->EndScene through the virtual table.
Downside: The DLL cannot be injected, when the process is already running. You have to start the process with the CREATE_SUSPENDED flag to hook the initial Direct3DCreate9.
Creating a new Device in a new window, as soon as the DLL gets injected. Then, getting the EndScene offset from this device and hooking it, resulting in a hook for the device which is used by the game.
Downside: as of some information I have read, creating a second device may interfere with the existing device, and it may bug with windowed vs. fullscreen mode etc.
Same as the third method. However, you'll do a pattern scan to get EndScene.
Downside: doesn't look that reliable.
How can I hook EndScene from an injected DLL, which may be loaded when the game is already running, without having to deal with different d3d9.dll's on other systems, and with a method which is reliable? How does FRAPS for example perform it's DirectX hooks?
The DLL should not apply to all games, just to specific processes where I inject it via CreateRemoteThread.
You install a system wide hook. (SetWindowsHookEx) With this done, you get to be loaded into every process.
Now when the hook is called, you look for a loaded d3d9.dll.
If one is loaded, you create a temporary D3D9 object, and walk the vtable to get the address of the EndScene method.
Then you can patch the EndScene call, with your own method. (Replace the first instruction in EndScene by a call to your method.
When you are done, you have to patch the call back, to call the original EndScene method. And then reinstall your patch.
This is the way FRAPS does it. (Link)
You can find a function address from the vtable of an interface.
So you can do the following (Pseudo-Code):
IDirect3DDevice9* pTempDev = ...;
const int EndSceneIndex = 26 (?);
typedef HRESULT (IDirect3DDevice9::* EndSceneFunc)( void );
BYTE* pVtable = reinterpret_cast<void*>( pTempDev );
EndSceneFunc = pVtable + sizeof(void*) * EndSceneIndex;
EndSceneFunc does now contain a pointer to the function itself. We can now either patch all call-sites or we can patch the function itself.
Beware that this all depends on the knowledge of the implementation of COM-Interfaces in Windows. But this works on all windows versions (either 32 or 64, not both at the same time).
I know this question is old, but this should work for any program using DirectX9, You are creating your own instance basically, and then getting the pointer to the VTable, then you just hook it. You will need detours 3.X btw:
//Just some typedefs:
typedef HRESULT (WINAPI* oEndScene) (LPDIRECT3DDEVICE9 D3DDevice);
static oEndScene EndScene;
//Do this in a function or whatever
HMODULE hDLL=GetModuleHandleA("d3d9");
LPDIRECT3D9(__stdcall*pDirect3DCreate9)(UINT) = (LPDIRECT3D9(__stdcall*)(UINT))GetProcAddress( hDLL, "Direct3DCreate9");
LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm;
HRESULT hRes = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm );
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,TempWndProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,("1"),NULL};
RegisterClassEx(&wc);
HWND hWnd = CreateWindow(("1"),NULL,WS_OVERLAPPEDWINDOW,100,100,300,300,GetDesktopWindow(),NULL,wc.hInstance,NULL);
hRes = pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT,
&d3dpp, &ppReturnedDeviceInterface);
pD3D->Release();
DestroyWindow(hWnd);
if(pD3D == NULL){
//printf ("WARNING: D3D FAILED");
return false;
}
pInterface = (unsigned long*)*((unsigned long*)ppReturnedDeviceInterface);
EndScene = (oEndScene) (DWORD) pInterface[42];
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)EndScene, newEndScene);
DetourTransactionCommit();
And then your function:
HRESULT WINAPI D3D9Hook::newEndScene(LPDIRECT3DDEVICE9 pDevice)
{
//Do your stuff here
//Call the original (if you want)
return EndScene(pDevice);
}
A slightly old question I know - but in case anyone is interested in doing this with C#, here is my example on hooking the Direct3D 9 API using C#. This utilizes EasyHook an open source .NET assembly that allows you to 'safely' install hooks from managed code into unmanaged functions. (Note: EasyHook takes care of all the issues surrounding DLL injection - e.g. CREATE_SUSPENDED, ACL's, 32 vs 64-bit and so on)
I use a similar VTable approach as mentioned by Christopher via a small C++ helper dll to dynamically determine the address of the IDirect3DDevice9 functions to hook. This is done by creating a temporary window handle, and creating a throw-away IDirect3Device9 within the injected assembly before then hooking the desired functions. This allows your application to hook a target that is already running (Update: note that this is possible entirely within C# also - see comments on the linked page).
Update: there is also an updated version for hooking Direct3D 9, 10 and 11 still using EasyHook and with SharpDX instead of SlimDX

Explicit Linking DLL and Program Hangs

I've the following piece of code in my program which dynamically links wtsapi32.dll file for session notifications like WTS_SESSION_LOCK and WTS_SESSION_UNLOCK and runs in background. After the first lock/unlock the program hangs and not responding.
Is this a right way of doing explicit linking ?
void RegisterSession(HWND hwnd)
{
typedef DWORD (WINAPI *tWTSRegisterSessionNotification)( HWND,DWORD );
tWTSRegisterSessionNotification pWTSRegisterSessionNotification=0;
HINSTANCE handle = ::LoadLibrary("wtsapi32.dll");
pWTSRegisterSessionNotification = (tWTSRegisterSessionNotification) :: GetProcAddress(handle,"WTSRegisterSessionNotification");
if (pWTSRegisterSessionNotification)
{
pWTSRegisterSessionNotification(hwnd,NOTIFY_FOR_THIS_SESSION);
}
::FreeLibrary(handle);
handle = NULL;
}
Edited:
I have another method UnRegisterSession() function which calls WTSUnRegisterSessionNotification, I am calling the RegisterSession() in WinMain method ( removed FreeLibrary as suggested by 1800) and calling UnRegisterSession() in WM_DESTROY of CALLBACK WindowProcedure function. But still the application hangs.
I'd say you probably cannot safely call FreeLibrary like that - you will be unloading the code you want to have call you. You should probably ensure not to free the dll until after you are finished getting notifications.
MS documentation suggests that you must call WTSUnRegisterSessionNotification before re-registering the session - as it only happens on your second attempt to lock it perhaps this is your issue?
With 1800 wrt the free library - you must keep this library loaded while you use it.
According to the documentation (http://msdn.microsoft.com/en-us/library/aa383841(VS.85).aspx):
"When a window no longer requires these notifications, it must call WTSUnRegisterSessionNotification before being destroyed."
I would try unregistering the notification during WM___CLOSE instead of WM_DESTROY.