Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1406 lines
31 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 "fxsapip.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 = NULL;
  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_READ | KEY_WRITE) : 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. SetLastError (Rslt);
  48. return NULL;
  49. }
  50. if (Disposition == REG_CREATED_NEW_KEY) {
  51. DebugPrint(( TEXT("Created new fax registry key, ec=%d"), Rslt ));
  52. }
  53. } else {
  54. Rslt = RegOpenKeyEx(
  55. hKey,
  56. KeyName,
  57. 0,
  58. SamDesired == 0 ? (KEY_READ | KEY_WRITE) : SamDesired,
  59. &hKeyNew
  60. );
  61. if (Rslt != ERROR_SUCCESS) {
  62. //
  63. // could not open the registry key
  64. //
  65. DebugPrint(( TEXT("RegOpenKeyEx() failed, ec=%d"), Rslt ));
  66. SetLastError (Rslt);
  67. return NULL;
  68. }
  69. }
  70. Assert (hKeyNew);
  71. SetLastError (ERROR_SUCCESS);
  72. return hKeyNew;
  73. }
  74. LPTSTR
  75. GetRegistryStringValue(
  76. HKEY hKey,
  77. DWORD RegType,
  78. LPCTSTR ValueName,
  79. LPCTSTR DefaultValue,
  80. LPDWORD StringSize
  81. )
  82. {
  83. BOOL Success = FALSE;
  84. DWORD Size;
  85. LONG Rslt;
  86. DWORD Type;
  87. LPBYTE Buffer = NULL;
  88. LPBYTE ExpandBuffer = NULL;
  89. LPTSTR ReturnBuff = NULL;
  90. Rslt = RegQueryValueEx(
  91. hKey,
  92. ValueName,
  93. NULL,
  94. &Type,
  95. NULL,
  96. &Size
  97. );
  98. if (Rslt != ERROR_SUCCESS)
  99. {
  100. if (Rslt == ERROR_FILE_NOT_FOUND)
  101. {
  102. if (DefaultValue)
  103. {
  104. Size = (RegType==REG_MULTI_SZ) ? MultiStringSize(DefaultValue) : StringSize( DefaultValue );
  105. }
  106. else
  107. {
  108. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d - and no default value was specified"), Rslt ));
  109. goto exit;
  110. }
  111. }
  112. else
  113. {
  114. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  115. goto exit;
  116. }
  117. }
  118. else
  119. {
  120. if (Type != RegType)
  121. {
  122. return NULL;
  123. }
  124. }
  125. if (Size == 0)
  126. {
  127. Size = 32;
  128. }
  129. Buffer = (LPBYTE) MemAlloc( Size );
  130. if (!Buffer)
  131. {
  132. goto exit;
  133. }
  134. Rslt = RegQueryValueEx(
  135. hKey,
  136. ValueName,
  137. NULL,
  138. &Type,
  139. Buffer,
  140. &Size
  141. );
  142. if (Rslt != ERROR_SUCCESS)
  143. {
  144. if (Rslt != ERROR_FILE_NOT_FOUND)
  145. {
  146. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  147. goto exit;
  148. }
  149. //
  150. // create the value since it doesn't exist
  151. //
  152. if (DefaultValue)
  153. {
  154. if ( RegType == REG_MULTI_SZ )
  155. {
  156. Assert(Size>=MultiStringSize(DefaultValue));
  157. memcpy ( (LPVOID) Buffer, (LPVOID)DefaultValue, MultiStringSize(DefaultValue) );
  158. }
  159. else
  160. {
  161. _tcscpy( (LPTSTR) Buffer, DefaultValue );
  162. }
  163. }
  164. else
  165. {
  166. DebugPrint((TEXT("Can't create DefaultValue since it's NULL")));
  167. goto exit;
  168. }
  169. Rslt = RegSetValueEx(
  170. hKey,
  171. ValueName,
  172. 0,
  173. RegType,
  174. Buffer,
  175. Size
  176. );
  177. if (Rslt != ERROR_SUCCESS)
  178. {
  179. //
  180. // could not set the registry value
  181. //
  182. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  183. goto exit;
  184. }
  185. }
  186. if (RegType == REG_EXPAND_SZ)
  187. {
  188. Rslt = ExpandEnvironmentStrings( (LPTSTR) Buffer, NULL, 0 );
  189. if (!Rslt)
  190. {
  191. goto exit;
  192. }
  193. Size = (Rslt + 1) * sizeof(WCHAR);
  194. ExpandBuffer = (LPBYTE) MemAlloc( Size );
  195. if (!ExpandBuffer) {
  196. goto exit;
  197. }
  198. Rslt = ExpandEnvironmentStrings( (LPTSTR) Buffer, (LPTSTR) ExpandBuffer, Rslt );
  199. if (Rslt == 0) {
  200. MemFree( ExpandBuffer );
  201. ExpandBuffer = NULL;
  202. DebugPrint(( TEXT("ExpandEnvironmentStrings() failed, ec=%d"), GetLastError() ));
  203. goto exit;
  204. }
  205. MemFree( Buffer );
  206. Buffer = ExpandBuffer;
  207. }
  208. Success = TRUE;
  209. if (StringSize)
  210. {
  211. *StringSize = Size;
  212. }
  213. exit:
  214. if (!Success)
  215. {
  216. MemFree( Buffer );
  217. if (StringSize)
  218. {
  219. *StringSize = 0;
  220. }
  221. if (DefaultValue)
  222. {
  223. Size = (RegType==REG_MULTI_SZ) ? MultiStringSize(DefaultValue) : StringSize( DefaultValue );
  224. ReturnBuff = (LPTSTR) MemAlloc( Size );
  225. if ( !ReturnBuff )
  226. return NULL;
  227. if ( RegType == REG_MULTI_SZ )
  228. memcpy ( (LPVOID)ReturnBuff, (LPVOID)DefaultValue, Size );
  229. else
  230. _tcscpy( ReturnBuff, DefaultValue );
  231. if (StringSize)
  232. {
  233. *StringSize = Size;
  234. }
  235. return ReturnBuff;
  236. }
  237. else
  238. {
  239. return NULL;
  240. }
  241. }
  242. return (LPTSTR) Buffer;
  243. }
  244. LPTSTR
  245. GetRegistryString(
  246. HKEY hKey,
  247. LPCTSTR ValueName,
  248. LPCTSTR DefaultValue
  249. )
  250. {
  251. return GetRegistryStringValue( hKey, REG_SZ, ValueName, DefaultValue, NULL );
  252. }
  253. LPTSTR
  254. GetRegistryStringExpand(
  255. HKEY hKey,
  256. LPCTSTR ValueName,
  257. LPCTSTR DefaultValue
  258. )
  259. {
  260. return GetRegistryStringValue( hKey, REG_EXPAND_SZ, ValueName, DefaultValue, NULL );
  261. }
  262. LPTSTR
  263. GetRegistryStringMultiSz(
  264. HKEY hKey,
  265. LPCTSTR ValueName,
  266. LPCTSTR DefaultValue,
  267. LPDWORD StringSize
  268. )
  269. {
  270. return GetRegistryStringValue( hKey, REG_MULTI_SZ, ValueName, DefaultValue, StringSize );
  271. }
  272. /*++
  273. Routine Description:
  274. Reads a REG_DWORD value from the registry. If the value doesn't exist, creates the
  275. value with the default value provided.
  276. Arguments:
  277. hKey [in] - Handle to an open registry key
  278. lpszValueName [in] - Registry value name
  279. lpdwDest [out] - Pointer to DWORD that will accept the value
  280. dwDefault [in] - Default value to use if value doesn't exist
  281. Return Value:
  282. TRUE if success
  283. FALSE if failed to read/create the value, error in LastError
  284. --*/
  285. BOOL GetRegistryDwordDefault(HKEY hKey, LPCTSTR lpszValueName, LPDWORD lpdwDest, DWORD dwDefault)
  286. {
  287. LONG lError;
  288. DWORD dwSize = sizeof(DWORD);
  289. DWORD dwType;
  290. if (!lpdwDest)
  291. {
  292. SetLastError(ERROR_INVALID_PARAMETER);
  293. return FALSE;
  294. }
  295. lError = RegQueryValueEx( hKey,
  296. lpszValueName,
  297. 0,
  298. &dwType,
  299. (LPBYTE)lpdwDest,
  300. &dwSize);
  301. if (lError==ERROR_FILE_NOT_FOUND)
  302. {
  303. // Not found - create with default value
  304. *lpdwDest = dwDefault;
  305. lError = RegSetValueEx( hKey,
  306. lpszValueName,
  307. 0,
  308. REG_DWORD,
  309. (LPBYTE)lpdwDest,
  310. sizeof(DWORD));
  311. if (lError != ERROR_SUCCESS)
  312. {
  313. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), lpszValueName, lError ));
  314. SetLastError(lError);
  315. return FALSE;
  316. }
  317. return TRUE;
  318. }
  319. if ((lError!=ERROR_SUCCESS) || (dwType!=REG_DWORD))
  320. {
  321. DebugPrint(( TEXT("RegQueryValueEx() failed[%s], ec=%d"), lpszValueName, lError ));
  322. SetLastError(lError);
  323. return FALSE;
  324. }
  325. return TRUE;
  326. }
  327. DWORD
  328. GetRegistryDword(
  329. HKEY hKey,
  330. LPCTSTR ValueName
  331. )
  332. {
  333. DWORD Value=0;
  334. if (!GetRegistryDwordDefault(hKey, ValueName, &Value, 0))
  335. {
  336. return 0;
  337. }
  338. return Value;
  339. }
  340. LPBYTE
  341. GetRegistryBinary(
  342. HKEY hKey,
  343. LPCTSTR ValueName,
  344. LPDWORD DataSize
  345. )
  346. {
  347. BOOL Success = FALSE;
  348. DWORD Size = 0;
  349. LONG Rslt;
  350. DWORD Type = REG_BINARY;
  351. LPBYTE Buffer = NULL;
  352. Rslt = RegQueryValueEx(
  353. hKey,
  354. ValueName,
  355. NULL,
  356. &Type,
  357. NULL,
  358. &Size
  359. );
  360. if (Rslt != ERROR_SUCCESS) {
  361. if (Rslt == ERROR_FILE_NOT_FOUND) {
  362. Size = 1;
  363. } else {
  364. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  365. goto exit;
  366. }
  367. } else {
  368. if (Type != REG_BINARY) {
  369. return NULL;
  370. }
  371. }
  372. if (Size == 0) {
  373. Size = 1;
  374. }
  375. Buffer = (LPBYTE) MemAlloc( Size );
  376. if (!Buffer) {
  377. goto exit;
  378. }
  379. Rslt = RegQueryValueEx(
  380. hKey,
  381. ValueName,
  382. NULL,
  383. &Type,
  384. Buffer,
  385. &Size
  386. );
  387. if (Rslt != ERROR_SUCCESS) {
  388. if (Rslt != ERROR_FILE_NOT_FOUND) {
  389. DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt ));
  390. goto exit;
  391. }
  392. //
  393. // create the value since it doesn't exist
  394. //
  395. Rslt = RegSetValueEx(
  396. hKey,
  397. ValueName,
  398. 0,
  399. REG_BINARY,
  400. Buffer,
  401. Size
  402. );
  403. if (Rslt != ERROR_SUCCESS) {
  404. //
  405. // could not set the registry value
  406. //
  407. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  408. goto exit;
  409. }
  410. }
  411. Success = TRUE;
  412. if (DataSize) {
  413. *DataSize = Size;
  414. }
  415. exit:
  416. if (!Success) {
  417. MemFree( Buffer );
  418. return NULL;
  419. }
  420. return Buffer;
  421. }
  422. DWORD
  423. GetSubKeyCount(
  424. HKEY hKey
  425. )
  426. {
  427. DWORD KeyCount = 0;
  428. LONG Rval;
  429. Rval = RegQueryInfoKey( hKey, NULL, NULL, NULL, &KeyCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
  430. if (Rval != ERROR_SUCCESS) {
  431. return 0;
  432. }
  433. return KeyCount;
  434. }
  435. DWORD
  436. GetMaxSubKeyLen(
  437. HKEY hKey
  438. )
  439. {
  440. DWORD MaxSubKeyLen = 0;
  441. LONG Rval;
  442. Rval = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, &MaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL );
  443. if (Rval != ERROR_SUCCESS) {
  444. return 0;
  445. }
  446. return MaxSubKeyLen;
  447. }
  448. BOOL
  449. SetRegistryDword(
  450. HKEY hKey,
  451. LPCTSTR ValueName,
  452. DWORD Value
  453. )
  454. {
  455. LONG Rslt;
  456. Rslt = RegSetValueEx(
  457. hKey,
  458. ValueName,
  459. 0,
  460. REG_DWORD,
  461. (LPBYTE) &Value,
  462. sizeof(DWORD)
  463. );
  464. if (Rslt != ERROR_SUCCESS)
  465. {
  466. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  467. SetLastError (Rslt);
  468. return FALSE;
  469. }
  470. return TRUE;
  471. }
  472. BOOL
  473. SetRegistryBinary(
  474. HKEY hKey,
  475. LPCTSTR ValueName,
  476. const LPBYTE Value,
  477. LONG Length
  478. )
  479. {
  480. LONG Rslt;
  481. Rslt = RegSetValueEx(
  482. hKey,
  483. ValueName,
  484. 0,
  485. REG_BINARY,
  486. (LPBYTE) Value,
  487. Length
  488. );
  489. if (Rslt != ERROR_SUCCESS) {
  490. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  491. return FALSE;
  492. }
  493. return TRUE;
  494. }
  495. BOOL
  496. SetRegistryStringValue(
  497. HKEY hKey,
  498. DWORD RegType,
  499. LPCTSTR ValueName,
  500. LPCTSTR Value,
  501. LONG Length
  502. )
  503. {
  504. LONG Rslt;
  505. Rslt = RegSetValueEx(
  506. hKey,
  507. ValueName,
  508. 0,
  509. RegType,
  510. (LPBYTE) Value,
  511. Length == -1 ? StringSize( Value ) : Length
  512. );
  513. if (Rslt != ERROR_SUCCESS) {
  514. DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt ));
  515. return FALSE;
  516. }
  517. return TRUE;
  518. }
  519. BOOL
  520. SetRegistryString(
  521. HKEY hKey,
  522. LPCTSTR ValueName,
  523. LPCTSTR Value
  524. )
  525. {
  526. return SetRegistryStringValue( hKey, REG_SZ, ValueName, Value, -1 );
  527. }
  528. BOOL
  529. SetRegistryStringExpand(
  530. HKEY hKey,
  531. LPCTSTR ValueName,
  532. LPCTSTR Value
  533. )
  534. {
  535. return SetRegistryStringValue( hKey, REG_EXPAND_SZ, ValueName, Value, -1 );
  536. }
  537. BOOL
  538. SetRegistryStringMultiSz(
  539. HKEY hKey,
  540. LPCTSTR ValueName,
  541. LPCTSTR Value,
  542. DWORD Length
  543. )
  544. {
  545. return SetRegistryStringValue( hKey, REG_MULTI_SZ, ValueName, Value, Length );
  546. }
  547. DWORD
  548. EnumerateRegistryKeys(
  549. HKEY hKey,
  550. LPCTSTR KeyName,
  551. BOOL ChangeValues,
  552. PREGENUMCALLBACK EnumCallback,
  553. LPVOID ContextData
  554. )
  555. {
  556. LONG Rslt;
  557. HKEY hSubKey = NULL;
  558. HKEY hKeyEnum = NULL;
  559. DWORD Index = 0;
  560. DWORD MaxSubKeyLen;
  561. DWORD SubKeyCount;
  562. LPTSTR SubKeyName = NULL;
  563. hSubKey = OpenRegistryKey( hKey, KeyName, ChangeValues, ChangeValues ? (KEY_READ | KEY_WRITE) : KEY_READ );
  564. if (!hSubKey) {
  565. goto exit;
  566. }
  567. Rslt = RegQueryInfoKey(
  568. hSubKey,
  569. NULL,
  570. NULL,
  571. NULL,
  572. &SubKeyCount,
  573. &MaxSubKeyLen,
  574. NULL,
  575. NULL,
  576. NULL,
  577. NULL,
  578. NULL,
  579. NULL
  580. );
  581. if (Rslt != ERROR_SUCCESS) {
  582. //
  583. // could not open the registry key
  584. //
  585. DebugPrint(( TEXT("RegQueryInfoKey() failed, ec=%d"), Rslt ));
  586. goto exit;
  587. }
  588. if (!EnumCallback( hSubKey, NULL, SubKeyCount, ContextData )) {
  589. goto exit;
  590. }
  591. MaxSubKeyLen += 4;
  592. SubKeyName = (LPTSTR) MemAlloc( (MaxSubKeyLen+1) * sizeof(WCHAR) );
  593. if (!SubKeyName) {
  594. goto exit;
  595. }
  596. while( TRUE ) {
  597. Rslt = RegEnumKey(
  598. hSubKey,
  599. Index,
  600. (LPTSTR) SubKeyName,
  601. MaxSubKeyLen
  602. );
  603. if (Rslt != ERROR_SUCCESS) {
  604. if (Rslt == ERROR_NO_MORE_ITEMS) {
  605. break;
  606. }
  607. DebugPrint(( TEXT("RegEnumKey() failed, ec=%d"), Rslt ));
  608. goto exit;
  609. }
  610. hKeyEnum = OpenRegistryKey( hSubKey, SubKeyName, ChangeValues, ChangeValues ? (KEY_READ | KEY_WRITE) : KEY_READ );
  611. if (!hKeyEnum) {
  612. continue;
  613. }
  614. if (!EnumCallback( hKeyEnum, SubKeyName, Index, ContextData )) {
  615. RegCloseKey( hKeyEnum );
  616. break;
  617. }
  618. RegCloseKey( hKeyEnum );
  619. Index += 1;
  620. }
  621. exit:
  622. if (hSubKey) {
  623. RegCloseKey( hSubKey );
  624. }
  625. MemFree( SubKeyName );
  626. return Index;
  627. }
  628. BOOL
  629. DeleteRegistryKey(
  630. HKEY hKey,
  631. LPCTSTR SubKey
  632. )
  633. {
  634. HKEY hKeyCurrent=NULL;
  635. TCHAR szName[MAX_PATH];
  636. DWORD dwName;
  637. long lResult;
  638. DEBUG_FUNCTION_NAME(TEXT("DeleteRegistryKey"));
  639. lResult = RegOpenKeyEx(hKey,SubKey,0,KEY_READ | KEY_WRITE | DELETE, &hKeyCurrent);
  640. if (lResult != ERROR_SUCCESS)
  641. {
  642. DebugPrintEx(
  643. DEBUG_ERR,
  644. TEXT("RegOpenKeyEx failed with %ld"),
  645. lResult);
  646. SetLastError (lResult);
  647. return FALSE;
  648. }
  649. for (;;)
  650. {
  651. dwName = sizeof(szName)/sizeof(TCHAR);
  652. lResult = RegEnumKeyEx(hKeyCurrent, 0, szName, &dwName, NULL, NULL, NULL, NULL);
  653. if (lResult == ERROR_SUCCESS)
  654. {
  655. if (!DeleteRegistryKey(hKeyCurrent,szName))
  656. {
  657. //
  658. // Some sons a NOT deleted. You can stop trying to remove stuff now.
  659. //
  660. return FALSE;
  661. }
  662. }
  663. else if (lResult == ERROR_NO_MORE_ITEMS)
  664. {
  665. //
  666. // No more sons, can delete father key
  667. //
  668. break;
  669. }
  670. else
  671. {
  672. //
  673. // other error
  674. //
  675. DebugPrintEx(
  676. DEBUG_ERR,
  677. TEXT("RegEnumKeyExKey failed with %ld"),
  678. lResult);
  679. RegCloseKey(hKeyCurrent);
  680. SetLastError (lResult);
  681. return FALSE;
  682. }
  683. }
  684. RegCloseKey(hKeyCurrent);
  685. lResult = RegDeleteKey(hKey, SubKey);
  686. if (ERROR_SUCCESS != lResult)
  687. {
  688. DebugPrintEx(
  689. DEBUG_ERR,
  690. TEXT("RegDeleteKey failed with %ld"),
  691. lResult);
  692. SetLastError (lResult);
  693. return FALSE;
  694. }
  695. return TRUE;
  696. }
  697. DWORD
  698. GetRegistryDwordEx(
  699. HKEY hKey,
  700. LPCTSTR ValueName,
  701. LPDWORD lpdwValue
  702. )
  703. /*++
  704. Routine name : GetRegistryDwordEx
  705. Routine description:
  706. Retrieves a dword from the registry.
  707. Author:
  708. Oded Sacher (OdedS), Dec, 1999
  709. Arguments:
  710. hKey [in ] - Handle to the open key
  711. ValueName [in ] - The value name
  712. lpdwValue [out ] - Pointer to a DWORD to recieve the value
  713. Return Value:
  714. Standard win 32 error code
  715. --*/
  716. {
  717. DWORD dwRes = ERROR_SUCCESS;
  718. DWORD dwType= REG_DWORD;
  719. DWORD dwSize=0;
  720. DEBUG_FUNCTION_NAME(TEXT("GetRegistryDwordEx"));
  721. Assert (ValueName && lpdwValue);
  722. dwRes = RegQueryValueEx(
  723. hKey,
  724. ValueName,
  725. NULL,
  726. &dwType,
  727. NULL,
  728. &dwSize
  729. );
  730. if (ERROR_SUCCESS != dwRes)
  731. {
  732. DebugPrintEx(
  733. DEBUG_ERR,
  734. TEXT("RegQueryValueEx failed with %ld"),
  735. dwRes);
  736. goto exit;
  737. }
  738. if (REG_DWORD != dwType)
  739. {
  740. // We expect only DWORD data here
  741. DebugPrintEx(
  742. DEBUG_ERR,
  743. TEXT("Error not a DWORD type"));
  744. dwRes = ERROR_BADDB; // The configuration registry database is corrupt.
  745. goto exit;
  746. }
  747. dwRes = RegQueryValueEx(
  748. hKey,
  749. ValueName,
  750. NULL,
  751. &dwType,
  752. (LPBYTE)lpdwValue,
  753. &dwSize
  754. );
  755. if (ERROR_SUCCESS != dwRes)
  756. {
  757. DebugPrintEx(
  758. DEBUG_ERR,
  759. TEXT("RegQueryValueEx failed with %ld"),
  760. dwRes);
  761. goto exit;
  762. }
  763. Assert (ERROR_SUCCESS == dwRes);
  764. exit:
  765. return dwRes;
  766. }
  767. /*++
  768. Routine name : DeleteDeviceEntry
  769. Routine description:
  770. Delete service device entry from devices.
  771. Author:
  772. Caliv Nir (t-nicali), Apr, 2001
  773. Arguments:
  774. serverPermanentID [in] - service device ID to be deleted
  775. Return Value:
  776. Win32 error code
  777. --*/
  778. DWORD
  779. DeleteDeviceEntry(DWORD serverPermanentID)
  780. {
  781. DWORD ec = ERROR_SUCCESS; // LastError for this function.
  782. HKEY hKeyDevices;
  783. TCHAR DevicesKeyName[MAX_PATH];
  784. DEBUG_FUNCTION_NAME(TEXT("DeleteDeviceEntry"));
  785. //
  786. // open - "fax\Devices\serverPermanentID" Registry Key
  787. //
  788. _stprintf( DevicesKeyName, TEXT("%s\\%010lu"), REGKEY_FAX_DEVICES, serverPermanentID );
  789. hKeyDevices = OpenRegistryKey( HKEY_LOCAL_MACHINE, DevicesKeyName, FALSE, KEY_READ | KEY_WRITE );
  790. if (!hKeyDevices)
  791. {
  792. ec = GetLastError();
  793. DebugPrintEx(
  794. DEBUG_WRN,
  795. TEXT("OpenRegistryKey failed with [%ld] the device entry might be missing."),
  796. ec
  797. );
  798. return ec;
  799. }
  800. //
  801. // delete our servers data (under GUID and "Permanent Lineid" value)
  802. //
  803. if (!DeleteRegistryKey( hKeyDevices, REGKEY_FAXSVC_DEVICE_GUID))
  804. {
  805. DebugPrintEx(
  806. DEBUG_WRN,
  807. TEXT("DeleteRegistryKey failed, the device GUID might be missing.")
  808. );
  809. }
  810. if (ERROR_SUCCESS != RegDeleteValue( hKeyDevices, REGVAL_PERMANENT_LINEID))
  811. {
  812. DebugPrintEx(
  813. DEBUG_WRN,
  814. TEXT("RegDeleteValue failed, the device \"PermanentLineID\" might be missing.")
  815. );
  816. }
  817. //
  818. // check to see wheter the key is now empty
  819. //
  820. DWORD dwcSubKeys = 0;
  821. DWORD dwcValues = 0;
  822. ec=RegQueryInfoKey(
  823. hKeyDevices, // handle to key
  824. NULL,
  825. NULL,
  826. NULL,
  827. &dwcSubKeys, // number of subkeys
  828. NULL,
  829. NULL,
  830. &dwcValues, // number of value entries
  831. NULL,
  832. NULL,
  833. NULL,
  834. NULL
  835. );
  836. if ( ERROR_SUCCESS != ec )
  837. {
  838. DebugPrintEx(
  839. DEBUG_WRN,
  840. TEXT("RegQueryInfoKey Abort deleteion.")
  841. );
  842. RegCloseKey(hKeyDevices);
  843. return ec;
  844. }
  845. RegCloseKey(hKeyDevices);
  846. if ( (0 == dwcSubKeys) && (0 == dwcValues) )
  847. {
  848. //
  849. // key is empty delete it
  850. //
  851. hKeyDevices = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_DEVICES, FALSE, KEY_WRITE | DELETE);
  852. if (!hKeyDevices)
  853. {
  854. ec = GetLastError();
  855. DebugPrintEx(
  856. DEBUG_ERR,
  857. TEXT("OpenRegistryKey failed with [%lu], Can't delete key."),
  858. ec
  859. );
  860. return ec;
  861. }
  862. DWORD dwLen = _tcslen( REGKEY_FAX_DEVICES ) + 1;
  863. Assert((DevicesKeyName + dwLen));
  864. Assert(*(DevicesKeyName + dwLen));
  865. DebugPrintEx(
  866. DEBUG_WRN,
  867. TEXT("Deleting Device entry %s"),
  868. (DevicesKeyName + dwLen)
  869. );
  870. ec = RegDeleteKey( hKeyDevices, (DevicesKeyName + dwLen));
  871. if ( ERROR_SUCCESS != ec )
  872. {
  873. DebugPrintEx(
  874. DEBUG_ERR,
  875. TEXT("RegDeleteKey failed, Can't delete key.")
  876. );
  877. }
  878. RegCloseKey(hKeyDevices);
  879. }
  880. return ec;
  881. }
  882. /*++
  883. Routine name : DeleteCacheEntry
  884. Routine description:
  885. Delete cache entry for a given Tapi ID
  886. Author:
  887. Caliv Nir (t-nicali), Apr, 2001
  888. Arguments:
  889. dwTapiPermanentLineID [in] - device Tapi permament ID
  890. Return Value:
  891. Win32 Error code (ERROR_SUCCESS on success)
  892. --*/
  893. DWORD
  894. DeleteCacheEntry(DWORD dwTapiPermanentLineID)
  895. {
  896. DWORD ec = ERROR_SUCCESS; // LastError for this function.
  897. HKEY hKey;
  898. TCHAR strTapiPermanentLineID[10];
  899. DEBUG_FUNCTION_NAME(TEXT("DeleteCacheEntry"));
  900. //
  901. // open - "fax\Device Cache" Registry Key
  902. //
  903. hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_DEVICES_CACHE, FALSE, KEY_READ | KEY_WRITE );
  904. if (!hKey)
  905. {
  906. ec = GetLastError();
  907. DebugPrintEx(
  908. DEBUG_ERR,
  909. TEXT("OpenRegistryKey failed, Can't delete key.")
  910. );
  911. return ec;
  912. }
  913. _stprintf( strTapiPermanentLineID, TEXT("%08lx"),dwTapiPermanentLineID );
  914. if (!DeleteRegistryKey(hKey, strTapiPermanentLineID))
  915. {
  916. ec = GetLastError();
  917. DebugPrintEx(
  918. DEBUG_ERR,
  919. TEXT("DeleteRegistryKey failed with (%ld), Can't delete key."),
  920. ec);
  921. }
  922. RegCloseKey(hKey);
  923. return ec;
  924. }
  925. /*++
  926. Routine name : DeleteTapiEntry
  927. Routine description:
  928. Delete Tapi entry when caching from TapiDevices, for a give Tapi ID
  929. Author:
  930. Caliv Nir (t-nicali), Apr, 2001
  931. Arguments:
  932. dwTapiPermanentLineID [in] - device Tapi permament ID
  933. Return Value:
  934. Win32 Error code (ERROR_SUCCESS on success)
  935. --*/
  936. DWORD
  937. DeleteTapiEntry(DWORD dwTapiPermanentLineID)
  938. {
  939. DWORD ec = ERROR_SUCCESS; // LastError for this function.
  940. HKEY hKey;
  941. TCHAR strTapiPermanentLineID[10];
  942. DEBUG_FUNCTION_NAME(TEXT("DeleteTapiEntry"));
  943. //
  944. // open - "fax\TAPIDevices" Registry Key
  945. //
  946. hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_TAPIDEVICES, FALSE, KEY_READ | KEY_WRITE );
  947. if (!hKey)
  948. {
  949. DebugPrintEx(
  950. DEBUG_ERR,
  951. TEXT("OpenRegistryKey failed, Can't delete key.")
  952. );
  953. return ERROR_OPEN_FAILED;
  954. }
  955. _stprintf( strTapiPermanentLineID, TEXT("%08lx"),dwTapiPermanentLineID );
  956. if (!DeleteRegistryKey(hKey, strTapiPermanentLineID))
  957. {
  958. ec = GetLastError();
  959. DebugPrintEx(
  960. DEBUG_ERR,
  961. TEXT("DeleteRegistryKey failed with (%ld), Can't delete key."),
  962. ec);
  963. }
  964. RegCloseKey(hKey);
  965. return ec;
  966. }
  967. /*++
  968. Routine name : CopyRegistrySubkeysByHandle
  969. Routine description:
  970. Copy a content of one registry key into another
  971. Author:
  972. Caliv Nir (t-nicali), Apr, 2001
  973. Arguments:
  974. hkeyDest [in] - handle for destination registry key
  975. hkeySrc [in] - handle for source registry key
  976. fForceRestore [in] - do we force restore of this hive?
  977. Return Value:
  978. Win32 Error code
  979. --*/
  980. DWORD
  981. CopyRegistrySubkeysByHandle(
  982. HKEY hkeyDest,
  983. HKEY hkeySrc,
  984. BOOL fForceRestore
  985. )
  986. {
  987. LPTSTR TempPath = NULL;
  988. DWORD dwTempPathLength = 0;
  989. LPCTSTR strFileName = TEXT("tempCacheFile");
  990. DWORD ec = ERROR_SUCCESS; // LastError for this function.
  991. DEBUG_FUNCTION_NAME(TEXT("CopyRegistrySubkeysByHandle"));
  992. dwTempPathLength = GetTempPath(0,NULL) + 1; // find out temp path size
  993. dwTempPathLength += _tcslen( strFileName ) + 1; // add the length of file name
  994. dwTempPathLength += 2; // just to be sure
  995. TempPath = (LPTSTR) MemAlloc( dwTempPathLength * sizeof(TCHAR) );
  996. if (!TempPath )
  997. {
  998. DebugPrintEx(
  999. DEBUG_ERR,
  1000. TEXT("MemAlloc failed. Can't continue")
  1001. );
  1002. ec = ERROR_NOT_ENOUGH_MEMORY;
  1003. goto Exit;
  1004. }
  1005. if (!GetTempPath( dwTempPathLength, TempPath ))
  1006. {
  1007. ec = GetLastError();
  1008. DebugPrintEx(
  1009. DEBUG_ERR,
  1010. TEXT("GetTempPath failed with [%ld]. Can't continue"),
  1011. ec);
  1012. goto Exit;
  1013. }
  1014. _tcscat(TempPath,strFileName);
  1015. //
  1016. // store hKeySrc in a file
  1017. //
  1018. HANDLE hOldPrivilege = EnablePrivilege(SE_BACKUP_NAME);
  1019. if (INVALID_HANDLE_VALUE != hOldPrivilege) // set proper previlege
  1020. {
  1021. ec = RegSaveKey(
  1022. hkeySrc, // handle to key
  1023. TempPath, // data file
  1024. NULL);
  1025. if (ec != ERROR_SUCCESS)
  1026. {
  1027. DebugPrintEx(
  1028. DEBUG_ERR,
  1029. TEXT("RegSaveKey failed with [%lu]. Can't continue"),
  1030. ec
  1031. );
  1032. ReleasePrivilege(hOldPrivilege);
  1033. goto Exit;
  1034. }
  1035. ReleasePrivilege(hOldPrivilege);
  1036. }
  1037. else
  1038. {
  1039. ec = GetLastError();
  1040. DebugPrintEx(
  1041. DEBUG_ERR,
  1042. TEXT("EnablePrivilege(SE_BACKUP_NAME) failed with [%lu]. Can't continue"),
  1043. ec
  1044. );
  1045. goto Exit;
  1046. }
  1047. //
  1048. // restore the registry values from the file into hkeyDest
  1049. //
  1050. hOldPrivilege = EnablePrivilege(SE_RESTORE_NAME);
  1051. if (INVALID_HANDLE_VALUE != hOldPrivilege) // set proper previlege
  1052. {
  1053. ec = RegRestoreKey(
  1054. hkeyDest, // handle to key where restore begins
  1055. TempPath, // registry file
  1056. fForceRestore ? REG_FORCE_RESTORE : 0); // options
  1057. if ( ec != ERROR_SUCCESS)
  1058. {
  1059. DebugPrintEx(
  1060. DEBUG_ERR,
  1061. TEXT("RegRestoreKey failed. Can't continue")
  1062. );
  1063. ReleasePrivilege(hOldPrivilege);
  1064. goto Exit;
  1065. }
  1066. ReleasePrivilege(hOldPrivilege);
  1067. }
  1068. else
  1069. {
  1070. ec = GetLastError();
  1071. DebugPrintEx(
  1072. DEBUG_ERR,
  1073. TEXT("EnablePrivilege(SE_RESTORE_NAME) failed with [%lu]. Can't continue")
  1074. );
  1075. goto Exit;
  1076. }
  1077. Exit:
  1078. if (TempPath)
  1079. {
  1080. if (!DeleteFile(TempPath))
  1081. {
  1082. DebugPrintEx( DEBUG_ERR,
  1083. TEXT("DeleteFile failed. file: %s. (ec=%ld)"),
  1084. TempPath,
  1085. GetLastError());
  1086. }
  1087. MemFree(TempPath);
  1088. }
  1089. return ec;
  1090. }
  1091. /*++
  1092. Routine name : CopyRegistrySubkeys
  1093. Routine description:
  1094. Copy a content of one registry key into another
  1095. Author:
  1096. Caliv Nir (t-nicali), Apr, 2001
  1097. Arguments:
  1098. strDest [in] - string of destination registry key name
  1099. strSrc [in] - string of source registry key name
  1100. fForceRestore [in] - do we force restore of the hive?
  1101. Return Value:
  1102. Win32 Error Code
  1103. --*/
  1104. DWORD
  1105. CopyRegistrySubkeys(
  1106. LPCTSTR strDest,
  1107. LPCTSTR strSrc,
  1108. BOOL fForceRestore
  1109. )
  1110. {
  1111. DWORD ec = ERROR_SUCCESS; // LastError for this function.
  1112. HKEY hKeyDest;
  1113. HKEY hKeySrc;
  1114. DEBUG_FUNCTION_NAME(TEXT("CopyRegistrySubkeys"));
  1115. //
  1116. // open source Key
  1117. //
  1118. hKeySrc = OpenRegistryKey( HKEY_LOCAL_MACHINE, strSrc, FALSE, KEY_READ );
  1119. if (!hKeySrc)
  1120. {
  1121. ec = GetLastError();
  1122. DebugPrintEx(
  1123. DEBUG_ERR,
  1124. TEXT("OpenRegistryKey failed with [%lu], Can't copy keys."),
  1125. ec
  1126. );
  1127. return ec;
  1128. }
  1129. //
  1130. // open destination Key
  1131. //
  1132. hKeyDest = OpenRegistryKey( HKEY_LOCAL_MACHINE, strDest, TRUE, KEY_READ | KEY_WRITE);
  1133. if (!hKeyDest)
  1134. {
  1135. ec = GetLastError();
  1136. RegCloseKey (hKeySrc);
  1137. DebugPrintEx(
  1138. DEBUG_ERR,
  1139. TEXT("OpenRegistryKey failed [%lu], Can't copy keys."),
  1140. ec
  1141. );
  1142. return ec;
  1143. }
  1144. //
  1145. // copy the keys using the registry Keys
  1146. //
  1147. ec = CopyRegistrySubkeysByHandle(hKeyDest,hKeySrc,fForceRestore);
  1148. if ( ERROR_SUCCESS != ec )
  1149. {
  1150. DebugPrintEx(
  1151. DEBUG_ERR,
  1152. TEXT("CopyRegistrySubkeysHkey failed with [%lu], Can't copy keys."),
  1153. ec
  1154. );
  1155. }
  1156. RegCloseKey (hKeyDest);
  1157. RegCloseKey (hKeySrc);
  1158. return ec;
  1159. }