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.

419 lines
11 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. ci.c
  5. Abstract:
  6. Battery Class Installer
  7. Author:
  8. Scott Brenden
  9. Environment:
  10. Notes:
  11. Revision History:
  12. --*/
  13. #include "proj.h"
  14. #include <initguid.h>
  15. #include <devguid.h>
  16. #ifdef DEBUG
  17. DWORD BattDebugPrintLevel = TF_ERROR | TF_WARNING;
  18. #endif
  19. BOOL APIENTRY LibMain(
  20. HANDLE hDll,
  21. DWORD dwReason,
  22. LPVOID lpReserved)
  23. {
  24. switch( dwReason ) {
  25. case DLL_PROCESS_ATTACH:
  26. TRACE_MSG (TF_FUNC, ("Battery Class Installer Loaded\n"));
  27. DisableThreadLibraryCalls(hDll);
  28. break;
  29. case DLL_PROCESS_DETACH:
  30. break;
  31. default:
  32. break;
  33. }
  34. return TRUE;
  35. }
  36. DWORD
  37. APIENTRY
  38. BatteryClassInstall(
  39. IN DI_FUNCTION DiFunction,
  40. IN HDEVINFO DevInfoHandle,
  41. IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
  42. )
  43. /*++
  44. Routine Description:
  45. This function is the class installer entry-point.
  46. Arguments:
  47. DiFunction - Requested installation function
  48. DevInfoHandle - Handle to a device information set
  49. DevInfoData - Pointer to device information about device to install
  50. Return Value:
  51. --*/
  52. {
  53. DWORD status;
  54. SP_DEVINSTALL_PARAMS devParams;
  55. //
  56. // Get the DeviceInstallParams, because some of the InstallFunction
  57. // handlers may find some of its fields useful. Keep in mind not
  58. // to set the DeviceInstallParams using this same structure at the
  59. // end. The handlers may have called functions which would change the
  60. // DeviceInstallParams, and simply calling SetupDiSetDeviceInstallParams
  61. // with this blanket structure would destroy those settings.
  62. //
  63. devParams.cbSize = sizeof(devParams);
  64. if (!SetupDiGetDeviceInstallParams(DevInfoHandle, DevInfoData, &devParams))
  65. {
  66. status = GetLastError();
  67. } else {
  68. TRACE_MSG (TF_GENERAL, ("DiFunction = %x\n", DiFunction));
  69. //
  70. // Dispatch the InstallFunction
  71. //
  72. switch (DiFunction) {
  73. case DIF_INSTALLDEVICE:
  74. status = InstallCompositeBattery (DevInfoHandle, DevInfoData, &devParams);
  75. if (status == ERROR_SUCCESS) {
  76. //
  77. // Let the default device installer actually install the battery.
  78. //
  79. status = ERROR_DI_DO_DEFAULT;
  80. }
  81. break;
  82. default:
  83. status = ERROR_DI_DO_DEFAULT;
  84. break;
  85. }
  86. }
  87. return status;
  88. }
  89. DWORD
  90. PRIVATE
  91. InstallCompositeBattery (
  92. IN HDEVINFO DevInfoHandle,
  93. IN PSP_DEVINFO_DATA DevInfoData, OPTIONAL
  94. IN OUT PSP_DEVINSTALL_PARAMS DevInstallParams
  95. )
  96. /*++
  97. Routine Description:
  98. This function installs the composite battery if it hasn't already been
  99. installed.
  100. Arguments:
  101. DevInfoHandle - Handle to a device information set
  102. DevInfoData - Pointer to device information about device to install
  103. DevInstallParams - Device install parameters associated with device
  104. Return Value:
  105. --*/
  106. {
  107. DWORD status;
  108. PSP_DEVINFO_DATA newDevInfoData;
  109. HDEVINFO newDevInfoHandle;
  110. SP_DRVINFO_DATA driverInfoData;
  111. //
  112. // Allocate local memory for a new device info structure
  113. //
  114. if(!(newDevInfoData = LocalAlloc(LPTR, sizeof(SP_DEVINFO_DATA)))) {
  115. status = GetLastError();
  116. TRACE_MSG (TF_ERROR, ("Couldn't allocate composite battery device info- %x\n", status));
  117. goto clean0;
  118. }
  119. //
  120. // Create a new device info list. Since we are "manufacturing" a completely new
  121. // device with the Composite Battery, we can't use any of the information from
  122. // the battery device list.
  123. //
  124. newDevInfoHandle = SetupDiCreateDeviceInfoList ((LPGUID)&GUID_DEVCLASS_SYSTEM, DevInstallParams->hwndParent);
  125. if (newDevInfoHandle == INVALID_HANDLE_VALUE) {
  126. status = GetLastError();
  127. TRACE_MSG (TF_ERROR, ("Can't create DevInfoList - %x\n", status));
  128. goto clean1;
  129. }
  130. //
  131. // Attempt to manufacture a new device information element for the root enumerated
  132. // composite battery.
  133. //
  134. newDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
  135. if(!SetupDiCreateDeviceInfo(newDevInfoHandle,
  136. TEXT("Root\\COMPOSITE_BATTERY\\0000"),
  137. (LPGUID)&GUID_DEVCLASS_SYSTEM,
  138. NULL,
  139. DevInstallParams->hwndParent, // same parent window as enumerated device
  140. 0,
  141. newDevInfoData)) {
  142. status = GetLastError();
  143. if (status == ERROR_DEVINST_ALREADY_EXISTS) {
  144. //
  145. // The composite battery is already installed. Our work is done.
  146. //
  147. TRACE_MSG (TF_GENERAL, ("Composite Battery Already Installed\n"));
  148. status = ERROR_SUCCESS;
  149. goto clean2;
  150. } else {
  151. TRACE_MSG (TF_ERROR, ("Error creating composite battery devinfo - %x\n", status));
  152. goto clean2;
  153. }
  154. }
  155. //
  156. // Register the device so it is not a phantom anymore
  157. //
  158. if (!SetupDiRegisterDeviceInfo(newDevInfoHandle, newDevInfoData, 0, NULL, NULL, NULL)) {
  159. status = GetLastError();
  160. TRACE_MSG (TF_ERROR, ("Couldn't register device - %x\n", status));
  161. goto clean3;
  162. }
  163. //
  164. // Set the hardware ID. For the composite battery it will be COMPOSITE_BATTERY
  165. //
  166. status = SetupDiSetDeviceRegistryProperty (
  167. newDevInfoHandle,
  168. newDevInfoData,
  169. SPDRP_HARDWAREID,
  170. TEXT("COMPOSITE_BATTERY\0"),
  171. sizeof(TEXT("COMPOSITE_BATTERY\0"))
  172. );
  173. if (!status) {
  174. status = GetLastError();
  175. TRACE_MSG(TF_ERROR, ("Couldn't set the HardwareID - %x\n", status));
  176. goto clean3;
  177. }
  178. //
  179. // Build a compatible driver list for this new device...
  180. //
  181. if(!SetupDiBuildDriverInfoList(newDevInfoHandle, newDevInfoData, SPDIT_COMPATDRIVER)) {
  182. status = GetLastError();
  183. TRACE_MSG(TF_ERROR, ("Couldn't build class driver list - %x\n", status));
  184. goto clean3;
  185. }
  186. //
  187. // Select the first driver in the list as this will be the most compatible
  188. //
  189. driverInfoData.cbSize = sizeof (SP_DRVINFO_DATA);
  190. if (!SetupDiEnumDriverInfo(newDevInfoHandle, newDevInfoData, SPDIT_COMPATDRIVER, 0, &driverInfoData)) {
  191. status = GetLastError();
  192. TRACE_MSG(TF_ERROR, ("Couldn't get driver list - %x\n", status));
  193. goto clean3;
  194. } else {
  195. TRACE_MSG(TF_GENERAL,("Driver info - \n"
  196. "------------- DriverType %x\n"
  197. "------------- Description %s\n"
  198. "------------- MfgName %s\n"
  199. "------------- ProviderName %s\n\n",
  200. driverInfoData.DriverType,
  201. driverInfoData.Description,
  202. driverInfoData.MfgName,
  203. driverInfoData.ProviderName));
  204. if (!SetupDiSetSelectedDriver(newDevInfoHandle, newDevInfoData, &driverInfoData)) {
  205. status = GetLastError();
  206. TRACE_MSG (TF_ERROR, ("Couldn't select driver - %x\n", status));
  207. goto clean4;
  208. }
  209. }
  210. //
  211. // Install the device
  212. //
  213. if (!SetupDiInstallDevice (newDevInfoHandle, newDevInfoData)) {
  214. status = GetLastError();
  215. TRACE_MSG (TF_ERROR, ("Couldn't install device - %x\n", status));
  216. goto clean4;
  217. }
  218. //
  219. // If we got here we were successful
  220. //
  221. status = ERROR_SUCCESS;
  222. SetLastError (status);
  223. goto clean1;
  224. clean4:
  225. SetupDiDestroyDriverInfoList (newDevInfoHandle, newDevInfoData, SPDIT_COMPATDRIVER);
  226. clean3:
  227. SetupDiDeleteDeviceInfo (newDevInfoHandle, newDevInfoData);
  228. clean2:
  229. SetupDiDestroyDeviceInfoList (newDevInfoHandle);
  230. clean1:
  231. LocalFree (newDevInfoData);
  232. clean0:
  233. return status;
  234. }
  235. DWORD
  236. APIENTRY
  237. BatteryClassCoInstaller (
  238. IN DI_FUNCTION InstallFunction,
  239. IN HDEVINFO DeviceInfoSet,
  240. IN PSP_DEVINFO_DATA DeviceInfoData,
  241. IN OUT PCOINSTALLER_CONTEXT_DATA Context
  242. )
  243. {
  244. SYSTEM_BATTERY_STATE batteryState;
  245. GLOBAL_POWER_POLICY powerPolicy;
  246. NTSTATUS Status;
  247. int i;
  248. UINT policyId;
  249. DWORD RetVal;
  250. if ((InstallFunction != DIF_INSTALLDEVICE) && (InstallFunction != DIF_REMOVE)) {
  251. //
  252. // Only handle DIF_INSTALLDEVICE or DIF_REMOVE request
  253. //
  254. return (NO_ERROR);
  255. }
  256. if (!Context->PostProcessing) {
  257. //
  258. // Wait until device is installed before Adjusting levels
  259. //
  260. return (ERROR_DI_POSTPROCESSING_REQUIRED);
  261. }
  262. RetVal = NO_ERROR;
  263. Status = NtPowerInformation (SystemBatteryState, NULL, 0, &batteryState, sizeof(batteryState));
  264. if (NT_SUCCESS(Status)) {
  265. if ((batteryState.BatteryPresent) && (batteryState.MaxCapacity != 0)) {
  266. //
  267. // Don't try to adjust levels if for some reason no battery was installed.
  268. //
  269. if (ReadGlobalPwrPolicy (&powerPolicy)) {
  270. if (powerPolicy.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel <
  271. (100 * batteryState.DefaultAlert1)/batteryState.MaxCapacity) {
  272. //
  273. // If Critical level is less than DefaultAlert1, this idicates the settings
  274. // are messed up. Reset both the Critical and the Low setting.
  275. //
  276. powerPolicy.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel =
  277. (100 * batteryState.DefaultAlert1)/batteryState.MaxCapacity;
  278. powerPolicy.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel =
  279. (100 * batteryState.DefaultAlert2)/batteryState.MaxCapacity;
  280. //
  281. // commit the fixed settings.
  282. //
  283. if (!WriteGlobalPwrPolicy (&powerPolicy)) {
  284. RetVal = GetLastError();
  285. }
  286. //
  287. // now make sure we commit these settings to the current policy as well.
  288. //
  289. if (GetActivePwrScheme (&policyId)) {
  290. if (!SetActivePwrScheme (policyId, &powerPolicy, NULL)) {
  291. RetVal = GetLastError();
  292. }
  293. } else {
  294. RetVal = GetLastError();
  295. }
  296. }
  297. }
  298. }
  299. } else {
  300. RetVal = ERROR_INTERNAL_ERROR;
  301. }
  302. return(RetVal);
  303. }