October 22nd, 2012 01:47 PM
#1
[RESOLVED] IShellDispatch: FolderItemVerbs? (Getting bizarre crash with CoUninitaialize!)
Hi!
I hope this is the correct sub-forum to post this issue.
I'm having a very bizarre problem with the IShellDispatch COM interface, more specifically with the FolderItemVerbs that drives me nuts!
Calling FolderItemVerbs::Release() followed by CoUninitialze() will result in crash. It's clearly reproducible, but only happens 1 out of 10 times
Running the problematic code in a loop 100% reproduces the crash
Please see the example program:
Code:
static int TestProc(const TCHAR *pcDirectoryName, const TCHAR *pcFileName)
{
int iSuccess = 0;
IShellDispatch *pShellDispatch = NULL;
Folder *pFolder = NULL; FolderItem *pItem = NULL;
FolderItemVerbs *pVerbs = NULL;
HRESULT hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void**)&pShellDispatch);
if(FAILED(hr) || (pShellDispatch == NULL))
{
iSuccess = -3;
return iSuccess;
}
variant_t vaDirectory(pcDirectoryName);
hr = pShellDispatch->NameSpace(vaDirectory, &pFolder);
if(FAILED(hr) || (pFolder == NULL))
{
iSuccess = -4;
pShellDispatch->Release();
return iSuccess;
}
variant_t vaFileName(pcFileName);
hr = pFolder->ParseName(vaFileName, &pItem);
if(FAILED(hr) || (pItem == NULL))
{
iSuccess = -5;
pFolder->Release();
pShellDispatch->Release();
return iSuccess;
}
hr = pItem->Verbs(&pVerbs);
if(FAILED(hr) || (pVerbs == NULL))
{
iSuccess = -6;
pItem->Release();
pFolder->Release();
pShellDispatch->Release();
return iSuccess;
}
/* Here we would do something with the FolderItemVerbs */
pVerbs->Release(); //If this line is commented out, we don't get a crash, but a massive memory leak!
pVerbs = NULL;
pItem->Release();
pItem = NULL;
pFolder->Release();
pFolder = NULL;
pShellDispatch->Release();
pShellDispatch = NULL;
iSuccess = 1;
return iSuccess;
}
//-----------------------------------------------------------------------------
static unsigned __stdcall ThreadProc(void* pArguments)
{
HRESULT hr = CoInitialize(NULL);
if((hr == S_OK) || (hr == S_FALSE))
{
threadParam_t *params = (threadParam_t*) pArguments;
params->returnValue = TestProc(params->pcDirectoryName, params->pcFileName);
CoUninitialize();
}
else
{
if(threadParam_t *params = (threadParam_t*) pArguments)
{
params->returnValue = -10;
}
}
return EXIT_SUCCESS;
}
Please download the *complete* example code is here:
http://pastie.org/private/0xsnajpia9lsmgnlf2afa
Please also note that I unambiguously tracked down to crash to FolderItemVerbs , because if I never create the FolderItemVerbs object, the crash is gone immediately.
Also if I never call "pVerbs->Release()" before CoUninitialize() the crash is gone too, but this will result in a massive memleak, obviously.
Another strange thing is that the crash will NOT happen, if I run the program under the Debugger! But I can run the program, wait for the crash and then let the Debugger handle the crash.
Unfortunately the Stack Trace that I get then doesn't help much:
http://pastie.org/private/cuwunlun2t5dc5lembpw
I don't think I'm doing anything wrong here. I have checked the code over and over again in the last two days. So this all seems to be a bug in FolderItemVerbs!
Has anybody encountered this before and/or can confirm that this is a bug in FolderItemVerbs? Also, is there any workaround for the problem?
Thanks in advance !!!
Last edited by MuldeR2; October 23rd, 2012 at 06:27 AM .
October 22nd, 2012 02:06 PM
#2
Re: IShellDispatch: FolderItemVerbs? (Getting bizarre crash with CoUninitaialize!)
Sorry, forgot to mention: The crash is an "0xC0000005: Access Violation" error.
(BTW: Am I blind or is there really no "Edit" button on this forum?)
October 22nd, 2012 02:37 PM
#3
Re: IShellDispatch: FolderItemVerbs? (Getting bizarre crash with CoUninitaialize!)
Originally Posted by
MuldeR2
(BTW: Am I blind or is there really no "Edit" button on this forum?)
Edit button will appear after about five your posts.
And please:use Code tags, not PHP ones
do NOT put more than one statements in one line
Otherwise your code is hard to read/understand!
Victor Nijegorodov
October 23rd, 2012 06:16 AM
#4
Re: [RESOLVED] IShellDispatch: FolderItemVerbs? (Getting bizarre crash with CoUninita
Okay, got the answer elsewehre.
It turns out this was caused by a "problematic" Shell Extension. In my case it was Tortoise GIT.
And it could be resolved by explicitely dispacthing all messages before CoUninitialize().
Code:
static int TestProc(const TCHAR *pcDirectoryName, const TCHAR *pcFileName)
{
/*see above*/
}
static void DispatchPendingMessages(void)
{
const DWORD uiTimeout = GetTickCount() + 10000;
const HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
unsigned int counter = 0;
if(hEvent)
{
for(;;)
{
MSG Message;
while(PeekMessage(&Message, NULL, WM_NULL, WM_NULL, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
const DWORD nWaitResult = MsgWaitForMultipleObjects(1, &hEvent, FALSE, 250, QS_ALLINPUT | QS_ALLPOSTMESSAGE);
if((nWaitResult == WAIT_TIMEOUT) || (nWaitResult == WAIT_FAILED) || (GetTickCount() >= uiTimeout)) break;
}
CloseHandle(hEvent);
}
}
static unsigned __stdcall ThreadProc(void* pArguments)
{
HRESULT hr = CoInitialize(NULL);
if((hr == S_OK) || (hr == S_FALSE))
{
threadParam_t *params = (threadParam_t*) pArguments;
params->returnValue = TestProc(params->pcDirectoryName, params->pcFileName);
DispatchPendingMessages(); //This is required before CoUninitialize() to avoid crash with certain Shell Extensions !!!
CoUninitialize();
}
else
{
if(threadParam_t *params = (threadParam_t*) pArguments)
{
params->returnValue = -10;
}
}
return EXIT_SUCCESS;
}
Last edited by MuldeR2; October 23rd, 2012 at 06:25 AM .
Posting Permissions
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Rules
Click Here to Expand Forum to Full Width
Bookmarks