// JP opened flex table

Click to See Complete Forum and Search --> : CoInitialize/CoUninitialize


George2
June 24th, 2008, 08:10 AM
Hello everyone,


I want to develop an automatic tool or manually using existing tool (e.g. WinDbg) to watch when CoInitialize/CoUninitialize is called. I suspect CoUninitialize is not called the same times as CoInitialize, and I want to get the call stack.

Any ideas or reference documents about how to do this?

(I do not have the full source codes, but I have symbol files. My current ideas is either to add to system level COM Runtime hook to monitor when the two functions are called and get stack trace if possible, or using WinDbg to monitor the two specific function calls -- but I do not know the command in WinDbg. :-) )


thanks in advance,
George

Marc G
June 24th, 2008, 08:16 AM
Run it in or attach it to the Visual Studio debugger and add a breakpoint on the function names CoInitialize and CoUninitialize

George2
June 24th, 2008, 08:22 AM
Hi Marc!


CoInitialize and CoUninitialize are COM Runtime function, not my code. How can I use Visual Studio or WinDbg to set breakpoint on them?

Run it in or attach it to the Visual Studio debugger and add a breakpoint on the function names CoInitialize and CoUninitialize


regards,
George

Marc G
June 24th, 2008, 09:56 AM
Right, I wasn't thinking about that...
I'm not sure how to do this in Visual Studio then. But maybe the following article helps you to do what you want in WinDBG: http://www.tellingmachine.com/?tag=/breakpoint

George2
June 25th, 2008, 04:22 AM
Hi Marc,


What harm will be if an application calls CoInitialize multiple times, and
CoUninitialize only one time? Any leak?

Right, I wasn't thinking about that...
I'm not sure how to do this in Visual Studio then. But maybe the following article helps you to do what you want in WinDBG: http://www.tellingmachine.com/?tag=/breakpoint


regards,
George

Igor Vartanov
June 25th, 2008, 05:27 AM
First, you always can intercept imported entries
E:\Temp\135>exports ole32 | grep CoInitialize
0x00030D10 64 59 CoInitialize
0x0004C826 65 60 CoInitializeEx
0x00037553 66 61 CoInitializeSecurity
0x0009F5F8 67 62 CoInitializeWOW

E:\Temp\135>exports ole32 | grep CoUninitialize
0x0004CC89 110 105 CoUninitialize
Second, in your code you can avoid explicit initialization/uninitialization by using simple C++ trick
typedef struct _ComInit
{
HRESULT hr;
_ComInit() { hr = ::CoInitialize(NULL); }
~_ComInit() { if (SUCCEEDED(hr)) ::CoUninitialize(); }
} ComInit;
and use ComInit variable for your threads.
DWORD WINAPI MyThread(LPVOID pVoid)
{
ComInit comInit;
if (FAILED(comInit.hr))
return -1;
else
{
// here your code goes
. . .
}
return 0;
}
And there in ComInit you can easily set breakpoints, as you wish. :)

George2
June 25th, 2008, 05:43 AM
Thanks Igor,


Two more comments after some experiments,

1.

I have tried to set break point in WinDbg by using bm CoInitialize, it shows it resides in Kernel32.DLL -- Kernel32!CoInitialize other than Ole32!CoInitialize. The same to CoUninitialize.

Where actually does the two functions reside? Any comments?

2.

Using your wrapper code is good to control all codes in my own code. But I suspect it is not only my code which will call the two functions, but also some other code (my application depends on some DLL) will call the two functions.

Your wrapper could only catch function calls inside my own code, correct? Any ideas to monitor all calls to CoInitialize and CoUninitialize in all of my own code and all the DLLs' code which my application depends?

First, you always can intercept imported entries

Second, in your code you can avoid explicit initialization/uninitialization by using simple C++ trick
typedef struct _ComInit
{
HRESULT hr;
_ComInit() { hr = ::CoInitialize(NULL); }
~_ComInit() { if (SUCCEEDED(hr)) ::CoUninitialize(); }
} ComInit;
and use ComInit variable for your threads.
DWORD WINAPI MyThread(LPVOID pVoid)
{
ComInit comInit;
if (FAILED(comInit.hr))
return -1;
else
{
// here your code goes
. . .
}
return 0;
}
And there in ComInit you can easily set breakpoints, as you wish. :)


regards,
George

Igor Vartanov
June 25th, 2008, 06:38 AM
We've been talking about exported entry interception. There are no CoInitializeXxx/CoUnintialize entries exported from kernel32.dll. At least in my w2k3. :)

And yes, in the case when you have to spy on some foreign module calls, you have to go with Windows API interception.

George2
June 25th, 2008, 07:41 AM
Hi Igor,


I am also using Windows Server 2003. Two more comments,

1.

Could you try to set break point in WinDbg? Does it show Kernel32!CoInitialize or show Ole32!CoInitialize?

2.

About "Windows API interception" -- I heard of Detour Tools. What tools/technologies do you prefer to do Windows API interception?

We've been talking about exported entry interception. There are no CoInitializeXxx/CoUnintialize entries exported from kernel32.dll. At least in my w2k3. :)

And yes, in the case when you have to spy on some foreign module calls, you have to go with Windows API interception.


regards,
George

Igor Vartanov
June 25th, 2008, 09:07 AM
1. No, sorry I have no time to assist you in your investigation.
2. Sorry again, I never do API interception, so I have nothing to prefer. Google on "API hooking OR API interception"

//JP added flex table