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.

788 lines
25 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. regfind.c
  5. Abstract:
  6. Search registry and reset the specific value data.
  7. Author:
  8. Geoffrey Guo (geoffguo) 08-Oct-2001 Created
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "StdAfx.h"
  13. #include "clmt.h"
  14. LONG QueryValue(HKEY, LPTSTR, LPTSTR, PREG_STRING_REPLACE, PVALLIST*, LPTSTR, DWORD, BOOL);
  15. LONG QueryEnumerateKey(HKEY, LPTSTR,LPTSTR,PREG_STRING_REPLACE, LPTSTR, LPTSTR, DWORD, BOOL);
  16. LONG SetRegValueChange (HKEY, LPTSTR, PVALLIST*, LPTSTR);
  17. //-----------------------------------------------------------------------//
  18. //
  19. // RegistryAnalyze()
  20. //
  21. // hRootKey : Regsitry handle
  22. // lpRegStr : Input parameter structure
  23. // lpRegExclusionList: MultiSZ string tells a list of Keypath RegRepace should skip
  24. //
  25. //-----------------------------------------------------------------------//
  26. HRESULT RegistryAnalyze(
  27. HKEY hRootKey,
  28. LPTSTR szUserName,
  29. LPTSTR szUserSid,
  30. PREG_STRING_REPLACE lpRegStr,
  31. LPTSTR lpRegExclusionList,
  32. DWORD TreatAsType,
  33. LPTSTR lpRootKeyPath,
  34. BOOL bStrChk)
  35. {
  36. TCHAR szRoot[MAX_PATH];
  37. LPTSTR lpRoot = TEXT("\0");
  38. HRESULT hResult = S_FALSE;
  39. LONG lResult;
  40. if (szUserName)
  41. {
  42. DPF(REGmsg, L"Enter RegistryAnalyze: szUserName=%s hKey=%d", szUserName, hRootKey);
  43. }
  44. else if (hRootKey == HKEY_CLASSES_ROOT)
  45. {
  46. DPF(REGmsg, L"Enter RegistryAnalyze: HKEY_CLASSES_ROOT");
  47. }
  48. else if (hRootKey == HKEY_LOCAL_MACHINE)
  49. {
  50. DPF(REGmsg, L"Enter RegistryAnalyze: HKEY_LOCAL_MACHINE");
  51. }
  52. else
  53. {
  54. DPF(REGmsg, L"Enter RegistryAnalyze: hKey=%d", hRootKey);
  55. }
  56. if (lpRegExclusionList)
  57. {
  58. hResult = ReplaceCurrentControlSet(lpRegExclusionList);
  59. if (FAILED(hResult))
  60. {
  61. return hResult;
  62. }
  63. }
  64. if (lpRegStr->lpSearchString && lpRegStr->lpReplaceString)
  65. {
  66. UpdateProgress();
  67. lpRegStr->cchMaxStrLen = GetMaxStrLen (lpRegStr);
  68. if (lpRootKeyPath)
  69. {
  70. lpRoot = lpRootKeyPath;
  71. }
  72. else
  73. {
  74. if (HKey2Str(hRootKey,szRoot,MAX_PATH))
  75. {
  76. lpRoot = szRoot;
  77. }
  78. }
  79. lResult = QueryEnumerateKey(hRootKey, szUserName, szUserSid, lpRegStr,
  80. lpRoot,lpRegExclusionList,TreatAsType, bStrChk);
  81. hResult = HRESULT_FROM_WIN32(lResult);
  82. }
  83. DPF(REGmsg, L"Exit RegistryAnalyze:");
  84. return hResult;
  85. }
  86. //-----------------------------------------------------------------------//
  87. //
  88. // ReadValue()
  89. //
  90. // hKey: Registry key
  91. // szValueName: Value name
  92. // lpType: Value type
  93. // lpBuf: Vaule data buffer
  94. // lpSize: Value data size
  95. // lpFullKey: Full sub-key path
  96. //-----------------------------------------------------------------------//
  97. LONG ReadValue (
  98. HKEY hKey,
  99. LPTSTR szValueName,
  100. LPDWORD lpType,
  101. LPBYTE *lpBuf,
  102. LPDWORD lpSize,
  103. LPTSTR lpFullKey)
  104. {
  105. LONG lResult;
  106. //
  107. // First find out how much memory to allocate.
  108. //
  109. lResult = My_QueryValueEx(hKey,
  110. szValueName,
  111. 0,
  112. lpType,
  113. NULL,
  114. lpSize);
  115. if (lResult != ERROR_SUCCESS)
  116. {
  117. DPF (REGerr, L"ReadValue1: RegQueryValueEx failed. lResult=%d", lResult);
  118. return lResult;
  119. }
  120. //There is a bug in W2K HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\VideoUpgradeDisplaySettings".
  121. //When the value name = Driver1, *lpSize will be 3. To cover Odd number of size, incease one byte for data buffer.
  122. *lpBuf = (LPBYTE) calloc(*lpSize+sizeof(TCHAR)+1, sizeof(BYTE));
  123. if (!(*lpBuf)) {
  124. DPF (REGerr, L"ReadValue: No enough memory");
  125. return ERROR_NOT_ENOUGH_MEMORY;
  126. }
  127. //
  128. // Now get the data
  129. //
  130. lResult = My_QueryValueEx(hKey,
  131. szValueName,
  132. 0,
  133. lpType,
  134. *lpBuf,
  135. lpSize);
  136. if (lResult != ERROR_SUCCESS)
  137. {
  138. if (*lpBuf)
  139. free(*lpBuf);
  140. DPF (REGerr, L"ReadValue2: RegQueryValueEx fail. lResult=%d", lResult);
  141. return lResult;
  142. }
  143. return ERROR_SUCCESS;
  144. }
  145. //-----------------------------------------------------------------------//
  146. //
  147. // SetRegValueChange()
  148. //
  149. // Set registry value based on the value list
  150. //
  151. // hKey: Registry key
  152. // lpValList: Updated value list
  153. // lpFullKey: Full sub-key path
  154. //-----------------------------------------------------------------------//
  155. LONG SetRegValueChange (
  156. HKEY hKey,
  157. LPTSTR szUserName,
  158. PVALLIST *lpValList,
  159. LPTSTR lpFullKey)
  160. {
  161. LONG lResult = ERROR_SUCCESS;
  162. HRESULT hResult;
  163. DWORD dwType;
  164. DWORD dwOldValueSize = 1, dwNewValueSize;
  165. LPBYTE lpBuf;
  166. LPTSTR lpOldValueData, lpNewValueData, lpNewValueName;
  167. PVALLIST lpVal;
  168. if (*lpValList)
  169. {
  170. lpVal = *lpValList;
  171. while (lpVal)
  172. {
  173. UpdateProgress();
  174. //Read old value data
  175. lResult = ReadValue(hKey,
  176. lpVal->lpPre_valuename,
  177. &dwType,
  178. &lpBuf,
  179. &dwOldValueSize,
  180. lpFullKey);
  181. if (lResult != ERROR_SUCCESS)
  182. {
  183. DPF (REGerr, L"SetRegValueChange: ReadValue failed");
  184. goto NextData;
  185. }
  186. /* //Set new value name or value data
  187. lResult = RegSetValueEx (hKey,
  188. lpVal->ve.ve_valuename,
  189. 0,
  190. lpVal->ve.ve_type,
  191. (LPBYTE)(lpVal->ve.ve_valueptr),
  192. lpVal->ve.ve_valuelen);
  193. */
  194. //Set old value name or value data
  195. lResult = RegSetValueEx (hKey,
  196. lpVal->lpPre_valuename,
  197. 0,
  198. dwType,
  199. lpBuf,
  200. dwOldValueSize);
  201. if (lResult == ERROR_SUCCESS)
  202. {
  203. if (lpVal->val_type & REG_CHANGE_VALUENAME)
  204. {
  205. //Delete old value if value name changed
  206. // lResult = RegDeleteValue(hKey, lpVal->lpPre_valuename);
  207. // if (lResult == ERROR_SUCCESS)
  208. DPF (REGinf, L"SetRegValueChange: Rename value %s to %s Key=%s",
  209. lpVal->lpPre_valuename, lpVal->ve.ve_valuename, lpFullKey);
  210. // else
  211. // DPF (REGerr, L"SetRegValueChange: RegDelValue failed. ValueName=%s Key=%s lResult=%d",
  212. // lpVal->lpPre_valuename, lpFullKey, lResult);
  213. }
  214. else
  215. DPF (REGinf, L"SetRegValueChange: Replace value data. Key=%s\\%s",
  216. lpFullKey, lpVal->ve.ve_valuename);
  217. } else
  218. DPF (REGerr, L"SetRegValueChange: RegSetValueEx Failed. Error=%d", lResult);
  219. if (lpVal->val_type & REG_CHANGE_VALUENAME)
  220. lpNewValueName = lpVal->ve.ve_valuename;
  221. else
  222. lpNewValueName = NULL;
  223. if (lpVal->val_type & REG_CHANGE_VALUEDATA)
  224. {
  225. lpOldValueData = (LPTSTR)lpBuf;
  226. dwNewValueSize = lpVal->ve.ve_valuelen;
  227. lpNewValueData = (LPTSTR)lpVal->ve.ve_valueptr;
  228. } else
  229. {
  230. dwOldValueSize = 0;
  231. lpOldValueData = NULL;
  232. dwNewValueSize = 0;
  233. lpNewValueData = NULL;
  234. }
  235. //Add registry value change information to INF file
  236. hResult = AddRegValueRename(
  237. lpFullKey,
  238. lpVal->lpPre_valuename,
  239. lpNewValueName,
  240. lpOldValueData,
  241. lpNewValueData,
  242. lpVal->ve.ve_type,
  243. lpVal->val_attrib,
  244. szUserName);
  245. lResult = HRESULT_CODE(hResult);
  246. if (lResult != ERROR_SUCCESS)
  247. {
  248. DPF (REGerr, L"SetRegValueChange: AddRegValueRename failed. Key = %s, error = %d", lpFullKey,lResult);
  249. if(lpBuf)
  250. {
  251. free(lpBuf);
  252. lpBuf = NULL;
  253. }
  254. break;
  255. }
  256. if(lpBuf)
  257. {
  258. free(lpBuf);
  259. lpBuf = NULL;
  260. }
  261. NextData:
  262. lpVal = lpVal->pvl_next;
  263. }
  264. RemoveValueList (lpValList);
  265. }
  266. return lResult;
  267. }
  268. //-----------------------------------------------------------------------//
  269. //
  270. // QueryValue()
  271. //
  272. // hKey: Registry key
  273. // szUserName: User name
  274. // szValueName: Value name
  275. // lpRegStr: Input parameter structure
  276. // lpValList: Updated value list
  277. // lpFullKey: Full sub-key path
  278. //-----------------------------------------------------------------------//
  279. LONG QueryValue(
  280. HKEY hKey,
  281. LPTSTR szUserName,
  282. LPTSTR szValueName,
  283. PREG_STRING_REPLACE lpRegStr,
  284. PVALLIST *lpValList,
  285. LPTSTR lpFullKey,
  286. DWORD TreatAsType,
  287. BOOL bStrChk)
  288. {
  289. LONG lResult;
  290. HRESULT hResult;
  291. DWORD dwType;
  292. DWORD cbSize = 1;
  293. LPBYTE lpBuf = NULL;
  294. lResult = ReadValue(hKey,
  295. szValueName,
  296. &dwType,
  297. &lpBuf,
  298. &cbSize,
  299. lpFullKey);
  300. if (lResult != ERROR_SUCCESS)
  301. goto Exit;
  302. switch (dwType)
  303. {
  304. case REG_MULTI_SZ:
  305. case REG_EXPAND_SZ:
  306. case REG_LINK:
  307. case REG_SZ:
  308. case REG_DWORD:
  309. hResult = ReplaceValueSettings (
  310. szUserName,
  311. (LPTSTR)lpBuf,
  312. cbSize,
  313. szValueName,
  314. dwType,
  315. lpRegStr,
  316. lpValList,
  317. lpFullKey,
  318. bStrChk);
  319. lResult = HRESULT_CODE(hResult);
  320. break;
  321. default:
  322. if ( TreatAsType )
  323. {
  324. dwType = dwType <<16;
  325. dwType = dwType + TreatAsType;
  326. hResult = ReplaceValueSettings (
  327. szUserName,
  328. (LPTSTR)lpBuf,
  329. cbSize,
  330. szValueName,
  331. dwType,
  332. lpRegStr,
  333. lpValList,
  334. lpFullKey,
  335. bStrChk);
  336. lResult = HRESULT_CODE(hResult);
  337. }
  338. break;
  339. }
  340. Exit:
  341. if(lpBuf)
  342. free(lpBuf);
  343. return lResult;
  344. }
  345. //-----------------------------------------------------------------------//
  346. //
  347. // QueryEnumerateKey() - Recursive
  348. //
  349. // hKey: Registry key
  350. // szUserName: User name
  351. // lpRegStr: Input parameter structure
  352. // lpFullKey: Full sub-key path
  353. // lpRegExclusionList: MultiSZ string tells a list of Keypath RegRepace should skip
  354. //-----------------------------------------------------------------------//
  355. LONG QueryEnumerateKey(
  356. HKEY hKey,
  357. LPTSTR szUserName,
  358. LPTSTR szUserSid,
  359. PREG_STRING_REPLACE lpRegStr,
  360. LPTSTR szFullKey,
  361. LPTSTR lpRegExclusionList,
  362. DWORD TreatAsType,
  363. BOOL bStrChk)
  364. {
  365. LONG lResult;
  366. HRESULT hResult;
  367. UINT i;
  368. DWORD cchSize, cchLen;
  369. DWORD dwNum;
  370. BOOL dwAccessDenied;
  371. HKEY hSubKey;
  372. TCHAR* szNameBuf = NULL;
  373. TCHAR* szKeyPath;
  374. TCHAR* szNewKeyPath;
  375. PVALLIST lpValList;
  376. // query source key info
  377. DWORD cchLenOfKeyName, cchLenOfValueName;
  378. TCHAR szKeyName[2*MAX_PATH];
  379. UpdateProgress();
  380. if (lpRegExclusionList && IsStrInMultiSz(szFullKey,lpRegExclusionList))
  381. {
  382. lResult = S_OK;
  383. goto Cleanup;
  384. }
  385. lResult = RegQueryInfoKey(hKey,
  386. NULL,
  387. NULL,
  388. NULL,
  389. NULL,
  390. &cchLenOfKeyName,
  391. NULL,
  392. NULL,
  393. &cchLenOfValueName,
  394. NULL,
  395. NULL,
  396. NULL);
  397. if (lResult != ERROR_SUCCESS)
  398. {
  399. DPF (REGerr, L"QueryEnumerateKey1: RegQueryInfoKey failed. Key=%s lResult=%d", szFullKey, lResult);
  400. return ERROR_SUCCESS;
  401. }
  402. // create buffer
  403. cchLenOfValueName++;
  404. szNameBuf = (TCHAR*) calloc(cchLenOfValueName, sizeof(TCHAR));
  405. if (!szNameBuf)
  406. {
  407. DPF (REGerr, L"QueryEnumerateKey1: No enough memory");
  408. return ERROR_NOT_ENOUGH_MEMORY;
  409. }
  410. //
  411. // enumerate all of the values
  412. //
  413. i = 0;
  414. lpValList = NULL;
  415. do
  416. {
  417. UpdateProgress();
  418. cchSize = cchLenOfValueName;
  419. lResult = RegEnumValue(hKey,
  420. i,
  421. szNameBuf,
  422. &cchSize,
  423. NULL,
  424. NULL,
  425. NULL,
  426. NULL);
  427. if (lResult == ERROR_MORE_DATA)
  428. {
  429. free(szNameBuf);
  430. //RegQueryInfoKey has a bug. *lpcMaxValueNameLen return 1 when
  431. //Key=HKLM\\SYSTEM\\ControlSet002\\Control\\Lsa\\SspiCache.
  432. cchSize = MAX_PATH;
  433. szNameBuf = (TCHAR*) calloc(cchSize+1, sizeof(TCHAR));
  434. if (!szNameBuf)
  435. {
  436. DPF (REGerr, L"QueryEnumerateKey2: No enough memory");
  437. return ERROR_NOT_ENOUGH_MEMORY;
  438. }
  439. cchLenOfValueName = cchSize+1;
  440. lResult = RegEnumValue(hKey,
  441. i,
  442. szNameBuf,
  443. &cchSize,
  444. NULL,
  445. NULL,
  446. NULL,
  447. NULL);
  448. }
  449. if (lResult == ERROR_SUCCESS)
  450. {
  451. lResult = QueryValue(hKey, szUserName, szNameBuf, lpRegStr, &lpValList,
  452. szFullKey, TreatAsType, bStrChk);
  453. // continue to query
  454. if(lResult == ERROR_ACCESS_DENIED)
  455. {
  456. DPF(REGerr, L"QueryEnumerateKey: Access denied ValueName=%s Key=%s", szNameBuf, szFullKey);
  457. }
  458. else if (lResult != ERROR_SUCCESS)
  459. {
  460. DPF(REGerr, L"QueryEnumerateKey: QueryValue failed. ValueName=%s Key=%s hResult=%d", szNameBuf, szFullKey, lResult);
  461. }
  462. lResult = ERROR_SUCCESS;
  463. }
  464. else if (lResult == ERROR_NO_MORE_ITEMS)
  465. {
  466. break;
  467. }
  468. else
  469. {
  470. DPF(REGerr, L"QueryEnumerateKey: RegEnumValue fails. Index=%d Key=%s Error=%d",
  471. i, szFullKey, lResult);
  472. }
  473. i++;
  474. } while (1);
  475. lResult = SetRegValueChange (hKey, szUserName, &lpValList, szFullKey);
  476. if (lResult != ERROR_SUCCESS)
  477. {
  478. DPF(REGerr, L"QueryEnumerateKey: SetRegValueChange failed ,error = %d",lResult);
  479. goto Cleanup;
  480. }
  481. if(szNameBuf)
  482. {
  483. free(szNameBuf);
  484. }
  485. //
  486. // Now Enumerate all of the keys
  487. //
  488. cchLenOfKeyName++;
  489. szNameBuf = (TCHAR*) calloc(cchLenOfKeyName, sizeof(TCHAR));
  490. if (!szNameBuf)
  491. {
  492. DPF (REGerr, L"QueryEnumerateKey4: No enough memory");
  493. return ERROR_NOT_ENOUGH_MEMORY;
  494. }
  495. i = 0;
  496. do
  497. {
  498. UpdateProgress();
  499. cchSize = cchLenOfKeyName;
  500. lResult = RegEnumKeyEx(hKey,
  501. i,
  502. szNameBuf,
  503. &cchSize,
  504. NULL,
  505. NULL,
  506. NULL,
  507. NULL);
  508. if (lResult == ERROR_MORE_DATA)
  509. {
  510. free(szNameBuf);
  511. //It should not get here except lpcMaxValueLen return wrong.
  512. cchSize = MAX_PATH;
  513. szNameBuf = (TCHAR*) calloc(cchSize+1, sizeof(TCHAR));
  514. if (!szNameBuf)
  515. {
  516. DPF (REGerr, L"QueryEnumerateKey3: No enough memory");
  517. return ERROR_NOT_ENOUGH_MEMORY;
  518. }
  519. cchLenOfKeyName = cchSize+1;
  520. lResult = RegEnumKeyEx(hKey,
  521. i,
  522. szNameBuf,
  523. &cchSize,
  524. NULL,
  525. NULL,
  526. NULL,
  527. NULL);
  528. }
  529. if (lResult != ERROR_SUCCESS)
  530. {
  531. if (lResult == ERROR_NO_MORE_ITEMS)
  532. {
  533. lResult = ERROR_SUCCESS;
  534. }
  535. else
  536. {
  537. DPF (REGerr, L"QueryEnumerateKey: RegEnumKeyEx failed. Key=%s Error=%d", szFullKey, lResult);
  538. }
  539. break;
  540. }
  541. //BUGBUG:XIAOZ following code is doubtful, why we need lpRegExclusionList != NULL
  542. //to exclude current control set, we should always exlcude it for performace
  543. //and it should be in lpRegExclusionList, we do not any special processing for this
  544. dwAccessDenied = FALSE;
  545. if (lpRegExclusionList)
  546. {
  547. //skip CurrentControlSet since it is a link to existing control set
  548. if (MyStrCmpI(szFullKey, L"HKLM\\SYSTEM") == 0 &&
  549. MyStrCmpI(szNameBuf, L"CurrentControlSet") == 0)
  550. {
  551. goto NextKey;
  552. }
  553. }
  554. //skip exclusive registry keys
  555. if (MyStrCmpI(szFullKey, TEXT("HKLM")) == 0 &&
  556. (MyStrCmpI(szNameBuf, TEXT("SAM")) == 0 || MyStrCmpI(szNameBuf, TEXT("SECURITY")) == 0) ||
  557. MyStrCmpI(szFullKey, TEXT("HKLM\\SYSTEM\\ControlSet001\\Enum\\PCI\\VEN_8086&DEV_7110&SUBSYS_00000000&REV_02\\2&ebb567f&0&38\\Device Parameters")) == 0 &&
  558. MyStrCmpI(szNameBuf, TEXT("BiosConfig")) == 0 )
  559. goto NextKey;
  560. TryAgain:
  561. //
  562. // open up the subkey, and enumerate it
  563. //
  564. lResult = RegOpenKeyEx(hKey,
  565. szNameBuf,
  566. 0,
  567. KEY_ALL_ACCESS
  568. // | ACCESS_SYSTEM_SECURITY
  569. ,
  570. &hSubKey);
  571. if (lResult != ERROR_SUCCESS)
  572. {
  573. if(lResult == ERROR_ACCESS_DENIED) // Try Read_Only
  574. {
  575. lResult = RegOpenKeyEx(hKey,
  576. szNameBuf,
  577. 0,
  578. KEY_READ,
  579. &hSubKey);
  580. if (lResult == ERROR_SUCCESS)
  581. {
  582. DPF(REGwar, L"QueryEnumerateKey: RegOpenKeyEx: Key=%s\\%s Read Only", szFullKey, szNameBuf);
  583. goto DoKey;
  584. }
  585. if (dwAccessDenied)
  586. {
  587. DPF(REGerr, L"QueryEnumerateKey: RegOpenKeyEx: Access Denied. Key=%s\\%s", szFullKey, szNameBuf);
  588. goto NextKey;
  589. }
  590. hResult = RenameRegRoot(szFullKey, szKeyName, 2*MAX_PATH-1, szUserSid, szNameBuf);
  591. AdjustObjectSecurity(szKeyName, SE_REGISTRY_KEY, TRUE);
  592. dwAccessDenied = TRUE;
  593. goto TryAgain;
  594. }
  595. DPF(REGerr, L"QueryEnumerateKey: RegOpenKeyEx failed. Key=%s\\%s Error=%d", szFullKey, szNameBuf, lResult);
  596. //skip the current key since it cannot be opened.
  597. goto NextKey;
  598. }
  599. DoKey:
  600. //
  601. // Build up the needed string and go down enumerating again
  602. //
  603. cchLen = lstrlen(szFullKey) + lstrlen(szNameBuf) + 2;
  604. szKeyPath = (TCHAR*) calloc(cchLen, sizeof(TCHAR));
  605. if (!szKeyPath)
  606. {
  607. lResult = ERROR_NOT_ENOUGH_MEMORY;
  608. DPF (REGerr, L"QueryEnumerateKey5: No enough memory");
  609. RegCloseKey(hSubKey);
  610. goto Cleanup;
  611. }
  612. //We calculte the buffer for szKeyPath, so here StringCchCopy should be
  613. //always success, assinging return value just make prefast happy
  614. hResult = StringCchCopy(szKeyPath, cchLen, szFullKey);
  615. hResult = StringCchCat(szKeyPath, cchLen, L"\\");
  616. hResult = StringCchCat(szKeyPath, cchLen, szNameBuf);
  617. dwNum = StrNumInMultiSZ(szNameBuf, lpRegStr->lpSearchString);
  618. if (dwNum != 0xFFFFFFFF)
  619. {
  620. LPTSTR lpKeyName;
  621. lpKeyName = GetStrInMultiSZ(dwNum, lpRegStr->lpReplaceString);
  622. cchLen = lstrlen(szFullKey) + lstrlen(lpKeyName) + 2;
  623. szNewKeyPath = (TCHAR*) calloc(cchLen, sizeof(TCHAR));
  624. if (!szNewKeyPath) {
  625. lResult = ERROR_NOT_ENOUGH_MEMORY;
  626. DPF (REGerr, L"QueryEnumerateKey6: No enough memory");
  627. RegCloseKey(hSubKey);
  628. free(szKeyPath);
  629. goto Cleanup;
  630. }
  631. if (szFullKey)
  632. {
  633. //We calculte the buffer for szNewKeyPath, so here StringCchCopy should be
  634. //always success, assinging return value just make prefast happy
  635. hResult = StringCchCopy(szNewKeyPath, cchLen, szFullKey);
  636. }
  637. //We calculte the buffer for szNewKeyPath, so here StringCchCopy should be
  638. //always success, assinging return value just make prefast happy
  639. hResult = StringCchCat(szNewKeyPath, cchLen, L"\\");
  640. hResult = StringCchCat(szNewKeyPath, cchLen, lpKeyName);
  641. hResult = AddRegKeyRename(szFullKey, szNameBuf, lpKeyName, szUserName);
  642. if (FAILED(hResult))
  643. {
  644. DPF(REGerr, L"QueryEnumerateKey: AddRegKeyRename failed. Key=%s", szKeyPath);
  645. }
  646. else
  647. {
  648. DPF(REGinf, L"QueryEnumerateKey: AddRegKeyRename succeed. Key=%s", szKeyPath);
  649. }
  650. free (szNewKeyPath);
  651. }
  652. // recursive query
  653. lResult = QueryEnumerateKey(hSubKey,
  654. szUserName,
  655. szUserSid,
  656. lpRegStr,
  657. szKeyPath,
  658. lpRegExclusionList,
  659. TreatAsType,
  660. bStrChk);
  661. if(lResult != ERROR_SUCCESS)
  662. {
  663. if (lResult == ERROR_NOT_ENOUGH_MEMORY)
  664. {
  665. if (szKeyPath)
  666. free(szKeyPath);
  667. RegCloseKey(hSubKey);
  668. goto Cleanup;
  669. } else
  670. DPF(REGerr, L"QueryEnumerateKey: QueryEnumerateKey failed. Key=%s lResult=%d", szKeyPath, lResult);
  671. }
  672. RegCloseKey(hSubKey);
  673. if(szKeyPath)
  674. free(szKeyPath);
  675. NextKey:
  676. if (dwAccessDenied)
  677. AdjustObjectSecurity(szKeyName, SE_REGISTRY_KEY, FALSE);
  678. i++;
  679. } while (1);
  680. Cleanup:
  681. if(szNameBuf)
  682. free(szNameBuf);
  683. return lResult;
  684. }