CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2012
    Posts
    3

    [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.

  2. #2
    Join Date
    Oct 2012
    Posts
    3

    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?)

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: IShellDispatch: FolderItemVerbs? (Getting bizarre crash with CoUninitaialize!)

    Quote Originally Posted by MuldeR2 View Post
    (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:
    1. use Code tags, not PHP ones
    2. do NOT put more than one statements in one line

    Otherwise your code is hard to read/understand!
    Victor Nijegorodov

  4. #4
    Join Date
    Oct 2012
    Posts
    3

    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
  •  





Click Here to Expand Forum to Full Width

Featured