Leaked source code of windows server 2003
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.

297 lines
7.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation
  6. //
  7. // File: sthread.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "hdwwiz.h"
  11. DWORD
  12. SearchDriversThread(
  13. PVOID pvHardwareWiz
  14. )
  15. {
  16. PHARDWAREWIZ HardwareWiz = (PHARDWAREWIZ) pvHardwareWiz;
  17. PSEARCHTHREAD SearchThread;
  18. DWORD Error = ERROR_SUCCESS;
  19. DWORD WaitResult;
  20. UINT Msg = 0;
  21. WPARAM wParam = 0;
  22. LPARAM lParam = 0;
  23. DWORD Delay;
  24. try {
  25. if (!HardwareWiz || !HardwareWiz->SearchThread) {
  26. return ERROR_INVALID_PARAMETER;
  27. }
  28. SearchThread = HardwareWiz->SearchThread;
  29. for (;;) {
  30. SetEvent(SearchThread->ReadyEvent);
  31. waitloop:
  32. if ((WaitResult = WaitForSingleObject(SearchThread->RequestEvent, 5000)) == WAIT_FAILED) {
  33. Error = GetLastError();
  34. break;
  35. }
  36. else if (WaitResult == WAIT_TIMEOUT) {
  37. goto waitloop;
  38. }
  39. if (SearchThread->Function == SEARCH_NULL) {
  40. Msg = 0;
  41. Delay = 0;
  42. }
  43. else if (SearchThread->Function == SEARCH_EXIT) {
  44. break;
  45. }
  46. else if (SearchThread->Function == SEARCH_DELAY) {
  47. Delay = SearchThread->Param;
  48. Msg = WUM_DELAYTIMER;
  49. wParam = TRUE;
  50. lParam = ERROR_SUCCESS;
  51. }
  52. else if (SearchThread->Function == SEARCH_DETECT) {
  53. Delay = 0;
  54. Msg = WUM_DETECT;
  55. wParam = TRUE;
  56. lParam = ERROR_SUCCESS;
  57. try {
  58. BuildDeviceDetection(SearchThread->hDlg, HardwareWiz);
  59. }
  60. except (EXCEPTION_EXECUTE_HANDLER) {
  61. lParam = GetExceptionCode();
  62. }
  63. }
  64. else if (SearchThread->Function == SEARCH_PNPENUM) {
  65. Delay = 0;
  66. Msg = WUM_PNPENUMERATE;
  67. wParam = TRUE;
  68. lParam = ERROR_SUCCESS;
  69. try {
  70. Delay = PNPEnumerate(HardwareWiz);
  71. }
  72. except (EXCEPTION_EXECUTE_HANDLER) {
  73. lParam = GetExceptionCode();
  74. }
  75. }
  76. else {
  77. Error = ERROR_INVALID_FUNCTION;
  78. break;
  79. }
  80. SearchThread->Function = SEARCH_NULL;
  81. WaitForSingleObject(SearchThread->CancelEvent, Delay);
  82. if (Msg && SearchThread->hDlg) {
  83. PostMessage(SearchThread->hDlg, Msg, wParam, lParam);
  84. }
  85. }
  86. }
  87. except(HdwUnhandledExceptionFilter(GetExceptionInformation())) {
  88. Error = RtlNtStatusToDosError(GetExceptionCode());
  89. }
  90. return Error;
  91. }
  92. BOOL
  93. SearchThreadRequest(
  94. PSEARCHTHREAD SearchThread,
  95. HWND hDlg,
  96. UCHAR Function,
  97. ULONG Param
  98. )
  99. {
  100. MSG Msg;
  101. DWORD WaitReturn;
  102. while ((WaitReturn = MsgWaitForMultipleObjects(1,
  103. &SearchThread->ReadyEvent,
  104. FALSE,
  105. INFINITE,
  106. QS_ALLEVENTS
  107. ))
  108. == WAIT_OBJECT_0 + 1)
  109. {
  110. while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
  111. if (!IsDialogMessage(hDlg,&Msg)) {
  112. TranslateMessage(&Msg);
  113. DispatchMessage(&Msg);
  114. }
  115. }
  116. }
  117. if (WaitReturn == WAIT_OBJECT_0) {
  118. ResetEvent(SearchThread->CancelEvent);
  119. SearchThread->CancelRequest = FALSE;
  120. SearchThread->hDlg = hDlg;
  121. SearchThread->Function = Function;
  122. SearchThread->Param = Param;
  123. SetEvent(SearchThread->RequestEvent);
  124. return TRUE;
  125. }
  126. return FALSE;
  127. }
  128. VOID
  129. CancelSearchRequest(
  130. PHARDWAREWIZ HardwareWiz
  131. )
  132. {
  133. PSEARCHTHREAD SearchThread;
  134. SearchThread = HardwareWiz->SearchThread;
  135. if (SearchThread->hDlg) {
  136. //
  137. // Cancel drivers search, and then request a NULL operation
  138. // to get in sync with the search thread.
  139. //
  140. if (SearchThread->Function == SEARCH_DRIVERS) {
  141. SetupDiCancelDriverInfoSearch(HardwareWiz->hDeviceInfo);
  142. }
  143. SearchThread->CancelRequest = TRUE;
  144. SetEvent(SearchThread->CancelEvent);
  145. SearchThreadRequest(SearchThread,
  146. NULL,
  147. SEARCH_NULL,
  148. 0
  149. );
  150. }
  151. }
  152. LONG
  153. CreateSearchThread(
  154. PHARDWAREWIZ HardwareWiz
  155. )
  156. {
  157. PSEARCHTHREAD SearchThread = HardwareWiz->SearchThread;
  158. DWORD ThreadId;
  159. SearchThread->hDlg = NULL;
  160. SearchThread->Function = 0;
  161. if (((SearchThread->RequestEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) ||
  162. ((SearchThread->ReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) ||
  163. ((SearchThread->CancelEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) ||
  164. ((SearchThread->hThread = CreateThread(NULL,
  165. 0,
  166. SearchDriversThread,
  167. HardwareWiz,
  168. 0,
  169. &ThreadId
  170. )) == NULL))
  171. {
  172. if (SearchThread->RequestEvent) {
  173. CloseHandle(SearchThread->RequestEvent);
  174. }
  175. if (SearchThread->ReadyEvent) {
  176. CloseHandle(SearchThread->ReadyEvent);
  177. }
  178. if (SearchThread->CancelEvent) {
  179. CloseHandle(SearchThread->CancelEvent);
  180. }
  181. return GetLastError();
  182. }
  183. return ERROR_SUCCESS;
  184. }
  185. void
  186. DestroySearchThread(
  187. PSEARCHTHREAD SearchThread
  188. )
  189. {
  190. //
  191. // Signal search thread to exit,
  192. //
  193. if (SearchThread->hThread) {
  194. DWORD ExitCode;
  195. if (GetExitCodeThread(SearchThread->hThread, &ExitCode) &&
  196. ExitCode == STILL_ACTIVE) {
  197. SearchThreadRequest(SearchThread, NULL, SEARCH_EXIT, 0);
  198. }
  199. WaitForSingleObject(SearchThread->hThread, INFINITE);
  200. CloseHandle(SearchThread->hThread);
  201. SearchThread->hThread = NULL;
  202. }
  203. if (SearchThread->ReadyEvent) {
  204. CloseHandle(SearchThread->ReadyEvent);
  205. SearchThread->ReadyEvent = NULL;
  206. }
  207. if (SearchThread->RequestEvent) {
  208. CloseHandle(SearchThread->RequestEvent);
  209. SearchThread->RequestEvent = NULL;
  210. }
  211. if (SearchThread->CancelEvent) {
  212. CloseHandle(SearchThread->CancelEvent);
  213. SearchThread->CancelEvent = NULL;
  214. }
  215. }