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.

285 lines
9.5 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2000
  4. *
  5. * TITLE: handler.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ByronC
  10. *
  11. * DATE: 15 Nov, 2000
  12. *
  13. * DESCRIPTION:
  14. * Declarations and definitions for the WIA messsage handler class.
  15. * This class gets called from the Service control function on PnP and Power
  16. * event notifications, and informas the device manager to take the appropriate
  17. * action.
  18. *
  19. *******************************************************************************/
  20. #include "precomp.h"
  21. #include "stiexe.h"
  22. HRESULT CMsgHandler::HandlePnPEvent(
  23. DWORD dwEventType,
  24. PVOID pEventData)
  25. {
  26. HRESULT hr = S_OK;
  27. PDEV_BROADCAST_HDR pDevHdr = (PDEV_BROADCAST_HDR)pEventData;
  28. ACTIVE_DEVICE *pActiveDevice = NULL;
  29. DEV_BROADCAST_HEADER *psDevBroadcast = NULL;
  30. DEVICE_BROADCAST_INFO *pdbiDevice = NULL;
  31. BOOL bFound = FALSE;
  32. USES_CONVERSION;
  33. DBG_TRC(("CMsgHandler::HandlePnPEvent, dwEventType = 0x%08X", dwEventType));
  34. DBG_WRN(("==> CMsgHandler::HandlePnPEvent"));
  35. //
  36. // Trace that we are here. For all messages, not intended for StillImage devices , we should refresh
  37. // device list if we are running on WIndows NT and registered for device interfaces other than StillImage
  38. //
  39. PDEV_BROADCAST_DEVNODE pDevNode = (PDEV_BROADCAST_DEVNODE)pDevHdr;
  40. PDEV_BROADCAST_DEVICEINTERFACE pDevInterface = (PDEV_BROADCAST_DEVICEINTERFACE)pDevHdr;
  41. switch (dwEventType) {
  42. case DBT_DEVICEREMOVECOMPLETE:
  43. case DBT_DEVICEQUERYREMOVE:
  44. case DBT_DEVICEREMOVEPENDING:
  45. DBG_TRC(("CMsgHandler::HandlePnPEvent, "
  46. "DBT_DEVICEQUERYREMOVE | DBT_DEVICEREMOVEPENDING | DBT_DEVICEREMOVECOMPLETE, "
  47. "dwEventType = %lu", dwEventType));
  48. if (IsStillImagePnPMessage(pDevHdr)) {
  49. //
  50. // Get device name and store along with the broadacast structure
  51. //
  52. pdbiDevice = new DEVICE_BROADCAST_INFO;
  53. if (!pdbiDevice) {
  54. DBG_WRN(("CMsgHandler::HandlePnPEvent, out of memory"));
  55. return E_OUTOFMEMORY;
  56. }
  57. //
  58. // Fill in information we have
  59. //
  60. pdbiDevice->m_uiDeviceChangeMessage = dwEventType;
  61. pdbiDevice->m_strBroadcastedName.CopyString(pDevInterface->dbcc_name) ;
  62. pdbiDevice->m_dwDevNode = pDevNode->dbcd_devnode;
  63. //
  64. // Try to find our internal device name for this device if it exists in
  65. // our internal set.
  66. //
  67. bFound = GetDeviceNameFromDevBroadcast((DEV_BROADCAST_HEADER *)pDevHdr,pdbiDevice);
  68. DBG_WRN(("==> GetDeviceNameFromDevBroadcast returned DeviceID (%ws)", (WCHAR*)(LPCWSTR)pdbiDevice->m_strDeviceName));
  69. if (bFound) {
  70. //
  71. // Mark that this device has been removed and throw disconnect event.
  72. //
  73. hr = g_pDevMan->ProcessDeviceRemoval((WCHAR*)(LPCWSTR)pdbiDevice->m_strDeviceName);
  74. }
  75. else {
  76. DBG_TRC(("CMsgHandler::HandlePnPEvent, - failed to get device name from broadcast"));
  77. }
  78. } else {
  79. //
  80. // Not exactly one of ours, but we are registered for it, so re-enumerate
  81. //
  82. g_pDevMan->ReEnumerateDevices(DEV_MAN_GEN_EVENTS);
  83. }
  84. break;
  85. case DBT_DEVICEARRIVAL:
  86. DBG_TRC(("CMsgHandler::HandlePnPEvent - DBT_DEVICEARRIVAL"));
  87. //
  88. // Device has arrived (not installed). We simply find out which of
  89. // our devices has changed state.
  90. //
  91. hr = g_pDevMan->ProcessDeviceArrival();
  92. if (FAILED(hr)) {
  93. DBG_WRN(("::CMsgHandler::HandlePnPEvent, unable to enumerate devices"));
  94. }
  95. break;
  96. default:
  97. DBG_TRC(("::CMsgHandler::HandlePnPEvent, Default case"));
  98. break;
  99. }
  100. //
  101. // Cleanup
  102. //
  103. if (pdbiDevice) {
  104. delete pdbiDevice;
  105. }
  106. return hr;
  107. }
  108. DWORD CMsgHandler::HandlePowerEvent(
  109. DWORD dwEventType,
  110. PVOID pEventData)
  111. {
  112. DWORD dwRet = NO_ERROR;
  113. UINT uiTraceMessage = 0;
  114. #ifdef DEBUG
  115. static LPCTSTR pszPwrEventNames[] = {
  116. TEXT("PBT_APMQUERYSUSPEND"), // 0x0000
  117. TEXT("PBT_APMQUERYSTANDBY"), // 0x0001
  118. TEXT("PBT_APMQUERYSUSPENDFAILED"), // 0x0002
  119. TEXT("PBT_APMQUERYSTANDBYFAILED"), // 0x0003
  120. TEXT("PBT_APMSUSPEND"), // 0x0004
  121. TEXT("PBT_APMSTANDBY"), // 0x0005
  122. TEXT("PBT_APMRESUMECRITICAL"), // 0x0006
  123. TEXT("PBT_APMRESUMESUSPEND"), // 0x0007
  124. TEXT("PBT_APMRESUMESTANDBY"), // 0x0008
  125. // TEXT(" PBTF_APMRESUMEFROMFAILURE"), // 0x00000001
  126. TEXT("PBT_APMBATTERYLOW"), // 0x0009
  127. TEXT("PBT_APMPOWERSTATUSCHANGE"), // 0x000A
  128. TEXT("PBT_APMOEMEVENT"), // 0x000B
  129. TEXT("PBT_UNKNOWN"), // 0x000C
  130. TEXT("PBT_UNKNOWN"), // 0x000D
  131. TEXT("PBT_UNKNOWN"), // 0x000E
  132. TEXT("PBT_UNKNOWN"), // 0x000F
  133. TEXT("PBT_UNKNOWN"), // 0x0010
  134. TEXT("PBT_UNKNOWN"), // 0x0011
  135. TEXT("PBT_APMRESUMEAUTOMATIC"), // 0x0012
  136. };
  137. UINT uiMsgIndex;
  138. uiMsgIndex = (dwEventType < (sizeof(pszPwrEventNames) / sizeof(TCHAR *) )) ?
  139. (UINT) dwEventType : 0x0010;
  140. DBG_TRC(("Still image APM Broadcast Message:%S Code:%x ",
  141. pszPwrEventNames[uiMsgIndex],dwEventType));
  142. #endif
  143. switch(dwEventType)
  144. {
  145. case PBT_APMQUERYSUSPEND:
  146. //
  147. // Request for permission to suspend
  148. //
  149. if(g_NumberOfActiveTransfers > 0) {
  150. //
  151. // Veto suspend while any transfers are in progress
  152. //
  153. dwRet = BROADCAST_QUERY_DENY;
  154. } else {
  155. //
  156. // Notify drivers that we're about to enter a power suspend state
  157. //
  158. g_pDevMan->NotifyRunningDriversOfEvent(&WIA_EVENT_POWER_SUSPEND);
  159. SchedulerSetPauseState(TRUE);
  160. }
  161. break;
  162. case PBT_APMQUERYSUSPENDFAILED:
  163. //
  164. // Suspension request denied - unpause the scheduler
  165. //
  166. SchedulerSetPauseState(FALSE);
  167. //
  168. // Notify drivers that we can resume
  169. //
  170. g_pDevMan->NotifyRunningDriversOfEvent(&WIA_EVENT_POWER_RESUME);
  171. break;
  172. case PBT_APMSUSPEND:
  173. //
  174. // Set the service state to paused
  175. //
  176. StiServicePause();
  177. uiTraceMessage = MSG_TRACE_PWR_SUSPEND;
  178. break;
  179. case PBT_APMRESUMECRITICAL:
  180. case PBT_APMRESUMEAUTOMATIC:
  181. // Operation resuming after critical suspension
  182. // Fall through
  183. case PBT_APMRESUMESUSPEND:
  184. //
  185. // Operation resuming after suspension
  186. // Restart all services which were active at the moment of suspend
  187. //
  188. //
  189. // ReEnumerate devices. NOTE: we should generate notification only events
  190. //
  191. g_pDevMan->ReEnumerateDevices(DEV_MAN_FULL_REFRESH | DEV_MAN_GEN_EVENTS);
  192. StiServiceResume();
  193. //
  194. // Notify drivers that we can resume
  195. //
  196. g_pDevMan->NotifyRunningDriversOfEvent(&WIA_EVENT_POWER_RESUME);
  197. uiTraceMessage = MSG_TRACE_PWR_RESUME;
  198. g_fFirstDevNodeChangeMsg = TRUE;
  199. break;
  200. default:
  201. //
  202. // This is a message we either don't know about, or have nothing to do.
  203. // In either case, we must return NO_ERROR, else the PnP Manager
  204. // will assume we're veto'ing the power request.
  205. //
  206. dwRet = NO_ERROR;
  207. }
  208. return dwRet;
  209. }
  210. HRESULT CMsgHandler::HandleCustomEvent(
  211. DWORD dwEventType)
  212. {
  213. HRESULT hr = S_OK;
  214. switch (dwEventType) {
  215. case STI_SERVICE_CONTROL_EVENT_REREAD :
  216. //
  217. // For each AVTICE_DEVICE we have, re-read the device settings
  218. //
  219. hr = g_pDevMan->ForEachDeviceInList(DEV_MAN_OP_DEV_REREAD, 0);
  220. if (FAILED(hr)) {
  221. DBG_WRN(("::CMsgHandler::HandleCustomEvent, unable to re-read device settings"));
  222. }
  223. break;
  224. default:
  225. //
  226. // Default case is to refresh our device list
  227. //
  228. hr = g_pDevMan->ReEnumerateDevices(DEV_MAN_FULL_REFRESH | DEV_MAN_GEN_EVENTS);
  229. if (FAILED(hr)) {
  230. DBG_WRN(("::CMsgHandler::HandleCustomEvent, unable to enumerate devices"));
  231. }
  232. }
  233. return hr;
  234. }
  235. HRESULT CMsgHandler::Initialize()
  236. {
  237. //
  238. // Nothing to do for now
  239. //
  240. return S_OK;
  241. }