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.

668 lines
20 KiB

  1. /*
  2. * title: hidbatt.c
  3. *
  4. * purpose: wdm kernel client interface between HID class and power class
  5. *
  6. * Initial checkin for the hid to battery class driver. This should be
  7. * the same for both Win 98 and NT 5. Alpha level source. Requires
  8. * modified composite battery driver and modified battery class driver for
  9. * windows 98 support
  10. *
  11. */
  12. #include "hidbatt.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(INIT,DriverEntry)
  15. #endif
  16. // Global
  17. ULONG HidBattDebug = HIDBATT_PRINT_NEVER;
  18. USHORT HidBreakFlag = HIDBATT_BREAK_NEVER;
  19. USHORT gusInstance = 0;
  20. //
  21. // Device Names
  22. //
  23. #define HidBattDeviceName L"\\Device\\HIDBattery"
  24. // local protos
  25. NTSTATUS
  26. HidBattSystemControl(
  27. IN PDEVICE_OBJECT DeviceObject,
  28. IN PIRP Irp
  29. );
  30. NTSTATUS
  31. DriverEntry(
  32. IN PDRIVER_OBJECT DriverObject,
  33. IN PUNICODE_STRING RegistryPath
  34. )
  35. {
  36. NTSTATUS status;
  37. HidBattPrint (HIDBATT_TRACE, ("HidBatt:DriverEntry\n"));
  38. HIDDebugBreak(HIDBATT_BREAK_FULL);
  39. /************************************************************************************/
  40. /* */
  41. /* fill in the slots for the functions in */
  42. /* the Driver object. */
  43. /* */
  44. /************************************************************************************/
  45. DriverObject->MajorFunction[IRP_MJ_CREATE] = HidBattOpen;
  46. DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidBattClose;
  47. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HidBattIoControl;
  48. DriverObject->MajorFunction[IRP_MJ_POWER] = HidBattPowerDispatch;
  49. DriverObject->MajorFunction[IRP_MJ_PNP] = HidBattPnpDispatch;
  50. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidBattSystemControl; // pass down to hid class
  51. DriverObject->DriverUnload = HidBattUnload; // this is unloadable with current rev of battery class
  52. DriverObject->DriverExtension->AddDevice = HidBattAddDevice;
  53. return STATUS_SUCCESS;
  54. }
  55. NTSTATUS
  56. HidBattAddDevice(
  57. IN PDRIVER_OBJECT DriverObject,
  58. IN PDEVICE_OBJECT pHidPdo
  59. )
  60. {
  61. BOOL bResult;
  62. PUNICODE_STRING unicodeString;
  63. PDEVICE_OBJECT pBatteryFdo = NULL;
  64. NTSTATUS ntStatus;
  65. CBatteryDevExt * pDevExt;
  66. UNICODE_STRING numberString;
  67. WCHAR numberBuffer[10];
  68. CUString * pBatteryName;
  69. // enters here with pdo of hidclass - power class object
  70. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  71. HidBattPrint (HIDBATT_TRACE, ("HidBattAddDevice\n"));
  72. /* sberard - Removed due to changes in hidclass.sys (bug #274422)
  73. HID_COLLECTION_INFORMATION HidInfo;
  74. RtlZeroMemory(&HidInfo,sizeof(HID_COLLECTION_INFORMATION));
  75. ntStatus = DoIoctl(
  76. pHidPdo,
  77. IOCTL_HID_GET_COLLECTION_INFORMATION,
  78. NULL,
  79. 0,
  80. &HidInfo,
  81. sizeof(HID_COLLECTION_INFORMATION),
  82. (CHidDevice *) NULL
  83. );
  84. if(NT_ERROR(ntStatus))
  85. {
  86. HidBattPrint (HIDBATT_ERROR_ONLY, ("HidBattAddDevice: IOCTL_HID_GET_COLLECTION_INFORMATION failed 0x%08x\n", ntStatus));
  87. return STATUS_UNSUCCESSFUL;
  88. }
  89. */
  90. // too early to communicate with device, stash hid pdo and complete
  91. pBatteryName = new (NonPagedPool, HidBattTag) CUString(HidBattDeviceName);
  92. if (!pBatteryName) {
  93. return STATUS_INSUFFICIENT_RESOURCES;
  94. }
  95. // Create the UPS PDO device name based on the battery instance
  96. //
  97. CUString * pInstanceNumber = new (NonPagedPool, HidBattTag) CUString(++gusInstance,10);
  98. if (!pInstanceNumber) {
  99. return STATUS_INSUFFICIENT_RESOURCES;
  100. }
  101. pBatteryName->Append(&pInstanceNumber->m_String);
  102. delete pInstanceNumber;
  103. ntStatus = IoCreateDevice(
  104. DriverObject,
  105. sizeof (CBatteryDevExt),
  106. &pBatteryName->m_String,
  107. FILE_DEVICE_BATTERY,
  108. 0,
  109. FALSE,
  110. &pBatteryFdo
  111. );
  112. if (ntStatus != STATUS_SUCCESS) {
  113. HidBattPrint(HIDBATT_ERROR, ("HidBattCreateFdo: error (0x%x) creating device object\n", ntStatus));
  114. delete pBatteryName;
  115. --gusInstance; // reflect loss of device to instance
  116. return(ntStatus);
  117. }
  118. // pBatteryFdo->DeviceExtension = new (NonPagedPool, HidBattTag) CBatteryDevExt;
  119. // pBatteryFdo->StackSize++; // add one stack entry for battery class
  120. // layer the battery pdo to the hid class pdo
  121. // so that we begin to receive the device irps
  122. PDEVICE_OBJECT pHidDeviceObject = IoAttachDeviceToDeviceStack(pBatteryFdo,pHidPdo);
  123. pDevExt = (CBatteryDevExt *) pBatteryFdo->DeviceExtension;
  124. pDevExt->m_RegistryPath.Length = 0;
  125. pDevExt->m_RegistryPath.MaximumLength = sizeof(pDevExt->m_RegistryBuffer);
  126. RtlZeroMemory(&pDevExt->m_RegistryBuffer, sizeof(pDevExt->m_RegistryBuffer));
  127. pDevExt->m_RegistryPath.Buffer = &pDevExt->m_RegistryBuffer[0]; // set buffer pointer
  128. pDevExt->m_pBattery = NULL;
  129. pBatteryFdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
  130. pBatteryFdo->Flags &= ~DO_DEVICE_INITIALIZING;
  131. pDevExt->m_pHidPdo = pHidPdo;
  132. pDevExt->m_pBatteryFdo = pBatteryFdo;
  133. pDevExt->m_pLowerDeviceObject = pHidDeviceObject;
  134. pDevExt->m_eExtType = eBatteryDevice;
  135. pDevExt->m_bFirstStart = TRUE;
  136. pDevExt->m_bJustStarted = FALSE;
  137. pDevExt->m_ulDefaultAlert1 = (ULONG)-1;
  138. pDevExt->m_pBatteryName = pBatteryName;
  139. IoInitializeRemoveLock (&pDevExt->m_RemoveLock, HidBattTag, 10, 20);
  140. IoInitializeRemoveLock (&pDevExt->m_StopLock, HidBattTag, 10, 20);
  141. IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
  142. IoReleaseRemoveLockAndWait (&pDevExt->m_StopLock, (PVOID) HidBattTag);
  143. return STATUS_SUCCESS;
  144. }
  145. NTSTATUS
  146. HidBattOpen(
  147. IN PDEVICE_OBJECT pDeviceObject,
  148. IN PIRP pIrp
  149. )
  150. {
  151. NTSTATUS ntStatus = STATUS_SUCCESS;
  152. PIO_STACK_LOCATION irpSp;
  153. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  154. HidBattPrint (HIDBATT_TRACE, ("HidBattOpen\n"));
  155. CBatteryDevExt * pDevExt = (CBatteryDevExt *) pDeviceObject->DeviceExtension;
  156. if (NT_SUCCESS (IoAcquireRemoveLock (&pDevExt->m_RemoveLock, (PVOID) HidBattTag))) {
  157. IoSkipCurrentIrpStackLocation (pIrp);
  158. ntStatus = IoCallDriver(pDevExt->m_pLowerDeviceObject, pIrp);
  159. HidBattPrint (HIDBATT_NOTE, ("HidBattOpen: lower driver returned 0x%08x\n", ntStatus));
  160. IoReleaseRemoveLock (&pDevExt->m_RemoveLock, (PVOID) HidBattTag);
  161. } else {
  162. ntStatus = STATUS_NO_SUCH_DEVICE;
  163. pIrp->IoStatus.Status = ntStatus;
  164. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  165. }
  166. return ntStatus;
  167. }
  168. NTSTATUS
  169. HidBattClose(
  170. IN PDEVICE_OBJECT pDeviceObject,
  171. IN PIRP pIrp
  172. )
  173. {
  174. NTSTATUS ntStatus = STATUS_SUCCESS;
  175. PIO_STACK_LOCATION irpSp;
  176. HidBattPrint (HIDBATT_TRACE, ("HidBattClose\n"));
  177. // get the device extension
  178. CBatteryDevExt * pDevExt = (CBatteryDevExt *) pDeviceObject->DeviceExtension;
  179. HidBattCallLowerDriver(ntStatus, pDevExt->m_pLowerDeviceObject, pIrp);
  180. HidBattPrint (HIDBATT_NOTE, ("HidBattClose: lower driver returned 0x%08x\n", ntStatus));
  181. return ntStatus;
  182. }
  183. NTSTATUS
  184. HidBattSystemControl(
  185. IN PDEVICE_OBJECT pDeviceObject,
  186. IN PIRP pIrp
  187. )
  188. {
  189. HidBattPrint (HIDBATT_TRACE, ("HidBattSystemControl\n"));
  190. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  191. // all system control calls are passed down for now.
  192. NTSTATUS ntStatus = STATUS_SUCCESS;
  193. CBatteryDevExt * pDevExt = (CBatteryDevExt *) pDeviceObject->DeviceExtension;
  194. HidBattCallLowerDriver(ntStatus,pDevExt->m_pLowerDeviceObject,pIrp);
  195. return ntStatus;
  196. }
  197. VOID
  198. HidBattUnload(
  199. IN PDRIVER_OBJECT pDriverObject
  200. )
  201. {
  202. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  203. // we can just return, no driver-only (non-device) resources were allocated
  204. return;
  205. }
  206. NTSTATUS
  207. HidBattPnpDispatch(
  208. IN PDEVICE_OBJECT pDeviceObject,
  209. IN PIRP pIrp
  210. )
  211. {
  212. /*++
  213. Routine Description:
  214. This routine is the dispatch routine for plug and play requests.
  215. Arguments:
  216. DeviceObject - Pointer to class device object.
  217. Irp - Pointer to the request packet.
  218. Return Value:
  219. Status is returned.
  220. --*/
  221. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  222. PIO_STACK_LOCATION pIrpStack;
  223. CBatteryDevExt * pDevExt;
  224. NTSTATUS ntStatus;
  225. BOOLEAN lockReleased = FALSE;
  226. // PAGED_CODE();
  227. ntStatus = STATUS_NOT_SUPPORTED;
  228. //
  229. // Get a pointer to the current parameters for this request. The
  230. // information is contained in the current stack location.
  231. //
  232. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  233. pDevExt = (CBatteryDevExt *) pDeviceObject->DeviceExtension;
  234. IoAcquireRemoveLock (&pDevExt->m_RemoveLock, (PVOID) HidBattTag);
  235. //
  236. // Dispatch minor function
  237. //
  238. switch (pIrpStack->MinorFunction)
  239. {
  240. case IRP_MN_STOP_DEVICE:
  241. {
  242. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_STOP_DEVICE\n"));
  243. ntStatus = HidBattStopDevice(pDeviceObject, pIrp);
  244. break;
  245. } // IRP_MN_STOP_DEVICE
  246. case IRP_MN_QUERY_DEVICE_RELATIONS:
  247. {
  248. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_QUERY_DEVICE_RELATIONS - type (%d)\n",
  249. pIrpStack->Parameters.QueryDeviceRelations.Type));
  250. break;
  251. } // IRP_MN_QUERY_DEVICE_RELATIONS
  252. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
  253. {
  254. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_FILTER_RESOURCE_REQUIREMENTS - type (%d)\n",
  255. pIrpStack->Parameters.QueryDeviceRelations.Type));
  256. break;
  257. } // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
  258. case IRP_MN_REMOVE_DEVICE:
  259. {
  260. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_REMOVE_DEVICE\n"));
  261. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: Waiting to remove\n"));
  262. IoReleaseRemoveLockAndWait (&pDevExt->m_RemoveLock, (PVOID) HidBattTag);
  263. lockReleased = TRUE;
  264. // then remove device from device stack
  265. IoDetachDevice(pDevExt->m_pLowerDeviceObject);
  266. // delete our device
  267. IoDeleteDevice(pDeviceObject);
  268. ntStatus = STATUS_SUCCESS;
  269. break;
  270. } // IRP_MN_REMOVE_DEVICE
  271. case IRP_MN_SURPRISE_REMOVAL:
  272. case IRP_MN_QUERY_REMOVE_DEVICE:
  273. {
  274. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_QUERY_REMOVE_DEVICE\n"));
  275. ntStatus = HidBattStopDevice(pDeviceObject, pIrp);
  276. ntStatus = STATUS_SUCCESS;
  277. break;
  278. } // IRP_MN_QUERY_REMOVE_DEVICE
  279. case IRP_MN_START_DEVICE:
  280. {
  281. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_START_DEVICE\n"));
  282. if (pDevExt->m_bFirstStart) {
  283. pDevExt->m_bJustStarted = TRUE;
  284. pDevExt->m_bFirstStart = FALSE;
  285. ntStatus = STATUS_SUCCESS;
  286. break;
  287. }
  288. // else fall through and do the same thing as the cancel remove.
  289. } // IRP_MN_START_DEVICE
  290. case IRP_MN_CANCEL_REMOVE_DEVICE:
  291. {
  292. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_CANCEL_REMOVE_DEVICE\n"));
  293. KEVENT cancelRemoveComplete;
  294. KeInitializeEvent(&cancelRemoveComplete, SynchronizationEvent, FALSE);
  295. IoCopyCurrentIrpStackLocationToNext (pIrp);
  296. IoSetCompletionRoutine (pIrp, HidBattIoCompletion, &cancelRemoveComplete, TRUE, TRUE, TRUE);
  297. pIrp->IoStatus.Status = STATUS_SUCCESS;
  298. ntStatus = IoCallDriver (pDevExt->m_pLowerDeviceObject, pIrp);
  299. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_CANCEL_REMOVE_DEVICE, Lower driver status: %08x\n", ntStatus));
  300. if (ntStatus == STATUS_PENDING) {
  301. KeWaitForSingleObject (&cancelRemoveComplete, Executive, KernelMode, FALSE, NULL);
  302. ntStatus = pIrp->IoStatus.Status;
  303. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_CANCEL_REMOVE_DEVICE, Lower driver 2nd status: %08x\n", ntStatus));
  304. }
  305. if (NT_SUCCESS (ntStatus)) {
  306. ntStatus = HidBattInitializeDevice (pDeviceObject, pIrp);
  307. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_CANCEL_REMOVE_DEVICE, Our status: %08x\n", ntStatus));
  308. }
  309. pIrp->IoStatus.Status = ntStatus;
  310. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  311. IoReleaseRemoveLock (&pDevExt->m_RemoveLock, (PVOID) HidBattTag);
  312. return ntStatus;
  313. } // IRP_MN_CANCEL_REMOVE_DEVICE
  314. case IRP_MN_QUERY_STOP_DEVICE:
  315. {
  316. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_QUERY_STOP_DEVICE\n"));
  317. ntStatus = STATUS_SUCCESS;
  318. break;
  319. } // IRP_MN_QUERY_STOP_DEVICE
  320. case IRP_MN_CANCEL_STOP_DEVICE:
  321. {
  322. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_CANCEL_STOP_DEVICE\n"));
  323. ntStatus = STATUS_SUCCESS;
  324. break;
  325. } // IRP_MN_CANCEL_STOP_DEVICE
  326. case IRP_MN_QUERY_RESOURCES:
  327. {
  328. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_QUERY_RESOURCES\n"));
  329. break;
  330. } // IRP_MN_QUERY_RESOURCES
  331. case IRP_MN_READ_CONFIG:
  332. {
  333. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_READ_CONFIG\n"));
  334. break;
  335. } // IRP_MN_READ_CONFIG
  336. case IRP_MN_WRITE_CONFIG:
  337. {
  338. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_WRITE_CONFIG\n"));
  339. break;
  340. } // IRP_MN_WRITE_CONFIG
  341. case IRP_MN_EJECT:
  342. {
  343. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_EJECT\n"));
  344. break;
  345. } // IRP_MN_EJECT
  346. case IRP_MN_SET_LOCK:
  347. {
  348. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_SET_LOCK\n"));
  349. break;
  350. } // IRP_MN_SET_LOCK
  351. case IRP_MN_QUERY_ID:
  352. {
  353. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_QUERY_ID\n"));
  354. break;
  355. } // IRP_MN_QUERY_ID
  356. case IRP_MN_QUERY_CAPABILITIES:
  357. {
  358. PDEVICE_CAPABILITIES deviceCaps;
  359. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_QUERY_CAPABILITIES\n"));
  360. deviceCaps = pIrpStack->Parameters.DeviceCapabilities.Capabilities;
  361. deviceCaps->Removable = TRUE;
  362. deviceCaps->SurpriseRemovalOK = TRUE;
  363. ntStatus = STATUS_SUCCESS;
  364. break;
  365. } // IRP_MN_QUERY_CAPABILITIES
  366. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  367. {
  368. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: IRP_MN_PNP_DEVICE_STATE\n"));
  369. if (pDevExt->m_bJustStarted == TRUE) {
  370. pDevExt->m_bJustStarted = FALSE;
  371. ntStatus = HidBattInitializeDevice (pDeviceObject, pIrp);
  372. }
  373. if (!NT_SUCCESS (ntStatus)) {
  374. HidBattPrint (HIDBATT_PNP, ("HidBattPnpDispatch: HidBattInitializeDevice failed %0x\n", ntStatus));
  375. pIrp->IoStatus.Information |= PNP_DEVICE_FAILED;
  376. pIrp->IoStatus.Status = STATUS_SUCCESS;
  377. }
  378. break;
  379. } // IRP_MN_PNP_DEVICE_STATE
  380. default:
  381. {
  382. HidBattPrint (HIDBATT_PNP,
  383. ("HidBattPnpDispatch: Unimplemented minor %0x\n",
  384. pIrpStack->MinorFunction));
  385. break;
  386. }
  387. }
  388. if (ntStatus != STATUS_NOT_SUPPORTED) {
  389. pIrp->IoStatus.Status = ntStatus;
  390. }
  391. if (NT_SUCCESS(ntStatus) || (ntStatus == STATUS_NOT_SUPPORTED)) {
  392. HidBattCallLowerDriver (ntStatus, pDevExt->m_pLowerDeviceObject, pIrp);
  393. } else {
  394. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  395. }
  396. if (lockReleased == FALSE) {
  397. IoReleaseRemoveLock (&pDevExt->m_RemoveLock, (PVOID) HidBattTag);
  398. }
  399. return ntStatus;
  400. }
  401. NTSTATUS
  402. HidBattPowerDispatch(
  403. IN PDEVICE_OBJECT pDeviceObject,
  404. IN PIRP pIrp
  405. )
  406. /*++
  407. Routine Description:
  408. This routine is the dispatch routine for power requests.
  409. Arguments:
  410. DeviceObject - Pointer to class device object.
  411. Irp - Pointer to the request packet.
  412. Return Value:
  413. Status is returned.
  414. --*/
  415. {
  416. PIO_STACK_LOCATION pIrpStack;
  417. CBatteryDevExt * pDevExt;
  418. NTSTATUS ntStatus;
  419. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  420. // PAGED_CODE();
  421. HidBattPrint ((HIDBATT_TRACE | HIDBATT_POWER), ("HidBattPowerDispatch\n"));
  422. //
  423. // Never fail a power IRP, even if we don't do anything.
  424. //
  425. ntStatus = STATUS_SUCCESS;
  426. pIrp->IoStatus.Information = 0;
  427. //
  428. // Get a pointer to the current parameters for this request. The
  429. // information is contained in the current stack location.
  430. //
  431. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  432. pDevExt = (CBatteryDevExt *) pDeviceObject->DeviceExtension;
  433. //
  434. // Dispatch minor function
  435. //
  436. // this switch currently does no dispatches, and is expanded only for
  437. // documentary purposes
  438. switch (pIrpStack->MinorFunction) {
  439. case IRP_MN_WAIT_WAKE: {
  440. HidBattPrint (HIDBATT_POWER, ("HidBattPowerDispatch: IRP_MN_WAIT_WAKE\n"));
  441. break;
  442. }
  443. case IRP_MN_POWER_SEQUENCE: {
  444. HidBattPrint (HIDBATT_POWER, ("HidBattPowerDispatch: IRP_MN_POWER_SEQUENCE\n"));
  445. break;
  446. }
  447. case IRP_MN_SET_POWER: {
  448. HidBattPrint (HIDBATT_POWER, ("HidBattPowerDispatch: IRP_MN_SET_POWER\n"));
  449. if (pIrpStack->Parameters.Power.Type == SystemPowerState &&
  450. pIrpStack->Parameters.Power.State.SystemState >= PowerSystemShutdown) {
  451. if (NT_SUCCESS(IoAcquireRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag)) )
  452. {
  453. //
  454. // Write default RemainingCapcitylimit back to UPS so when the system reboots,
  455. // the data returned by the device will be correct.
  456. //
  457. pDevExt->m_pBattery->GetSetValue(REMAINING_CAPACITY_LIMIT_INDEX,
  458. &pDevExt->m_ulDefaultAlert1,TRUE);
  459. IoReleaseRemoveLock (&pDevExt->m_StopLock, (PVOID) HidBattTag);
  460. }
  461. }
  462. break;
  463. }
  464. case IRP_MN_QUERY_POWER: {
  465. HidBattPrint (HIDBATT_POWER, ("HidBattPowerDispatch: IRP_MN_QUERY_POWER\n"));
  466. break;
  467. }
  468. default: {
  469. HidBattPrint(HIDBATT_LOW, ("HidBattPowerDispatch: minor %d\n",
  470. pIrpStack->MinorFunction));
  471. break;
  472. }
  473. }
  474. PoStartNextPowerIrp(pIrp); // inform system we are done with this irp
  475. IoSkipCurrentIrpStackLocation(pIrp);
  476. ntStatus = PoCallDriver(pDevExt->m_pLowerDeviceObject,pIrp);
  477. return ntStatus;
  478. }
  479. NTSTATUS HidBattSetInformation(
  480. IN PVOID Context,
  481. IN ULONG BatteryTag,
  482. IN BATTERY_SET_INFORMATION_LEVEL Level,
  483. IN PVOID Buffer OPTIONAL
  484. )
  485. {
  486. /*
  487. Routine Description:
  488. Called by the class driver to set the battery's charge/discharge state.
  489. The smart battery does not support the critical bias function of this
  490. call.
  491. Arguments:
  492. Context - Miniport context value for battery
  493. BatteryTag - Tag of current battery
  494. Level - Action being asked for
  495. Return Value:
  496. NTSTATUS
  497. --*/
  498. // charge and discharge forcing not supported for UPS's
  499. HidBattPrint (HIDBATT_TRACE, ("HidBattSetInformation\n"));
  500. HIDDebugBreak(HIDBATT_BREAK_ALWAYS);
  501. return STATUS_UNSUCCESSFUL;
  502. }