199 lines
5.2 KiB
C++
199 lines
5.2 KiB
C++
|
//=======================================================================
|
||
|
//
|
||
|
// 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);
|
||
|
}
|