windows-nt/Source/XPSP1/NT/enduser/windows.com/wuau/wuauclt/wrkthread.cpp
2020-09-26 16:20:57 +08:00

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);
}