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.

362 lines
8.5 KiB

  1. /* Copyright (c) 1996, Microsoft Corporation, all rights reserved
  2. **
  3. ** wait.c
  4. ** Waiting for services popup
  5. ** Listed alphabetically
  6. **
  7. ** 02/17/96 Steve Cobb
  8. */
  9. #include <windows.h> // Win32 root
  10. #include <debug.h> // Trace and assert
  11. #include <nouiutil.h> // No-HWND utilities
  12. #include <uiutil.h> // Our public header
  13. #include <wait.rch> // Our resource constants
  14. /* Set when RasLoad has completed successfully in this process context.
  15. */
  16. BOOL g_fRasLoaded = FALSE;
  17. /* Waiting for services thread argument block.
  18. */
  19. #define WSARGS struct tagWSARGS
  20. WSARGS
  21. {
  22. HINSTANCE hInst;
  23. HWND hwndOwner;
  24. HANDLE hEventUp;
  25. HANDLE hEventDie;
  26. };
  27. /* Waiting for services thread context.
  28. */
  29. #define WSINFO struct tagWSINFO
  30. WSINFO
  31. {
  32. HANDLE hEventDie;
  33. DWORD dwThreadId;
  34. HICON hIcon;
  35. };
  36. /*----------------------------------------------------------------------------
  37. ** Local prototypes
  38. **----------------------------------------------------------------------------
  39. */
  40. VOID
  41. StartWaitingForServices(
  42. HINSTANCE hInst,
  43. HWND hwndOwner,
  44. WSINFO* pInfo );
  45. VOID
  46. StopWaitingForServices(
  47. IN WSINFO* pInfo );
  48. DWORD
  49. WsThread(
  50. LPVOID pArg );
  51. INT_PTR CALLBACK
  52. WsDlgProc(
  53. HWND hwnd,
  54. UINT unMsg,
  55. WPARAM wParam,
  56. LPARAM lParam );
  57. /*----------------------------------------------------------------------------
  58. ** Routines
  59. **----------------------------------------------------------------------------
  60. */
  61. DWORD
  62. LoadRas(
  63. IN HINSTANCE hInst,
  64. IN HWND hwnd )
  65. /* Starts the RASMAN service and loads the RASMAN and RASAPI32 entrypoint
  66. ** addresses. The "waiting for services" popup is displayed, if
  67. ** indicated. 'HInst' and 'hwnd' are the owning instance and window.
  68. **
  69. ** Returns 0 if successful or an error code.
  70. */
  71. {
  72. DWORD dwErr;
  73. WSINFO info;
  74. TRACE("LoadRas");
  75. ZeroMemory(&info, sizeof(WSINFO));
  76. if (g_fRasLoaded)
  77. dwErr = 0;
  78. else
  79. {
  80. if (IsRasmanServiceRunning())
  81. info.hEventDie = NULL;
  82. else
  83. StartWaitingForServices( hInst, hwnd, &info );
  84. dwErr = LoadRasapi32Dll();
  85. if (dwErr == 0)
  86. {
  87. dwErr = LoadRasmanDll();
  88. if (dwErr == 0)
  89. {
  90. ASSERT(g_pRasInitialize);
  91. TRACE("RasInitialize");
  92. dwErr = g_pRasInitialize();
  93. TRACE1("RasInitialize=%d",dwErr);
  94. }
  95. }
  96. StopWaitingForServices( &info );
  97. if (dwErr == 0)
  98. g_fRasLoaded = TRUE;
  99. }
  100. TRACE1("LoadRas=%d",dwErr);
  101. return dwErr;
  102. }
  103. VOID
  104. StartWaitingForServices(
  105. HINSTANCE hInst,
  106. HWND hwndOwner,
  107. WSINFO* pInfo )
  108. /* Popup the "waiting for services" dialog in another thread. 'HInst' and
  109. ** 'hwnd' are the owning instance and window. Fills caller's 'pInfo' with
  110. ** context to pass to StopWaitingForServices.
  111. */
  112. {
  113. #ifndef NT4STUFF
  114. // Set the hourglass cursor
  115. pInfo->hIcon = SetCursor (LoadCursor (NULL, IDC_WAIT));
  116. ShowCursor (TRUE);
  117. #else
  118. WSARGS* pArgs;
  119. HANDLE hThread;
  120. HANDLE hEventUp;
  121. pInfo->hEventDie = NULL;
  122. pArgs = (WSARGS* )Malloc( sizeof(*pArgs) );
  123. if (!pArgs)
  124. return;
  125. ZeroMemory( pArgs, sizeof(*pArgs) );
  126. pArgs->hInst = hInst;
  127. pArgs->hwndOwner = hwndOwner;
  128. hEventUp = pArgs->hEventUp =
  129. CreateEvent( NULL, FALSE, FALSE, NULL );
  130. if (!hEventUp)
  131. {
  132. Free( pArgs );
  133. return;
  134. }
  135. pInfo->hEventDie = pArgs->hEventDie =
  136. CreateEvent( NULL, FALSE, FALSE, NULL );
  137. if (!pInfo->hEventDie)
  138. {
  139. Free( pArgs );
  140. CloseHandle( hEventUp );
  141. return;
  142. }
  143. /* Create a thread so paint messages for the popup get processed. The
  144. ** current thread is going to be tied up starting RAS Manager.
  145. */
  146. hThread = CreateThread( NULL, 0, WsThread, pArgs, 0, &pInfo->dwThreadId );
  147. if (hThread)
  148. {
  149. /* Don't begin churning on RASMAN until the popup has displayed
  150. ** itself.
  151. */
  152. SetThreadPriority( hThread, THREAD_PRIORITY_HIGHEST );
  153. WaitForSingleObject( hEventUp, INFINITE );
  154. CloseHandle( hThread );
  155. }
  156. else
  157. {
  158. /* Thread was DOA.
  159. */
  160. CloseHandle( pInfo->hEventDie );
  161. pInfo->hEventDie = NULL;
  162. Free( pArgs );
  163. }
  164. CloseHandle( hEventUp );
  165. #endif
  166. }
  167. VOID
  168. StopWaitingForServices(
  169. IN WSINFO* pInfo )
  170. /* Terminate the "waiting for services" popup. 'PInfo' is the context
  171. ** from StartWaitingForServices.
  172. */
  173. {
  174. TRACE("StopWaitingForServices");
  175. #ifndef NT4STUFF
  176. if (pInfo->hIcon == NULL)
  177. pInfo->hIcon = LoadCursor (NULL, IDC_ARROW);
  178. SetCursor (pInfo->hIcon);
  179. ShowCursor (TRUE);
  180. #else
  181. if (pInfo->hEventDie)
  182. {
  183. /* The post triggers the message loop to action, but you can't rely on
  184. ** the posted message arriving in the thread message loop. For
  185. ** example, if user holds the mouse down on the window caption, the
  186. ** message never appears, presumably because it's flushed by some
  187. ** sub-loop during "move window" processing. Set the event to make
  188. ** sure the popup knows to quit the next time it processes a message.
  189. */
  190. SetEvent( pInfo->hEventDie );
  191. PostThreadMessage( pInfo->dwThreadId, WM_CLOSE, 0, 0 );
  192. }
  193. #endif
  194. }
  195. DWORD
  196. WsThread(
  197. LPVOID pArg )
  198. /* Waiting for services thread main.
  199. */
  200. {
  201. WSARGS* pArgs;
  202. HWND hwnd;
  203. MSG msg;
  204. TRACE("WsThread running");
  205. pArgs = (WSARGS* )pArg;
  206. hwnd = CreateDialog( pArgs->hInst,
  207. MAKEINTRESOURCE( DID_WS_WaitingForServices ),
  208. NULL, WsDlgProc );
  209. if (hwnd)
  210. {
  211. LONG lStyle;
  212. /* Make ourselves topmost if the owner window is, otherwise we may not
  213. ** be visible under the topmost window, such as the winlogin window.
  214. ** Note that if you actally create the dialog with an owner you have
  215. ** all kinds of thread related problems. In retrospect, should have
  216. ** written this such that the "waiting" dialog happened in the main
  217. ** thread and the LoadLibraries and RasInitialize happened in the
  218. ** created thread which would automatically avoid this kind of
  219. ** problem, but this works too.
  220. */
  221. lStyle = GetWindowLong( pArgs->hwndOwner, GWL_EXSTYLE );
  222. if (lStyle & WS_EX_TOPMOST)
  223. {
  224. TRACE("TOPMOST");
  225. SetWindowPos( hwnd, HWND_TOPMOST,
  226. 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
  227. }
  228. CenterWindow( hwnd, pArgs->hwndOwner );
  229. ShowWindow( hwnd, SW_SHOW );
  230. UpdateWindow( hwnd );
  231. SetForegroundWindow( hwnd );
  232. }
  233. /* Tell other thread to go on.
  234. */
  235. SetEvent( pArgs->hEventUp );
  236. if (hwnd)
  237. {
  238. TRACE("WsThread msg-loop running");
  239. while (GetMessage( &msg, NULL, 0, 0 ))
  240. {
  241. if (WaitForSingleObject( pArgs->hEventDie, 0 ) == WAIT_OBJECT_0)
  242. {
  243. /* Normal termination.
  244. */
  245. DestroyWindow( hwnd );
  246. break;
  247. }
  248. if (!IsDialogMessage( hwnd, &msg ))
  249. {
  250. TranslateMessage( &msg );
  251. DispatchMessage( &msg );
  252. }
  253. }
  254. if (pArgs->hwndOwner)
  255. SetForegroundWindow( pArgs->hwndOwner );
  256. }
  257. CloseHandle( pArgs->hEventDie );
  258. Free( pArgs );
  259. TRACE("WsThread terminating");
  260. return 0;
  261. }
  262. INT_PTR CALLBACK
  263. WsDlgProc(
  264. HWND hwnd,
  265. UINT unMsg,
  266. WPARAM wParam,
  267. LPARAM lParam )
  268. /* Standard Win32 dialog procedure.
  269. */
  270. {
  271. if (unMsg == WM_INITDIALOG)
  272. {
  273. HMENU hmenu;
  274. /* Remove Close from the system menu since some people think it kills
  275. ** the app and not just the popup.
  276. */
  277. hmenu = GetSystemMenu( hwnd, FALSE );
  278. if (hmenu && DeleteMenu( hmenu, SC_CLOSE, MF_BYCOMMAND ))
  279. DrawMenuBar( hwnd );
  280. return TRUE;
  281. }
  282. return FALSE;
  283. }
  284. VOID
  285. UnloadRas(
  286. void )
  287. /* Unload the DLLs loaded by LoadRas().
  288. */
  289. {
  290. if (g_fRasLoaded)
  291. {
  292. g_fRasLoaded = FALSE;
  293. UnloadRasmanDll();
  294. UnloadRasapi32Dll();
  295. }
  296. }