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.

459 lines
11 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. msgloop.cxx
  5. Abstract:
  6. This file contains the message pump for SENS.
  7. Author:
  8. Gopal Parupudi <GopalP>
  9. [Notes:]
  10. optional-notes
  11. Revision History:
  12. GopalP 11/5/1997 Start.
  13. --*/
  14. #include <precomp.hxx>
  15. #include <dbt.h>
  16. #define SENS_WINDOW_CLASS_NAME SENS_STRING("SENS Hidden Window class")
  17. #define SENS_HIDDEN_WINDOW_NAME SENS_STRING("SENS")
  18. #if defined(SENS_NT4)
  19. #define SENS_MODULE_NAME SENS_STRING("SENS.EXE")
  20. #else // SENS_NT4
  21. #define SENS_MODULE_NAME SENS_STRING("SENS.DLL")
  22. #endif // SENS_NT4
  23. //
  24. // Globals
  25. //
  26. HWND ghwndSens;
  27. DWORD gMessageLoopTid;
  28. HANDLE ghCleanupEvent;
  29. SYSTEM_POWER_STATUS gSystemPowerState;
  30. LRESULT CALLBACK
  31. SensMainWndProc(
  32. HWND hwnd,
  33. UINT msg,
  34. WPARAM wParam,
  35. LPARAM lParam
  36. )
  37. /*++
  38. Routine Description:
  39. Arguments:
  40. None.
  41. Return Value:
  42. None.
  43. --*/
  44. {
  45. LRESULT lResult = TRUE;
  46. #ifdef DETAIL_DEBUG
  47. SensPrintA(SENS_INFO, ("SensMainWndProc(): Received a msg (0x%x) - (0x%x)\n",
  48. msg, wParam));
  49. #endif // DETAIL_DEBUG
  50. switch (msg)
  51. {
  52. //
  53. // Power Management Notifications.
  54. //
  55. case WM_POWERBROADCAST:
  56. {
  57. DWORD dwPowerEvent = (DWORD) wParam;
  58. SYSTEM_POWER_STATUS CurSPstate;
  59. SENSEVENT_POWER Data;
  60. BOOL bRet;
  61. SensPrintA(SENS_INFO, ("SensMainWndProc(): Received WM_POWERBROADCAST msg - (0x%x)\n",
  62. wParam));
  63. bRet = GetSystemPowerStatus(&CurSPstate);
  64. ASSERT(bRet);
  65. switch (dwPowerEvent)
  66. {
  67. case PBT_APMBATTERYLOW:
  68. {
  69. // Save the new state. A critsec is not necessary as this Message to be serialized.
  70. memcpy(&gSystemPowerState, &CurSPstate, sizeof(SYSTEM_POWER_STATUS));
  71. Data.eType = SENS_EVENT_POWER_BATTERY_LOW;
  72. memcpy(&Data.PowerStatus, &CurSPstate, sizeof(SYSTEM_POWER_STATUS));
  73. // Fire BatteryLow event
  74. SensFireEvent(&Data);
  75. break;
  76. }
  77. case PBT_APMPOWERSTATUSCHANGE:
  78. {
  79. //
  80. // OnACPower event is fired when
  81. // o previously the machine was not on AC
  82. // o now, it is on AC
  83. //
  84. if ( (CurSPstate.ACLineStatus == AC_LINE_ONLINE)
  85. && (gSystemPowerState.ACLineStatus != AC_LINE_ONLINE))
  86. {
  87. Data.eType = SENS_EVENT_POWER_ON_ACPOWER;
  88. }
  89. else
  90. //
  91. // OnBatteryPower event is fired when
  92. // o previously the machine was on AC
  93. // o now, it is not on AC
  94. // o the machine has a system battery
  95. //
  96. if ( (CurSPstate.ACLineStatus == AC_LINE_OFFLINE)
  97. && (gSystemPowerState.ACLineStatus == AC_LINE_ONLINE)
  98. && ((CurSPstate.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == 0))
  99. {
  100. Data.eType = SENS_EVENT_POWER_ON_BATTERYPOWER;
  101. }
  102. //
  103. // A Power change we don't care about.
  104. //
  105. else
  106. {
  107. break;
  108. }
  109. // Save the new state. A critsec is not necessary as this Message to be serialized.
  110. memcpy(&gSystemPowerState, &CurSPstate, sizeof(SYSTEM_POWER_STATUS));
  111. memcpy(&Data.PowerStatus, &CurSPstate, sizeof(SYSTEM_POWER_STATUS));
  112. // Fire the event.
  113. SensFireEvent(&Data);
  114. break;
  115. }
  116. default:
  117. // Unrecognized Power event.
  118. break;
  119. } // switch (dwPowerEvent)
  120. break;
  121. }
  122. #if defined(SENS_CHICAGO)
  123. //
  124. // PnP Device Notifications.
  125. //
  126. case WM_DEVICECHANGE:
  127. {
  128. SensPrintA(SENS_INFO, ("SensMainWndProc(): Received a WM_DEVICECHANGE msg - (0x%x)\n",
  129. wParam));
  130. PDEV_BROADCAST_NET pdbNet = (PDEV_BROADCAST_NET) lParam;
  131. switch (wParam)
  132. {
  133. case DBT_DEVICEARRIVAL:
  134. {
  135. if (pdbNet->dbcn_devicetype == DBT_DEVTYP_NET)
  136. {
  137. SENSEVENT_PNP Data;
  138. ASSERT(pdbNet->dbcn_size == sizeof(DEV_BROADCAST_NET));
  139. Data.eType = SENS_EVENT_PNP_DEVICE_ARRIVED;
  140. Data.Size = pdbNet->dbcn_size;
  141. Data.DevType = pdbNet->dbcn_devicetype;
  142. Data.Resource = pdbNet->dbcn_resource;
  143. Data.Flags = pdbNet->dbcn_flags;
  144. SensFireEvent(&Data);
  145. // Force a recalculation of LAN Connectivity
  146. gdwLastLANTime -= (MAX_LAN_INTERVAL + 1);
  147. //EvaluateConnectivity(TYPE_LAN);
  148. }
  149. break;
  150. }
  151. case DBT_DEVICEREMOVECOMPLETE:
  152. {
  153. if (pdbNet->dbcn_devicetype == DBT_DEVTYP_NET)
  154. {
  155. SENSEVENT_PNP Data;
  156. ASSERT(pdbNet->dbcn_size == sizeof(DEV_BROADCAST_NET));
  157. Data.eType = SENS_EVENT_PNP_DEVICE_REMOVED;
  158. Data.Size = pdbNet->dbcn_size;
  159. Data.DevType = pdbNet->dbcn_devicetype;
  160. Data.Resource = pdbNet->dbcn_resource;
  161. Data.Flags = pdbNet->dbcn_flags;
  162. SensFireEvent(&Data);
  163. // Force a recalculation of LAN Connectivity
  164. gdwLastLANTime -= (MAX_LAN_INTERVAL + 1);
  165. //EvaluateConnectivity(TYPE_LAN);
  166. }
  167. break;
  168. }
  169. }
  170. break;
  171. }
  172. #endif // SENS_CHICAGO
  173. case WM_SENS_CLEANUP:
  174. //
  175. // Cleanup the Window resources of SENS
  176. //
  177. PostQuitMessage(0);
  178. break;
  179. default:
  180. lResult = DefWindowProc(hwnd, msg, wParam, lParam);
  181. break;
  182. } // switch (msg)
  183. return lResult;
  184. }
  185. DWORD WINAPI
  186. SensMessageLoopThreadRoutine(
  187. LPVOID lpParam
  188. )
  189. /*++
  190. Routine Description:
  191. Arguments:
  192. None.
  193. Return Value:
  194. None.
  195. --*/
  196. {
  197. WNDCLASS wc;
  198. BOOL f;
  199. BOOL bRet;
  200. HINSTANCE hInstance = NULL;
  201. MSG msg;
  202. //
  203. // Save away the ThreadId
  204. //
  205. gMessageLoopTid = GetCurrentThreadId();
  206. //
  207. // Save a snapshot of the System Power State.
  208. //
  209. bRet = GetSystemPowerStatus(&gSystemPowerState);
  210. if (bRet == FALSE)
  211. {
  212. SensPrintA(SENS_ERR, ("SensMessageLoopThread(): GetSystemPowerStatus() failed with "
  213. "GLE = %d\n", GetLastError()));
  214. }
  215. //
  216. // Create an event to signal the cleanup of all window resources.
  217. //
  218. ghCleanupEvent = CreateEvent(
  219. NULL, // Handle cannot be inherited
  220. FALSE, // It is an auto-reset event
  221. FALSE, // Intial state is non-signalled
  222. SENS_STRING("Sens Hidden Window Cleanup Event") // Name of the event
  223. );
  224. if (ghCleanupEvent == NULL)
  225. {
  226. SensPrintA(SENS_ERR, ("ServiceStart(): CreateEvent(ghCleanupEvent)"
  227. " failed with %d.", GetLastError()));
  228. }
  229. //
  230. // Register window class
  231. //
  232. hInstance = GetModuleHandle(SENS_MODULE_NAME);
  233. ASSERT(hInstance);
  234. memset(&wc, 0x0, sizeof(WNDCLASS));
  235. wc.style = 0;
  236. wc.lpfnWndProc = (WNDPROC) SensMainWndProc;
  237. wc.cbClsExtra = 0;
  238. wc.cbWndExtra = 0;
  239. wc.hIcon = NULL;
  240. wc.hInstance = hInstance;
  241. wc.hCursor = NULL;
  242. wc.hbrBackground = NULL;
  243. wc.lpszMenuName = NULL;
  244. wc.lpszClassName = SENS_WINDOW_CLASS_NAME;
  245. f = RegisterClass(&wc);
  246. ASSERT(f);
  247. // Create a hidden window
  248. ghwndSens = CreateWindow(
  249. SENS_WINDOW_CLASS_NAME, // Class Name
  250. SENS_HIDDEN_WINDOW_NAME, // Window Name
  251. NULL, // Window Style
  252. 0, // Horizontal position
  253. 0, // Vertical position
  254. 0, // Window width
  255. 0, // Window height
  256. NULL, // Handle to parent window
  257. NULL, // Handle to menu
  258. hInstance, // Handle to application instance
  259. NULL // window creation data
  260. );
  261. if (ghwndSens)
  262. {
  263. ShowWindow(ghwndSens, SW_HIDE);
  264. //
  265. // Message pump.
  266. //
  267. while ((bRet = GetMessage(&msg, ghwndSens, NULL, NULL)) > 0)
  268. {
  269. TranslateMessage(&msg);
  270. DispatchMessage(&msg);
  271. }
  272. #ifdef DETAIL_DEBUG
  273. SensPrintA(SENS_DBG, ("SensMessageLoopThread(): Out of message pump !\n"));
  274. #endif // DETAIL_DEBUG
  275. // Check for bad return value from GetMessage()
  276. if (bRet == -1)
  277. {
  278. SensPrintA(SENS_ERR, ("SensMessageLoopThread(): GetMessage() failed with GLE of %d\n",
  279. GetLastError()));
  280. }
  281. BOOL bRet;
  282. // Cleanup the window.
  283. bRet = DestroyWindow(ghwndSens);
  284. ASSERT(bRet);
  285. if (bRet != TRUE)
  286. {
  287. SensPrintA(SENS_ERR, ("SensMessageLoopThread(): DestroyWindow() failed with %d\n",
  288. GetLastError()));
  289. }
  290. // Unregister the window class
  291. bRet = UnregisterClass(SENS_WINDOW_CLASS_NAME, hInstance);
  292. ASSERT(bRet);
  293. // Window cleanup done. Set the event.
  294. if (ghCleanupEvent)
  295. {
  296. SetEvent(ghCleanupEvent);
  297. }
  298. }
  299. else
  300. {
  301. SensPrintA(SENS_ERR, ("SensMessageLoopThread(): CreateWindow() failed with GLE of %d\n",
  302. GetLastError()));
  303. }
  304. return 0;
  305. }
  306. BOOL
  307. InitMessageLoop(
  308. void
  309. )
  310. /*++
  311. Routine Description:
  312. Arguments:
  313. None.
  314. Return Value:
  315. None.
  316. --*/
  317. {
  318. #if defined(SENS_CHICAGO)
  319. BOOL bStatus;
  320. HANDLE hThread;
  321. DWORD dwThreadId;
  322. bStatus = FALSE;
  323. hThread = CreateThread(
  324. NULL,
  325. 0,
  326. SensMessageLoopThreadRoutine,
  327. NULL,
  328. 0,
  329. &dwThreadId
  330. );
  331. if (NULL != hThread)
  332. {
  333. bStatus = TRUE;
  334. CloseHandle(hThread);
  335. }
  336. else
  337. {
  338. SensPrintA(SENS_INFO, ("InitMessageLoop() returning %d with GLE of %d\n",
  339. bStatus, GetLastError()));
  340. }
  341. return bStatus;
  342. #else // SENS_CHICAGO
  343. return TRUE;
  344. #endif // SENS_CHICAGO
  345. }