win32 message queue, multithreading, COM problem
 
Hello,
I am trying to get a simple program working that involves a console 
application that spawns a thread; the thread will call an ATL COM object, 
create a small dialog box and windows message queue, and loop until the user 
presses the escape key.  The COM object is created using STA model...I am 
calling it from child thread only.
I do not understand what is wrong here.  When I hit the escape key, the 
program goes into an infinite loop starting at the cleanup of the thread 
(CLEANUP02), runs past the ReleaseMutex call, and then resumes back at 
CLEANUP02.
The COM object was from a codeproject application Systemtraydemo.
Here is my source code:
#ifndef _MT
#define _MT
#endif
#include <windows.h>
#include "stdio.h"
#include <iostream>
#include "process.h"
#define INITGUID
#include <objbase.h>
#include "SystemTrayDemo.h"
#include "resource.h"
// global flag
bool bDone = false;
 // this function is called by a new thread
unsigned _stdcall InputThreadProc(LPVOID lpMutex)
{
            HANDLE hMutex = (HANDLE) lpMutex;
    // create the dialog window
    HWND hWnd = ::CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG),NULL,NULL);
    if ( hWnd!=NULL )
    {
        // show dialog
        ShowWindow(hWnd,SW_SHOW);
    }
    else
    {
        printf("Failed to create dialog\n");
        return -1;
    }
    // message loop to process user input
            // Create Icon here
            int count=0;
            std::cout<<"main: Entry"<<std::endl;
            IClassFactory *pCf;
            IUnknown *pUnk;
            IMyServer *pMyServer;
            HRESULT hr;
            std::cout<<"main: calling CoInitialize() \n"<<std::endl;
            hr=CoInitialize(NULL);
            if(FAILED(hr))
            {
               std::cout<<"main: CoInitialize Failed!\n"<<std::endl;
               exit(-1);
            }
            std::cout<<"main: CoInitialize OK\n"<<std::endl;
            std::cout<<"main: Calling CoGetClassObject\n"<<std::endl;
            hr=CoGetClassObject(CLSID_MyServer,CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory,(void**)&pCf);
            if(FAILED(hr))
            {
               std::cout<<"main: CoGetClassObject Failed!\n"<<std::endl;
               goto EXIT00;
            }
            std::cout<<"main: CoGetClassObject OK\n"<<std::endl;
            std::cout<<"main:  calling 
pCf->CreateInstance(NULL,IID_IUnknown,...)"<<std::endl;
            hr=pCf->CreateInstance(NULL,IID_IUnknown,(void**) &pUnk);
            if(FAILED(hr))
            {
               std::cout<<"main: pCf->CreateInstance(NULL,IID_IUnknown,...) 
Failed!\n"<<std::endl;
               goto CLEANUP00;
            }
            std::cout<<"main:  pCf->CreateInstance(NULL,IID_IUnknown,...) 
OK"<<std::endl;
            std::cout<<"main:  calling 
pUnk->QueryInterface(IID_IMyServer,...)"<<std::endl;
            hr=pUnk->QueryInterface(IID_IMyServer,(void**) &pMyServer);
            if(FAILED(hr))
            {
               std::cout<<"main: pUnk->QueryInterface(IID_IMyServer,...) 
Failed!\n"<<std::endl;
               goto CLEANUP01;
            }
               std::cout<<"main: pUnk->QueryInterface(IID_IMyServer,...) 
OK\n"<<std::endl;
               std::cout<<"main: Now Calling into the IMyServer 
Interface\n"<<std::endl;
            hr=pMyServer->Visible(VARIANT_TRUE);
            if(FAILED(hr))
            {
               std::cout<<"main: pMyServer->Visible() Failed!\n"<<std::endl;
               goto CLEANUP02;
            }
            hr=pMyServer->Animate(VARIANT_TRUE,200);
            if(FAILED(hr))
            {
               std::cout<<"main: pMyServer->Animate() Failed!\n"<<std::endl;
               goto CLEANUP02;
            }
            std::cout<<"main: pMyServer->Animate() OK!\n"<<std::endl;
    MSG msg;
    while(!bDone)
    {
                         GetMessage(&msg, NULL, 0, 0);
         if ( msg.message==WM_KEYUP )
         {
             int nVirtKey = (int) msg.wParam;
             // if the user pressed the ESCAPE key, then
             // print the text the user entered and quit
             if ( nVirtKey==VK_ESCAPE )
             {
                 DestroyWindow(hWnd);
                                 bDone = true;
                 break;
             }
         }
            // process message
         TranslateMessage(&msg);
         DispatchMessage(&msg);
    }
CLEANUP02:
            std::cout<<"main: calling IMyServer::Release"<<std::endl;
            if(pMyServer){
                                    pMyServer->Release();
                                    pMyServer = NULL;
            }
CLEANUP01:
            std::cout<<"main: calling IUnknown::Release"<<std::endl;
            if(pUnk){
                                    pUnk->Release();
                                    pUnk = NULL;
            }
CLEANUP00:
            std::cout<<"main: calling IClassFactory::Release"<<std::endl;
            if(pCf){
                        pCf->Release();
                        pCf = NULL;
            }
EXIT00:
            CoUninitialize();
            std::cout<<"main: We are done!"<<std::endl;
            ReleaseMutex(hMutex);
}
int main(int argc, char* argv[])
{
            HANDLE handle;
            HANDLE hMutex;
            unsigned uUnUsedThreadId;
    hMutex = CreateMutex(NULL,FALSE,NULL);
            if(hMutex==NULL)
            {
                        printf("Primary Thread - error calling 
CreateMutex().\n");
                        exit(0xFFFFFFFF);
            }
            // create a new thread to allow user input
            handle = (HANDLE) _beginthreadex(NULL,0,InputThreadProc, (void*) 
hMutex, 0, &uUnUsedThreadId);
    if( (int) handle==-1)
    {
        printf("Failed to create thread");
        return 0;
    }
    // wait for the new thread to finish
    handle = (HANDLE) WaitForSingleObject(handle,INFINITE);
            return 0;
}