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.

1725 lines
52 KiB

  1. /*******************************************************************************
  2. *
  3. * Copyright 1999 American Power Conversion, All Rights Reserved
  4. *
  5. * TITLE: UPSREG.C
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: SteveT
  10. *
  11. * DATE: 07 June, 1999
  12. *
  13. *******************************************************************************/
  14. /*
  15. * system includes
  16. */
  17. #include <windows.h>
  18. #include <tchar.h>
  19. /*
  20. * local includes
  21. */
  22. //#include "upsdefines.h"
  23. #include "upsreg.h"
  24. #include "regdefs.h"
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. /*
  29. * Reg entry info structure declaration
  30. */
  31. struct _reg_entry
  32. {
  33. HKEY hKey; /* the key */
  34. LPTSTR lpSubKey; /* address of SubKey name */
  35. LPTSTR lpValueName; /* address of name of value to query */
  36. DWORD ulType; /* buffer for value type */
  37. LPBYTE lpData; /* address of data buffer */
  38. DWORD cbData; /* data buffer size */
  39. BOOL changed; /* ID of dialog that changed this entry */
  40. };
  41. /*
  42. * local function pre-declarations
  43. */
  44. void freeBlock(struct _reg_entry *aBlock[]);
  45. void readBlock(struct _reg_entry *aBlock[], BOOL changed);
  46. void writeBlock(struct _reg_entry *aBlock[], BOOL forceAll);
  47. LONG setDwordValue(struct _reg_entry *aRegEntry, DWORD aValue);
  48. LONG setStringValue(struct _reg_entry *aRegEntry, LPCTSTR aBuffer);
  49. static BOOL isRegistryInitialized();
  50. static void CheckForUpgrade();
  51. static void InitializeServiceKeys();
  52. static void InitializeServiceProviders();
  53. static void InitializeConfigValues();
  54. static void InitializeStatusValues();
  55. /*
  56. * Reg entry value name declarations
  57. */
  58. #define UPS_VENDOR _T("Vendor")
  59. #define UPS_MODEL _T("Model")
  60. #define UPS_SERIALNUMBER _T("SerialNumber")
  61. #define UPS_FIRMWAREREV _T("FirmwareRev")
  62. #define UPS_UTILITYSTATUS _T("UtilityPowerStatus")
  63. #define UPS_RUNTIME _T("TotalUPSRuntime")
  64. #define UPS_BATTERYSTATUS _T("BatteryStatus")
  65. #define UPS_PORT _T("Port")
  66. #define UPS_OPTIONS _T("Options")
  67. #define UPS_SHUTDOWNWAIT _T("ShutdownWait")
  68. #define UPS_FIRSTMESSAGEDELAY _T("FirstMessageDelay")
  69. #define UPS_MESSAGEINTERVAL _T("MessageInterval")
  70. #define UPS_SERVICEDLL _T("ServiceProviderDLL")
  71. #define UPS_NOTIFYENABLE _T("NotifyEnable")
  72. #define UPS_SHUTBATTENABLE _T("ShutdownOnBatteryEnable")
  73. #define UPS_SHUTBATTWAIT _T("ShutdownOnBatteryWait")
  74. #define UPS_RUNTASKENABLE _T("RunTaskEnable")
  75. #define UPS_TASKNAME _T("TaskName")
  76. #define UPS_TURNUPSOFFENABLE _T("TurnUPSOffEnable")
  77. #define UPS_APCLINKURL _T("APCLinkURL")
  78. #define UPS_CUSTOMOPTIONS _T("CustomOptions")
  79. #define UPS_UPGRADE _T("Upgrade")
  80. #define UPS_COMMSTATUS _T("CommStatus")
  81. #define UPS_CRITICALPOWERACTION _T("CriticalPowerAction")
  82. #define UPS_TURNUPSOFFWAIT _T("TurnUPSOffWait")
  83. #define UPS_SHOWTAB _T("ShowUPSTab")
  84. #define UPS_BATTERYCAPACITY _T("BatteryCapacity")
  85. #define UPS_IMAGEPATH _T("ImagePath")
  86. #define UPS_ERRORCONTROL _T("ErrorControl")
  87. #define UPS_OBJECTNAME _T("ObjectName")
  88. #define UPS_START _T("Start")
  89. #define UPS_TYPE _T("Type")
  90. // This specifies the key to examine to determine if the registry
  91. // has been updated for the UPS Service.
  92. #define UPS_SERVICE_INITIALIZED_KEY TEXT("SYSTEM\\CurrentControlSet\\Services\\UPS\\Config")
  93. // Specifies the name of the BatteryLife key used in the NT 4.0 UPS Service
  94. #define UPS_BATTLIFE_KEY TEXT("BatteryLife")
  95. // This specifies the default name for the shutdown Task
  96. #define DEFAULT_SHUTDOWN_TASK_NAME TEXT("")
  97. // Default values for the Config settings
  98. #define DEFAULT_CONFIG_VENDOR_OLD TEXT("\\(NONE)")
  99. #define DEFAULT_CONFIG_VENDOR TEXT("")
  100. #define DEFAULT_CONFIG_MODEL TEXT("")
  101. #define DEFAULT_CONFIG_PORT TEXT("COM1")
  102. #define DEFAULT_CONFIG_OPTIONS 0x7e
  103. #define DEFAULT_CONFIG_FIRSTMSG_DELAY 5
  104. #define DEFAULT_CONFIG_MESSAGE_INTERVAL 120
  105. #define DEFAULT_CONFIG_PROVIDER_DLL TEXT("")
  106. #define DEFAULT_CONFIG_NOTIFY_ENABLE 1
  107. #define DEFAULT_CONFIG_SHUTDOWN_ONBATT_ENABLE FALSE
  108. #define DEFAULT_CONFIG_SHUTDOWN_ONBATT_WAIT 2
  109. #define DEFAULT_CONFIG_RUNTASK_ENABLE FALSE
  110. #define DEFAULT_CONFIG_TASK_NAME DEFAULT_SHUTDOWN_TASK_NAME
  111. #define DEFAULT_CONFIG_TURNOFF_UPS_ENABLE TRUE
  112. #define DEFAULT_CONFIG_CUSTOM_OPTIONS UPS_DEFAULT_SIGMASK
  113. #define DEFAULT_CONFIG_CRITICALPOWERACTION UPS_SHUTDOWN_SHUTDOWN
  114. #define DEFAULT_CONFIG_TURNOFF_UPS_WAIT 180
  115. #define DEFAULT_CONFIG_ERRORCONTROL 1
  116. #define DEFAULT_CONFIG_OBJECTNAME TEXT("LocalSystem")
  117. #define DEFAULT_CONFIG_START SERVICE_DEMAND_START
  118. #define DEFAULT_CONFIG_TYPE 16
  119. #define DEFAULT_CONFIG_SHOWUPSTAB FALSE
  120. // Default values for the Status settings
  121. #define DEFAULT_STATUS_SERIALNO TEXT("")
  122. #define DEFAULT_STATUS_FIRMWARE_REV TEXT("")
  123. #define DEFAULT_STATUS_UTILITY_STAT 0
  124. #define DEFAULT_STATUS_TOTAL_RUNTIME 0
  125. #define DEFAULT_STATUS_BATTERY_STAT 0
  126. #define DEFAULT_STATUS_BATTERY_CAPACITY 0
  127. // Default values for upgraded services
  128. #define UPGRADE_CONFIG_VENDOR_OLD TEXT("\\Generic")
  129. #define UPGRADE_CONFIG_VENDOR TEXT("")
  130. #define UPGRADE_CONFIG_MODEL TEXT("")
  131. /*
  132. * Allocate the individual Configuration Reg entry records
  133. */
  134. struct _reg_entry UPSConfigVendor = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_VENDOR,REG_SZ,NULL,0,FALSE};
  135. struct _reg_entry UPSConfigModel = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_MODEL,REG_SZ,NULL,0,FALSE};
  136. struct _reg_entry UPSConfigPort = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_PORT,REG_SZ,NULL,0,FALSE};
  137. struct _reg_entry UPSConfigOptions = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_OPTIONS,REG_DWORD,NULL,0,FALSE};
  138. struct _reg_entry UPSConfigServiceDLL = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_SERVICEDLL,REG_SZ,NULL,0,FALSE};
  139. struct _reg_entry UPSConfigNotifyEnable = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_NOTIFYENABLE,REG_DWORD,NULL,0,FALSE};
  140. struct _reg_entry UPSConfigFirstMessageDelay= {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_FIRSTMESSAGEDELAY,REG_DWORD,NULL,0,FALSE};
  141. struct _reg_entry UPSConfigMessageInterval = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_MESSAGEINTERVAL,REG_DWORD,NULL,0,FALSE};
  142. struct _reg_entry UPSConfigShutBattEnable = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_SHUTBATTENABLE,REG_DWORD,NULL,0,FALSE};
  143. struct _reg_entry UPSConfigShutBattWait = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_SHUTBATTWAIT,REG_DWORD,NULL,0,FALSE};
  144. struct _reg_entry UPSConfigRunTaskEnable = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_RUNTASKENABLE,REG_DWORD,NULL,0,FALSE};
  145. struct _reg_entry UPSConfigTaskName = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_TASKNAME,REG_SZ,NULL,0,FALSE};
  146. struct _reg_entry UPSConfigTurnOffEnable = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_TURNUPSOFFENABLE,REG_DWORD,NULL,0,FALSE};
  147. struct _reg_entry UPSConfigCustomOptions = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_CUSTOMOPTIONS,REG_DWORD,NULL,0,FALSE};
  148. struct _reg_entry UPSConfigAPCLinkURL = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_APCLINKURL,REG_SZ,NULL,0,FALSE};
  149. struct _reg_entry UPSConfigShutdownWait = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_SHUTDOWNWAIT,REG_DWORD,NULL,0,FALSE};
  150. struct _reg_entry UPSConfigUpgrade = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_UPGRADE,REG_DWORD,NULL,0,FALSE};
  151. struct _reg_entry UPSConfigCriticalPowerAction = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_CRITICALPOWERACTION,REG_DWORD,NULL,0,FALSE};
  152. struct _reg_entry UPSConfigTurnOffWait = {HKEY_LOCAL_MACHINE,UPS_CONFIG_ROOT,UPS_TURNUPSOFFWAIT,REG_DWORD,NULL,0,FALSE};
  153. struct _reg_entry UPSConfigImagePath = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_IMAGEPATH,REG_EXPAND_SZ,NULL,0,FALSE};
  154. struct _reg_entry UPSConfigObjectName = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_OBJECTNAME,REG_EXPAND_SZ,NULL,0,FALSE};
  155. struct _reg_entry UPSConfigErrorControl = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_ERRORCONTROL,REG_DWORD,NULL,0,FALSE};
  156. struct _reg_entry UPSConfigStart = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_START,REG_DWORD,NULL,0,FALSE};
  157. struct _reg_entry UPSConfigType = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_TYPE,REG_DWORD,NULL,0,FALSE};
  158. struct _reg_entry UPSConfigShowUPSTab = {HKEY_LOCAL_MACHINE,UPS_DEFAULT_ROOT,UPS_SHOWTAB,REG_DWORD,NULL,0,FALSE};
  159. /*
  160. * Allocate the individual Status Reg entry records
  161. */
  162. struct _reg_entry UPSStatusSerialNum = {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_SERIALNUMBER,REG_SZ,NULL,0,FALSE};
  163. struct _reg_entry UPSStatusFirmRev = {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_FIRMWAREREV,REG_SZ,NULL,0,FALSE};
  164. struct _reg_entry UPSStatusUtilityStatus= {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_UTILITYSTATUS,REG_DWORD,NULL,0,FALSE};
  165. struct _reg_entry UPSStatusRuntime = {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_RUNTIME,REG_DWORD,NULL,0,FALSE};
  166. struct _reg_entry UPSStatusBatteryStatus= {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_BATTERYSTATUS,REG_DWORD,NULL,0,FALSE};
  167. struct _reg_entry UPSStatusCommStatus = {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_COMMSTATUS,REG_DWORD,NULL,0,FALSE};
  168. struct _reg_entry UPSStatusBatteryCapacity = {HKEY_LOCAL_MACHINE,UPS_STATUS_ROOT,UPS_BATTERYCAPACITY,REG_DWORD,NULL,0,FALSE};
  169. /*
  170. * Allocate an array of pointers to the Configuration Reg entry records
  171. */
  172. struct _reg_entry *ConfigBlock[] = {&UPSConfigVendor,
  173. &UPSConfigModel,
  174. &UPSConfigPort,
  175. &UPSConfigOptions,
  176. &UPSConfigServiceDLL,
  177. &UPSConfigNotifyEnable,
  178. &UPSConfigFirstMessageDelay,
  179. &UPSConfigMessageInterval,
  180. &UPSConfigShutBattEnable,
  181. &UPSConfigShutBattWait,
  182. &UPSConfigRunTaskEnable,
  183. &UPSConfigTaskName,
  184. &UPSConfigTurnOffEnable,
  185. &UPSConfigCustomOptions,
  186. &UPSConfigAPCLinkURL,
  187. &UPSConfigShutdownWait,
  188. &UPSConfigUpgrade,
  189. &UPSConfigCriticalPowerAction,
  190. &UPSConfigTurnOffWait,
  191. &UPSConfigImagePath,
  192. &UPSConfigObjectName,
  193. &UPSConfigErrorControl,
  194. &UPSConfigStart,
  195. &UPSConfigType,
  196. &UPSConfigShowUPSTab,
  197. NULL};
  198. /*
  199. * Allocate an array of pointers to the Status Reg entry records
  200. */
  201. struct _reg_entry *StatusBlock[] = {&UPSStatusSerialNum,
  202. &UPSStatusFirmRev,
  203. &UPSStatusUtilityStatus,
  204. &UPSStatusRuntime,
  205. &UPSStatusBatteryStatus,
  206. &UPSStatusCommStatus,
  207. &UPSStatusBatteryCapacity,
  208. NULL};
  209. /******************************************************************
  210. * Public functions
  211. */
  212. LONG GetUPSConfigVendor( LPTSTR aBuffer)
  213. {
  214. return getStringValue( &UPSConfigVendor, aBuffer);
  215. }
  216. LONG GetUPSConfigModel( LPTSTR aBuffer)
  217. {
  218. return getStringValue( &UPSConfigModel, aBuffer);
  219. }
  220. LONG GetUPSConfigPort( LPTSTR aBuffer)
  221. {
  222. return getStringValue( &UPSConfigPort, aBuffer);
  223. }
  224. LONG GetUPSConfigOptions( LPDWORD aValue)
  225. {
  226. return getDwordValue( &UPSConfigOptions, aValue);
  227. }
  228. LONG GetUPSConfigServiceDLL( LPTSTR aBuffer)
  229. {
  230. return getStringValue( &UPSConfigServiceDLL, aBuffer);
  231. }
  232. LONG GetUPSConfigNotifyEnable( LPDWORD aValue)
  233. {
  234. return getDwordValue( &UPSConfigNotifyEnable, aValue);
  235. }
  236. LONG GetUPSConfigFirstMessageDelay( LPDWORD aValue)
  237. {
  238. return getDwordValue( &UPSConfigFirstMessageDelay, aValue);
  239. }
  240. LONG GetUPSConfigMessageInterval( LPDWORD aValue)
  241. {
  242. return getDwordValue( &UPSConfigMessageInterval, aValue);
  243. }
  244. LONG GetUPSConfigShutdownOnBatteryEnable( LPDWORD aValue)
  245. {
  246. return getDwordValue( &UPSConfigShutBattEnable, aValue);
  247. }
  248. LONG GetUPSConfigShutdownOnBatteryWait( LPDWORD aValue)
  249. {
  250. return getDwordValue( &UPSConfigShutBattWait, aValue);
  251. }
  252. LONG GetUPSConfigRunTaskEnable( LPDWORD aValue)
  253. {
  254. return getDwordValue( &UPSConfigRunTaskEnable, aValue);
  255. }
  256. LONG GetUPSConfigTaskName( LPTSTR aBuffer)
  257. {
  258. return getStringValue( &UPSConfigTaskName, aBuffer);
  259. }
  260. LONG GetUPSConfigTurnOffEnable( LPDWORD aValue)
  261. {
  262. return getDwordValue( &UPSConfigTurnOffEnable, aValue);
  263. }
  264. LONG GetUPSConfigCustomOptions( LPDWORD aValue)
  265. {
  266. return getDwordValue( &UPSConfigCustomOptions, aValue);
  267. }
  268. LONG GetUPSConfigAPCLinkURL( LPTSTR aBuffer)
  269. {
  270. return getStringValue( &UPSConfigAPCLinkURL, aBuffer);
  271. }
  272. LONG GetUPSConfigShutdownWait( LPDWORD aValue)
  273. {
  274. return getDwordValue( &UPSConfigShutdownWait, aValue);
  275. }
  276. LONG GetUPSConfigUpgrade( LPDWORD aValue)
  277. {
  278. return getDwordValue( &UPSConfigUpgrade, aValue);
  279. }
  280. LONG GetUPSConfigCriticalPowerAction( LPDWORD aValue)
  281. {
  282. return getDwordValue( &UPSConfigCriticalPowerAction, aValue);
  283. }
  284. LONG GetUPSConfigTurnOffWait( LPDWORD aValue)
  285. {
  286. return getDwordValue( &UPSConfigTurnOffWait, aValue);
  287. }
  288. LONG GetUPSConfigShowUPSTab( LPDWORD aValue)
  289. {
  290. return getDwordValue( &UPSConfigShowUPSTab, aValue);
  291. }
  292. LONG GetUPSConfigImagePath( LPTSTR aBuffer)
  293. {
  294. return getStringValue( &UPSConfigImagePath, aBuffer);
  295. }
  296. LONG GetUPSConfigObjectName( LPTSTR aBuffer)
  297. {
  298. return getStringValue( &UPSConfigObjectName, aBuffer);
  299. }
  300. LONG GetUPSConfigErrorControl( LPDWORD aValue)
  301. {
  302. return getDwordValue( &UPSConfigErrorControl, aValue);
  303. }
  304. LONG GetUPSConfigStart( LPDWORD aValue)
  305. {
  306. return getDwordValue( &UPSConfigStart, aValue);
  307. }
  308. LONG GetUPSConfigType( LPDWORD aValue)
  309. {
  310. return getDwordValue( &UPSConfigType, aValue);
  311. }
  312. ///////////////////////////////////////////
  313. LONG SetUPSConfigVendor( LPCTSTR aBuffer)
  314. {
  315. return setStringValue( &UPSConfigVendor, aBuffer);
  316. }
  317. LONG SetUPSConfigModel( LPCTSTR aBuffer)
  318. {
  319. return setStringValue( &UPSConfigModel, aBuffer);
  320. }
  321. LONG SetUPSConfigPort( LPCTSTR aBuffer)
  322. {
  323. return setStringValue( &UPSConfigPort, aBuffer);
  324. }
  325. LONG SetUPSConfigOptions( DWORD aValue)
  326. {
  327. return setDwordValue( &UPSConfigOptions, aValue);
  328. }
  329. LONG SetUPSConfigServiceDLL( LPCTSTR aBuffer)
  330. {
  331. return setStringValue( &UPSConfigServiceDLL, aBuffer);
  332. }
  333. LONG SetUPSConfigNotifyEnable( DWORD aValue)
  334. {
  335. return setDwordValue( &UPSConfigNotifyEnable, aValue);
  336. }
  337. LONG SetUPSConfigFirstMessageDelay( DWORD aValue)
  338. {
  339. return setDwordValue( &UPSConfigFirstMessageDelay, aValue);
  340. }
  341. LONG SetUPSConfigMessageInterval( DWORD aValue)
  342. {
  343. return setDwordValue( &UPSConfigMessageInterval, aValue);
  344. }
  345. LONG SetUPSConfigShutdownOnBatteryEnable( DWORD aValue)
  346. {
  347. return setDwordValue( &UPSConfigShutBattEnable, aValue);
  348. }
  349. LONG SetUPSConfigShutdownOnBatteryWait( DWORD aValue)
  350. {
  351. return setDwordValue( &UPSConfigShutBattWait, aValue);
  352. }
  353. LONG SetUPSConfigRunTaskEnable( DWORD aValue)
  354. {
  355. return setDwordValue( &UPSConfigRunTaskEnable, aValue);
  356. }
  357. LONG SetUPSConfigTaskName( LPCTSTR aBuffer)
  358. {
  359. return setStringValue( &UPSConfigTaskName, aBuffer);
  360. }
  361. LONG SetUPSConfigTurnOffEnable( DWORD aValue)
  362. {
  363. return setDwordValue( &UPSConfigTurnOffEnable, aValue);
  364. }
  365. LONG SetUPSConfigCustomOptions( DWORD aValue)
  366. {
  367. return setDwordValue( &UPSConfigCustomOptions, aValue);
  368. }
  369. LONG SetUPSConfigAPCLinkURL( LPCTSTR aBuffer)
  370. {
  371. return setStringValue( &UPSConfigAPCLinkURL, aBuffer);
  372. }
  373. LONG SetUPSConfigShutdownWait( DWORD aValue)
  374. {
  375. return setDwordValue( &UPSConfigShutdownWait, aValue);
  376. }
  377. LONG SetUPSConfigUpgrade( DWORD aValue)
  378. {
  379. return setDwordValue( &UPSConfigUpgrade, aValue);
  380. }
  381. LONG SetUPSConfigCriticalPowerAction( DWORD aValue)
  382. {
  383. return setDwordValue( &UPSConfigCriticalPowerAction, aValue);
  384. }
  385. LONG SetUPSConfigTurnOffWait( DWORD aValue)
  386. {
  387. return setDwordValue( &UPSConfigTurnOffWait, aValue);
  388. }
  389. LONG SetUPSConfigShowUPSTab( DWORD aValue)
  390. {
  391. return setDwordValue( &UPSConfigShowUPSTab, aValue);
  392. }
  393. LONG SetUPSConfigImagePath( LPCTSTR aBuffer)
  394. {
  395. return setStringValue( &UPSConfigImagePath, aBuffer);
  396. }
  397. LONG SetUPSConfigObjectName( LPCTSTR aBuffer)
  398. {
  399. return setStringValue( &UPSConfigObjectName, aBuffer);
  400. }
  401. LONG SetUPSConfigErrorControl( DWORD aValue)
  402. {
  403. return setDwordValue( &UPSConfigErrorControl, aValue);
  404. }
  405. LONG SetUPSConfigStart( DWORD aValue)
  406. {
  407. return setDwordValue( &UPSConfigStart, aValue);
  408. }
  409. LONG SetUPSConfigType( DWORD aValue)
  410. {
  411. return setDwordValue( &UPSConfigType, aValue);
  412. }
  413. ////////////////////////////////////////////////
  414. LONG GetUPSStatusSerialNum( LPTSTR aBuffer)
  415. {
  416. return getStringValue( &UPSStatusSerialNum, aBuffer);
  417. }
  418. LONG GetUPSStatusFirmRev( LPTSTR aBuffer)
  419. {
  420. return getStringValue( &UPSStatusFirmRev, aBuffer);
  421. }
  422. LONG GetUPSStatusUtilityStatus( LPDWORD aValue)
  423. {
  424. return getDwordValue( &UPSStatusUtilityStatus, aValue);
  425. }
  426. LONG GetUPSStatusRuntime( LPDWORD aValue)
  427. {
  428. return getDwordValue( &UPSStatusRuntime, aValue);
  429. }
  430. LONG GetUPSStatusBatteryStatus( LPDWORD aValue)
  431. {
  432. return getDwordValue( &UPSStatusBatteryStatus, aValue);
  433. }
  434. LONG GetUPSStatusCommStatus( LPDWORD aValue)
  435. {
  436. return getDwordValue( &UPSStatusCommStatus, aValue);
  437. }
  438. LONG GetUPSBatteryCapacity( LPDWORD aValue)
  439. {
  440. return getDwordValue( &UPSStatusBatteryCapacity, aValue);
  441. }
  442. /////////////////////////////////////////
  443. LONG SetUPSStatusSerialNum( LPCTSTR aBuffer)
  444. {
  445. return setStringValue( &UPSStatusSerialNum, aBuffer);
  446. }
  447. LONG SetUPSStatusFirmRev( LPCTSTR aBuffer)
  448. {
  449. return setStringValue( &UPSStatusFirmRev, aBuffer);
  450. }
  451. LONG SetUPSStatusUtilityStatus( DWORD aValue)
  452. {
  453. return setDwordValue( &UPSStatusUtilityStatus,aValue);
  454. }
  455. LONG SetUPSStatusRuntime( DWORD aValue)
  456. {
  457. return setDwordValue( &UPSStatusRuntime,aValue);
  458. }
  459. LONG SetUPSStatusBatteryStatus( DWORD aValue)
  460. {
  461. return setDwordValue( &UPSStatusBatteryStatus,aValue);
  462. }
  463. LONG SetUPSStatusCommStatus( DWORD aValue)
  464. {
  465. return setDwordValue( &UPSStatusCommStatus,aValue);
  466. }
  467. LONG SetUPSStatusBatteryCapacity( DWORD aValue)
  468. {
  469. return setDwordValue( &UPSStatusBatteryCapacity,aValue);
  470. }
  471. //////////////////////////////////////////////////////////////
  472. void FreeUPSConfigBlock()
  473. {
  474. freeBlock(ConfigBlock);
  475. }
  476. void FreeUPSStatusBlock()
  477. {
  478. freeBlock(StatusBlock);
  479. }
  480. void InitUPSConfigBlock()
  481. {
  482. readBlock(ConfigBlock,FALSE);
  483. }
  484. void InitUPSStatusBlock()
  485. {
  486. readBlock(StatusBlock,FALSE);
  487. }
  488. void RestoreUPSConfigBlock()
  489. {
  490. readBlock(ConfigBlock, TRUE);
  491. }
  492. void RestoreUPSStatusBlock()
  493. {
  494. readBlock(StatusBlock, TRUE);
  495. }
  496. void SaveUPSConfigBlock(BOOL forceAll)
  497. {
  498. writeBlock(ConfigBlock, forceAll);
  499. }
  500. void SaveUPSStatusBlock(BOOL forceAll)
  501. {
  502. writeBlock(StatusBlock, forceAll);
  503. }
  504. /******************************************************************
  505. * Local functions
  506. */
  507. /*
  508. * freeBlock()
  509. *
  510. * Description: Frees storage allocated when a block of registry
  511. * entries is read
  512. *
  513. * Parameters: aBlock - pointer to an array of _reg_entry structures
  514. *
  515. * Returns:
  516. */
  517. void freeBlock(struct _reg_entry *aBlock[])
  518. {
  519. while ((NULL != aBlock) && (NULL != *aBlock))
  520. {
  521. struct _reg_entry *anEntry = *aBlock;
  522. if (NULL != anEntry->lpData)
  523. {
  524. LocalFree(anEntry->lpData);
  525. }
  526. anEntry->lpData = NULL;
  527. anEntry->cbData = 0;
  528. anEntry->changed = FALSE;
  529. aBlock++;
  530. }
  531. }
  532. /*
  533. * readBlock()
  534. *
  535. * Description: Loads all of the items in a array of registry entries
  536. *
  537. * Parameters: aBlock - pointer to an array of _reg_entry structures
  538. * changed - boolean which, when true, causes only the
  539. * structures that are marked as changed to be loaded.
  540. *
  541. * Returns:
  542. */
  543. void readBlock(struct _reg_entry *aBlock[], BOOL changed)
  544. {
  545. LONG res;
  546. HKEY hkResult;
  547. while ((NULL != aBlock) && (NULL != *aBlock))
  548. {
  549. struct _reg_entry *anEntry = *aBlock;
  550. /*
  551. * if changed is FALSE, we read all entries
  552. * otherwise, only re-read the changed entries
  553. */
  554. if ((FALSE == changed) || (TRUE == anEntry->changed))
  555. {
  556. /*
  557. * delete current value, in case this is a reload
  558. */
  559. if (NULL != anEntry->lpData)
  560. {
  561. LocalFree(anEntry->lpData);
  562. }
  563. anEntry->lpData = NULL;
  564. anEntry->cbData = 0;
  565. anEntry->changed = FALSE;
  566. /*
  567. * open key
  568. */
  569. res = RegOpenKeyEx( anEntry->hKey,
  570. anEntry->lpSubKey,
  571. 0,
  572. KEY_QUERY_VALUE,
  573. &hkResult);
  574. if (ERROR_SUCCESS == res)
  575. {
  576. DWORD ulTmpType;
  577. /*
  578. * query for the data size
  579. */
  580. res = RegQueryValueEx( hkResult,
  581. anEntry->lpValueName,
  582. NULL,
  583. &ulTmpType,
  584. NULL,
  585. &anEntry->cbData);
  586. /*
  587. * if the data has 0 size, we don't read it
  588. */
  589. if ((ERROR_SUCCESS == res) &&
  590. (anEntry->cbData > 0) &&
  591. (anEntry->ulType == ulTmpType) &&
  592. (NULL != (anEntry->lpData = (LPBYTE)LocalAlloc(LMEM_FIXED, anEntry->cbData))))
  593. // (NULL != (anEntry->lpData = (LPBYTE)malloc(anEntry->cbData))))
  594. {
  595. /*
  596. * query for data
  597. */
  598. res = RegQueryValueEx( hkResult,
  599. anEntry->lpValueName,
  600. NULL,
  601. &ulTmpType,
  602. anEntry->lpData,
  603. &anEntry->cbData);
  604. /*
  605. * something went wrong; reset
  606. */
  607. if (ERROR_SUCCESS != res)
  608. {
  609. LocalFree(anEntry->lpData);
  610. anEntry->lpData = NULL;
  611. anEntry->cbData = 0;
  612. }
  613. }
  614. else
  615. {
  616. anEntry->cbData = 0;
  617. }
  618. RegCloseKey(hkResult);
  619. }
  620. }
  621. aBlock++;
  622. }
  623. }
  624. /*
  625. * writeBlock()
  626. *
  627. * Description: Stores all of the items in a array of registry entries
  628. *
  629. * Parameters: aBlock - pointer to an array of _reg_entry structures
  630. * forceAll - boolean which, when true, causes all of the
  631. * structures to be written to the registry, otherwise only
  632. * those entries that are marked as changed are stored.
  633. *
  634. * Returns:
  635. */
  636. void writeBlock(struct _reg_entry *aBlock[], BOOL forceAll)
  637. {
  638. LONG res;
  639. HKEY hkResult;
  640. while ((NULL != aBlock) && (NULL != *aBlock))
  641. {
  642. struct _reg_entry *anEntry = *aBlock;
  643. /*
  644. * if forcall is true, write out everything
  645. * otherwise only write out the changed entries
  646. */
  647. if ((NULL != anEntry->lpData) &&
  648. ((TRUE == forceAll) || (TRUE == anEntry->changed)))
  649. {
  650. /*
  651. * open key
  652. */
  653. res = RegOpenKeyEx( anEntry->hKey,
  654. anEntry->lpSubKey,
  655. 0,
  656. KEY_SET_VALUE,
  657. &hkResult);
  658. if (ERROR_SUCCESS == res)
  659. {
  660. /*
  661. * set data
  662. */
  663. res = RegSetValueEx( hkResult,
  664. anEntry->lpValueName,
  665. 0,
  666. anEntry->ulType,
  667. anEntry->lpData,
  668. anEntry->cbData);
  669. RegCloseKey(hkResult);
  670. }
  671. anEntry->changed = FALSE;
  672. }
  673. aBlock++;
  674. }
  675. }
  676. /*
  677. * setDwordValue()
  678. *
  679. * Description: Sets the value of a REG_DWORD entry record.
  680. *
  681. * Parameters: aRegEntry - pointer to a _reg_entry structure
  682. * aValue - the value to store in the entry
  683. *
  684. * Returns: ERROR_SUCCESS, E_OUTOFMEMORY, ERROR_INVALID_PARAMETER
  685. */
  686. LONG setDwordValue(struct _reg_entry *aRegEntry, DWORD aValue)
  687. {
  688. LONG res = ERROR_SUCCESS;
  689. if (NULL != aRegEntry)
  690. {
  691. /*
  692. * if a value already exists, delete it
  693. */
  694. if (NULL != aRegEntry->lpData)
  695. {
  696. LocalFree (aRegEntry->lpData);
  697. aRegEntry->lpData = NULL;
  698. aRegEntry->cbData = 0;
  699. }
  700. /*
  701. * set value
  702. */
  703. aRegEntry->cbData = sizeof(DWORD);
  704. if (NULL != (aRegEntry->lpData = LocalAlloc(LMEM_FIXED, aRegEntry->cbData)))
  705. {
  706. *((DWORD*)aRegEntry->lpData) = aValue;
  707. aRegEntry->changed = TRUE;
  708. }
  709. else
  710. {
  711. res = E_OUTOFMEMORY;
  712. aRegEntry->cbData = 0;
  713. }
  714. }
  715. else
  716. {
  717. res = ERROR_INVALID_PARAMETER;
  718. }
  719. return res;
  720. }
  721. /*
  722. * setStringValue()
  723. *
  724. * Description: Sets the value of a REG_SZ entry record.
  725. *
  726. * Parameters: aRegEntry - pointer to a _reg_entry structure
  727. * aBuffer - pointer to the string to store in the entry
  728. *
  729. * Returns: ERROR_SUCCESS, E_OUTOFMEMORY, ERROR_INVALID_PARAMETER
  730. */
  731. LONG setStringValue(struct _reg_entry *aRegEntry, LPCTSTR aBuffer)
  732. {
  733. LONG res = ERROR_SUCCESS;
  734. if ((NULL != aRegEntry) && (NULL != aBuffer))
  735. {
  736. /*
  737. * if value already exists, delete it
  738. */
  739. if (NULL != aRegEntry->lpData)
  740. {
  741. LocalFree(aRegEntry->lpData);
  742. aRegEntry->lpData = NULL;
  743. aRegEntry->cbData = 0;
  744. }
  745. /*
  746. * set value
  747. */
  748. aRegEntry->cbData = (_tcslen(aBuffer)+1)*sizeof(TCHAR);
  749. if (NULL != (aRegEntry->lpData = LocalAlloc(LMEM_FIXED, aRegEntry->cbData)))
  750. {
  751. _tcscpy((LPTSTR)aRegEntry->lpData,aBuffer);
  752. aRegEntry->changed = TRUE;
  753. }
  754. else
  755. {
  756. res = E_OUTOFMEMORY;
  757. aRegEntry->cbData = 0;
  758. }
  759. }
  760. else
  761. {
  762. res = ERROR_INVALID_PARAMETER;
  763. }
  764. return res;
  765. }
  766. /*
  767. * getStringValue()
  768. *
  769. * Description: Gets the value of a REG_SZ entry record.
  770. *
  771. * Parameters: aRegEntry - pointer to a _reg_entry structure
  772. * aBuffer - pointer to the string to receive the string
  773. *
  774. * Returns: ERROR_SUCCESS, REGDB_E_INVALIDVALUE, ERROR_INVALID_PARAMETER
  775. */
  776. LONG getStringValue(struct _reg_entry *aRegEntry, LPTSTR aBuffer)
  777. {
  778. LONG res = ERROR_SUCCESS;
  779. if ((NULL != aRegEntry) && (NULL != aBuffer))
  780. {
  781. if (NULL != aRegEntry->lpData)
  782. {
  783. _tcscpy(aBuffer, (LPCTSTR)aRegEntry->lpData);
  784. }
  785. else
  786. {
  787. res = REGDB_E_INVALIDVALUE;
  788. }
  789. }
  790. else
  791. {
  792. res = ERROR_INVALID_PARAMETER;
  793. }
  794. return res;
  795. }
  796. /*
  797. * getDwordValue()
  798. *
  799. * Description: Gets the value of a REG_DWORD entry record.
  800. *
  801. * Parameters: aRegEntry - pointer to a _reg_entry structure
  802. * aValue - pointer to the variable to receive the value
  803. *
  804. * Returns: ERROR_SUCCESS, REGDB_E_INVALIDVALUE, ERROR_INVALID_PARAMETER
  805. */
  806. LONG getDwordValue(struct _reg_entry *aRegEntry, LPDWORD aValue)
  807. {
  808. LONG res = ERROR_SUCCESS;
  809. if ((NULL != aRegEntry) && (NULL != aValue))
  810. {
  811. if (NULL != aRegEntry->lpData)
  812. {
  813. *aValue = *((DWORD*)aRegEntry->lpData);
  814. }
  815. else
  816. {
  817. res = REGDB_E_INVALIDVALUE;
  818. }
  819. }
  820. else
  821. {
  822. res = ERROR_INVALID_PARAMETER;
  823. }
  824. return res;
  825. }
  826. /**
  827. * InitializeRegistry
  828. *
  829. * Description:
  830. * This function initiates the registry for the UPS service and the
  831. * configuration application. When called, this function calls the
  832. * function isRegistryInitialized(..) to determine if the registry
  833. * has been initialied. If it has not, the following Keys are updated:
  834. * Status
  835. * Config
  836. * ServiceProviders
  837. *
  838. * The values for the ServiceProviders key is supplied in the regdefs.h
  839. * header file.
  840. *
  841. * Parameters:
  842. * none
  843. *
  844. * Returns:
  845. * TRUE if able to open registry keys with write access.
  846. */
  847. BOOL InitializeRegistry() {
  848. BOOL ret_val = FALSE;
  849. HKEY key;
  850. TCHAR szKeyName[MAX_PATH] = _T("");
  851. // Initialize UPS Service registry keys
  852. InitializeServiceKeys();
  853. // Check to see if the registry is already initialized
  854. if (isRegistryInitialized() == FALSE) {
  855. CheckForUpgrade();
  856. InitializeServiceProviders();
  857. InitializeConfigValues();
  858. InitializeStatusValues();
  859. }
  860. /*
  861. * Remove "(None)" and "Generic" Service Provider keys if they exist
  862. * This fixes a localization bug introduced in RC2
  863. */
  864. _tcscpy(szKeyName, UPS_SERVICE_ROOT);
  865. _tcscat(szKeyName, DEFAULT_CONFIG_VENDOR_OLD);
  866. RegDeleteKey(HKEY_LOCAL_MACHINE, szKeyName);
  867. _tcscpy(szKeyName, UPS_SERVICE_ROOT);
  868. _tcscat(szKeyName, UPGRADE_CONFIG_VENDOR_OLD);
  869. RegDeleteKey(HKEY_LOCAL_MACHINE, szKeyName);
  870. // ...and check if we have write access
  871. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  872. UPS_DEFAULT_ROOT,
  873. 0,
  874. KEY_WRITE,
  875. &key) == ERROR_SUCCESS )
  876. {
  877. RegCloseKey(key);
  878. ret_val = TRUE;
  879. }
  880. return ret_val;
  881. }
  882. /**
  883. * isRegistryInitialized
  884. *
  885. * Description:
  886. * This function determines if the registry has been initialized for
  887. * the UPS service. This is done by examine the registry key specified
  888. * by the identifier UPS_SERVICE_INITIALIED_KEY. If the key is present,
  889. * the registry is assumed to be initialized and TRUE is returned.
  890. * Otherwise, FALSE is returned.
  891. *
  892. * Parameters:
  893. * none
  894. *
  895. * Returns:
  896. * TRUE - if the registry has been initialized for the UPS service
  897. * FALSE - otherwise
  898. */
  899. static BOOL isRegistryInitialized() {
  900. BOOL ret_val = FALSE;
  901. HKEY key;
  902. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UPS_SERVICE_INITIALIZED_KEY,
  903. 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
  904. ret_val = TRUE;
  905. RegCloseKey(key);
  906. }
  907. return ret_val;
  908. }
  909. /**
  910. * CheckForUpgrade
  911. *
  912. * Description:
  913. * This function determines if this installation is an upgrade from
  914. * the WINNT 4.x UPS service. This is done by checking to see if the
  915. * Config registry key is present. If it is not present and the Options
  916. * key is set to UPS_INSTALLED, then the Upgrade registry key is set to
  917. * TRUE. Otherwise, it is set to FALSE.
  918. *
  919. * Parameters:
  920. * none
  921. *
  922. * Returns:
  923. * nothing
  924. */
  925. static void CheckForUpgrade() {
  926. DWORD result;
  927. HKEY key;
  928. DWORD options = 0;
  929. // Create the Config key
  930. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, UPS_CONFIG_ROOT, 0, NULL,
  931. REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, &result) == ERROR_SUCCESS) {
  932. // close the key, we only needed to create it
  933. RegCloseKey(key);
  934. // Check to see if the Config key was present
  935. if (result != REG_OPENED_EXISTING_KEY) {
  936. // Config key was not found
  937. InitUPSConfigBlock();
  938. // Check the port value
  939. if (ERROR_SUCCESS != GetUPSConfigOptions(&options)) {
  940. // Options key is not found
  941. SetUPSConfigUpgrade(FALSE);
  942. }
  943. else if (options & UPS_INSTALLED) {
  944. // The Options key is present and UPS_INSTALLED is set
  945. // This is an upgrade
  946. SetUPSConfigUpgrade(TRUE);
  947. }
  948. else {
  949. // The Config key is present and UPS_INSTALLED is not set
  950. SetUPSConfigUpgrade(FALSE);
  951. }
  952. }
  953. else {
  954. // Config key does not exist
  955. SetUPSConfigUpgrade(FALSE);
  956. }
  957. // Write the Config values, force a save of all values
  958. SaveUPSConfigBlock(TRUE);
  959. // Free the Config block
  960. FreeUPSConfigBlock();
  961. }
  962. }
  963. /**
  964. * InitializeServiceKeys
  965. *
  966. * Description:
  967. * This function initializes the UPS service registry keys to
  968. * default values, if the values are not present.
  969. *
  970. * Parameters:
  971. * none
  972. *
  973. * Returns:
  974. * nothing
  975. */
  976. static void InitializeServiceKeys() {
  977. TCHAR tmpString[MAX_PATH];
  978. DWORD tmpDword;
  979. // Initialize the registry functions
  980. InitUPSConfigBlock();
  981. // Check the service keys and initialize any missing keys
  982. if (GetUPSConfigImagePath(tmpString) != ERROR_SUCCESS) {
  983. SetUPSConfigImagePath(DEFAULT_CONFIG_IMAGEPATH);
  984. }
  985. if (GetUPSConfigObjectName(tmpString) != ERROR_SUCCESS) {
  986. SetUPSConfigObjectName(DEFAULT_CONFIG_OBJECTNAME);
  987. }
  988. if (GetUPSConfigErrorControl(&tmpDword) != ERROR_SUCCESS) {
  989. SetUPSConfigErrorControl(DEFAULT_CONFIG_ERRORCONTROL);
  990. }
  991. if (GetUPSConfigStart(&tmpDword) != ERROR_SUCCESS) {
  992. SetUPSConfigStart(DEFAULT_CONFIG_START);
  993. }
  994. if (GetUPSConfigType(&tmpDword) != ERROR_SUCCESS) {
  995. SetUPSConfigType(DEFAULT_CONFIG_TYPE);
  996. }
  997. // Write the Config values, force a save of all values
  998. SaveUPSConfigBlock(TRUE);
  999. // Free the Status block
  1000. FreeUPSConfigBlock();
  1001. }
  1002. /**
  1003. * InitializeServiceProviders
  1004. *
  1005. * Description:
  1006. * This function initializes the ServiceProviders registry keys with the
  1007. * data provided in the global structure _theStaticProvidersTable. This
  1008. * structure is defined in the file regdefs.h and is automatically
  1009. * generated.
  1010. *
  1011. * Parameters:
  1012. * none
  1013. *
  1014. * Returns:
  1015. * nothing
  1016. */
  1017. static void InitializeServiceProviders() {
  1018. DWORD result;
  1019. HKEY key;
  1020. int index = 0;
  1021. // Loop through the list of Service Providers
  1022. while (_theStaticProvidersTable[index].theModelName != NULL) {
  1023. // Open the vendor registry key
  1024. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, _theStaticProvidersTable[index].theVendorKey,
  1025. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, &result) == ERROR_SUCCESS) {
  1026. // Set the model value
  1027. RegSetValueEx(key, _theStaticProvidersTable[index].theModelName, 0, REG_SZ,
  1028. (LPSTR) _theStaticProvidersTable[index].theValue,
  1029. wcslen(_theStaticProvidersTable[index].theValue)*sizeof(TCHAR));
  1030. RegCloseKey(key);
  1031. }
  1032. // Increment counter
  1033. index++;
  1034. }
  1035. }
  1036. /**
  1037. * InitializeConfigValues
  1038. *
  1039. * Description:
  1040. * This function initializes the Config registry keys with
  1041. * default values.
  1042. *
  1043. * Parameters:
  1044. * none
  1045. *
  1046. * Returns:
  1047. * nothing
  1048. */
  1049. static void InitializeConfigValues() {
  1050. DWORD result;
  1051. HKEY key;
  1052. DWORD options_val, batt_life, type;
  1053. DWORD batt_life_size = sizeof(DWORD);
  1054. // Create the Config key
  1055. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, UPS_CONFIG_ROOT, 0, NULL,
  1056. REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, &result) == ERROR_SUCCESS) {
  1057. // close the key, we only needed to create it
  1058. RegCloseKey(key);
  1059. // Initialize the registry functions
  1060. InitUPSConfigBlock();
  1061. // Set default values
  1062. SetUPSConfigServiceDLL(DEFAULT_CONFIG_PROVIDER_DLL);
  1063. SetUPSConfigNotifyEnable(DEFAULT_CONFIG_NOTIFY_ENABLE);
  1064. SetUPSConfigShutdownOnBatteryEnable(DEFAULT_CONFIG_SHUTDOWN_ONBATT_ENABLE);
  1065. SetUPSConfigShutdownOnBatteryWait(DEFAULT_CONFIG_SHUTDOWN_ONBATT_WAIT);
  1066. SetUPSConfigRunTaskEnable(DEFAULT_CONFIG_RUNTASK_ENABLE);
  1067. SetUPSConfigTaskName(DEFAULT_CONFIG_TASK_NAME);
  1068. SetUPSConfigTurnOffEnable(DEFAULT_CONFIG_TURNOFF_UPS_ENABLE);
  1069. SetUPSConfigCustomOptions(DEFAULT_CONFIG_CUSTOM_OPTIONS);
  1070. SetUPSConfigCriticalPowerAction(DEFAULT_CONFIG_CRITICALPOWERACTION);
  1071. SetUPSConfigTurnOffWait(DEFAULT_CONFIG_TURNOFF_UPS_WAIT);
  1072. // If this is not an upgrade, set the appropriate values
  1073. if ((GetUPSConfigUpgrade(&result) != ERROR_SUCCESS) || (result == FALSE)) {
  1074. SetUPSConfigVendor(DEFAULT_CONFIG_VENDOR);
  1075. SetUPSConfigModel(DEFAULT_CONFIG_MODEL);
  1076. SetUPSConfigPort(DEFAULT_CONFIG_PORT);
  1077. SetUPSConfigOptions(DEFAULT_CONFIG_OPTIONS);
  1078. SetUPSConfigFirstMessageDelay(DEFAULT_CONFIG_FIRSTMSG_DELAY);
  1079. SetUPSConfigMessageInterval(DEFAULT_CONFIG_MESSAGE_INTERVAL);
  1080. }
  1081. else {
  1082. // This is an upgrade
  1083. SetUPSConfigVendor(UPGRADE_CONFIG_VENDOR);
  1084. SetUPSConfigModel(UPGRADE_CONFIG_MODEL);
  1085. // Migrate the run command file option bit to the RunTaskEnable key
  1086. if ((GetUPSConfigOptions(&options_val) == ERROR_SUCCESS) &&
  1087. (options_val & UPS_RUNCMDFILE)) {
  1088. // Run command file is enabled, set RunTaskEnable to TRUE
  1089. SetUPSConfigRunTaskEnable(TRUE);
  1090. }
  1091. else {
  1092. // Run command file is not enabled
  1093. SetUPSConfigRunTaskEnable(FALSE);
  1094. }
  1095. // Migrate the BatteryLife value to the ShutdownOnBatteryWait value
  1096. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UPS_DEFAULT_ROOT, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS) {
  1097. result = RegQueryValueEx(key, UPS_BATTLIFE_KEY, NULL, &type, (LPBYTE) &batt_life, &batt_life_size);
  1098. if ((result == ERROR_SUCCESS) && (type == REG_DWORD)) {
  1099. // Migrate the value and enable shutdown on battery
  1100. SetUPSConfigShutdownOnBatteryWait(batt_life);
  1101. SetUPSConfigShutdownOnBatteryEnable(TRUE);
  1102. // Delete the value
  1103. RegDeleteValue(key, UPS_BATTLIFE_KEY);
  1104. }
  1105. // Close the key
  1106. RegCloseKey(key);
  1107. }
  1108. }
  1109. // Write the Config values, force a save of all values
  1110. SaveUPSConfigBlock(TRUE);
  1111. // Free the Config block
  1112. FreeUPSConfigBlock();
  1113. }
  1114. }
  1115. /**
  1116. * InitializeStatusValues
  1117. *
  1118. * Description:
  1119. * This function initializes the Status registry keys with
  1120. * default values.
  1121. *
  1122. * Parameters:
  1123. * none
  1124. *
  1125. * Returns:
  1126. * nothing
  1127. */
  1128. static void InitializeStatusValues() {
  1129. DWORD result;
  1130. HKEY key;
  1131. // Create the Status key
  1132. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, UPS_STATUS_ROOT, 0, NULL,
  1133. REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, &result) == ERROR_SUCCESS) {
  1134. // close the key, we only needed to create it
  1135. RegCloseKey(key);
  1136. // Initialize the registry functions
  1137. InitUPSStatusBlock();
  1138. // Put in default values
  1139. SetUPSStatusSerialNum(DEFAULT_STATUS_SERIALNO);
  1140. SetUPSStatusFirmRev(DEFAULT_STATUS_FIRMWARE_REV);
  1141. SetUPSStatusUtilityStatus(DEFAULT_STATUS_UTILITY_STAT);
  1142. SetUPSStatusRuntime(DEFAULT_STATUS_TOTAL_RUNTIME);
  1143. SetUPSStatusBatteryStatus(DEFAULT_STATUS_BATTERY_STAT);
  1144. SetUPSStatusBatteryCapacity(DEFAULT_STATUS_BATTERY_CAPACITY);
  1145. // Write the Config values, force a save of all values
  1146. SaveUPSStatusBlock(TRUE);
  1147. // Free the Status block
  1148. FreeUPSStatusBlock();
  1149. }
  1150. }
  1151. ///////////////////////////////////////////////////////////////////////////////
  1152. // upsdata.c
  1153. ///////////////////////////////////////////////////////////////////////////////
  1154. //Note that the order of the following RegField is linked to the enum
  1155. //tUPSDataItemID.
  1156. //Do not change these value without due care and attention. It's OK to change
  1157. //them as long as the enum is updated to match.
  1158. //To access the RegField associated with Firmware, for example, use
  1159. //g_upsRegFields[(DWORD) eREG_FIRMWARE_REVISION]
  1160. static RegField g_upsRegFields[] = {
  1161. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("Vendor"), REG_SZ },
  1162. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("Model"), REG_SZ },
  1163. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("SerialNumber"), REG_SZ },
  1164. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("FirmwareRev"), REG_SZ },
  1165. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("UtilityPowerStatus"), REG_DWORD },
  1166. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("TotalUPSRuntime"), REG_DWORD },
  1167. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("BatteryCapacity"), REG_DWORD },
  1168. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("BatteryStatus"), REG_DWORD },
  1169. { HKEY_LOCAL_MACHINE, UPS_KEY_NAME, TEXT("Options"), REG_DWORD },
  1170. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("ServiceProviderDLL"), REG_EXPAND_SZ },
  1171. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("ShutdownOnBatteryEnable"), REG_DWORD },
  1172. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("ShutdownOnBatteryWait"), REG_DWORD },
  1173. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("TurnUPSOffEnable"), REG_DWORD },
  1174. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("APCLinkURL"), REG_SZ },
  1175. { HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, TEXT("Upgrade"), REG_DWORD },
  1176. { HKEY_LOCAL_MACHINE, STATUS_KEY_NAME, TEXT("CommStatus"), REG_DWORD },
  1177. { HKEY_LOCAL_MACHINE, UPS_KEY_NAME, TEXT("Port"), REG_SZ } };
  1178. // functions
  1179. ///////////////////////////////////////////////////////////////////////////////
  1180. DWORD ReadRegistryValue (const tUPSDataItemID aDataItemID,
  1181. DWORD aAllowedTypes,
  1182. DWORD * aTypePtr,
  1183. LPBYTE aReturnBuffer,
  1184. DWORD * aBufferSizePtr);
  1185. ///////////////////////////////////////////////////////////////////////////////
  1186. ///////////////////////////////////////////////////////////////////////////////
  1187. ///////////////////////////////////////////////////////////////////////////////
  1188. //////////////////////////////////////////////////////////////////////////_/_//
  1189. //////////////////////////////////////////////////////////////////////////_/_//
  1190. // RegField * GetRegField (DWORD aIndex);
  1191. //
  1192. // Description: This function returns a pointer to a RegField from the
  1193. // static array of RegFields named g_upsRegFields. The parameter
  1194. // aIndex is an index into this array.
  1195. //
  1196. // Additional Information:
  1197. //
  1198. // Parameters:
  1199. //
  1200. // DWORD aIndex :- A index into array of known RegFields g_upsRegFields
  1201. //
  1202. // Return Value: If aIndex is within range this function returns a point to
  1203. // the corresponding RegField, otherwise it ASSERTs and returns
  1204. // NULL.
  1205. //
  1206. RegField * GetRegField (DWORD aIndex) {
  1207. static const DWORD numRegFields = DIMENSION_OF(g_upsRegFields);
  1208. RegField * pRequiredReg = NULL;
  1209. if (aIndex < numRegFields) {
  1210. pRequiredReg = &g_upsRegFields[aIndex];
  1211. }
  1212. else {
  1213. _ASSERT(FALSE);
  1214. }
  1215. return(pRequiredReg);
  1216. }
  1217. //////////////////////////////////////////////////////////////////////////_/_//
  1218. //////////////////////////////////////////////////////////////////////////_/_//
  1219. // BOOL GetUPSDataItemDWORD (const tUPSDataItemID aDataItemID, DWORD * aReturnValuePtr);
  1220. //
  1221. // Description: This function reads the DWORD value from the registry that
  1222. // corresponds to the registry field identified by aDataItemID.
  1223. // The registry value must be one of the DWORD types (REG_DWORD,
  1224. // REG_DWORD_LITTLE_ENDIAN, REG_DWORD_BIG_ENDIAN)
  1225. //
  1226. // For example, if aDataItemID is eREG_UPS_OPTIONS (=7), the
  1227. // RegField at index 7 in g_upsRegFields identifies the required
  1228. // registry information. The RegField identifies that the registry
  1229. // key is HKLM\SYSTEM\CurrentControlSet\Services\UPS and the
  1230. // value name is Options and it's of type DWORD. Using this
  1231. // information this function gets the information from the
  1232. // registry and puts the result in aReturnValuePtr.
  1233. //
  1234. // Additional Information:
  1235. //
  1236. // Parameters:
  1237. //
  1238. // const tUPSDataItemID aDataItemID :- This parameter identifies the registry
  1239. // value being queried. The value ranges
  1240. // from eREG_VENDOR_NAME (which equals 0)
  1241. // to eREG_PORT, the values incrementing
  1242. // by 1 for each enum in the range. The
  1243. // range of values in tUPSDataItemID
  1244. // corresponds directly to the number of
  1245. // elements in the array g_upsRegFields
  1246. // because this enum is used to index the
  1247. // elements in g_upsRegFields.
  1248. //
  1249. // DWORD * aReturnValuePtr :- The DWORD value is returned through this
  1250. // pointer.
  1251. //
  1252. // Return Value:
  1253. //
  1254. BOOL GetUPSDataItemDWORD (const tUPSDataItemID aDataItemID, DWORD * aReturnValuePtr) {
  1255. BOOL bGotValue = FALSE;
  1256. DWORD nDWORDSize = sizeof(DWORD);
  1257. if (ReadRegistryValue(aDataItemID, REG_DWORD, NULL, (LPBYTE) aReturnValuePtr, &nDWORDSize) == ERROR_SUCCESS) {
  1258. bGotValue = TRUE;
  1259. }
  1260. return(bGotValue);
  1261. }
  1262. //////////////////////////////////////////////////////////////////////////_/_//
  1263. //////////////////////////////////////////////////////////////////////////_/_//
  1264. // BOOL GetUPSDataItemString (const tUPSDataItemID aDataItemID,
  1265. // LPTSTR aBufferPtr,
  1266. // DWORD * pSizeOfBufferPtr);
  1267. //
  1268. // Description: This function reads the string value from the registry that
  1269. // corresponds to the registry field identified by aDataItemID.
  1270. // The registry value must be one of the string types (REG_SZ or
  1271. // REG_EXPAND_SZ)
  1272. //
  1273. // Additional Information:
  1274. //
  1275. // Parameters:
  1276. //
  1277. // const tUPSDataItemID aDataItemID :- This parameter identifies the registry
  1278. // value being queried. The value must be
  1279. // one of the string types (REG_SZ or
  1280. // REG_EXPAND_SZ).
  1281. //
  1282. // LPTSTR aBufferPtr :- The buffer into which the data is to be placed. This
  1283. // parameter can be NULL in which case no data is
  1284. // retrieved.
  1285. //
  1286. // DWORD * pSizeOfBufferPtr :- This should point to a DWORD that contains the
  1287. // size of the buffer. This parameter cannot be
  1288. // NULL. When this function returns this value
  1289. // will contain the size actually required. This
  1290. // is useful if the user want to determine how
  1291. // big a buffer is required by calling this
  1292. // function with aBufferPtr set to NULL and
  1293. // pSizeOfBufferPtr pointing to a DWORD that
  1294. // is set to 0. When the function returns the
  1295. // DWORD pointed to by pSizeOfBufferPtr should
  1296. // contain the size of string required. This can
  1297. // then be used to dynamically allocate memory
  1298. // and call this function again with the buffer
  1299. // included this time.
  1300. //
  1301. // Return Value: The function returns TRUE if successful, FALSE otherwise.
  1302. //
  1303. BOOL GetUPSDataItemString (const tUPSDataItemID aDataItemID,
  1304. LPTSTR aBufferPtr,
  1305. DWORD * pSizeOfBufferPtr) {
  1306. BOOL bGotValue = FALSE;
  1307. DWORD nType = 0;
  1308. if (ReadRegistryValue(aDataItemID,
  1309. REG_SZ | REG_EXPAND_SZ,
  1310. &nType,
  1311. (LPBYTE) aBufferPtr,
  1312. pSizeOfBufferPtr) == ERROR_SUCCESS) {
  1313. //RegQueryValueEx stores the size of the data, in bytes, in the variable
  1314. //pointed to by lpcbData. If the data has the REG_SZ, REG_MULTI_SZ or
  1315. //REG_EXPAND_SZ type, then lpcbData will also include the size of the
  1316. //terminating null character.
  1317. //For Unicode the terminating NULL character is two-bytes.
  1318. if ((pSizeOfBufferPtr != NULL) && (*pSizeOfBufferPtr > sizeof(TCHAR))) {
  1319. if (nType == REG_EXPAND_SZ) {
  1320. TCHAR expandBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1321. DWORD expandBufferSize = DIMENSION_OF(expandBuffer);
  1322. //ExpandEnvironmentStrings return number of bytes(ANSI) or
  1323. //number of character(UNICODE) including the NULL character
  1324. if (ExpandEnvironmentStrings(aBufferPtr, expandBuffer, expandBufferSize) > 0) {
  1325. _tcscpy(aBufferPtr, expandBuffer);
  1326. }
  1327. }
  1328. bGotValue = TRUE;
  1329. }
  1330. }
  1331. return(bGotValue);
  1332. }
  1333. //////////////////////////////////////////////////////////////////////////_/_//
  1334. //////////////////////////////////////////////////////////////////////////_/_//
  1335. // DWORD ReadRegistryValue (const tUPSDataItemID aDataItemID,
  1336. // DWORD aAllowedTypes,
  1337. // DWORD * aTypePtr,
  1338. // LPBYTE aReturnBuffer,
  1339. // DWORD * aBufferSizePtr);
  1340. //
  1341. // Description: This function reads the registry value identified by
  1342. // aDataItemID. This function can read any type of registry value
  1343. // but the value must match that identified in the RegField
  1344. // description for this field.
  1345. //
  1346. // For example, if aDataItemID is eREG_UPS_OPTIONS (=7), the
  1347. // RegField at index 7 in g_upsRegFields identifies the required
  1348. // registry information. The RegField identifies that the registry
  1349. // key is HKLM\SYSTEM\CurrentControlSet\Services\UPS and the
  1350. // value name is Options and it's of type DWORD. This function
  1351. // will succeed only if it's called with an aAllowedTypes value
  1352. // equal to REG_DWORD.
  1353. //
  1354. // Additional Information:
  1355. //
  1356. // Parameters:
  1357. //
  1358. // const tUPSDataItemID aDataItemID :- This parameter identifies the registry
  1359. // value being queried.
  1360. //
  1361. // DWORD aAllowedTypes :- This identifies the allowed type of the registry
  1362. // data. The registry value types are not bit value
  1363. // that can be |'d (the types are sequentially
  1364. // numbered 0, 1, 2, 3, 4, not 0, 1, 2, 4, 8).
  1365. // However, the parameter is still called
  1366. // aAllowedTypes because we actually call the function
  1367. // with a value of REG_SZ | REG_EXPAND_SZ (1 | 2) to
  1368. // allow the same function to work if the value is
  1369. // either of these. Except for this case assume that
  1370. // the aAllowedTypes is actually aAllowedType.
  1371. //
  1372. // DWORD * aTypePtr :- A pointer to the buffer that will receive the type.
  1373. // If the type is not required then this parameter can be
  1374. // set to NULL.
  1375. //
  1376. // LPBYTE aReturnBuffer :- The buffer into which the data is to be placed.
  1377. // This parameter can be NULL in which case no data
  1378. // is retrieved.
  1379. //
  1380. // DWORD * aBufferSizePtr :- This should point to a DWORD that contains the
  1381. // size of the buffer. This parameter cannot be
  1382. // NULL. When this function returns this value
  1383. // will contain the size actually required.
  1384. //
  1385. // Return Value: This function returns a Win32 error code, ERROS_SUCCESS on
  1386. // success.
  1387. //
  1388. DWORD ReadRegistryValue (const tUPSDataItemID aDataItemID,
  1389. DWORD aAllowedTypes,
  1390. DWORD * aTypePtr,
  1391. LPBYTE aReturnBuffer,
  1392. DWORD * aBufferSizePtr) {
  1393. RegField * pRegField = GetRegField((DWORD) aDataItemID);
  1394. _ASSERT(pRegField != NULL);
  1395. _ASSERT((pRegField->theValueType & aAllowedTypes) == pRegField->theValueType);
  1396. return(ReadRegistryValueData(pRegField->theRootKey,
  1397. pRegField->theKeyName,
  1398. pRegField->theValueName,
  1399. aAllowedTypes,
  1400. aTypePtr,
  1401. (LPTSTR) aReturnBuffer,
  1402. aBufferSizePtr));
  1403. }
  1404. //////////////////////////////////////////////////////////////////////////_/_//
  1405. //////////////////////////////////////////////////////////////////////////_/_//
  1406. // DWORD ReadRegistryValueData (HKEY aRootKey,
  1407. // LPCTSTR aKeyName,
  1408. // LPCTSTR aValueName,
  1409. // DWORD aAllowedTypes,
  1410. // DWORD * aTypePtr,
  1411. // LPTSTR aReturnBuffer,
  1412. // DWORD * aBufferSizePtr);
  1413. //
  1414. // Description:
  1415. //
  1416. // Additional Information:
  1417. //
  1418. // Parameters:
  1419. //
  1420. // HKEY aRootKey :- A handle to an open registry key.
  1421. //
  1422. // LPCTSTR aKeyName :- The name of the key relative to the open key.
  1423. //
  1424. // LPCTSTR aValueName :- The name of the value to read
  1425. //
  1426. // DWORD aAllowedTypes :- See help on ReadRegistryValue.
  1427. //
  1428. // DWORD * aTypePtr :- A pointer to the buffer that will receive the type.
  1429. // If the type is not required then this parameter can be
  1430. // set to NULL.
  1431. //
  1432. // LPBYTE aReturnBuffer :- The buffer into which the data is to be placed.
  1433. // This parameter can be NULL in which case no data
  1434. // is retrieved.
  1435. //
  1436. // DWORD * aBufferSizePtr :- This should point to a DWORD that contains the
  1437. // size of the buffer. This parameter cannot be
  1438. // NULL. When this function returns this value
  1439. // will contain the size actually required.
  1440. //
  1441. // Return Value: This function returns a Win32 error code, ERROS_SUCCESS on
  1442. // success.
  1443. //
  1444. DWORD ReadRegistryValueData (HKEY aRootKey,
  1445. LPCTSTR aKeyName,
  1446. LPCTSTR aValueName,
  1447. DWORD aAllowedTypes,
  1448. DWORD * aTypePtr,
  1449. LPTSTR aReturnBuffer,
  1450. DWORD * aBufferSizePtr) {
  1451. DWORD nType = 0;
  1452. DWORD errCode = ERROR_INVALID_PARAMETER;
  1453. HKEY hOpenKey = NULL;
  1454. if ((errCode = RegOpenKeyEx(aRootKey,
  1455. aKeyName,
  1456. 0,
  1457. KEY_READ,
  1458. &hOpenKey)) == ERROR_SUCCESS) {
  1459. _ASSERT(hOpenKey != NULL);
  1460. //Key exists and is now open
  1461. if ((errCode = RegQueryValueEx(hOpenKey,
  1462. aValueName,
  1463. NULL,
  1464. &nType,
  1465. (LPBYTE) aReturnBuffer,
  1466. aBufferSizePtr)) == ERROR_SUCCESS) {
  1467. if (aTypePtr != NULL) {
  1468. *aTypePtr = nType;
  1469. }
  1470. if ((nType & aAllowedTypes) == 0) {
  1471. //The value type in the registry does not match the expected
  1472. //type for this function call.
  1473. _ASSERT(FALSE);
  1474. }
  1475. if ((aReturnBuffer != NULL) && (*aBufferSizePtr == 1)) {
  1476. //If the registry entry was in fact empty, the buffer needs to
  1477. //be 1 character, for the NULL termination.
  1478. *aReturnBuffer = TEXT('\0');
  1479. }
  1480. }
  1481. else {
  1482. //Something prevented us from reading the value.
  1483. //The value may not exist, the buffer size might
  1484. //not be large enough. May be using the function to
  1485. //read a DWORD value on a registry value that is a
  1486. //shorter string.
  1487. if (errCode == ERROR_MORE_DATA) {
  1488. //There is most likely a mismatch between the type we expect
  1489. //and the actual type of this registry value.
  1490. _ASSERT(FALSE);
  1491. }
  1492. }
  1493. RegCloseKey(hOpenKey);
  1494. }
  1495. return(errCode);
  1496. }
  1497. #ifdef __cplusplus
  1498. }
  1499. #endif