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.

302 lines
7.2 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1998
  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;
  21. WPARAM wParam;
  22. LPARAM lParam;
  23. DWORD Delay;
  24. try {
  25. if (!HardwareWiz || !HardwareWiz->SearchThread) {
  26. return ERROR_INVALID_PARAMETER;
  27. }
  28. SearchThread = HardwareWiz->SearchThread;
  29. while (TRUE) {
  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_ALLINPUT
  107. QS_ALLEVENTS
  108. ))
  109. == WAIT_OBJECT_0 + 1)
  110. {
  111. while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
  112. if (!IsDialogMessage(hDlg,&Msg)) {
  113. TranslateMessage(&Msg);
  114. DispatchMessage(&Msg);
  115. }
  116. }
  117. }
  118. if (WaitReturn == WAIT_OBJECT_0) {
  119. ResetEvent(SearchThread->CancelEvent);
  120. SearchThread->CancelRequest = FALSE;
  121. SearchThread->hDlg = hDlg;
  122. SearchThread->Function = Function;
  123. SearchThread->Param = Param;
  124. SetEvent(SearchThread->RequestEvent);
  125. return TRUE;
  126. }
  127. return FALSE;
  128. }
  129. VOID
  130. CancelSearchRequest(
  131. PHARDWAREWIZ HardwareWiz
  132. )
  133. {
  134. PSEARCHTHREAD SearchThread;
  135. SearchThread = HardwareWiz->SearchThread;
  136. if (SearchThread->hDlg) {
  137. //
  138. // Cancel drivers search, and then request a NULL operation
  139. // to get in sync with the search thread.
  140. //
  141. if (SearchThread->Function == SEARCH_DRIVERS) {
  142. SetupDiCancelDriverInfoSearch(HardwareWiz->hDeviceInfo);
  143. }
  144. SearchThread->CancelRequest = TRUE;
  145. SetEvent(SearchThread->CancelEvent);
  146. SearchThreadRequest(SearchThread,
  147. NULL,
  148. SEARCH_NULL,
  149. 0
  150. );
  151. }
  152. }
  153. LONG
  154. CreateSearchThread(
  155. PHARDWAREWIZ HardwareWiz
  156. )
  157. {
  158. PSEARCHTHREAD SearchThread = HardwareWiz->SearchThread;
  159. DWORD ThreadId;
  160. SearchThread->hDlg = NULL;
  161. SearchThread->Function = 0;
  162. if (!(SearchThread->RequestEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) ||
  163. !(SearchThread->ReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) ||
  164. !(SearchThread->CancelEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) ||
  165. !(SearchThread->hThread = CreateThread(NULL,
  166. 0,
  167. SearchDriversThread,
  168. HardwareWiz,
  169. 0,
  170. &ThreadId
  171. )))
  172. {
  173. if (SearchThread->RequestEvent) {
  174. CloseHandle(SearchThread->RequestEvent);
  175. }
  176. if (SearchThread->ReadyEvent) {
  177. CloseHandle(SearchThread->ReadyEvent);
  178. }
  179. if (SearchThread->CancelEvent) {
  180. CloseHandle(SearchThread->CancelEvent);
  181. }
  182. return GetLastError();
  183. }
  184. return ERROR_SUCCESS;
  185. }
  186. void
  187. DestroySearchThread(
  188. PSEARCHTHREAD SearchThread
  189. )
  190. {
  191. //
  192. // Signal search thread to exit,
  193. //
  194. if (SearchThread->hThread) {
  195. DWORD ExitCode;
  196. if (GetExitCodeThread(SearchThread->hThread, &ExitCode) &&
  197. ExitCode == STILL_ACTIVE) {
  198. SearchThreadRequest(SearchThread, NULL, SEARCH_EXIT, 0);
  199. }
  200. WaitForSingleObject(SearchThread->hThread, INFINITE);
  201. CloseHandle(SearchThread->hThread);
  202. SearchThread->hThread = NULL;
  203. }
  204. if (SearchThread->ReadyEvent) {
  205. CloseHandle(SearchThread->ReadyEvent);
  206. SearchThread->ReadyEvent = NULL;
  207. }
  208. if (SearchThread->RequestEvent) {
  209. CloseHandle(SearchThread->RequestEvent);
  210. SearchThread->RequestEvent = NULL;
  211. }
  212. if (SearchThread->CancelEvent) {
  213. CloseHandle(SearchThread->CancelEvent);
  214. SearchThread->CancelEvent = NULL;
  215. }
  216. }