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.

787 lines
21 KiB

  1. //+---------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 1994.
  5. //
  6. // File: virtreg.cpp
  7. //
  8. // Contents: Implements the class CVirtualRegistry which manages a
  9. // virtual registry
  10. //
  11. // Classes:
  12. //
  13. // Methods: CVirtualRegistry::CVirtualRegistry
  14. // CVirtualRegistry::~CVirtualRegistry
  15. // CVirtualRegistry::ReadRegSzNamedValue
  16. // CVirtualRegistry::NewRegSzNamedValue
  17. // CVirtualRegistry::ChgRegSzNamedValue
  18. // CVirtualRegistry::ReadRegDwordNamedValue
  19. // CVirtualRegistry::NewRegDwordNamedValue
  20. // CVirtualRegistry::ChgRegDwordNamedValue
  21. // CVirtualRegistry::NewRegSingleACL
  22. // CVirtualRegistry::ChgRegACL
  23. // CVirtualRegistry::NewRegKeyACL
  24. // CVirtualRegistry::ReadLsaPassword
  25. // CVirtualRegistry::NewLsaPassword
  26. // CVirtualRegistry::ChgLsaPassword
  27. // CVirtualRegistry::ReadSrvIdentity
  28. // CVirtualRegistry::NewSrvIdentity
  29. // CVirtualRegistry::ChgSrvIdentity
  30. // CVirtualRegistry::MarkForDeletion
  31. // CVirtualRegistry::GetAt
  32. // CVirtualRegistry::Remove
  33. // CVirtualRegistry::Cancel
  34. // CVirtualRegistry::Apply
  35. // CVirtualRegistry::ApplyAll
  36. // CVirtualRegistry::Ok
  37. // CVirtualRegistry::SearchForRegEntry
  38. // CVirtualRegistry::SearchForLsaEntry
  39. // CVirtualRegistry::SearchForSrvEntry
  40. //
  41. // History: 23-Apr-96 BruceMa Created.
  42. // 15-Dec-96 RonanS Tidied up to remove memory leaks
  43. // Use array of pointers to avoid bitwise copy
  44. //
  45. //----------------------------------------------------------------------
  46. #include "stdafx.h"
  47. #include "afxtempl.h"
  48. #include "assert.h"
  49. extern "C"
  50. {
  51. #include "ntlsa.h"
  52. }
  53. #include "winsvc.h"
  54. #include "types.h"
  55. #include "datapkt.h"
  56. extern "C"
  57. {
  58. #include <getuser.h>
  59. }
  60. #include "util.h"
  61. #include "virtreg.h"
  62. #include "tchar.h"
  63. #ifdef _DEBUG
  64. #define new DEBUG_NEW
  65. #undef THIS_FILE
  66. static char BASED_CODE THIS_FILE[] = __FILE__;
  67. #endif
  68. CVirtualRegistry::CVirtualRegistry(void)
  69. {
  70. m_pkts.SetSize(0, 8);
  71. }
  72. CVirtualRegistry::~CVirtualRegistry(void)
  73. {
  74. // ronans - remove any remaining items
  75. RemoveAll();
  76. }
  77. // Read a named string value from the registry and cache it
  78. int CVirtualRegistry::ReadRegSzNamedValue(HKEY hRoot,
  79. TCHAR *szKeyPath,
  80. TCHAR *szValueName,
  81. int *pIndex)
  82. {
  83. int err;
  84. HKEY hKey;
  85. ULONG lSize;
  86. DWORD dwType;
  87. TCHAR *szVal = new TCHAR[MAX_PATH];
  88. // Check if we already have an entry for this
  89. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  90. if (*pIndex >= 0)
  91. {
  92. CDataPacket *pCdp = GetAt(*pIndex);
  93. ASSERT(pCdp); // should always be non null
  94. if (pCdp -> fDelete)
  95. {
  96. *pIndex = -1;
  97. delete szVal;
  98. return ERROR_FILE_NOT_FOUND;
  99. }
  100. else
  101. {
  102. delete szVal;
  103. return ERROR_SUCCESS;
  104. }
  105. }
  106. // Open the referenced key
  107. if ((err = RegOpenKeyEx(hRoot, szKeyPath, 0, KEY_ALL_ACCESS, &hKey)) != ERROR_SUCCESS)
  108. {
  109. g_util.CkForAccessDenied(err);
  110. delete szVal;
  111. return err;
  112. }
  113. // Attempt to read the named value
  114. lSize = MAX_PATH * sizeof(TCHAR);
  115. if ((err = RegQueryValueEx(hKey, szValueName, NULL, &dwType, (BYTE *) szVal,
  116. &lSize))
  117. != ERROR_SUCCESS)
  118. {
  119. g_util.CkForAccessDenied(err);
  120. if (hKey != hRoot)
  121. {
  122. RegCloseKey(hKey);
  123. }
  124. delete szVal;
  125. return err;
  126. }
  127. // Build a data packet
  128. if (dwType == REG_SZ)
  129. {
  130. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, szVal);
  131. ASSERT(pNewPacket);
  132. if (!pNewPacket)
  133. {
  134. return ERROR_NOT_ENOUGH_MEMORY;
  135. }
  136. *pIndex = m_pkts.Add(pNewPacket);
  137. pNewPacket->fDirty = FALSE;
  138. delete szVal;
  139. return ERROR_SUCCESS;
  140. }
  141. else
  142. {
  143. delete szVal;
  144. return ERROR_BAD_TOKEN_TYPE;
  145. }
  146. }
  147. int CVirtualRegistry::NewRegSzNamedValue(HKEY hRoot,
  148. TCHAR *szKeyPath,
  149. TCHAR *szValueName,
  150. TCHAR *szVal,
  151. int *pIndex)
  152. {
  153. // It may be in the virtual registry but marked for deletion
  154. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  155. if (*pIndex >= 0)
  156. {
  157. CDataPacket *pCdp = GetAt(*pIndex);
  158. pCdp->MarkForDeletion(FALSE);
  159. pCdp->ChgSzValue(szVal);
  160. return ERROR_SUCCESS;
  161. }
  162. // Build a data packet and add it
  163. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, szVal);
  164. ASSERT(pNewPacket);
  165. if (!pNewPacket)
  166. return ERROR_NOT_ENOUGH_MEMORY;
  167. *pIndex = m_pkts.Add(pNewPacket);
  168. return ERROR_SUCCESS;
  169. }
  170. void CVirtualRegistry::ChgRegSzNamedValue(int nIndex, TCHAR *szVal)
  171. {
  172. CDataPacket * pCdp = m_pkts.ElementAt(nIndex);
  173. pCdp->ChgSzValue(szVal);
  174. pCdp->fDirty = TRUE;
  175. }
  176. // Read a named DWORD value from the registry
  177. int CVirtualRegistry::ReadRegDwordNamedValue(HKEY hRoot,
  178. TCHAR *szKeyPath,
  179. TCHAR *szValueName,
  180. int *pIndex)
  181. {
  182. int err;
  183. HKEY hKey;
  184. ULONG lSize;
  185. DWORD dwType;
  186. DWORD dwVal;
  187. // Check if we already have an entry for this
  188. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  189. if (*pIndex >= 0)
  190. {
  191. return ERROR_SUCCESS;
  192. }
  193. // Open the referenced key
  194. if ((err = RegOpenKeyEx(hRoot, szKeyPath, 0, KEY_ALL_ACCESS, &hKey)) != ERROR_SUCCESS)
  195. {
  196. g_util.CkForAccessDenied(err);
  197. return err;
  198. }
  199. // Attempt to read the named value
  200. lSize = sizeof(DWORD);
  201. if ((err = RegQueryValueEx(hKey, szValueName, NULL, &dwType, (BYTE *) &dwVal,
  202. &lSize))
  203. != ERROR_SUCCESS)
  204. {
  205. g_util.CkForAccessDenied(err);
  206. if (hKey != hRoot)
  207. {
  208. RegCloseKey(hKey);
  209. }
  210. return err;
  211. }
  212. // Close the registry key
  213. if (hKey != hRoot)
  214. {
  215. RegCloseKey(hKey);
  216. }
  217. // Build a data packet
  218. if (dwType == REG_DWORD)
  219. {
  220. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, dwVal);
  221. ASSERT(pNewPacket);
  222. if (!pNewPacket)
  223. {
  224. return ERROR_NOT_ENOUGH_MEMORY;
  225. }
  226. *pIndex = m_pkts.Add(pNewPacket);
  227. pNewPacket->fDirty = FALSE;
  228. return ERROR_SUCCESS;
  229. }
  230. else
  231. {
  232. return ERROR_BAD_TOKEN_TYPE;
  233. }
  234. }
  235. int CVirtualRegistry::NewRegDwordNamedValue(HKEY hRoot,
  236. TCHAR *szKeyPath,
  237. TCHAR *szValueName,
  238. DWORD dwVal,
  239. int *pIndex)
  240. {
  241. // It may be in the virtual registry but marked for deletion
  242. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  243. if (*pIndex >= 0)
  244. {
  245. CDataPacket *pCdp = GetAt(*pIndex);
  246. pCdp->MarkForDeletion(FALSE);
  247. pCdp -> pkt.nvdw.dwValue = dwVal;
  248. return ERROR_SUCCESS;
  249. }
  250. // Build a data packet and add it
  251. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, dwVal);
  252. ASSERT(pNewPacket);
  253. if (!pNewPacket)
  254. return ERROR_NOT_ENOUGH_MEMORY;
  255. *pIndex = m_pkts.Add(pNewPacket);
  256. pNewPacket->fDirty = FALSE;
  257. return ERROR_SUCCESS;
  258. }
  259. void CVirtualRegistry::ChgRegDwordNamedValue(int nIndex, DWORD dwVal)
  260. {
  261. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  262. pCdp -> pkt.nvdw.dwValue = dwVal;
  263. pCdp -> fDirty = TRUE;
  264. }
  265. int CVirtualRegistry::NewRegSingleACL(HKEY hRoot,
  266. TCHAR *szKeyPath,
  267. TCHAR *szValueName,
  268. SECURITY_DESCRIPTOR *pacl,
  269. BOOL fSelfRelative,
  270. int *pIndex)
  271. {
  272. // Build a data packet and add it
  273. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, pacl, fSelfRelative);
  274. ASSERT(pNewPacket);
  275. if (!pNewPacket)
  276. return ERROR_NOT_ENOUGH_MEMORY;
  277. *pIndex = m_pkts.Add(pNewPacket);
  278. return ERROR_SUCCESS;
  279. }
  280. void CVirtualRegistry::ChgRegACL(int nIndex,
  281. SECURITY_DESCRIPTOR *pacl,
  282. BOOL fSelfRelative)
  283. {
  284. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  285. pCdp -> ChgACL(pacl, fSelfRelative);
  286. pCdp -> fDirty = TRUE;
  287. }
  288. int CVirtualRegistry::NewRegKeyACL(HKEY hKey,
  289. HKEY *phClsids,
  290. unsigned cClsids,
  291. TCHAR *szTitle,
  292. SECURITY_DESCRIPTOR *paclOrig,
  293. SECURITY_DESCRIPTOR *pacl,
  294. BOOL fSelfRelative,
  295. int *pIndex)
  296. {
  297. // Build a data packet and add it
  298. CDataPacket * pNewPacket = new CDataPacket(hKey, phClsids, cClsids, szTitle, paclOrig, pacl, fSelfRelative);
  299. ASSERT(pNewPacket);
  300. if (!pNewPacket)
  301. return ERROR_NOT_ENOUGH_MEMORY;
  302. *pIndex = m_pkts.Add(pNewPacket);
  303. return ERROR_SUCCESS;
  304. }
  305. int CVirtualRegistry::ReadLsaPassword(CLSID &clsid,
  306. int *pIndex)
  307. {
  308. #ifdef UNICODE
  309. LSA_OBJECT_ATTRIBUTES sObjAttributes;
  310. HANDLE hPolicy = NULL;
  311. LSA_UNICODE_STRING sKey;
  312. TCHAR szKey[GUIDSTR_MAX + 5];
  313. PLSA_UNICODE_STRING psPassword;
  314. // Check if we already have an entry fo this
  315. *pIndex = SearchForLsaEntry(clsid);
  316. if (*pIndex >= 0)
  317. {
  318. return ERROR_SUCCESS;
  319. }
  320. // Formulate the access key
  321. _tcscpy(szKey, TEXT("SCM:"));
  322. g_util.StringFromGUID(clsid, &szKey[4], GUIDSTR_MAX);
  323. szKey[GUIDSTR_MAX + 4] = TEXT('\0');
  324. // UNICODE_STRING length fields are in bytes and include the NULL
  325. // terminator
  326. sKey.Length = (_tcslen(szKey) + 1) * sizeof(TCHAR);
  327. sKey.MaximumLength = (GUIDSTR_MAX + 5) * sizeof(TCHAR);
  328. sKey.Buffer = szKey;
  329. // Open the local security policy
  330. InitializeObjectAttributes(&sObjAttributes, NULL, 0L, NULL, NULL);
  331. if (!NT_SUCCESS(LsaOpenPolicy(NULL, &sObjAttributes,
  332. POLICY_GET_PRIVATE_INFORMATION, &hPolicy)))
  333. {
  334. return GetLastError();
  335. }
  336. // Read the user's password
  337. if (!NT_SUCCESS(LsaRetrievePrivateData(hPolicy, &sKey, &psPassword)))
  338. {
  339. LsaClose(hPolicy);
  340. return GetLastError();
  341. }
  342. // Close the policy handle, we're done with it now.
  343. LsaClose(hPolicy);
  344. // Build a data packet
  345. CDataPacket * pNewPacket = new CDataPacket(psPassword->Buffer, clsid);
  346. ASSERT(pNewPacket);
  347. if (!pNewPacket)
  348. return ERROR_NOT_ENOUGH_MEMORY;
  349. pNewPacket->fDirty = FALSE;
  350. *pIndex = m_pkts.Add(pNewPacket);
  351. #endif
  352. return ERROR_SUCCESS;
  353. }
  354. int CVirtualRegistry::NewLsaPassword(CLSID &clsid,
  355. TCHAR *szPassword,
  356. int *pIndex)
  357. {
  358. // Build a data packet and add it
  359. CDataPacket * pNewPacket = new CDataPacket(szPassword, clsid);
  360. ASSERT(pNewPacket);
  361. if (!pNewPacket)
  362. return ERROR_NOT_ENOUGH_MEMORY;
  363. *pIndex = m_pkts.Add(pNewPacket);
  364. return ERROR_SUCCESS;
  365. }
  366. void CVirtualRegistry::ChgLsaPassword(int nIndex,
  367. TCHAR *szPassword)
  368. {
  369. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  370. delete pCdp -> pkt.pw.szPassword;
  371. pCdp -> pkt.pw.szPassword = new TCHAR[_tcslen(szPassword) + 1];
  372. _tcscpy(pCdp -> pkt.pw.szPassword, szPassword);
  373. pCdp -> fDirty = TRUE;
  374. }
  375. int CVirtualRegistry::ReadSrvIdentity(TCHAR *szService,
  376. int *pIndex)
  377. {
  378. SC_HANDLE hSCManager;
  379. SC_HANDLE hService;
  380. QUERY_SERVICE_CONFIG sServiceQueryConfig;
  381. DWORD dwSize;
  382. // Check if we already have an entry fo this
  383. *pIndex = SearchForSrvEntry(szService);
  384. if (*pIndex >= 0)
  385. {
  386. return ERROR_SUCCESS;
  387. }
  388. // Open the service control manager
  389. if (hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ))
  390. {
  391. // Open a handle to the requested service
  392. if (hService = OpenService(hSCManager, szService, GENERIC_READ))
  393. {
  394. // Close the service manager's database
  395. CloseServiceHandle(hSCManager);
  396. // Query the service
  397. if (QueryServiceConfig(hService, &sServiceQueryConfig,
  398. sizeof(SERVICE_QUERY_CONFIG), &dwSize))
  399. {
  400. // Build a data packet
  401. CDataPacket * pNewPacket = new CDataPacket(szService, sServiceQueryConfig.lpServiceStartName);
  402. ASSERT(pNewPacket);
  403. if (!pNewPacket)
  404. return ERROR_NOT_ENOUGH_MEMORY;
  405. pNewPacket->fDirty = FALSE;
  406. *pIndex = m_pkts.Add(pNewPacket);
  407. // Return success
  408. CloseServiceHandle(hSCManager);
  409. CloseServiceHandle(hService);
  410. return ERROR_SUCCESS;
  411. }
  412. }
  413. CloseServiceHandle(hSCManager);
  414. }
  415. return GetLastError();
  416. }
  417. int CVirtualRegistry::NewSrvIdentity(TCHAR *szService,
  418. TCHAR *szIdentity,
  419. int *pIndex)
  420. {
  421. // Build a data packet and add it
  422. CDataPacket * pNewPacket = new CDataPacket(szService, szIdentity);
  423. ASSERT(pNewPacket);
  424. if (!pNewPacket)
  425. return ERROR_NOT_ENOUGH_MEMORY;
  426. *pIndex = m_pkts.Add(pNewPacket);
  427. return ERROR_SUCCESS;
  428. }
  429. void CVirtualRegistry::ChgSrvIdentity(int nIndex,
  430. TCHAR *szIdentity)
  431. {
  432. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  433. delete pCdp -> pkt.si.szIdentity;
  434. pCdp -> pkt.si.szIdentity = new TCHAR[_tcslen(szIdentity) + 1];
  435. _tcscpy(pCdp -> pkt.si.szIdentity, szIdentity);
  436. pCdp -> fDirty = TRUE;
  437. }
  438. void CVirtualRegistry::MarkForDeletion(int nIndex)
  439. {
  440. CDataPacket *pCdp = GetAt(nIndex);
  441. pCdp -> fDelete = TRUE;
  442. pCdp -> fDirty = TRUE;
  443. }
  444. CDataPacket * CVirtualRegistry::GetAt(int nIndex)
  445. {
  446. return m_pkts.ElementAt(nIndex);
  447. }
  448. void CVirtualRegistry::Remove(int nIndex)
  449. {
  450. CDataPacket * pCdp = GetAt(nIndex);
  451. // ronans - must always destroy even if packet has not been marked dirty
  452. if (pCdp)
  453. delete pCdp;
  454. // overwrite with empty data packet
  455. m_pkts.SetAt(nIndex, new CDataPacket);
  456. }
  457. void CVirtualRegistry::RemoveAll(void)
  458. {
  459. int nSize = m_pkts.GetSize();
  460. for (int k = 0; k < nSize; k++)
  461. Remove(k);
  462. m_pkts.RemoveAll();
  463. }
  464. void CVirtualRegistry::Cancel(int nIndex)
  465. {
  466. int nSize = m_pkts.GetSize();
  467. for (int k = nIndex; k < nSize; k++)
  468. {
  469. m_pkts.SetAt(nIndex, new CDataPacket);
  470. }
  471. }
  472. int CVirtualRegistry::Apply(int nIndex)
  473. {
  474. int err = ERROR_SUCCESS;
  475. int nSize = m_pkts.GetSize();
  476. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  477. if (pCdp -> fDirty)
  478. {
  479. switch (pCdp -> tagType)
  480. {
  481. case Empty:
  482. break;
  483. case NamedValueSz:
  484. if (pCdp -> fDelete)
  485. {
  486. g_util.DeleteRegValue(pCdp -> pkt.nvsz.hRoot,
  487. pCdp -> pkt.nvsz.szKeyPath,
  488. pCdp -> pkt.nvsz.szValueName);
  489. }
  490. else
  491. {
  492. err = g_util.WriteRegSzNamedValue(pCdp -> pkt.nvsz.hRoot,
  493. pCdp -> pkt.nvsz.szKeyPath,
  494. pCdp -> pkt.nvsz.szValueName,
  495. pCdp -> pkt.nvsz.szValue,
  496. _tcslen(pCdp -> pkt.nvsz.szValue) + 1);
  497. }
  498. break;
  499. case NamedValueDword:
  500. if (pCdp -> fDelete)
  501. {
  502. g_util.DeleteRegValue(pCdp -> pkt.nvdw.hRoot,
  503. pCdp -> pkt.nvdw.szKeyPath,
  504. pCdp -> pkt.nvdw.szValueName);
  505. }
  506. else
  507. {
  508. err = g_util.WriteRegDwordNamedValue(pCdp -> pkt.nvdw.hRoot,
  509. pCdp -> pkt.nvdw.szKeyPath,
  510. pCdp -> pkt.nvdw.szValueName,
  511. pCdp -> pkt.nvdw.dwValue);
  512. }
  513. break;
  514. case SingleACL:
  515. if (pCdp -> fDelete)
  516. {
  517. HKEY hKey;
  518. if (RegOpenKeyEx(pCdp -> pkt.acl.hRoot,
  519. pCdp -> pkt.acl.szKeyPath,
  520. 0,
  521. KEY_ALL_ACCESS,
  522. &hKey) == ERROR_SUCCESS)
  523. {
  524. RegDeleteValue(hKey, pCdp -> pkt.acl.szValueName);
  525. RegCloseKey(hKey);
  526. }
  527. }
  528. else
  529. {
  530. err = g_util.WriteRegSingleACL(pCdp -> pkt.acl.hRoot,
  531. pCdp -> pkt.acl.szKeyPath,
  532. pCdp -> pkt.acl.szValueName,
  533. pCdp -> pkt.acl.pSec);
  534. }
  535. break;
  536. case RegKeyACL:
  537. err = g_util.WriteRegKeyACL(pCdp -> pkt.racl.hKey,
  538. pCdp -> pkt.racl.phClsids,
  539. pCdp -> pkt.racl.cClsids,
  540. pCdp -> pkt.racl.pSec,
  541. pCdp -> pkt.racl.pSecOrig);
  542. break;
  543. case Password:
  544. err = g_util.WriteLsaPassword(pCdp -> pkt.pw.appid,
  545. pCdp -> pkt.pw.szPassword);
  546. break;
  547. case ServiceIdentity:
  548. err = g_util.WriteSrvIdentity(pCdp -> pkt.si.szServiceName,
  549. pCdp -> pkt.si.szIdentity);
  550. break;
  551. }
  552. }
  553. // Cleanup work
  554. if (err == ERROR_SUCCESS)
  555. {
  556. pCdp -> fDirty = FALSE;
  557. }
  558. else
  559. {
  560. if (err == ERROR_ACCESS_DENIED)
  561. {
  562. g_util.CkForAccessDenied(ERROR_ACCESS_DENIED);
  563. }
  564. else
  565. {
  566. g_util.PostErrorMessage();
  567. }
  568. }
  569. return err;;
  570. }
  571. int CVirtualRegistry::ApplyAll(void)
  572. {
  573. int nSize = m_pkts.GetSize();
  574. // Persist all non-empty data packets
  575. for (int k = 0; k < nSize; k++)
  576. {
  577. Apply(k);
  578. }
  579. return ERROR_SUCCESS;
  580. }
  581. int CVirtualRegistry::Ok(int nIndex)
  582. {
  583. return 0;
  584. }
  585. int CVirtualRegistry::SearchForRegEntry(HKEY hRoot,
  586. TCHAR *szKeyPath,
  587. TCHAR *szValueName)
  588. {
  589. int nSize = m_pkts.GetSize();
  590. for (int k = 0; k < nSize; k++)
  591. {
  592. CDataPacket *pCdp = GetAt(k);
  593. if ((pCdp -> tagType == NamedValueSz &&
  594. pCdp -> pkt.nvsz.hRoot == hRoot &&
  595. (_tcscmp(pCdp -> pkt.nvsz.szKeyPath, szKeyPath) == 0) &&
  596. (_tcscmp(pCdp -> pkt.nvsz.szValueName, szValueName) == 0)) ||
  597. (pCdp -> tagType == NamedValueDword &&
  598. pCdp -> pkt.nvdw.hRoot == hRoot &&
  599. (_tcscmp(pCdp -> pkt.nvdw.szKeyPath, szKeyPath) == 0) &&
  600. (_tcscmp(pCdp -> pkt.nvdw.szValueName, szValueName) == 0)))
  601. {
  602. return k;
  603. }
  604. }
  605. return -1;
  606. }
  607. int CVirtualRegistry::SearchForLsaEntry(CLSID appid)
  608. {
  609. int nSize = m_pkts.GetSize();
  610. for (int k = 0; k < nSize; k++)
  611. {
  612. CDataPacket *pCdp = GetAt(k);
  613. if (pCdp -> tagType == Password &&
  614. g_util.IsEqualGuid(pCdp -> pkt.pw.appid, appid))
  615. {
  616. return k;
  617. }
  618. }
  619. return -1;
  620. }
  621. int CVirtualRegistry::SearchForSrvEntry(TCHAR *szServiceName)
  622. {
  623. int nSize = m_pkts.GetSize();
  624. for (int k = 0; k < nSize; k++)
  625. {
  626. CDataPacket *pCdp = GetAt(k);
  627. if (pCdp -> tagType == ServiceIdentity &&
  628. (_tcscmp(pCdp -> pkt.si.szServiceName, szServiceName)))
  629. {
  630. return k;
  631. }
  632. }
  633. return -1;
  634. }