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.

1254 lines
28 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: reg.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "windows.h"
  11. #include <stdio.h>
  12. #include <string.h>
  13. //#include <assert.h>
  14. #include "crtem.h"
  15. #include "unicode.h"
  16. //
  17. // FIsWinNT: check OS type on x86. On non-x86, assume WinNT
  18. //
  19. #ifdef _M_IX86
  20. BOOL WINAPI FIsWinNTCheck(void) {
  21. OSVERSIONINFO osVer;
  22. memset(&osVer, 0, sizeof(OSVERSIONINFO));
  23. osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  24. if( GetVersionEx(&osVer) )
  25. return (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
  26. else
  27. return (FALSE);
  28. }
  29. BOOL WINAPI FIsWinNT(void) {
  30. static BOOL fIKnow = FALSE;
  31. static BOOL fIsWinNT = FALSE;
  32. if(fIKnow)
  33. return(fIsWinNT);
  34. fIsWinNT = FIsWinNTCheck();
  35. // even on an error, this is as good as it gets
  36. fIKnow = TRUE;
  37. return(fIsWinNT);
  38. }
  39. #else
  40. BOOL WINAPI FIsWinNT(void) {
  41. return(TRUE);
  42. }
  43. #endif
  44. BOOL
  45. WINAPI
  46. FIsWinNT5Check(
  47. VOID
  48. )
  49. {
  50. OSVERSIONINFO osVer;
  51. memset(&osVer, 0, sizeof(OSVERSIONINFO));
  52. osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  53. if( GetVersionEx(&osVer) )
  54. return ( osVer.dwMajorVersion >= 5 );
  55. else
  56. return (FALSE);
  57. }
  58. BOOL
  59. WINAPI
  60. FIsWinNT5(
  61. VOID
  62. )
  63. {
  64. static BOOL fIKnow = FALSE;
  65. static BOOL fIsWinNT5 = FALSE;
  66. if(!FIsWinNT())
  67. return FALSE;
  68. if(fIKnow)
  69. return(fIsWinNT5);
  70. fIsWinNT5 = FIsWinNT5Check();
  71. // even on an error, this is as good as it gets
  72. fIKnow = TRUE;
  73. return(fIsWinNT5);
  74. }
  75. // make MBCS from Unicode string
  76. //
  77. // Include parameters specifying the length of the input wide character
  78. // string and return number of bytes converted. An input length of -1 indicates
  79. // null terminated.
  80. //
  81. // This extended version was added to handle REG_MULTI_SZ which contains
  82. // multiple null terminated strings.
  83. BOOL WINAPI MkMBStrEx(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, int cchW,
  84. char ** pszMB, int *pcbConverted) {
  85. int cbConverted;
  86. // sfield: don't bring in crt for assert. you get free assert via
  87. // an exception if these are null
  88. // assert(pszMB != NULL);
  89. *pszMB = NULL;
  90. // assert(pcbConverted != NULL);
  91. *pcbConverted = 0;
  92. if(wsz == NULL)
  93. return(TRUE);
  94. // how long is the mb string
  95. cbConverted = WideCharToMultiByte( 0,
  96. 0,
  97. wsz,
  98. cchW,
  99. NULL,
  100. 0,
  101. NULL,
  102. NULL);
  103. if (cbConverted <= 0)
  104. return(FALSE);
  105. // get a buffer long enough
  106. if(pbBuff != NULL && (DWORD) cbConverted <= cbBuff)
  107. *pszMB = (char *) pbBuff;
  108. else
  109. *pszMB = (char *) malloc(cbConverted);
  110. if(*pszMB == NULL) {
  111. SetLastError(ERROR_OUTOFMEMORY);
  112. return(FALSE);
  113. }
  114. // now convert to MB
  115. *pcbConverted = WideCharToMultiByte(0,
  116. 0,
  117. wsz,
  118. cchW,
  119. *pszMB,
  120. cbConverted,
  121. NULL,
  122. NULL);
  123. return(TRUE);
  124. }
  125. // make MBCS from Unicode string
  126. BOOL WINAPI MkMBStr(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, char ** pszMB) {
  127. int cbConverted;
  128. return MkMBStrEx(pbBuff, cbBuff, wsz, -1, pszMB, &cbConverted);
  129. }
  130. void WINAPI FreeMBStr(PBYTE pbBuff, char * szMB) {
  131. if((szMB != NULL) && (pbBuff != (PBYTE)szMB))
  132. free(szMB);
  133. }
  134. // #endif // _M_IX86
  135. // make Unicode string from MBCS
  136. LPWSTR WINAPI MkWStr(char * szMB) {
  137. LPWSTR wsz = NULL;
  138. int cbConverted;
  139. if(szMB == NULL)
  140. goto Ret;
  141. // how long is the unicode string
  142. if (0 >= (cbConverted = MultiByteToWideChar( 0,
  143. 0,
  144. szMB,
  145. -1,
  146. NULL,
  147. 0)))
  148. goto Ret;
  149. // get a buffer long enough
  150. wsz = (LPWSTR) malloc(cbConverted * sizeof(WCHAR));
  151. if(wsz == NULL) {
  152. SetLastError(ERROR_OUTOFMEMORY);
  153. goto Ret;
  154. }
  155. // now convert to MB
  156. MultiByteToWideChar(0,
  157. 0,
  158. szMB,
  159. -1,
  160. wsz,
  161. cbConverted);
  162. Ret:
  163. return(wsz);
  164. }
  165. void WINAPI FreeWStr(LPWSTR wsz) {
  166. if(wsz != NULL)
  167. free(wsz);
  168. }
  169. #ifdef _M_IX86
  170. LONG WINAPI RegCreateKeyEx9x (
  171. HKEY hKey,
  172. LPCWSTR lpSubKey,
  173. DWORD Reserved,
  174. LPWSTR lpClass,
  175. DWORD dwOptions,
  176. REGSAM samDesired,
  177. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  178. PHKEY phkResult,
  179. LPDWORD lpdwDisposition
  180. ) {
  181. BYTE rgb1[_MAX_PATH];
  182. BYTE rgb2[_MAX_PATH];
  183. char * szSubKey = NULL;
  184. char * szClass = NULL;
  185. LONG err;
  186. err = FALSE;
  187. if(
  188. MkMBStr(rgb1, _MAX_PATH, lpSubKey, &szSubKey) &&
  189. MkMBStr(rgb2, _MAX_PATH, lpClass, &szClass) )
  190. err = RegCreateKeyExA (
  191. hKey,
  192. szSubKey,
  193. Reserved,
  194. szClass,
  195. dwOptions,
  196. samDesired,
  197. lpSecurityAttributes,
  198. phkResult,
  199. lpdwDisposition
  200. );
  201. FreeMBStr(rgb1, szSubKey);
  202. FreeMBStr(rgb2, szClass);
  203. return(err);
  204. }
  205. LONG WINAPI RegCreateKeyExU (
  206. HKEY hKey,
  207. LPCWSTR lpSubKey,
  208. DWORD Reserved,
  209. LPWSTR lpClass,
  210. DWORD dwOptions,
  211. REGSAM samDesired,
  212. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  213. PHKEY phkResult,
  214. LPDWORD lpdwDisposition
  215. ) {
  216. if(FIsWinNT())
  217. return( RegCreateKeyExW (
  218. hKey,
  219. lpSubKey,
  220. Reserved,
  221. lpClass,
  222. dwOptions,
  223. samDesired,
  224. lpSecurityAttributes,
  225. phkResult,
  226. lpdwDisposition
  227. ));
  228. else
  229. return( RegCreateKeyEx9x (
  230. hKey,
  231. lpSubKey,
  232. Reserved,
  233. lpClass,
  234. dwOptions,
  235. samDesired,
  236. lpSecurityAttributes,
  237. phkResult,
  238. lpdwDisposition
  239. ));
  240. }
  241. LONG WINAPI RegDeleteKey9x (
  242. HKEY hKey,
  243. LPCWSTR lpSubKey
  244. ) {
  245. BYTE rgb1[_MAX_PATH];
  246. char * szSubKey = NULL;
  247. LONG err;
  248. err = FALSE;
  249. if(MkMBStr(rgb1, _MAX_PATH, lpSubKey, &szSubKey))
  250. err = RegDeleteKeyA (
  251. hKey,
  252. szSubKey
  253. );
  254. FreeMBStr(rgb1, szSubKey);
  255. return(err);
  256. }
  257. LONG WINAPI RegDeleteKeyU (
  258. HKEY hKey,
  259. LPCWSTR lpSubKey
  260. ) {
  261. if(FIsWinNT())
  262. return( RegDeleteKeyW (
  263. hKey,
  264. lpSubKey
  265. ));
  266. else
  267. return( RegDeleteKey9x (
  268. hKey,
  269. lpSubKey
  270. ));
  271. }
  272. LONG WINAPI RegEnumKeyEx9x (
  273. HKEY hKey,
  274. DWORD dwIndex,
  275. LPWSTR lpName,
  276. LPDWORD lpcbName,
  277. LPDWORD lpReserved,
  278. LPWSTR lpClass,
  279. LPDWORD lpcbClass,
  280. PFILETIME lpftLastWriteTime
  281. ) {
  282. char rgch[_MAX_PATH];
  283. char * szKeyName;
  284. DWORD cbKeyName;
  285. char rgch1[_MAX_PATH];
  286. char * szClassName;
  287. DWORD cbClassName;
  288. int cchW;
  289. LONG err;
  290. szKeyName = rgch;
  291. cbKeyName = sizeof(rgch);
  292. szClassName = rgch1;
  293. cbClassName = sizeof(rgch1);
  294. err = RegEnumKeyExA (
  295. hKey,
  296. dwIndex,
  297. szKeyName,
  298. &cbKeyName,
  299. lpReserved,
  300. szClassName,
  301. &cbClassName,
  302. lpftLastWriteTime
  303. );
  304. if((err != ERROR_SUCCESS) && (err != ERROR_INSUFFICIENT_BUFFER))
  305. return err;
  306. err = ERROR_SUCCESS;
  307. cbKeyName++; // count the NULL terminator
  308. cbClassName++; // count the NULL terminator
  309. if ((sizeof(rgch) < cbKeyName) || (sizeof(rgch1) < cbClassName)) {
  310. szKeyName = (char *) malloc(cbKeyName);
  311. if(!szKeyName)
  312. return ERROR_OUTOFMEMORY;
  313. szClassName = (char *) malloc(cbClassName);
  314. if(!szClassName) {
  315. free(szKeyName);
  316. return ERROR_OUTOFMEMORY;
  317. }
  318. err = RegEnumKeyExA (
  319. hKey,
  320. dwIndex,
  321. szKeyName,
  322. &cbKeyName,
  323. lpReserved,
  324. szClassName,
  325. &cbClassName,
  326. lpftLastWriteTime
  327. );
  328. cbKeyName++; // count the NULL terminator
  329. cbClassName++; // count the NULL terminator
  330. }
  331. if(err == ERROR_SUCCESS) {
  332. cchW = MultiByteToWideChar(
  333. 0, // codepage
  334. 0, // dwFlags
  335. szKeyName,
  336. cbKeyName,
  337. lpName,
  338. *lpcbName);
  339. if(cchW == 0)
  340. err = GetLastError();
  341. else
  342. *lpcbName = cchW - 1; // does not include NULL
  343. }
  344. if(szKeyName != rgch)
  345. free(szKeyName);
  346. if(err == ERROR_SUCCESS) {
  347. //
  348. // it's legal for lpClass/lpcbClass to be NULL, so only copy if they are not NOT
  349. //
  350. if(lpClass != NULL) {
  351. // note: RegEnumKeyEx specifies that lpcbClass can only be NULL
  352. // if lpClass is NULL, so the correct behavior is to fault if
  353. // lpClass is non-null and lpcbClass is NULL; this behavior is
  354. // does happen here.
  355. //
  356. cchW = MultiByteToWideChar(
  357. 0, // codepage
  358. 0, // dwFlags
  359. szClassName,
  360. cbClassName,
  361. lpClass,
  362. *lpcbClass);
  363. if(cchW == 0)
  364. err = GetLastError();
  365. }
  366. if(lpcbClass != NULL)
  367. *lpcbClass = cbClassName - 1; // does not include NULL
  368. }
  369. if(szClassName != rgch1)
  370. free(szClassName);
  371. return err;
  372. }
  373. LONG WINAPI RegEnumKeyExU (
  374. HKEY hKey,
  375. DWORD dwIndex,
  376. LPWSTR lpName,
  377. LPDWORD lpcbName,
  378. LPDWORD lpReserved,
  379. LPWSTR lpClass,
  380. LPDWORD lpcbClass,
  381. PFILETIME lpftLastWriteTime
  382. ) {
  383. if(FIsWinNT())
  384. return( RegEnumKeyExW (
  385. hKey,
  386. dwIndex,
  387. lpName,
  388. lpcbName,
  389. lpReserved,
  390. lpClass,
  391. lpcbClass,
  392. lpftLastWriteTime
  393. ));
  394. else
  395. return( RegEnumKeyEx9x (
  396. hKey,
  397. dwIndex,
  398. lpName,
  399. lpcbName,
  400. lpReserved,
  401. lpClass,
  402. lpcbClass,
  403. lpftLastWriteTime
  404. ));
  405. }
  406. static LONG WINAPI ConvertRegValue (
  407. DWORD dwType,
  408. LPBYTE pbInData,
  409. DWORD cbInData,
  410. LPBYTE pbOutData,
  411. LPDWORD pcbOutData
  412. ) {
  413. LONG err = ERROR_SUCCESS;
  414. DWORD cbOrigOutData;
  415. if (NULL == pcbOutData)
  416. return ERROR_SUCCESS;
  417. cbOrigOutData = *pcbOutData;
  418. if (0 == cbInData)
  419. *pcbOutData = 0;
  420. else if (REG_SZ == dwType || REG_EXPAND_SZ == dwType ||
  421. REG_MULTI_SZ == dwType) {
  422. int cchW;
  423. // First get length needed for wide characters
  424. cchW = MultiByteToWideChar(
  425. 0, // codepage
  426. 0, // dwFlags
  427. (LPCSTR) pbInData,
  428. cbInData,
  429. NULL, // lpWideCharStr
  430. 0); // cchWideChar
  431. *pcbOutData = cchW * sizeof(WCHAR);
  432. if(cchW == 0)
  433. err = GetLastError();
  434. else if (pbOutData) {
  435. if (cbOrigOutData < *pcbOutData)
  436. err = ERROR_MORE_DATA;
  437. else
  438. // Convert to Unicode data
  439. MultiByteToWideChar(
  440. 0, // codepage
  441. 0, // dwFlags
  442. (LPCSTR) pbInData,
  443. cbInData,
  444. (LPWSTR) pbOutData,
  445. cchW);
  446. }
  447. } else {
  448. // Copy to output
  449. *pcbOutData = cbInData;
  450. if (pbOutData) {
  451. if (cbOrigOutData < cbInData)
  452. err = ERROR_MORE_DATA;
  453. else
  454. memcpy(pbOutData, pbInData, cbInData);
  455. }
  456. }
  457. return err;
  458. }
  459. #define MAX_REG_VALUE_DATA 256
  460. LONG WINAPI RegEnumValue9x (
  461. HKEY hKey,
  462. DWORD dwIndex,
  463. LPWSTR lpValueName,
  464. LPDWORD lpcchValueName,
  465. LPDWORD lpReserved,
  466. LPDWORD lpType,
  467. LPBYTE lpData,
  468. LPDWORD lpcbData
  469. ) {
  470. char rgch[_MAX_PATH];
  471. char * szValueName;
  472. DWORD cbValueName;
  473. DWORD dwType;
  474. LONG err;
  475. BYTE rgbData[MAX_REG_VALUE_DATA];
  476. BYTE *pbData;
  477. DWORD cbData;
  478. szValueName = rgch;
  479. cbValueName = sizeof(rgch);
  480. pbData = rgbData;
  481. cbData = sizeof(rgbData);
  482. err = RegEnumValueA (
  483. hKey,
  484. dwIndex,
  485. szValueName,
  486. &cbValueName,
  487. lpReserved,
  488. &dwType,
  489. pbData,
  490. &cbData
  491. );
  492. if (lpType)
  493. *lpType = dwType;
  494. if((err != ERROR_SUCCESS) && (err != ERROR_INSUFFICIENT_BUFFER) &&
  495. (err != ERROR_MORE_DATA))
  496. goto ErrorReturn;
  497. err = ERROR_SUCCESS;
  498. cbValueName++; // count the NULL terminator
  499. if (sizeof(rgch) < cbValueName || sizeof(rgbData) < cbData) {
  500. if (sizeof(rgch) < cbValueName) {
  501. szValueName = (char *) malloc( cbValueName);
  502. if(!szValueName) {
  503. err = ERROR_OUTOFMEMORY;
  504. goto ErrorReturn;
  505. }
  506. }
  507. if (sizeof(rgbData) < cbData) {
  508. pbData = (BYTE *) malloc(cbData);
  509. if(!pbData) {
  510. err = ERROR_OUTOFMEMORY;
  511. goto ErrorReturn;
  512. }
  513. }
  514. err = RegEnumValueA (
  515. hKey,
  516. dwIndex,
  517. szValueName,
  518. &cbValueName,
  519. lpReserved,
  520. lpType,
  521. pbData,
  522. &cbData
  523. );
  524. cbValueName++; // count the NULL terminator
  525. }
  526. if (err == ERROR_SUCCESS) {
  527. int cchW;
  528. cchW = MultiByteToWideChar(
  529. 0, // codepage
  530. 0, // dwFlags
  531. szValueName,
  532. cbValueName,
  533. lpValueName,
  534. lpValueName ? *lpcchValueName : 0);
  535. if(cchW == 0)
  536. err = GetLastError();
  537. else
  538. *lpcchValueName = cchW - 1; // does not include NULL
  539. } else
  540. *lpcchValueName = 0;
  541. if (err == ERROR_SUCCESS)
  542. err = ConvertRegValue (
  543. dwType,
  544. pbData,
  545. cbData,
  546. lpData,
  547. lpcbData);
  548. else if (lpcbData)
  549. *lpcbData = 0;
  550. CommonReturn:
  551. if(szValueName != rgch && szValueName)
  552. free(szValueName);
  553. if(pbData != rgbData && pbData)
  554. free(pbData);
  555. return err;
  556. ErrorReturn:
  557. *lpcchValueName = 0;
  558. if (lpcbData)
  559. *lpcbData = 0;
  560. goto CommonReturn;
  561. }
  562. LONG WINAPI RegEnumValueU (
  563. HKEY hKey,
  564. DWORD dwIndex,
  565. LPWSTR lpValueName,
  566. LPDWORD lpcchValueName,
  567. LPDWORD lpReserved,
  568. LPDWORD lpType,
  569. LPBYTE lpData,
  570. LPDWORD lpcbData
  571. ) {
  572. if(FIsWinNT())
  573. return( RegEnumValueW (
  574. hKey,
  575. dwIndex,
  576. lpValueName,
  577. lpcchValueName,
  578. lpReserved,
  579. lpType,
  580. lpData,
  581. lpcbData
  582. ));
  583. else
  584. return( RegEnumValue9x (
  585. hKey,
  586. dwIndex,
  587. lpValueName,
  588. lpcchValueName,
  589. lpReserved,
  590. lpType,
  591. lpData,
  592. lpcbData
  593. ));
  594. }
  595. LONG RegDeleteValue9x (
  596. HKEY hKey,
  597. LPCWSTR lpValueName
  598. ) {
  599. BYTE rgb[_MAX_PATH];
  600. char * szValueName;
  601. LONG err;
  602. err = FALSE;
  603. if(MkMBStr(rgb, _MAX_PATH, lpValueName, &szValueName))
  604. err = RegDeleteValueA (
  605. hKey,
  606. szValueName
  607. );
  608. FreeMBStr(rgb, szValueName);
  609. return(err);
  610. }
  611. LONG RegDeleteValueU (
  612. HKEY hKey,
  613. LPCWSTR lpValueName
  614. ) {
  615. if(FIsWinNT())
  616. return(RegDeleteValueW (
  617. hKey,
  618. lpValueName
  619. ));
  620. else
  621. return(RegDeleteValue9x (
  622. hKey,
  623. lpValueName
  624. ));
  625. }
  626. LONG RegQueryValueEx9x(
  627. HKEY hKey,
  628. LPCWSTR lpValueName,
  629. LPDWORD lpReserved,
  630. LPDWORD lpType,
  631. LPBYTE lpData,
  632. LPDWORD lpcbData
  633. ) {
  634. BYTE rgb[_MAX_PATH];
  635. char * szValueName = NULL;
  636. LONG err;
  637. DWORD dwType;
  638. BYTE rgbData[MAX_REG_VALUE_DATA];
  639. BYTE *pbData;
  640. DWORD cbData;
  641. pbData = rgbData;
  642. cbData = sizeof(rgbData);
  643. if(MkMBStr(rgb, _MAX_PATH, lpValueName, &szValueName))
  644. err = RegQueryValueExA (
  645. hKey,
  646. szValueName,
  647. lpReserved,
  648. &dwType,
  649. pbData,
  650. &cbData
  651. );
  652. else {
  653. err = ERROR_OUTOFMEMORY;
  654. goto ErrorReturn;
  655. }
  656. if (lpType)
  657. *lpType = dwType;
  658. if((err != ERROR_SUCCESS) && (err != ERROR_INSUFFICIENT_BUFFER) &&
  659. (err != ERROR_MORE_DATA))
  660. goto ErrorReturn;
  661. err = ERROR_SUCCESS;
  662. if (sizeof(rgbData) < cbData) {
  663. pbData = (BYTE *) malloc(cbData);
  664. if(!pbData) {
  665. err = ERROR_OUTOFMEMORY;
  666. goto ErrorReturn;
  667. }
  668. err = RegQueryValueExA (
  669. hKey,
  670. szValueName,
  671. lpReserved,
  672. &dwType,
  673. pbData,
  674. &cbData
  675. );
  676. }
  677. if (err == ERROR_SUCCESS)
  678. err = ConvertRegValue (
  679. dwType,
  680. pbData,
  681. cbData,
  682. lpData,
  683. lpcbData);
  684. else if (lpcbData)
  685. *lpcbData = 0;
  686. CommonReturn:
  687. FreeMBStr(rgb, szValueName);
  688. if(pbData != rgbData && pbData)
  689. free(pbData);
  690. return err;
  691. ErrorReturn:
  692. if (lpcbData)
  693. *lpcbData = 0;
  694. goto CommonReturn;
  695. }
  696. LONG RegQueryValueExU(
  697. HKEY hKey,
  698. LPCWSTR lpValueName,
  699. LPDWORD lpReserved,
  700. LPDWORD lpType,
  701. LPBYTE lpData,
  702. LPDWORD lpcbData
  703. ) {
  704. if (lpReserved != NULL) {
  705. return (ERROR_INVALID_PARAMETER);
  706. }
  707. if(FIsWinNT())
  708. return(RegQueryValueExW (
  709. hKey,
  710. lpValueName,
  711. lpReserved,
  712. lpType,
  713. lpData,
  714. lpcbData
  715. ));
  716. else
  717. return(RegQueryValueEx9x (
  718. hKey,
  719. lpValueName,
  720. lpReserved,
  721. lpType,
  722. lpData,
  723. lpcbData
  724. ));
  725. }
  726. LONG WINAPI RegSetValueEx9x (
  727. HKEY hKey,
  728. LPCWSTR lpValueName,
  729. DWORD Reserved,
  730. DWORD dwType,
  731. CONST BYTE* lpData,
  732. DWORD cbData
  733. ) {
  734. BYTE rgb1[_MAX_PATH];
  735. char * szValueName;
  736. LONG err;
  737. err = ERROR_OUTOFMEMORY;
  738. if(MkMBStr(rgb1, _MAX_PATH, lpValueName, &szValueName))
  739. {
  740. // convert the data to ascii if necessary
  741. if (0 != cbData / sizeof(WCHAR) &&
  742. (REG_SZ == dwType || REG_EXPAND_SZ == dwType ||
  743. REG_MULTI_SZ == dwType))
  744. {
  745. char * szData;
  746. int cbConverted;
  747. if(MkMBStrEx(NULL, 0, (LPWSTR)lpData, cbData/sizeof(WCHAR),
  748. &szData, &cbConverted))
  749. {
  750. err = RegSetValueExA (
  751. hKey,
  752. szValueName,
  753. Reserved,
  754. dwType,
  755. (BYTE*)szData,
  756. cbConverted
  757. );
  758. FreeMBStr(NULL, szData);
  759. }
  760. }
  761. else
  762. {
  763. err = RegSetValueExA (
  764. hKey,
  765. szValueName,
  766. Reserved,
  767. dwType,
  768. lpData,
  769. cbData
  770. );
  771. }
  772. FreeMBStr(rgb1, szValueName);
  773. }
  774. return(err);
  775. }
  776. LONG WINAPI RegSetValueExU (
  777. HKEY hKey,
  778. LPCWSTR lpValueName,
  779. DWORD Reserved,
  780. DWORD dwType,
  781. CONST BYTE* lpData,
  782. DWORD cbData
  783. ) {
  784. if(FIsWinNT())
  785. return(RegSetValueExW (
  786. hKey,
  787. lpValueName,
  788. Reserved,
  789. dwType,
  790. lpData,
  791. cbData
  792. ));
  793. else
  794. return(RegSetValueEx9x (
  795. hKey,
  796. lpValueName,
  797. Reserved,
  798. dwType,
  799. lpData,
  800. cbData
  801. ));
  802. }
  803. LONG WINAPI RegQueryInfoKey9x (
  804. HKEY hKey,
  805. LPWSTR lpClass,
  806. LPDWORD lpcbClass,
  807. LPDWORD lpReserved,
  808. LPDWORD lpcSubKeys,
  809. LPDWORD lpcbMaxSubKeyLen,
  810. LPDWORD lpcbMaxClassLen,
  811. LPDWORD lpcValues,
  812. LPDWORD lpcbMaxValueNameLen,
  813. LPDWORD lpcbMaxValueLen,
  814. LPDWORD lpcbSecurityDescriptor,
  815. PFILETIME lpftLastWriteTime
  816. ) {
  817. BYTE rgb[_MAX_PATH];
  818. char * szClass;
  819. LONG err;
  820. err = FALSE;
  821. if(MkMBStr(rgb, _MAX_PATH, lpClass, &szClass))
  822. err = RegQueryInfoKeyA (
  823. hKey,
  824. szClass,
  825. lpcbClass,
  826. lpReserved,
  827. lpcSubKeys,
  828. lpcbMaxSubKeyLen,
  829. lpcbMaxClassLen,
  830. lpcValues,
  831. lpcbMaxValueNameLen,
  832. lpcbMaxValueLen,
  833. lpcbSecurityDescriptor,
  834. lpftLastWriteTime
  835. );
  836. if (lpcbMaxValueLen)
  837. // Need to double for converting to unicode characters.
  838. *lpcbMaxValueLen = *lpcbMaxValueLen * 2;
  839. FreeMBStr(rgb, szClass);
  840. return(err);
  841. }
  842. LONG WINAPI RegQueryInfoKeyU (
  843. HKEY hKey,
  844. LPWSTR lpClass,
  845. LPDWORD lpcbClass,
  846. LPDWORD lpReserved,
  847. LPDWORD lpcSubKeys,
  848. LPDWORD lpcbMaxSubKeyLen,
  849. LPDWORD lpcbMaxClassLen,
  850. LPDWORD lpcValues,
  851. LPDWORD lpcbMaxValueNameLen,
  852. LPDWORD lpcbMaxValueLen,
  853. LPDWORD lpcbSecurityDescriptor,
  854. PFILETIME lpftLastWriteTime
  855. ) {
  856. if(FIsWinNT())
  857. return( RegQueryInfoKeyW (
  858. hKey,
  859. lpClass,
  860. lpcbClass,
  861. lpReserved,
  862. lpcSubKeys,
  863. lpcbMaxSubKeyLen,
  864. lpcbMaxClassLen,
  865. lpcValues,
  866. lpcbMaxValueNameLen,
  867. lpcbMaxValueLen,
  868. lpcbSecurityDescriptor,
  869. lpftLastWriteTime
  870. ));
  871. else
  872. return( RegQueryInfoKey9x (
  873. hKey,
  874. lpClass,
  875. lpcbClass,
  876. lpReserved,
  877. lpcSubKeys,
  878. lpcbMaxSubKeyLen,
  879. lpcbMaxClassLen,
  880. lpcValues,
  881. lpcbMaxValueNameLen,
  882. lpcbMaxValueLen,
  883. lpcbSecurityDescriptor,
  884. lpftLastWriteTime
  885. ));
  886. }
  887. LONG WINAPI RegOpenKeyEx9x(
  888. HKEY hKey, // handle of open key
  889. LPCWSTR lpSubKey, // address of name of subkey to open
  890. DWORD ulOptions, // reserved
  891. REGSAM samDesired, // security access mask
  892. PHKEY phkResult // address of handle of open key
  893. ) {
  894. BYTE rgb1[_MAX_PATH];
  895. char * szSubKey = NULL;
  896. LONG err;
  897. err = FALSE;
  898. if(MkMBStr(rgb1, _MAX_PATH, lpSubKey, &szSubKey) )
  899. err = RegOpenKeyExA(
  900. hKey,
  901. szSubKey,
  902. ulOptions,
  903. samDesired,
  904. phkResult);
  905. FreeMBStr(rgb1, szSubKey);
  906. return(err);
  907. }
  908. LONG WINAPI RegOpenKeyExU(
  909. HKEY hKey, // handle of open key
  910. LPCWSTR lpSubKey, // address of name of subkey to open
  911. DWORD ulOptions, // reserved
  912. REGSAM samDesired, // security access mask
  913. PHKEY phkResult // address of handle of open key
  914. ) {
  915. if(FIsWinNT())
  916. return( RegOpenKeyExW(
  917. hKey,
  918. lpSubKey,
  919. ulOptions,
  920. samDesired,
  921. phkResult
  922. ));
  923. else
  924. return( RegOpenKeyEx9x(
  925. hKey,
  926. lpSubKey,
  927. ulOptions,
  928. samDesired,
  929. phkResult
  930. ));
  931. }
  932. LONG WINAPI RegConnectRegistry9x (
  933. LPWSTR lpMachineName,
  934. HKEY hKey,
  935. PHKEY phkResult
  936. ) {
  937. BYTE rgb1[_MAX_PATH];
  938. char * szMachineName = NULL;
  939. LONG err;
  940. err = FALSE;
  941. if(MkMBStr(rgb1, _MAX_PATH, lpMachineName, &szMachineName) )
  942. err = RegConnectRegistryA(
  943. szMachineName,
  944. hKey,
  945. phkResult);
  946. FreeMBStr(rgb1, szMachineName);
  947. return(err);
  948. }
  949. LONG WINAPI RegConnectRegistryU (
  950. LPWSTR lpMachineName,
  951. HKEY hKey,
  952. PHKEY phkResult
  953. ) {
  954. if(FIsWinNT())
  955. return( RegConnectRegistryW(
  956. lpMachineName,
  957. hKey,
  958. phkResult
  959. ));
  960. else
  961. return( RegConnectRegistry9x(
  962. lpMachineName,
  963. hKey,
  964. phkResult
  965. ));
  966. }
  967. #endif // _M_IX86
  968. LONG WINAPI RegCreateHKCUKeyExU (
  969. HKEY hKey,
  970. LPCWSTR lpSubKey,
  971. DWORD Reserved,
  972. LPWSTR lpClass,
  973. DWORD dwOptions,
  974. REGSAM samDesired,
  975. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  976. PHKEY phkResult,
  977. LPDWORD lpdwDisposition
  978. ) {
  979. if ((hKey != HKEY_CURRENT_USER) || !(FIsWinNT()))
  980. {
  981. return(RegCreateKeyExU(hKey, lpSubKey, Reserved, lpClass, dwOptions,
  982. samDesired, lpSecurityAttributes, phkResult,
  983. lpdwDisposition));
  984. }
  985. HKEY hCurUser;
  986. LONG err;
  987. if ((err = RegOpenHKCU(&hCurUser)) != ERROR_SUCCESS)
  988. {
  989. return(err);
  990. }
  991. err = RegCreateKeyExW(hCurUser, lpSubKey, Reserved, lpClass, dwOptions,
  992. samDesired, lpSecurityAttributes, phkResult,
  993. lpdwDisposition);
  994. RegCloseHKCU(hCurUser);
  995. return(err);
  996. }
  997. LONG WINAPI RegCreateHKCUKeyExA (
  998. HKEY hKey,
  999. LPCSTR lpSubKey,
  1000. DWORD Reserved,
  1001. LPSTR lpClass,
  1002. DWORD dwOptions,
  1003. REGSAM samDesired,
  1004. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  1005. PHKEY phkResult,
  1006. LPDWORD lpdwDisposition
  1007. )
  1008. {
  1009. if ((hKey != HKEY_CURRENT_USER) || !(FIsWinNT()))
  1010. {
  1011. return(RegCreateKeyExA(hKey, lpSubKey, Reserved, lpClass, dwOptions,
  1012. samDesired, lpSecurityAttributes, phkResult,
  1013. lpdwDisposition));
  1014. }
  1015. HKEY hCurUser;
  1016. LONG err;
  1017. if ((err = RegOpenHKCU(&hCurUser)) != ERROR_SUCCESS)
  1018. {
  1019. return(err);
  1020. }
  1021. err = RegCreateKeyExA(hCurUser, lpSubKey, Reserved, lpClass, dwOptions,
  1022. samDesired, lpSecurityAttributes, phkResult,
  1023. lpdwDisposition);
  1024. RegCloseHKCU(hCurUser);
  1025. return(err);
  1026. }
  1027. LONG WINAPI RegOpenHKCUKeyExU(
  1028. HKEY hKey, // handle of open key
  1029. LPCWSTR lpSubKey, // address of name of subkey to open
  1030. DWORD ulOptions, // reserved
  1031. REGSAM samDesired, // security access mask
  1032. PHKEY phkResult // address of handle of open key
  1033. ) {
  1034. if ((hKey != HKEY_CURRENT_USER) || !(FIsWinNT()))
  1035. {
  1036. return(RegOpenKeyExU(hKey, lpSubKey, ulOptions,
  1037. samDesired, phkResult));
  1038. }
  1039. HKEY hCurUser;
  1040. LONG err;
  1041. if ((err = RegOpenHKCU(&hCurUser)) != ERROR_SUCCESS)
  1042. {
  1043. return(err);
  1044. }
  1045. err = RegOpenKeyExW(hCurUser, lpSubKey, ulOptions, samDesired, phkResult);
  1046. RegCloseHKCU(hCurUser);
  1047. return(err);
  1048. }
  1049. LONG WINAPI RegOpenHKCUKeyExA(
  1050. HKEY hKey, // handle of open key
  1051. LPCSTR lpSubKey, // address of name of subkey to open
  1052. DWORD ulOptions, // reserved
  1053. REGSAM samDesired, // security access mask
  1054. PHKEY phkResult // address of handle of open key
  1055. ) {
  1056. if ((hKey != HKEY_CURRENT_USER) || !(FIsWinNT()))
  1057. {
  1058. return(RegOpenKeyExA(hKey, lpSubKey, ulOptions,
  1059. samDesired, phkResult));
  1060. }
  1061. HKEY hCurUser;
  1062. LONG err;
  1063. if ((err = RegOpenHKCU(&hCurUser)) != ERROR_SUCCESS)
  1064. {
  1065. return(err);
  1066. }
  1067. err = RegOpenKeyExA(hCurUser, lpSubKey, ulOptions, samDesired, phkResult);
  1068. RegCloseHKCU(hCurUser);
  1069. return(err);
  1070. }