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.

1598 lines
36 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. registry.cxx
  5. Abstract:
  6. Functions to read/write registry parameters
  7. Contents:
  8. OpenInternetSettingsKey
  9. CloseInternetSettingsKey
  10. InternetGetComputerName
  11. InternetDeleteRegistryValue
  12. InternetReadRegistryDword
  13. InternetWriteRegistryDword
  14. InternetReadRegistryString
  15. InternetWriteRegistryString
  16. InternetReadRegistryBinary
  17. (InternetReadRegistryDwordKey)
  18. (InternetReadRegistryStringKey)
  19. (InternetReadRegistryBinaryKey)
  20. (InternetGetPrivateProfileString)
  21. (ReadRegistryOemString)
  22. (WriteRegistryDword)
  23. ReadRegistryDword
  24. Author:
  25. Richard L Firth (rfirth) 20-Mar-1995
  26. Environment:
  27. Win32(s) user-level DLL
  28. Revision History:
  29. 20-Mar-1995 rfirth
  30. Created
  31. --*/
  32. #include <wininetp.h>
  33. char vszDelimiters[] = ";, ";
  34. //
  35. // manifests
  36. //
  37. #define INTERNET_CLIENT_KEY "Internet Settings"
  38. #define SYSTEM_INI_FILE_NAME "SYSTEM.INI"
  39. #define NETWORK_SECTION_NAME "Network"
  40. #define COMPUTER_NAME_VALUE "ComputerName"
  41. #define PROFILE_INT_BUFFER_LENGTH 128
  42. #define MIME_TO_FILE_EXTENSION_KEY "MIME\\Database\\Content Type\\"
  43. #define EXTENSION_VALUE "Extension"
  44. //
  45. // macros
  46. //
  47. #define INTERNET_SETTINGS_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
  48. #define INTERNET_CACHE_SETTINGS_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\5.0\\Cache"
  49. //
  50. // private prototypes
  51. //
  52. PRIVATE
  53. DWORD
  54. InternetReadRegistryDwordKey(
  55. IN HKEY ParameterKey,
  56. IN LPCSTR ParameterName,
  57. OUT LPDWORD ParameterValue
  58. );
  59. PRIVATE
  60. DWORD
  61. InternetReadRegistryStringKey(
  62. IN HKEY ParameterKey,
  63. IN LPCSTR ParameterName,
  64. OUT LPSTR ParameterValue,
  65. IN OUT LPDWORD ParameterLength
  66. );
  67. //PRIVATE
  68. //DWORD
  69. //InternetReadRegistryBinaryKey(
  70. // IN HKEY ParameterKey,
  71. // IN LPCSTR ParameterName,
  72. // OUT LPBYTE ParameterValue,
  73. // IN OUT LPDWORD ParameterLength
  74. // );
  75. //
  76. //PRIVATE
  77. //DWORD
  78. //InternetGetPrivateProfileString(
  79. // IN LPSTR IniFileName,
  80. // IN LPSTR SectionName,
  81. // IN LPCSTR ParameterName,
  82. // OUT LPSTR ParameterValue,
  83. // IN OUT LPDWORD ParameterLength
  84. // );
  85. PRIVATE
  86. DWORD
  87. ReadRegistryOemString(
  88. IN HKEY Key,
  89. IN LPCSTR ParameterName,
  90. OUT LPSTR String,
  91. IN OUT LPDWORD Length
  92. );
  93. PRIVATE
  94. DWORD
  95. WriteRegistryDword(
  96. IN HKEY Key,
  97. IN LPCSTR ParameterName,
  98. IN DWORD ParameterValue
  99. );
  100. //
  101. // private data
  102. //
  103. PRIVATE HKEY hKeyInternetSettings = NULL;
  104. //
  105. // functions
  106. //
  107. DWORD
  108. OpenInternetSettingsKey(
  109. VOID
  110. )
  111. /*++
  112. Routine Description:
  113. Opens registry key for Internet Settings branch
  114. Arguments:
  115. None.
  116. Return Value:
  117. DWORD
  118. Success - ERROR_SUCCESS
  119. Failure - ERROR_NOT_ENOUGH_MEMORY
  120. --*/
  121. {
  122. DEBUG_ENTER((DBG_REGISTRY,
  123. Dword,
  124. "OpenInternetSettingsKey",
  125. NULL
  126. ));
  127. DWORD error = ERROR_SUCCESS;
  128. if (!GeneralInitCritSec.Lock())
  129. {
  130. goto quit;
  131. error = ERROR_NOT_ENOUGH_MEMORY;
  132. }
  133. if (hKeyInternetSettings == NULL) {
  134. DWORD dwDisposition;
  135. REGCREATEKEYEX(HKEY_LOCAL_MACHINE,
  136. INTERNET_SETTINGS_KEY,
  137. 0, // reserved
  138. NULL, // class
  139. 0, // options
  140. KEY_READ | KEY_WRITE,
  141. NULL, // security attributes
  142. &hKeyInternetSettings,
  143. &dwDisposition
  144. );
  145. }
  146. GeneralInitCritSec.Unlock();
  147. quit:
  148. DEBUG_LEAVE(error);
  149. return error;
  150. }
  151. DWORD
  152. CloseInternetSettingsKey(
  153. VOID
  154. )
  155. /*++
  156. Routine Description:
  157. Closes Internet Settings registry key
  158. Arguments:
  159. None.
  160. Return Value:
  161. DWORD
  162. Success - ERROR_SUCCESS
  163. Failure -
  164. --*/
  165. {
  166. DEBUG_ENTER((DBG_REGISTRY,
  167. Dword,
  168. "CloseInternetSettingsKey",
  169. NULL
  170. ));
  171. DWORD error = ERROR_SUCCESS;
  172. if (hKeyInternetSettings != NULL) {
  173. error = REGCLOSEKEY(hKeyInternetSettings);
  174. hKeyInternetSettings = NULL;
  175. }
  176. DEBUG_LEAVE(error);
  177. return error;
  178. }
  179. PUBLIC
  180. DWORD
  181. InternetDeleteRegistryValue(
  182. IN LPSTR ParameterName
  183. )
  184. /*++
  185. Routine Description:
  186. Delets an entry from a the Internet Client registry key if the platform
  187. is NT/Win95.
  188. Arguments:
  189. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  190. Return Value:
  191. DWORD
  192. Success - ERROR_SUCCESS
  193. Failure - ERROR_PATH_NOT_FOUND
  194. --*/
  195. {
  196. DWORD error;
  197. DEBUG_ENTER((DBG_REGISTRY,
  198. Dword,
  199. "InternetDeleteRegistryValue",
  200. "%q",
  201. ParameterName
  202. ));
  203. HKEY clientKey;
  204. //
  205. // open the registry key containing the Internet client values (this is
  206. // in the same place on NT and Win95)
  207. //
  208. error = REGOPENKEYEX(HKEY_CURRENT_USER,
  209. INTERNET_SETTINGS_KEY,
  210. 0, // reserved
  211. KEY_ALL_ACCESS,
  212. &clientKey
  213. );
  214. if (error == ERROR_SUCCESS) {
  215. error = RegDeleteValue(clientKey,
  216. ParameterName
  217. );
  218. REGCLOSEKEY(clientKey);
  219. }
  220. DEBUG_LEAVE(error);
  221. return error;
  222. }
  223. DWORD
  224. InternetReadRegistryDword(
  225. IN LPCSTR ParameterName,
  226. OUT LPDWORD ParameterValue
  227. )
  228. /*++
  229. Routine Description:
  230. Reads a single DWORD from a the Internet Client registry key if the platform
  231. is NT/Win95, else reads the value from SYSTEM.INI if we are running on Win32s
  232. Arguments:
  233. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  234. ParameterValue - pointer to place to store retrieved value
  235. Return Value:
  236. DWORD
  237. Success - ERROR_SUCCESS
  238. Failure - ERROR_PATH_NOT_FOUND
  239. --*/
  240. {
  241. DEBUG_ENTER((DBG_REGISTRY,
  242. Dword,
  243. "InternetReadRegistryDword",
  244. "%q, %x",
  245. ParameterName,
  246. ParameterValue
  247. ));
  248. DWORD error = InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE,
  249. ParameterName,
  250. ParameterValue
  251. );
  252. DEBUG_LEAVE(error);
  253. return error;
  254. }
  255. #ifdef WININET6
  256. DWORD
  257. InternetIDEWriteRegistryDword(
  258. IN LPCSTR ParameterName,
  259. IN DWORD ParameterValue
  260. )
  261. /*++
  262. Routine Description:
  263. Writes a single DWORD from to the Internet Client registry key if the platform
  264. is NT/Win95, otherwise it fails.
  265. Arguments:
  266. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  267. ParameterValue - value to store in registry.
  268. Return Value:
  269. DWORD
  270. Success - ERROR_SUCCESS
  271. Failure - ERROR_PATH_NOT_FOUND
  272. --*/
  273. {
  274. DEBUG_ENTER((DBG_REGISTRY,
  275. Dword,
  276. "InternetIDEWriteRegistryDword",
  277. "%q, %x",
  278. ParameterName,
  279. ParameterValue
  280. ));
  281. DWORD error = GlobalIdentity
  282. ? WriteIDRegDword(ParameterName, ParameterValue)
  283. : InternetWriteRegistryDword(ParameterName, ParameterValue);
  284. DEBUG_LEAVE(error);
  285. return error;
  286. }
  287. DWORD
  288. InternetIDEReadRegistryDword(
  289. IN LPCSTR ParameterName,
  290. OUT LPDWORD ParameterValue
  291. )
  292. /*++
  293. Routine Description:
  294. If we're in an identity-mode, we'll read from the special location.
  295. Otherwise, read from the old location.
  296. Arguments:
  297. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  298. ParameterValue - pointer to place to store retrieved value
  299. Return Value:
  300. DWORD
  301. Success - ERROR_SUCCESS
  302. Failure - ERROR_PATH_NOT_FOUND
  303. --*/
  304. {
  305. DEBUG_ENTER((DBG_REGISTRY,
  306. Dword,
  307. "InternetIDEReadRegistryDword",
  308. "%q, %x",
  309. ParameterName,
  310. ParameterValue
  311. ));
  312. DWORD error = GlobalIdentity
  313. ? ReadIDRegDword(ParameterName, ParameterValue)
  314. : InternetReadRegistryDwordKey(HKEY_CURRENT_USER, ParameterName, ParameterValue);
  315. DEBUG_LEAVE(error);
  316. return error;
  317. }
  318. #endif
  319. DWORD
  320. InternetCacheReadRegistryDword(
  321. IN LPCSTR ParameterName,
  322. OUT LPDWORD ParameterValue
  323. )
  324. /*++
  325. Routine Description:
  326. Reads a single DWORD from a the Internet Client registry key if the platform
  327. is NT/Win95, else reads the value from SYSTEM.INI if we are running on Win32s
  328. Arguments:
  329. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  330. ParameterValue - pointer to place to store retrieved value
  331. Return Value:
  332. DWORD
  333. Success - ERROR_SUCCESS
  334. Failure - ERROR_PATH_NOT_FOUND
  335. --*/
  336. {
  337. DEBUG_ENTER((DBG_REGISTRY,
  338. Dword,
  339. "InternetCacheReadRegistryDword",
  340. "%q, %x",
  341. ParameterName,
  342. ParameterValue
  343. ));
  344. DWORD error = ERROR_SUCCESS;
  345. HKEY clientKey;
  346. error = REGOPENKEYEX(HKEY_CURRENT_USER,
  347. INTERNET_CACHE_SETTINGS_KEY,
  348. 0, // reserved
  349. KEY_QUERY_VALUE,
  350. &clientKey
  351. );
  352. if (error == ERROR_SUCCESS) {
  353. error = ReadRegistryDword(clientKey,
  354. ParameterName,
  355. ParameterValue
  356. );
  357. REGCLOSEKEY(clientKey);
  358. }
  359. DEBUG_LEAVE(error);
  360. return error;
  361. }
  362. DWORD
  363. InternetWriteRegistryDword(
  364. IN LPCSTR ParameterName,
  365. IN DWORD ParameterValue
  366. )
  367. /*++
  368. Routine Description:
  369. Writes a single DWORD from to the Internet Client registry key if the platform
  370. is NT/Win95, otherwise it fails.
  371. Arguments:
  372. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  373. ParameterValue - value to store in registry.
  374. Return Value:
  375. DWORD
  376. Success - ERROR_SUCCESS
  377. Failure - ERROR_PATH_NOT_FOUND
  378. --*/
  379. {
  380. DEBUG_ENTER((DBG_REGISTRY,
  381. Dword,
  382. "InternetWriteRegistryDword",
  383. "%q, %x",
  384. ParameterName,
  385. ParameterValue
  386. ));
  387. DWORD error;
  388. if (hKeyInternetSettings != NULL) {
  389. error = WriteRegistryDword(hKeyInternetSettings,
  390. ParameterName,
  391. ParameterValue
  392. );
  393. } else {
  394. error = ERROR_SUCCESS;
  395. }
  396. DEBUG_PRINT(REGISTRY,
  397. INFO,
  398. ("InternetWriteRegistryDword(%q): value = %d (%#x)\n",
  399. ParameterName,
  400. ParameterValue,
  401. ParameterValue
  402. ));
  403. DEBUG_LEAVE(error);
  404. return error;
  405. }
  406. DWORD
  407. InternetReadRegistryString(
  408. IN LPCSTR ParameterName,
  409. OUT LPSTR ParameterValue,
  410. IN OUT LPDWORD ParameterLength
  411. )
  412. /*++
  413. Routine Description:
  414. Reads a string from the Internet Client registry key on NT/Win95, or reads
  415. the corresponding value from SYSTEM.INI on a Win32s platform
  416. Arguments:
  417. ParameterName - name of value parameter within key (e.g. EmailName)
  418. ParameterValue - pointer to string buffer for returned string
  419. ParameterLength - IN: number of bytes in ParameterValue
  420. OUT: number of bytes in string (excluding trailing '\0')
  421. Return Value:
  422. DWORD
  423. Success - ERROR_SUCCESS
  424. Failure - ERROR_PATH_NOT_FOUND
  425. --*/
  426. {
  427. DEBUG_ENTER((DBG_REGISTRY,
  428. Dword,
  429. "InternetReadRegistryString",
  430. "%q, %x, %x [%d]",
  431. ParameterName,
  432. ParameterValue,
  433. ParameterLength,
  434. *ParameterLength
  435. ));
  436. DWORD error = InternetReadRegistryStringKey(HKEY_CURRENT_USER,
  437. ParameterName,
  438. ParameterValue,
  439. ParameterLength
  440. );
  441. DEBUG_LEAVE(error);
  442. return error;
  443. }
  444. //
  445. //DWORD
  446. //InternetWriteRegistryString(
  447. // IN LPCSTR ParameterName,
  448. // IN LPSTR ParameterValue
  449. // )
  450. //
  451. ///*++
  452. //
  453. //Routine Description:
  454. //
  455. // Writes a string to the Internet Client registry key on NT/Win95, or writes
  456. // the corresponding value to SYSTEM.INI on Win32s platform
  457. //
  458. //Arguments:
  459. //
  460. // ParameterName - name of value parameter within key (e.g. EmailName)
  461. //
  462. // ParameterValue - pointer to string to write
  463. //
  464. //Return Value:
  465. //
  466. // DWORD
  467. // Success - ERROR_SUCCESS
  468. //
  469. // Failure -
  470. //
  471. //--*/
  472. //
  473. //{
  474. // DEBUG_ENTER((DBG_REGISTRY,
  475. // Dword,
  476. // "InternetWriteRegistryString",
  477. // "%.40q, %.80q",
  478. // ParameterName,
  479. // ParameterValue
  480. // ));
  481. //
  482. // DWORD error;
  483. //
  484. // if (IsPlatformWin32s()) {
  485. //
  486. // BOOL ok;
  487. //
  488. // ok = WritePrivateProfileString(INTERNET_CLIENT_KEY,
  489. // ParameterName,
  490. // ParameterValue,
  491. // SYSTEM_INI_FILE_NAME
  492. // );
  493. // error = ok ? ERROR_SUCCESS : GetLastError();
  494. // } else {
  495. //
  496. // //
  497. // // BUGBUG - currently, nothing needs to write to registry if NT or Win95
  498. // //
  499. //
  500. // INET_ASSERT(FALSE);
  501. //
  502. // }
  503. //
  504. // DEBUG_LEAVE(error);
  505. //
  506. // return error;
  507. //}
  508. //
  509. //
  510. //DWORD
  511. //InternetReadRegistryBinary(
  512. // IN LPCSTR ParameterName,
  513. // OUT LPBYTE ParameterValue,
  514. // IN OUT LPDWORD ParameterLength
  515. // )
  516. //
  517. ///*++
  518. //
  519. //Routine Description:
  520. //
  521. // Reads a binary value from the Internet Client registry key on NT/Win95, or
  522. // reads the corresponding value from SYSTEM.INI on a Win32s platform
  523. //
  524. //Arguments:
  525. //
  526. // ParameterName - name of value parameter within key (e.g. EmailName)
  527. //
  528. // ParameterValue - pointer to buffer for returned data
  529. //
  530. // ParameterLength - IN: number of bytes in ParameterValue
  531. // OUT: number of bytes in buffer, or required size
  532. //
  533. //Return Value:
  534. //
  535. // DWORD
  536. // Success - ERROR_SUCCESS
  537. //
  538. // Failure - ERROR_PATH_NOT_FOUND
  539. // The parameter wasn't found
  540. //
  541. // ERROR_MORE_DATA
  542. // The buffer isn't large enough
  543. //
  544. //--*/
  545. //
  546. //{
  547. // DEBUG_ENTER((DBG_REGISTRY,
  548. // Dword,
  549. // "InternetReadRegistryBinary",
  550. // "%q, %#x, %#x [%d]",
  551. // ParameterName,
  552. // ParameterValue,
  553. // ParameterLength,
  554. // *ParameterLength
  555. // ));
  556. //
  557. // DWORD error;
  558. //
  559. // error = InternetReadRegistryBinaryKey(HKEY_CURRENT_USER,
  560. // ParameterName,
  561. // ParameterValue,
  562. // ParameterLength
  563. // );
  564. //
  565. // DEBUG_LEAVE(error);
  566. //
  567. // return error;
  568. //}
  569. //
  570. // private functions
  571. //
  572. PUBLIC
  573. DWORD
  574. InternetReadRegistryDwordKey(
  575. IN HKEY ParameterKey,
  576. IN LPCSTR ParameterName,
  577. OUT LPDWORD ParameterValue
  578. )
  579. /*++
  580. Routine Description:
  581. Reads a single DWORD from a the Internet Client registry key if the platform
  582. is NT/Win95, else reads the value from SYSTEM.INI if we are running on Win32s.
  583. Does not modify the *ParameterValue if the registry variable cannot be read
  584. Arguments:
  585. ParameterKey - root registry key (e.g. HKEY_CURRENT_USER)
  586. ParameterName - name of the parameter to retrieve (e.g. AccessType)
  587. ParameterValue - pointer to place to store retrieved value
  588. Return Value:
  589. DWORD
  590. Success - ERROR_SUCCESS
  591. Failure - ERROR_PATH_NOT_FOUND
  592. --*/
  593. {
  594. DEBUG_ENTER((DBG_REGISTRY,
  595. Dword,
  596. "InternetReadRegistryDwordKey",
  597. "%s, %q, %x",
  598. (ParameterKey == HKEY_LOCAL_MACHINE)
  599. ? "HKEY_LOCAL_MACHINE"
  600. : (ParameterKey == HKEY_CURRENT_USER)
  601. ? "HKEY_CURRENT_USER"
  602. : "???",
  603. ParameterName,
  604. ParameterValue
  605. ));
  606. DWORD error = ERROR_SUCCESS;
  607. HKEY clientKey = hKeyInternetSettings;
  608. if (ParameterKey != HKEY_CURRENT_USER) {
  609. error = REGOPENKEYEX(ParameterKey,
  610. INTERNET_SETTINGS_KEY,
  611. 0, // reserved
  612. KEY_QUERY_VALUE,
  613. &clientKey
  614. );
  615. } else if (clientKey == NULL) {
  616. error = ERROR_PATH_NOT_FOUND;
  617. }
  618. if (error == ERROR_SUCCESS) {
  619. error = ReadRegistryDword(clientKey,
  620. ParameterName,
  621. ParameterValue
  622. );
  623. if (clientKey != hKeyInternetSettings) {
  624. REGCLOSEKEY(clientKey);
  625. }
  626. }
  627. DEBUG_PRINT(REGISTRY,
  628. INFO,
  629. ("InternetReadRegistryDwordKey(%q): value = %d (%#x)\n",
  630. ParameterName,
  631. *ParameterValue,
  632. *ParameterValue
  633. ));
  634. DEBUG_LEAVE(error);
  635. return error;
  636. }
  637. PRIVATE
  638. DWORD
  639. InternetReadRegistryStringKey(
  640. IN HKEY ParameterKey,
  641. IN LPCSTR ParameterName,
  642. OUT LPSTR ParameterValue,
  643. IN OUT LPDWORD ParameterLength
  644. )
  645. /*++
  646. Routine Description:
  647. Reads a string from the Internet Client registry key on NT/Win95, or reads
  648. the corresponding value from SYSTEM.INI on a Win32s platform
  649. Arguments:
  650. ParameterKey - root registry key (e.g. HKEY_LOCAL_MACHINE)
  651. ParameterName - name of value parameter within key (e.g. EmailName)
  652. ParameterValue - pointer to string buffer for returned string
  653. ParameterLength - IN: number of bytes in ParameterValue
  654. OUT: number of bytes in string (excluding trailing '\0')
  655. Return Value:
  656. DWORD
  657. Success - ERROR_SUCCESS
  658. Failure - ERROR_PATH_NOT_FOUND
  659. --*/
  660. {
  661. DEBUG_ENTER((DBG_REGISTRY,
  662. Dword,
  663. "InternetReadRegistryStringKey",
  664. "%s (%x), %q, %x, %x [%d]",
  665. (ParameterKey == HKEY_LOCAL_MACHINE)
  666. ? "HKEY_LOCAL_MACHINE"
  667. : (ParameterKey == HKEY_CURRENT_USER)
  668. ? "HKEY_CURRENT_USER"
  669. : "???",
  670. ParameterKey,
  671. ParameterName,
  672. ParameterValue,
  673. ParameterLength,
  674. *ParameterLength
  675. ));
  676. //
  677. // zero-terminate the string
  678. //
  679. if (*ParameterLength > 0) {
  680. *ParameterValue = '\0';
  681. }
  682. DWORD error = ERROR_SUCCESS;
  683. HKEY clientKey = hKeyInternetSettings;
  684. if (ParameterKey != HKEY_CURRENT_USER) {
  685. error = REGOPENKEYEX(ParameterKey,
  686. INTERNET_SETTINGS_KEY,
  687. 0, // reserved
  688. KEY_QUERY_VALUE,
  689. &clientKey
  690. );
  691. } else if (clientKey == NULL) {
  692. error = ERROR_PATH_NOT_FOUND;
  693. }
  694. if (error == ERROR_SUCCESS) {
  695. error = ReadRegistryOemString(clientKey,
  696. ParameterName,
  697. ParameterValue,
  698. ParameterLength
  699. );
  700. if (clientKey != hKeyInternetSettings) {
  701. REGCLOSEKEY(clientKey);
  702. }
  703. }
  704. DEBUG_PRINT(REGISTRY,
  705. INFO,
  706. ("InternetReadRegistryStringKey(%q): value = %q\n",
  707. ParameterName,
  708. ParameterValue
  709. ));
  710. DEBUG_LEAVE(error);
  711. return error;
  712. }
  713. //
  714. //PRIVATE
  715. //DWORD
  716. //InternetReadRegistryBinaryKey(
  717. // IN HKEY ParameterKey,
  718. // IN LPCSTR ParameterName,
  719. // OUT LPBYTE ParameterValue,
  720. // IN OUT LPDWORD ParameterLength
  721. // )
  722. //
  723. ///*++
  724. //
  725. //Routine Description:
  726. //
  727. // Reads a binary value from the Internet Client registry key on NT/Win95, or
  728. // reads the corresponding value from SYSTEM.INI on a Win32s platform
  729. //
  730. //Arguments:
  731. //
  732. // ParameterKey - root registry key (e.g. HKEY_LOCAL_MACHINE)
  733. //
  734. // ParameterName - name of value parameter within key (e.g. EmailName)
  735. //
  736. // ParameterValue - pointer to buffer for returned data
  737. //
  738. // ParameterLength - IN: number of bytes in ParameterValue
  739. // OUT: number of bytes in buffer, or required size
  740. //
  741. //Return Value:
  742. //
  743. // DWORD
  744. // Success - ERROR_SUCCESS
  745. //
  746. // Failure - ERROR_PATH_NOT_FOUND
  747. // The parameter wasn't found
  748. //
  749. // ERROR_MORE_DATA
  750. // The buffer isn't large enough
  751. //
  752. //--*/
  753. //
  754. //{
  755. // DEBUG_ENTER((DBG_REGISTRY,
  756. // Dword,
  757. // "InternetReadRegistryBinaryKey",
  758. // "%s (%x), %q, %#x, %#x [%d]",
  759. // (ParameterKey == HKEY_LOCAL_MACHINE)
  760. // ? "HKEY_LOCAL_MACHINE"
  761. // : (ParameterKey == HKEY_CURRENT_USER)
  762. // ? "HKEY_CURRENT_USER"
  763. // : "???",
  764. // ParameterKey,
  765. // ParameterName,
  766. // ParameterValue,
  767. // ParameterLength,
  768. // *ParameterLength
  769. // ));
  770. //
  771. // DWORD error;
  772. // HKEY clientKey;
  773. //
  774. // //
  775. // // open the registry key containing the Internet client values (this is
  776. // // in the same place on NT and Win95)
  777. // //
  778. //
  779. // error = REGOPENKEYEX(ParameterKey,
  780. // INTERNET_SETTINGS_KEY,
  781. // 0, // reserved
  782. // KEY_QUERY_VALUE,
  783. // &clientKey
  784. // );
  785. //
  786. // if (error == ERROR_SUCCESS) {
  787. //
  788. // DWORD valueType;
  789. //
  790. // error = RegQueryValueEx(clientKey,
  791. // ParameterName,
  792. // NULL, // reserved
  793. // &valueType,
  794. // ParameterValue,
  795. // ParameterLength
  796. // );
  797. // REGCLOSEKEY(clientKey);
  798. // }
  799. //
  800. // DEBUG_PRINT(REGISTRY,
  801. // INFO,
  802. // ("InternetReadRegistryBinaryKey(%q): length = %d\n",
  803. // ParameterName,
  804. // *ParameterLength
  805. // ));
  806. //
  807. // DEBUG_LEAVE(error);
  808. //
  809. // return error;
  810. //}
  811. //
  812. //
  813. //PRIVATE
  814. //DWORD
  815. //InternetGetPrivateProfileString(
  816. // IN LPSTR IniFileName,
  817. // IN LPSTR SectionName,
  818. // IN LPCSTR ParameterName,
  819. // OUT LPSTR ParameterValue,
  820. // IN OUT LPDWORD ParameterLength
  821. // )
  822. //
  823. ///*++
  824. //
  825. //Routine Description:
  826. //
  827. // Reads an string out of an INI file. Mainly just for Win32s
  828. //
  829. //Arguments:
  830. //
  831. // IniFileName - name of INI file to read
  832. //
  833. // SectionName - name of section in INI file to read
  834. //
  835. // ParameterName - name of entry in section to read
  836. //
  837. // ParameterValue - returned string
  838. //
  839. // ParameterLength - IN: Length of ParameterValue
  840. // OUT: Number of characters in ParameterValue, excluding
  841. // terminating NUL
  842. //
  843. //Return Value:
  844. //
  845. // DWORD
  846. // Success - ERROR_SUCCESS
  847. //
  848. // Failure - ERROR_PATH_NOT_FOUND
  849. // ERROR_FILE_NOT_FOUND
  850. //
  851. //--*/
  852. //
  853. //{
  854. // DWORD error;
  855. // DWORD nChars;
  856. //
  857. // nChars = GetPrivateProfileString(SectionName,
  858. // ParameterName,
  859. // "", // lpszDefault
  860. // ParameterValue,
  861. // *ParameterLength,
  862. // IniFileName
  863. // );
  864. // if (nChars > 0) {
  865. // *ParameterLength = nChars;
  866. // error = ERROR_SUCCESS;
  867. // } else {
  868. // error = ERROR_PATH_NOT_FOUND;
  869. // }
  870. // return error;
  871. //}
  872. PRIVATE
  873. DWORD
  874. ReadRegistryOemString(
  875. IN HKEY Key,
  876. IN LPCSTR ParameterName,
  877. OUT LPSTR String,
  878. IN OUT LPDWORD Length
  879. )
  880. /*++
  881. Routine Description:
  882. Reads a string out of the registry as an OEM string
  883. Arguments:
  884. Key - open registry key where to read value from
  885. ParameterName - name of registry value to read
  886. String - place to put it
  887. Length - IN: length of String buffer in characters
  888. OUT: length of String in characters, as if returned from
  889. strlen()
  890. Return Value:
  891. DWORD
  892. Success - ERROR_SUCCESS
  893. Failure - ERROR_FILE_NOT_FOUND
  894. Couldn't find the parameter
  895. ERROR_PATH_NOT_FOUND
  896. Couldn't find the parameter
  897. --*/
  898. {
  899. DEBUG_ENTER((DBG_REGISTRY,
  900. Dword,
  901. "ReadRegistryOemString",
  902. "%#x, %q, %#x, %#x [%d]",
  903. Key,
  904. ParameterName,
  905. String,
  906. Length,
  907. *Length
  908. ));
  909. LONG error;
  910. DWORD valueType;
  911. LPSTR str;
  912. DWORD valueLength;
  913. //
  914. // first, get the length of the string
  915. //
  916. valueLength = *Length;
  917. error = RegQueryValueEx(Key,
  918. ParameterName,
  919. NULL, // reserved
  920. &valueType,
  921. (LPBYTE)String,
  922. &valueLength
  923. );
  924. if (error != ERROR_SUCCESS) {
  925. goto quit;
  926. }
  927. //
  928. // we only support REG_SZ (single string) values in this function
  929. //
  930. if (valueType != REG_SZ) {
  931. error = ERROR_PATH_NOT_FOUND;
  932. goto quit;
  933. }
  934. //
  935. // if 1 or 0 chars returned then the string is empty
  936. //
  937. if (valueLength <= sizeof(char)) {
  938. error = ERROR_PATH_NOT_FOUND;
  939. goto quit;
  940. }
  941. //
  942. // convert the ANSI string to OEM character set in place. According to Win
  943. // help, this always succeeds
  944. //
  945. CharToOem(String, String);
  946. //
  947. // return the length as if returned from strlen() (i.e. drop the '\0')
  948. //
  949. *Length = valueLength - sizeof(char);
  950. DEBUG_PRINT(REGISTRY,
  951. INFO,
  952. ("ReadRegistryOemString(%q) returning %q (%d chars)\n",
  953. ParameterName,
  954. String,
  955. *Length
  956. ));
  957. quit:
  958. DEBUG_LEAVE(error);
  959. return error;
  960. }
  961. DWORD
  962. ReadRegistryDword(
  963. IN HKEY Key,
  964. IN LPCSTR ParameterName,
  965. OUT LPDWORD ParameterValue
  966. )
  967. /*++
  968. Routine Description:
  969. Reads a DWORD parameter from the registry
  970. Won't modify *ParameterValue unless a valid value is read from the registry
  971. Arguments:
  972. Key - handle of open registry key where parameter resides
  973. ParameterName - name of DWORD parameter to read
  974. ParameterValue - returned DWORD parameter read from registry
  975. Return Value:
  976. DWORD
  977. Success - ERROR_SUCCESS
  978. Failure - ERROR_PATH_NOT_FOUND
  979. One of the following occurred:
  980. - the parameter is not in the specified registry key
  981. - the parameter is the wrong type
  982. - the parameter is the wrong size
  983. --*/
  984. {
  985. DEBUG_ENTER((DBG_REGISTRY,
  986. Dword,
  987. "ReadRegistryDword",
  988. "%x, %q, %x",
  989. Key,
  990. ParameterName,
  991. ParameterValue
  992. ));
  993. DWORD error;
  994. DWORD valueLength;
  995. DWORD valueType;
  996. DWORD value;
  997. valueLength = sizeof(*ParameterValue);
  998. error = (DWORD)RegQueryValueEx(Key,
  999. ParameterName,
  1000. NULL, // reserved
  1001. &valueType,
  1002. (LPBYTE)&value,
  1003. &valueLength
  1004. );
  1005. //
  1006. // if the size or type aren't correct then return an error, else only if
  1007. // success was returned do we modify *ParameterValue
  1008. //
  1009. if (error == ERROR_SUCCESS) {
  1010. if (((valueType != REG_DWORD)
  1011. && (valueType != REG_BINARY))
  1012. || (valueLength != sizeof(DWORD))) {
  1013. DEBUG_PRINT(REGISTRY,
  1014. ERROR,
  1015. ("valueType = %d, valueLength = %d\n",
  1016. valueType,
  1017. valueLength
  1018. ));
  1019. error = ERROR_PATH_NOT_FOUND;
  1020. } else {
  1021. *ParameterValue = value;
  1022. }
  1023. }
  1024. DEBUG_LEAVE(error);
  1025. return error;
  1026. }
  1027. PRIVATE
  1028. DWORD
  1029. WriteRegistryDword(
  1030. IN HKEY Key,
  1031. IN LPCSTR ParameterName,
  1032. IN DWORD ParameterValue
  1033. )
  1034. /*++
  1035. Routine Description:
  1036. Writes a DWORD parameter from the registry
  1037. Will write ParameterValue to the key.
  1038. Arguments:
  1039. Key - handle of open registry key where parameter resides
  1040. ParameterName - name of DWORD parameter to write
  1041. ParameterValue - DWORD parameter to write from registry
  1042. Return Value:
  1043. DWORD
  1044. Success - ERROR_SUCCESS
  1045. Failure - ERROR_PATH_NOT_FOUND
  1046. One of the following occurred:
  1047. - the parameter is not in the specified registry key
  1048. - the parameter is the wrong type
  1049. - the parameter is the wrong size
  1050. --*/
  1051. {
  1052. DEBUG_ENTER((DBG_REGISTRY,
  1053. Dword,
  1054. "WriteRegistryDword",
  1055. "%x, %q, %x",
  1056. Key,
  1057. ParameterName,
  1058. ParameterValue
  1059. ));
  1060. DWORD error;
  1061. DWORD valueLength;
  1062. DWORD valueType;
  1063. DWORD value;
  1064. valueLength = sizeof(ParameterValue);
  1065. valueType = REG_DWORD;
  1066. value = ParameterValue;
  1067. error = (DWORD)RegSetValueEx(Key,
  1068. ParameterName,
  1069. NULL, // reserved
  1070. valueType,
  1071. (LPBYTE)&value,
  1072. valueLength
  1073. );
  1074. DEBUG_PRINT(REGISTRY,
  1075. INFO,
  1076. ("added: valueType = %d, valueLength = %d\n",
  1077. valueType,
  1078. valueLength
  1079. ));
  1080. DEBUG_LEAVE(error);
  1081. return error;
  1082. }
  1083. #if INET_DEBUG
  1084. typedef struct {
  1085. LIST_ENTRY entry;
  1086. HKEY hkey;
  1087. char * file;
  1088. int line;
  1089. char name[1];
  1090. } DBGREGKEYINFO;
  1091. SERIALIZED_LIST DbgRegKeyList;
  1092. VOID DbgRegKey_Init(VOID) {
  1093. InitializeSerializedList(&DbgRegKeyList);
  1094. }
  1095. VOID DbgRegKey_Terminate(VOID) {
  1096. TerminateSerializedList(&DbgRegKeyList);
  1097. }
  1098. void regkey_add(const char * name, HKEY hkey, char * file, int line) {
  1099. if (!name) {
  1100. name = "";
  1101. }
  1102. int len = lstrlen(name);
  1103. DBGREGKEYINFO * p = (DBGREGKEYINFO *)ALLOCATE_FIXED_MEMORY(sizeof(DBGREGKEYINFO) + len);
  1104. if (p) {
  1105. //dprintf("Wininet.DbgRegKey: adding %q\n", name);
  1106. memcpy(p->name, name, len + 1);
  1107. p->line = line;
  1108. p->file = file;
  1109. p->hkey = hkey;
  1110. InsertAtHeadOfSerializedList(&DbgRegKeyList, &p->entry);
  1111. }
  1112. }
  1113. void regkey_remove(HKEY hkey) {
  1114. if (LockSerializedList(&DbgRegKeyList))
  1115. {
  1116. DBGREGKEYINFO * p = (DBGREGKEYINFO *)HeadOfSerializedList(&DbgRegKeyList);
  1117. while (p != (DBGREGKEYINFO *)SlSelf(&DbgRegKeyList)) {
  1118. if (p->hkey == hkey) {
  1119. RemoveFromSerializedList(&DbgRegKeyList, (PLIST_ENTRY)p);
  1120. //dprintf("Wininet.DbgRegKey: removing %q\n", p->name);
  1121. FREE_MEMORY(p);
  1122. break;
  1123. }
  1124. p = (DBGREGKEYINFO *)p->entry.Flink;
  1125. }
  1126. UnlockSerializedList(&DbgRegKeyList);
  1127. }
  1128. }
  1129. char * regkey_name(HKEY hkey, const char * subname) {
  1130. switch ((INT_PTR)hkey) {
  1131. case (INT_PTR)HKEY_CLASSES_ROOT:
  1132. return NEW_STRING("HKEY_CLASSES_ROOT");
  1133. case (INT_PTR)HKEY_CURRENT_USER:
  1134. return NEW_STRING("HKEY_CURRENT_USER");
  1135. case (INT_PTR)HKEY_LOCAL_MACHINE:
  1136. return NEW_STRING("HKEY_LOCAL_MACHINE");
  1137. case (INT_PTR)HKEY_USERS:
  1138. return NEW_STRING("HKEY_USERS");
  1139. case (INT_PTR)HKEY_PERFORMANCE_DATA:
  1140. return NEW_STRING("HKEY_PERFORMANCE_DATA");
  1141. case (INT_PTR)HKEY_CURRENT_CONFIG:
  1142. return NEW_STRING("HKEY_CURRENT_CONFIG");
  1143. case (INT_PTR)HKEY_DYN_DATA:
  1144. return NEW_STRING("HKEY_DYN_DATA");
  1145. }
  1146. char * name = NULL;
  1147. if (LockSerializedList(&DbgRegKeyList))
  1148. {
  1149. DBGREGKEYINFO * p = (DBGREGKEYINFO *)HeadOfSerializedList(&DbgRegKeyList);
  1150. while (p != (DBGREGKEYINFO *)SlSelf(&DbgRegKeyList)) {
  1151. if (p->hkey == hkey) {
  1152. int len = lstrlen(p->name);
  1153. int slen = lstrlen(subname);
  1154. name = (char *)ALLOCATE_FIXED_MEMORY(len + 1 + slen + 1);
  1155. if (name) {
  1156. memcpy(name, p->name, len);
  1157. name[len] = '\\';
  1158. memcpy(name + len + 1, subname, slen + 1);
  1159. }
  1160. break;
  1161. }
  1162. p = (DBGREGKEYINFO *)p->entry.Flink;
  1163. }
  1164. UnlockSerializedList(&DbgRegKeyList);
  1165. }
  1166. return name;
  1167. }
  1168. void regkey_freename(char * name) {
  1169. if (name) {
  1170. FREE_MEMORY(name);
  1171. }
  1172. }
  1173. LONG
  1174. DbgRegOpenKey(
  1175. IN HKEY hKey,
  1176. IN LPCTSTR lpszSubKey,
  1177. OUT PHKEY phkResult,
  1178. char * file,
  1179. int line
  1180. )
  1181. {
  1182. char * keyname = regkey_name(hKey, lpszSubKey);
  1183. LONG rc = RegOpenKey(hKey, lpszSubKey, phkResult);
  1184. if (rc == 0) {
  1185. regkey_add(keyname, *phkResult, file, line);
  1186. }
  1187. regkey_freename(keyname);
  1188. return rc;
  1189. }
  1190. LONG
  1191. DbgRegOpenKeyEx(
  1192. IN HKEY hKey,
  1193. IN LPCSTR lpSubKey,
  1194. IN DWORD ulOptions,
  1195. IN REGSAM samDesired,
  1196. OUT PHKEY phkResult,
  1197. char * file,
  1198. int line
  1199. )
  1200. {
  1201. char * keyname = regkey_name(hKey, lpSubKey);
  1202. LONG rc = RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, phkResult);
  1203. if (rc == 0) {
  1204. regkey_add(keyname, *phkResult, file, line);
  1205. }
  1206. regkey_freename(keyname);
  1207. return rc;
  1208. }
  1209. LONG
  1210. DbgRegCreateKeyEx(
  1211. IN HKEY hKey,
  1212. IN LPCSTR lpSubKey,
  1213. IN DWORD Reserved,
  1214. IN LPSTR lpClass,
  1215. IN DWORD dwOptions,
  1216. IN REGSAM samDesired,
  1217. IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  1218. OUT PHKEY phkResult,
  1219. OUT LPDWORD lpdwDisposition,
  1220. char * file,
  1221. int line
  1222. )
  1223. {
  1224. char * keyname = regkey_name(hKey, lpSubKey);
  1225. LONG rc = RegCreateKeyEx(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
  1226. if (rc == 0) {
  1227. regkey_add(keyname, *phkResult, file, line);
  1228. }
  1229. regkey_freename(keyname);
  1230. return rc;
  1231. }
  1232. LONG
  1233. DbgRegCloseKey(
  1234. IN HKEY hKey
  1235. )
  1236. {
  1237. LONG rc = RegCloseKey(hKey);
  1238. if (rc == 0) {
  1239. regkey_remove(hKey);
  1240. }
  1241. return rc;
  1242. }
  1243. #endif // INET_DEBUG