|
|
//=======================================================================
//
// Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
//
// File: wrkthread.cpp
//
// Creator: PeterWi
//
// Purpose: Worker thread.
//
//=======================================================================
#include "pch.h"
#pragma hdrstop
const CLSID CLSID_CV3 = {0xCEBC955E,0x58AF,0x11D2,{0xA3,0x0A,0x00,0xA0,0xC9,0x03,0x49,0x2B}};
HANDLE CClientWrkThread::m_hEvtInstallDone = NULL;
//=======================================================================
//
// CClientWrkThread::~CClientWrkThread
//
// Destructor
//
//=======================================================================
CClientWrkThread::~CClientWrkThread() { SafeCloseHandleNULL(m_hEvtDirectiveStart); SafeCloseHandleNULL(m_hEvtDirectiveDone); SafeCloseHandleNULL(m_hEvtInstallDone); SafeCloseHandleNULL(m_hWrkThread); }
void CClientWrkThread::m_Terminate() { if (NULL != m_hWrkThread) { m_DoDirective(enWrkThreadTerminate); WaitForSingleObject(m_hWrkThread, INFINITE); } }
//=======================================================================
//
// CClientWrkThread::m_WorkerThread
//
// Client worker thread that does long duration activities.
//
//=======================================================================
DWORD WINAPI CClientWrkThread::m_WorkerThread(void * lpParameter) { // HRESULT hr;
CClientWrkThread * pWrkThread = (CClientWrkThread *)lpParameter; DWORD dwRet = 0;
DEBUGMSG("WUAUCLT: Installation worker thread starting");
if ( FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) ) { DEBUGMSG("m_WorkerThread() fails to initialize COM"); return 1; }
SetEvent(pWrkThread->m_hEvtDirectiveDone);
DEBUGMSG("WUAUCLT: Installation worker thread waiting for directive");
// wait for directive or termination of client.
do { if ( SUCCEEDED(pWrkThread->m_WaitForDirective()) ) { switch ( pWrkThread->m_enDirective ) { case enWrkThreadInstall: case enWrkThreadAutoInstall: { DEBUGMSG("m_WorkerThread() doing install"); HRESULT hr = gpClientCatalog->InstallItems(enWrkThreadAutoInstall == pWrkThread->m_enDirective); SetEvent(m_hEvtInstallDone); if (S_OK != hr) { //install failed or nothing to install
QUITAUClient(); goto done; } break; }
case enWrkThreadTerminate: DEBUGMSG("m_WorkerThread() terminating"); goto done; break;
default: DEBUGMSG("ClientWrkThread: bad directive %d", pWrkThread->m_enDirective); break; } } else { dwRet = 1; // FAIL //fixcode: nobody look at this
QUITAUClient(); goto done; } } while (1);
done: DEBUGMSG("WUAUCLT CClientWrkThread::m_WorkerThread releasing");
CoUninitialize();
DEBUGMSG("WUAUCLT: Worker thread ended, ret = %lu", dwRet);
return dwRet; }
//=======================================================================
//
// CClientWrkThread::m_Init
//
// Init routine to do things that can fail.
//
//=======================================================================
HRESULT CClientWrkThread::m_Init(void) { DWORD dwID;
if ( (NULL == (m_hEvtDirectiveStart = CreateEvent(NULL, FALSE, FALSE, NULL))) || (NULL == (m_hEvtDirectiveDone = CreateEvent(NULL, FALSE, FALSE, NULL))) || (NULL == (m_hEvtInstallDone = CreateEvent(NULL, FALSE, FALSE, NULL))) || (NULL == (m_hWrkThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CClientWrkThread::m_WorkerThread, (LPVOID)this /*m_pCatalog*/, 0, &dwID)))) { return HRESULT_FROM_WIN32(GetLastError()); }
CONST HANDLE grHandles[] = { m_hEvtDirectiveDone, m_hWrkThread }; DWORD dwRet = WaitForMultipleObjects(ARRAYSIZE(grHandles), grHandles, FALSE, INFINITE);
// thread only returns on failure
if ( (WAIT_OBJECT_0 + 1) == dwRet ) { return E_FAIL; } else if (WAIT_FAILED == dwRet) { return HRESULT_FROM_WIN32(GetLastError()); }
return S_OK; }
//=======================================================================
//
// ClientWrkThread::m_WaitForDirective
//
// Routine that worker thread waits with for a new directive.
//
//=======================================================================
HRESULT CClientWrkThread::m_WaitForDirective(void) { DWORD dwRet = WaitForSingleObject(m_hEvtDirectiveStart, INFINITE);
return (WAIT_OBJECT_0 == dwRet) ? S_OK : E_FAIL; }
//=======================================================================
//
// ClientWrkThread::m_DoDirective
//
// Method to tell thread to start doing directive.
//
//=======================================================================
void CClientWrkThread::m_DoDirective(enumWrkThreadDirective enDirective) { m_enDirective = enDirective; SetEvent(m_hEvtDirectiveStart); }
/////////////////////////////////////////////////////////////////////////////////////////////
// wait until installation is done
////////////////////////////////////////////////////////////////////////////////////////////
void CClientWrkThread::WaitUntilDone() { WaitForSingleObject(m_hEvtInstallDone, INFINITE); }
|