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.

783 lines
21 KiB

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