Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.2 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: wrkthread.cpp
  6. //
  7. // Creator: PeterWi
  8. //
  9. // Purpose: Worker thread.
  10. //
  11. //=======================================================================
  12. #include "pch.h"
  13. #pragma hdrstop
  14. const CLSID CLSID_CV3 = {0xCEBC955E,0x58AF,0x11D2,{0xA3,0x0A,0x00,0xA0,0xC9,0x03,0x49,0x2B}};
  15. HANDLE CClientWrkThread::m_hEvtInstallDone = NULL;
  16. //=======================================================================
  17. //
  18. // CClientWrkThread::~CClientWrkThread
  19. //
  20. // Destructor
  21. //
  22. //=======================================================================
  23. CClientWrkThread::~CClientWrkThread()
  24. {
  25. SafeCloseHandleNULL(m_hEvtDirectiveStart);
  26. SafeCloseHandleNULL(m_hEvtDirectiveDone);
  27. SafeCloseHandleNULL(m_hEvtInstallDone);
  28. SafeCloseHandleNULL(m_hWrkThread);
  29. }
  30. void CClientWrkThread::m_Terminate()
  31. {
  32. if (NULL != m_hWrkThread)
  33. {
  34. m_DoDirective(enWrkThreadTerminate);
  35. WaitForSingleObject(m_hWrkThread, INFINITE);
  36. }
  37. }
  38. //=======================================================================
  39. //
  40. // CClientWrkThread::m_WorkerThread
  41. //
  42. // Client worker thread that does long duration activities.
  43. //
  44. //=======================================================================
  45. DWORD WINAPI CClientWrkThread::m_WorkerThread(void * lpParameter)
  46. {
  47. // HRESULT hr;
  48. CClientWrkThread * pWrkThread = (CClientWrkThread *)lpParameter;
  49. DWORD dwRet = 0;
  50. DEBUGMSG("WUAUCLT: Installation worker thread starting");
  51. if ( FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) )
  52. {
  53. DEBUGMSG("m_WorkerThread() fails to initialize COM");
  54. return 1;
  55. }
  56. SetEvent(pWrkThread->m_hEvtDirectiveDone);
  57. DEBUGMSG("WUAUCLT: Installation worker thread waiting for directive");
  58. // wait for directive or termination of client.
  59. do
  60. {
  61. if ( SUCCEEDED(pWrkThread->m_WaitForDirective()) )
  62. {
  63. switch ( pWrkThread->m_enDirective )
  64. {
  65. case enWrkThreadInstall:
  66. case enWrkThreadAutoInstall:
  67. {
  68. DEBUGMSG("m_WorkerThread() doing install");
  69. HRESULT hr = gpClientCatalog->InstallItems(enWrkThreadAutoInstall == pWrkThread->m_enDirective);
  70. SetEvent(m_hEvtInstallDone);
  71. if (S_OK != hr)
  72. {
  73. //install failed or nothing to install
  74. QUITAUClient();
  75. goto done;
  76. }
  77. break;
  78. }
  79. case enWrkThreadTerminate:
  80. DEBUGMSG("m_WorkerThread() terminating");
  81. goto done;
  82. break;
  83. default:
  84. DEBUGMSG("ClientWrkThread: bad directive %d", pWrkThread->m_enDirective);
  85. break;
  86. }
  87. }
  88. else
  89. {
  90. dwRet = 1; // FAIL //fixcode: nobody look at this
  91. QUITAUClient();
  92. goto done;
  93. }
  94. } while (1);
  95. done:
  96. DEBUGMSG("WUAUCLT CClientWrkThread::m_WorkerThread releasing");
  97. CoUninitialize();
  98. DEBUGMSG("WUAUCLT: Worker thread ended, ret = %lu", dwRet);
  99. return dwRet;
  100. }
  101. //=======================================================================
  102. //
  103. // CClientWrkThread::m_Init
  104. //
  105. // Init routine to do things that can fail.
  106. //
  107. //=======================================================================
  108. HRESULT CClientWrkThread::m_Init(void)
  109. {
  110. DWORD dwID;
  111. if ( (NULL == (m_hEvtDirectiveStart = CreateEvent(NULL, FALSE, FALSE, NULL)))
  112. || (NULL == (m_hEvtDirectiveDone = CreateEvent(NULL, FALSE, FALSE, NULL)))
  113. || (NULL == (m_hEvtInstallDone = CreateEvent(NULL, FALSE, FALSE, NULL)))
  114. || (NULL == (m_hWrkThread = CreateThread(NULL,
  115. 0,
  116. (LPTHREAD_START_ROUTINE)CClientWrkThread::m_WorkerThread,
  117. (LPVOID)this /*m_pCatalog*/,
  118. 0,
  119. &dwID))))
  120. {
  121. return HRESULT_FROM_WIN32(GetLastError());
  122. }
  123. CONST HANDLE grHandles[] = { m_hEvtDirectiveDone, m_hWrkThread };
  124. DWORD dwRet = WaitForMultipleObjects(ARRAYSIZE(grHandles), grHandles, FALSE, INFINITE);
  125. // thread only returns on failure
  126. if ( (WAIT_OBJECT_0 + 1) == dwRet )
  127. {
  128. return E_FAIL;
  129. }
  130. else if (WAIT_FAILED == dwRet)
  131. {
  132. return HRESULT_FROM_WIN32(GetLastError());
  133. }
  134. return S_OK;
  135. }
  136. //=======================================================================
  137. //
  138. // ClientWrkThread::m_WaitForDirective
  139. //
  140. // Routine that worker thread waits with for a new directive.
  141. //
  142. //=======================================================================
  143. HRESULT CClientWrkThread::m_WaitForDirective(void)
  144. {
  145. DWORD dwRet = WaitForSingleObject(m_hEvtDirectiveStart, INFINITE);
  146. return (WAIT_OBJECT_0 == dwRet) ? S_OK : E_FAIL;
  147. }
  148. //=======================================================================
  149. //
  150. // ClientWrkThread::m_DoDirective
  151. //
  152. // Method to tell thread to start doing directive.
  153. //
  154. //=======================================================================
  155. void CClientWrkThread::m_DoDirective(enumWrkThreadDirective enDirective)
  156. {
  157. m_enDirective = enDirective;
  158. SetEvent(m_hEvtDirectiveStart);
  159. }
  160. /////////////////////////////////////////////////////////////////////////////////////////////
  161. // wait until installation is done
  162. ////////////////////////////////////////////////////////////////////////////////////////////
  163. void CClientWrkThread::WaitUntilDone()
  164. {
  165. WaitForSingleObject(m_hEvtInstallDone, INFINITE);
  166. }