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.

672 lines
13 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. registry.c
  5. Abstract:
  6. This module provides a generic table driven access
  7. to the registry.
  8. Author:
  9. Wesley Witt (wesw) 9-June-1996
  10. Revision History:
  11. --*/
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <tchar.h>
  16. #include "winfax.h"
  17. #include "faxutil.h"
  18. #include "faxreg.h"
  19. HKEY
  20. OpenRegistryKey(
  21. HKEY hKey,
  22. LPCTSTR KeyName,
  23. BOOL CreateNewKey,
  24. REGSAM SamDesired
  25. )
  26. {
  27. LONG Rslt;
  28. HKEY hKeyNew;
  29. DWORD Disposition;
  30. if (CreateNewKey) {
  31. Rslt = RegCreateKeyEx(
  32. hKey,
  33. KeyName,
  34. 0,
  35. NULL,
  36. REG_OPTION_NON_VOLATILE,
  37. SamDesired == 0 ? KEY_ALL_ACCESS : SamDesired,
  38. NULL,
  39. &hKeyNew,
  40. &Disposition
  41. );
  42. if (Rslt != ERROR_SUCCESS) {
  43. //
  44. // could not open the registry key
  45. //
  46. DebugPrint(( TEXT("RegCreateKeyEx() failed, ec=%d"), Rslt ));
  47. return NULL;
  48. }
  49. if (Disposition == REG_CREATED_NEW_KEY) {
  50. DebugPrint(( TEXT("Created new fax registry key, ec=%d"), Rslt ));
  51. }
  52. } else {
  53. Rslt = RegOpenKeyEx(
  54. hKey,
  55. KeyName,
  56. 0,
  57. SamDesired == 0 ? KEY_ALL_ACCESS : SamDesired,
  58. &hKeyNew
  59. );
  60. if (Rslt != ERROR_SUCCESS) {
  61. //
  62. // could not open the registry key
  63. //
  64. DebugPrint(( TEXT("RegOpenKeyEx() failed, ec=%d"), Rslt ));
  65. return NULL;
  66. }
  67. }
  68. return hKeyNew;
  69. }
  70. LPTSTR
  71. GetRegistryStringValue(
  72. HKEY hKey,
  73. DWORD RegType,
  74. LPCTSTR ValueName,
  75. LPCTSTR DefaultValue,
  76. LPDWORD StringSize
  77. )
  78. {
  79. BOOL Success = FALSE;
  80. DWORD Size;
  81. LONG Rslt;
  82. DWORD Type;
  83. LPBYTE Buffer = NULL;
  84. LPBYTE ExpandBuffer = NULL;
  85. Rslt = RegQueryValueEx(
  86. hKey,
  87. ValueName,
  88. NULL,
  89. &Type,
  90. NULL,
  91. &Size
  92. );
  93. if (Rslt != ERROR_SUCCESS) {
  94. if (Rslt == ERROR_FILE_NOT_FOUND) {
  95. Size = StringSize( DefaultValue );
  96. } else {
  97. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  98. goto exit;
  99. }
  100. } else {
  101. if (Type != RegType) {
  102. return NULL;
  103. }
  104. }
  105. if (Size == 0) {
  106. Size = 32;
  107. }
  108. Buffer = (LPBYTE) MemAlloc( Size );
  109. if (!Buffer) {
  110. goto exit;
  111. }
  112. Rslt = RegQueryValueEx(
  113. hKey,
  114. ValueName,
  115. NULL,
  116. &Type,
  117. Buffer,
  118. &Size
  119. );
  120. if (Rslt != ERROR_SUCCESS) {
  121. if (Rslt != ERROR_FILE_NOT_FOUND) {
  122. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  123. goto exit;
  124. }
  125. //
  126. // create the value since it doesn't exist
  127. //
  128. _tcscpy( (LPTSTR) Buffer, DefaultValue );
  129. Rslt = RegSetValueEx(
  130. hKey,
  131. ValueName,
  132. 0,
  133. RegType,
  134. Buffer,
  135. Size
  136. );
  137. if (Rslt != ERROR_SUCCESS) {
  138. //
  139. // could not set the registry value
  140. //
  141. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  142. goto exit;
  143. }
  144. }
  145. if (RegType == REG_EXPAND_SZ) {
  146. Rslt = ExpandEnvironmentStrings( (LPTSTR) Buffer, NULL, 0 );
  147. if (!Rslt) {
  148. goto exit;
  149. }
  150. ExpandBuffer = (LPBYTE) MemAlloc( (Rslt + 1) * sizeof(WCHAR) );
  151. if (!ExpandBuffer) {
  152. goto exit;
  153. }
  154. Rslt = ExpandEnvironmentStrings( (LPTSTR) Buffer, (LPTSTR) ExpandBuffer, Rslt );
  155. if (Rslt == 0) {
  156. MemFree( ExpandBuffer );
  157. DebugPrint(( TEXT("ExpandEnvironmentStrings() failed, ec=%d"), GetLastError() ));
  158. goto exit;
  159. }
  160. MemFree( Buffer );
  161. Buffer = ExpandBuffer;
  162. }
  163. Success = TRUE;
  164. if (StringSize) {
  165. *StringSize = Size;
  166. }
  167. exit:
  168. if (!Success) {
  169. MemFree( Buffer );
  170. return StringDup( DefaultValue );
  171. }
  172. return (LPTSTR) Buffer;
  173. }
  174. LPTSTR
  175. GetRegistryString(
  176. HKEY hKey,
  177. LPCTSTR ValueName,
  178. LPCTSTR DefaultValue
  179. )
  180. {
  181. return GetRegistryStringValue( hKey, REG_SZ, ValueName, DefaultValue, NULL );
  182. }
  183. LPTSTR
  184. GetRegistryStringExpand(
  185. HKEY hKey,
  186. LPCTSTR ValueName,
  187. LPCTSTR DefaultValue
  188. )
  189. {
  190. return GetRegistryStringValue( hKey, REG_EXPAND_SZ, ValueName, DefaultValue, NULL );
  191. }
  192. LPTSTR
  193. GetRegistryStringMultiSz(
  194. HKEY hKey,
  195. LPCTSTR ValueName,
  196. LPCTSTR DefaultValue,
  197. LPDWORD StringSize
  198. )
  199. {
  200. return GetRegistryStringValue( hKey, REG_MULTI_SZ, ValueName, DefaultValue, StringSize );
  201. }
  202. DWORD
  203. GetRegistryDword(
  204. HKEY hKey,
  205. LPCTSTR ValueName
  206. )
  207. {
  208. DWORD Size = sizeof(DWORD);
  209. LONG Rslt;
  210. DWORD Type;
  211. DWORD Value = 0;
  212. Rslt = RegQueryValueEx(
  213. hKey,
  214. ValueName,
  215. NULL,
  216. &Type,
  217. (LPBYTE) &Value,
  218. &Size
  219. );
  220. if (Rslt != ERROR_SUCCESS) {
  221. //
  222. // create the value since it doesn't exist
  223. //
  224. Value = 0;
  225. Rslt = RegSetValueEx(
  226. hKey,
  227. ValueName,
  228. 0,
  229. REG_DWORD,
  230. (LPBYTE) &Value,
  231. Size
  232. );
  233. if (Rslt != ERROR_SUCCESS) {
  234. //
  235. // could not set the registry value
  236. //
  237. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  238. Value = 0;
  239. }
  240. }
  241. return Value;
  242. }
  243. LPBYTE
  244. GetRegistryBinary(
  245. HKEY hKey,
  246. LPCTSTR ValueName,
  247. LPDWORD DataSize
  248. )
  249. {
  250. BOOL Success = FALSE;
  251. DWORD Size;
  252. LONG Rslt;
  253. DWORD Type;
  254. LPBYTE Buffer = NULL;
  255. Rslt = RegQueryValueEx(
  256. hKey,
  257. ValueName,
  258. NULL,
  259. &Type,
  260. NULL,
  261. &Size
  262. );
  263. if (Rslt != ERROR_SUCCESS) {
  264. if (Rslt == ERROR_FILE_NOT_FOUND) {
  265. Size = 1;
  266. } else {
  267. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  268. goto exit;
  269. }
  270. } else {
  271. if (Type != REG_BINARY) {
  272. return NULL;
  273. }
  274. }
  275. if (Size == 0) {
  276. Size = 1;
  277. }
  278. Buffer = (LPBYTE) MemAlloc( Size );
  279. if (!Buffer) {
  280. goto exit;
  281. }
  282. Rslt = RegQueryValueEx(
  283. hKey,
  284. ValueName,
  285. NULL,
  286. &Type,
  287. Buffer,
  288. &Size
  289. );
  290. if (Rslt != ERROR_SUCCESS) {
  291. if (Rslt != ERROR_FILE_NOT_FOUND) {
  292. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  293. goto exit;
  294. }
  295. //
  296. // create the value since it doesn't exist
  297. //
  298. Rslt = RegSetValueEx(
  299. hKey,
  300. ValueName,
  301. 0,
  302. REG_BINARY,
  303. Buffer,
  304. Size
  305. );
  306. if (Rslt != ERROR_SUCCESS) {
  307. //
  308. // could not set the registry value
  309. //
  310. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  311. goto exit;
  312. }
  313. }
  314. Success = TRUE;
  315. if (DataSize) {
  316. *DataSize = Size;
  317. }
  318. exit:
  319. if (!Success) {
  320. MemFree( Buffer );
  321. return NULL;
  322. }
  323. return Buffer;
  324. }
  325. DWORD
  326. GetSubKeyCount(
  327. HKEY hKey
  328. )
  329. {
  330. DWORD KeyCount = 0;
  331. LONG Rval;
  332. Rval = RegQueryInfoKey( hKey, NULL, NULL, NULL, &KeyCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
  333. if (Rval != ERROR_SUCCESS) {
  334. return 0;
  335. }
  336. return KeyCount;
  337. }
  338. DWORD
  339. GetMaxSubKeyLen(
  340. HKEY hKey
  341. )
  342. {
  343. DWORD MaxSubKeyLen = 0;
  344. LONG Rval;
  345. Rval = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, &MaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL );
  346. if (Rval != ERROR_SUCCESS) {
  347. return 0;
  348. }
  349. return MaxSubKeyLen;
  350. }
  351. BOOL
  352. SetRegistryDword(
  353. HKEY hKey,
  354. LPCTSTR ValueName,
  355. DWORD Value
  356. )
  357. {
  358. LONG Rslt;
  359. Rslt = RegSetValueEx(
  360. hKey,
  361. ValueName,
  362. 0,
  363. REG_DWORD,
  364. (LPBYTE) &Value,
  365. sizeof(DWORD)
  366. );
  367. if (Rslt != ERROR_SUCCESS) {
  368. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  369. return FALSE;
  370. }
  371. return TRUE;
  372. }
  373. BOOL
  374. SetRegistryBinary(
  375. HKEY hKey,
  376. LPCTSTR ValueName,
  377. const LPBYTE Value,
  378. LONG Length
  379. )
  380. {
  381. LONG Rslt;
  382. Rslt = RegSetValueEx(
  383. hKey,
  384. ValueName,
  385. 0,
  386. REG_BINARY,
  387. (LPBYTE) Value,
  388. Length
  389. );
  390. if (Rslt != ERROR_SUCCESS) {
  391. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  392. return FALSE;
  393. }
  394. return TRUE;
  395. }
  396. BOOL
  397. SetRegistryStringValue(
  398. HKEY hKey,
  399. DWORD RegType,
  400. LPCTSTR ValueName,
  401. LPCTSTR Value,
  402. LONG Length
  403. )
  404. {
  405. LONG Rslt;
  406. Rslt = RegSetValueEx(
  407. hKey,
  408. ValueName,
  409. 0,
  410. RegType,
  411. (LPBYTE) Value,
  412. Length == -1 ? StringSize( Value ) : Length
  413. );
  414. if (Rslt != ERROR_SUCCESS) {
  415. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  416. return FALSE;
  417. }
  418. return TRUE;
  419. }
  420. BOOL
  421. SetRegistryString(
  422. HKEY hKey,
  423. LPCTSTR ValueName,
  424. LPCTSTR Value
  425. )
  426. {
  427. return SetRegistryStringValue( hKey, REG_SZ, ValueName, Value, -1 );
  428. }
  429. BOOL
  430. SetRegistryStringExpand(
  431. HKEY hKey,
  432. LPCTSTR ValueName,
  433. LPCTSTR Value
  434. )
  435. {
  436. return SetRegistryStringValue( hKey, REG_EXPAND_SZ, ValueName, Value, -1 );
  437. }
  438. BOOL
  439. SetRegistryStringMultiSz(
  440. HKEY hKey,
  441. LPCTSTR ValueName,
  442. LPCTSTR Value,
  443. DWORD Length
  444. )
  445. {
  446. return SetRegistryStringValue( hKey, REG_MULTI_SZ, ValueName, Value, Length );
  447. }
  448. DWORD
  449. EnumerateRegistryKeys(
  450. HKEY hKey,
  451. LPCTSTR KeyName,
  452. BOOL ChangeValues,
  453. PREGENUMCALLBACK EnumCallback,
  454. LPVOID ContextData
  455. )
  456. {
  457. LONG Rslt;
  458. HKEY hSubKey = NULL;
  459. HKEY hKeyEnum = NULL;
  460. DWORD Index = 0;
  461. DWORD MaxSubKeyLen;
  462. DWORD SubKeyCount;
  463. LPTSTR SubKeyName = NULL;
  464. hSubKey = OpenRegistryKey( hKey, KeyName, ChangeValues, ChangeValues ? KEY_ALL_ACCESS : KEY_READ );
  465. if (!hSubKey) {
  466. goto exit;
  467. }
  468. Rslt = RegQueryInfoKey(
  469. hSubKey,
  470. NULL,
  471. NULL,
  472. NULL,
  473. &SubKeyCount,
  474. &MaxSubKeyLen,
  475. NULL,
  476. NULL,
  477. NULL,
  478. NULL,
  479. NULL,
  480. NULL
  481. );
  482. if (Rslt != ERROR_SUCCESS) {
  483. //
  484. // could not open the registry key
  485. //
  486. DebugPrint(( TEXT("RegQueryInfoKey() failed, ec=%d"), Rslt ));
  487. goto exit;
  488. }
  489. if (!EnumCallback( hSubKey, NULL, SubKeyCount, ContextData )) {
  490. goto exit;
  491. }
  492. MaxSubKeyLen += 4;
  493. SubKeyName = (LPTSTR) MemAlloc( (MaxSubKeyLen+1) * sizeof(WCHAR) );
  494. if (!SubKeyName) {
  495. goto exit;
  496. }
  497. while( TRUE ) {
  498. Rslt = RegEnumKey(
  499. hSubKey,
  500. Index,
  501. (LPTSTR) SubKeyName,
  502. MaxSubKeyLen
  503. );
  504. if (Rslt != ERROR_SUCCESS) {
  505. if (Rslt == ERROR_NO_MORE_ITEMS) {
  506. break;
  507. }
  508. DebugPrint(( TEXT("RegEnumKey() failed, ec=%d"), Rslt ));
  509. goto exit;
  510. }
  511. hKeyEnum = OpenRegistryKey( hSubKey, SubKeyName, ChangeValues, ChangeValues ? KEY_ALL_ACCESS : KEY_READ );
  512. if (!hKeyEnum) {
  513. continue;
  514. }
  515. if (!EnumCallback( hKeyEnum, SubKeyName, Index, ContextData )) {
  516. RegCloseKey( hKeyEnum );
  517. break;
  518. }
  519. RegCloseKey( hKeyEnum );
  520. Index += 1;
  521. }
  522. exit:
  523. if (hSubKey) {
  524. RegCloseKey( hSubKey );
  525. }
  526. MemFree( SubKeyName );
  527. return Index;
  528. }
  529. BOOL
  530. DeleteRegistryKey(
  531. HKEY hKey,
  532. LPCTSTR SubKey
  533. )
  534. {
  535. DWORD Count = 0;
  536. HKEY hKeyCurrent;
  537. TCHAR szName[100];
  538. DWORD dwName;
  539. long rslt;
  540. rslt = RegOpenKey(hKey,SubKey,&hKeyCurrent);
  541. if (rslt != ERROR_SUCCESS) {
  542. DebugPrint(( TEXT("RegOpenKey() failed, ec=%d"), rslt ));
  543. return FALSE;
  544. }
  545. while(1) {
  546. dwName = sizeof(szName);
  547. rslt = RegEnumKeyEx(hKeyCurrent,Count,szName,&dwName,NULL,NULL,NULL,NULL);
  548. if (rslt == ERROR_SUCCESS) {
  549. DeleteRegistryKey(hKeyCurrent,szName);
  550. Count++;
  551. } else if (rslt == ERROR_NO_MORE_ITEMS) {
  552. break;
  553. } else {
  554. //
  555. // other error
  556. //
  557. DebugPrint(( TEXT("RegEnumKeyExKey() failed, ec=%d"), rslt ));
  558. RegCloseKey(hKeyCurrent);
  559. return FALSE;
  560. }
  561. }
  562. RegCloseKey(hKeyCurrent);
  563. RegDeleteKey(hKey, SubKey);
  564. return TRUE;
  565. }