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.

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