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.

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