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.

773 lines
20 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. // Open the referenced key
  161. if ((err = RegOpenKeyEx(hRoot, szKeyPath, 0, KEY_ALL_ACCESS, &hKey)) == ERROR_SUCCESS)
  162. {
  163. // Build a data packet
  164. CRegMultiSzNamedValueDp * pNewPacket = new CRegMultiSzNamedValueDp(hRoot, szKeyPath, szValueName);
  165. ASSERT(pNewPacket);
  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. }
  187. return err;
  188. }
  189. int CVirtualRegistry::NewRegSzNamedValue(HKEY hRoot,
  190. TCHAR *szKeyPath,
  191. TCHAR *szValueName,
  192. TCHAR *szVal,
  193. int *pIndex)
  194. {
  195. // It may be in the virtual registry but marked for deletion
  196. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  197. if (*pIndex >= 0)
  198. {
  199. CRegSzNamedValueDp * pCdp = (CRegSzNamedValueDp *)GetAt(*pIndex);
  200. pCdp->MarkForDeletion(FALSE);
  201. pCdp->ChgSzValue(szVal);
  202. return ERROR_SUCCESS;
  203. }
  204. // Build a data packet and add it
  205. CRegSzNamedValueDp * pNewPacket = new CRegSzNamedValueDp (hRoot, szKeyPath, szValueName, szVal);
  206. ASSERT(pNewPacket);
  207. if (!pNewPacket)
  208. return ERROR_NOT_ENOUGH_MEMORY;
  209. *pIndex = (int)m_pkts.Add(pNewPacket);
  210. return ERROR_SUCCESS;
  211. }
  212. int CVirtualRegistry::NewRegMultiSzNamedValue(HKEY hRoot,
  213. TCHAR *szKeyPath,
  214. TCHAR *szValueName,
  215. int *pIndex)
  216. {
  217. // It may be in the virtual registry but marked for deletion
  218. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  219. if (*pIndex >= 0)
  220. {
  221. CRegMultiSzNamedValueDp * pCdp = (CRegMultiSzNamedValueDp *)GetAt(*pIndex);
  222. pCdp->MarkForDeletion(FALSE);
  223. pCdp->Clear();
  224. pCdp -> SetModified(TRUE);
  225. return ERROR_SUCCESS;
  226. }
  227. // Build a data packet and add it
  228. CRegMultiSzNamedValueDp * pNewPacket = new CRegMultiSzNamedValueDp (hRoot, szKeyPath, szValueName);
  229. ASSERT(pNewPacket);
  230. if (!pNewPacket)
  231. return ERROR_NOT_ENOUGH_MEMORY;
  232. pNewPacket -> SetModified(TRUE);
  233. *pIndex = (int)m_pkts.Add(pNewPacket);
  234. return ERROR_SUCCESS;
  235. }
  236. void CVirtualRegistry::ChgRegSzNamedValue(int nIndex, TCHAR *szVal)
  237. {
  238. CRegSzNamedValueDp* pCdp = (CRegSzNamedValueDp*)m_pkts.ElementAt(nIndex);
  239. pCdp->ChgSzValue(szVal);
  240. }
  241. // Read a named DWORD value from the registry
  242. int CVirtualRegistry::ReadRegDwordNamedValue(HKEY hRoot,
  243. TCHAR *szKeyPath,
  244. TCHAR *szValueName,
  245. int *pIndex)
  246. {
  247. int err;
  248. HKEY hKey;
  249. ULONG lSize;
  250. DWORD dwType;
  251. DWORD dwVal;
  252. // Check if we already have an entry for this
  253. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  254. if (*pIndex >= 0)
  255. {
  256. return ERROR_SUCCESS;
  257. }
  258. // Open the referenced key
  259. if ((err = RegOpenKeyEx(hRoot, szKeyPath, 0, KEY_ALL_ACCESS, &hKey)) != ERROR_SUCCESS)
  260. {
  261. g_util.CkForAccessDenied(err);
  262. return err;
  263. }
  264. // Attempt to read the named value
  265. lSize = sizeof(DWORD);
  266. if ((err = RegQueryValueEx(hKey, szValueName, NULL, &dwType, (BYTE *) &dwVal,
  267. &lSize))
  268. != ERROR_SUCCESS)
  269. {
  270. g_util.CkForAccessDenied(err);
  271. if (hKey != hRoot)
  272. {
  273. RegCloseKey(hKey);
  274. }
  275. return err;
  276. }
  277. // Close the registry key
  278. if (hKey != hRoot)
  279. {
  280. RegCloseKey(hKey);
  281. }
  282. // Build a data packet
  283. if (dwType == REG_DWORD)
  284. {
  285. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, dwVal);
  286. ASSERT(pNewPacket);
  287. if (!pNewPacket)
  288. {
  289. return ERROR_NOT_ENOUGH_MEMORY;
  290. }
  291. *pIndex = (int)m_pkts.Add(pNewPacket);
  292. pNewPacket-> SetModified(FALSE);
  293. return ERROR_SUCCESS;
  294. }
  295. else
  296. {
  297. return ERROR_BAD_TOKEN_TYPE;
  298. }
  299. }
  300. int CVirtualRegistry::NewRegDwordNamedValue(HKEY hRoot,
  301. TCHAR *szKeyPath,
  302. TCHAR *szValueName,
  303. DWORD dwVal,
  304. int *pIndex)
  305. {
  306. // It may be in the virtual registry but marked for deletion
  307. *pIndex = SearchForRegEntry(hRoot, szKeyPath, szValueName);
  308. if (*pIndex >= 0)
  309. {
  310. CDataPacket * pCdp = GetAt(*pIndex);
  311. pCdp->MarkForDeletion(FALSE);
  312. pCdp->pkt.nvdw.dwValue = dwVal;
  313. pCdp->SetModified(TRUE);
  314. return ERROR_SUCCESS;
  315. }
  316. // Build a data packet and add it
  317. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, dwVal);
  318. ASSERT(pNewPacket);
  319. if (!pNewPacket)
  320. return ERROR_NOT_ENOUGH_MEMORY;
  321. *pIndex = (int)m_pkts.Add(pNewPacket);
  322. pNewPacket->SetModified(TRUE);
  323. return ERROR_SUCCESS;
  324. }
  325. void CVirtualRegistry::ChgRegDwordNamedValue(int nIndex, DWORD dwVal)
  326. {
  327. CDataPacket * pCdp = m_pkts.ElementAt(nIndex);
  328. pCdp->pkt.nvdw.dwValue = dwVal;
  329. pCdp->SetModified( TRUE);
  330. }
  331. int CVirtualRegistry::NewRegSingleACL(HKEY hRoot,
  332. TCHAR *szKeyPath,
  333. TCHAR *szValueName,
  334. SECURITY_DESCRIPTOR *pacl,
  335. BOOL fSelfRelative,
  336. int *pIndex)
  337. {
  338. // Build a data packet and add it
  339. CDataPacket * pNewPacket = new CDataPacket(hRoot, szKeyPath, szValueName, pacl, fSelfRelative);
  340. ASSERT(pNewPacket);
  341. if (!pNewPacket)
  342. return ERROR_NOT_ENOUGH_MEMORY;
  343. *pIndex = (int)m_pkts.Add(pNewPacket);
  344. return ERROR_SUCCESS;
  345. }
  346. void CVirtualRegistry::ChgRegACL(int nIndex,
  347. SECURITY_DESCRIPTOR *pacl,
  348. BOOL fSelfRelative)
  349. {
  350. CDataPacket * pCdp = m_pkts.ElementAt(nIndex);
  351. pCdp->ChgACL(pacl, fSelfRelative);
  352. pCdp->SetModified(TRUE);
  353. }
  354. int CVirtualRegistry::NewRegKeyACL(HKEY hKey,
  355. HKEY *phClsids,
  356. unsigned cClsids,
  357. TCHAR *szTitle,
  358. SECURITY_DESCRIPTOR *paclOrig,
  359. SECURITY_DESCRIPTOR *pacl,
  360. BOOL fSelfRelative,
  361. int *pIndex)
  362. {
  363. // Build a data packet and add it
  364. CDataPacket * pNewPacket = new CDataPacket(hKey, phClsids, cClsids, szTitle, paclOrig, pacl, fSelfRelative);
  365. ASSERT(pNewPacket);
  366. if (!pNewPacket)
  367. return ERROR_NOT_ENOUGH_MEMORY;
  368. *pIndex = (int)m_pkts.Add(pNewPacket);
  369. return ERROR_SUCCESS;
  370. }
  371. int CVirtualRegistry::ReadLsaPassword(CLSID &clsid,
  372. int *pIndex)
  373. {
  374. #if !defined(STANDALONE_BUILD)
  375. LSA_OBJECT_ATTRIBUTES sObjAttributes;
  376. HANDLE hPolicy = NULL;
  377. LSA_UNICODE_STRING sKey;
  378. TCHAR szKey[GUIDSTR_MAX + 5];
  379. PLSA_UNICODE_STRING psPassword;
  380. // Check if we already have an entry fo this
  381. *pIndex = SearchForLsaEntry(clsid);
  382. if (*pIndex >= 0)
  383. {
  384. return ERROR_SUCCESS;
  385. }
  386. // Formulate the access key
  387. lstrcpyW(szKey, L"SCM:");
  388. g_util.StringFromGUID(clsid, &szKey[4], GUIDSTR_MAX);
  389. szKey[GUIDSTR_MAX + 4] = L'\0';
  390. // UNICODE_STRING length fields are in bytes and include the NULL
  391. // terminator
  392. sKey.Length = (USHORT)((lstrlenW(szKey) + 1) * sizeof(WCHAR));
  393. sKey.MaximumLength = (GUIDSTR_MAX + 5) * sizeof(WCHAR);
  394. sKey.Buffer = szKey;
  395. // Open the local security policy
  396. InitializeObjectAttributes(&sObjAttributes, NULL, 0L, NULL, NULL);
  397. if (!NT_SUCCESS(LsaOpenPolicy(NULL, &sObjAttributes,
  398. POLICY_GET_PRIVATE_INFORMATION, &hPolicy)))
  399. {
  400. return GetLastError();
  401. }
  402. // Read the user's password
  403. if (!NT_SUCCESS(LsaRetrievePrivateData(hPolicy, &sKey, &psPassword)))
  404. {
  405. LsaClose(hPolicy);
  406. return GetLastError();
  407. }
  408. // Close the policy handle, we're done with it now.
  409. LsaClose(hPolicy);
  410. // Build a data packet
  411. CDataPacket * pNewPacket = new CDataPacket(psPassword->Buffer, clsid);
  412. ASSERT(pNewPacket);
  413. if (!pNewPacket)
  414. return ERROR_NOT_ENOUGH_MEMORY;
  415. pNewPacket->SetModified( FALSE );
  416. *pIndex = (int)m_pkts.Add(pNewPacket);
  417. #endif
  418. return ERROR_SUCCESS;
  419. }
  420. int CVirtualRegistry::NewLsaPassword(CLSID &clsid,
  421. TCHAR *szPassword,
  422. int *pIndex)
  423. {
  424. // Build a data packet and add it
  425. CDataPacket * pNewPacket = new CDataPacket(szPassword, clsid);
  426. ASSERT(pNewPacket);
  427. if (!pNewPacket)
  428. return ERROR_NOT_ENOUGH_MEMORY;
  429. *pIndex = (int)m_pkts.Add(pNewPacket);
  430. return ERROR_SUCCESS;
  431. }
  432. void CVirtualRegistry::ChgLsaPassword(int nIndex,
  433. TCHAR *szPassword)
  434. {
  435. CDataPacket * pCdp = m_pkts.ElementAt(nIndex);
  436. pCdp -> ChgPassword(szPassword);
  437. pCdp -> SetModified(TRUE);
  438. }
  439. int CVirtualRegistry::ReadSrvIdentity(TCHAR *szService,
  440. int *pIndex)
  441. {
  442. SC_HANDLE hSCManager;
  443. SC_HANDLE hService;
  444. QUERY_SERVICE_CONFIG sServiceQueryConfig;
  445. DWORD dwSize;
  446. // Check if we already have an entry fo this
  447. *pIndex = SearchForSrvEntry(szService);
  448. if (*pIndex >= 0)
  449. {
  450. return ERROR_SUCCESS;
  451. }
  452. // Open the service control manager
  453. if (hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ))
  454. {
  455. // Open a handle to the requested service
  456. if (hService = OpenService(hSCManager, szService, GENERIC_READ))
  457. {
  458. // Close the service manager's database
  459. CloseServiceHandle(hSCManager);
  460. // Query the service
  461. if (QueryServiceConfig(hService, &sServiceQueryConfig,
  462. sizeof(QUERY_SERVICE_CONFIG), &dwSize))
  463. {
  464. // Build a data packet
  465. CDataPacket * pNewPacket = new CDataPacket(szService, sServiceQueryConfig.lpServiceStartName);
  466. ASSERT(pNewPacket);
  467. if (!pNewPacket)
  468. return ERROR_NOT_ENOUGH_MEMORY;
  469. pNewPacket->SetModified(FALSE);
  470. *pIndex = (int)m_pkts.Add(pNewPacket);
  471. // Return success
  472. CloseServiceHandle(hSCManager);
  473. CloseServiceHandle(hService);
  474. return ERROR_SUCCESS;
  475. }
  476. }
  477. CloseServiceHandle(hSCManager);
  478. }
  479. return GetLastError();
  480. }
  481. int CVirtualRegistry::NewSrvIdentity(TCHAR *szService,
  482. TCHAR *szIdentity,
  483. int *pIndex)
  484. {
  485. // Build a data packet and add it
  486. CDataPacket * pNewPacket = new CDataPacket(szService, szIdentity);
  487. ASSERT(pNewPacket);
  488. if (!pNewPacket)
  489. return ERROR_NOT_ENOUGH_MEMORY;
  490. *pIndex = (int)m_pkts.Add(pNewPacket);
  491. return ERROR_SUCCESS;
  492. }
  493. void CVirtualRegistry::ChgSrvIdentity(int nIndex,
  494. TCHAR *szIdentity)
  495. {
  496. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  497. pCdp -> ChgSrvIdentity(szIdentity);
  498. pCdp -> SetModified( TRUE);
  499. }
  500. void CVirtualRegistry::MarkForDeletion(int nIndex)
  501. {
  502. CDataPacket * pCdp = GetAt(nIndex);
  503. pCdp->MarkForDeletion(TRUE);
  504. pCdp->SetModified(TRUE);
  505. }
  506. void CVirtualRegistry::MarkHiveForDeletion(int nIndex)
  507. {
  508. CDataPacket * pCdp = GetAt(nIndex);
  509. pCdp->MarkHiveForDeletion(TRUE);
  510. pCdp->SetModified(TRUE);
  511. }
  512. CDataPacket * CVirtualRegistry::GetAt(int nIndex)
  513. {
  514. return m_pkts.ElementAt(nIndex);
  515. }
  516. void CVirtualRegistry::Remove(int nIndex)
  517. {
  518. CDataPacket * pCdp = GetAt(nIndex);
  519. // ronans - must always destroy even if packet has not been marked dirty
  520. if (pCdp)
  521. delete pCdp;
  522. // overwrite with empty data packet
  523. m_pkts.SetAt(nIndex, new CDataPacket);
  524. }
  525. void CVirtualRegistry::RemoveAll(void)
  526. {
  527. int nSize = (int)m_pkts.GetSize();
  528. for (int k = 0; k < nSize; k++)
  529. {
  530. Remove(k);
  531. CDataPacket * pCdp = GetAt(k);
  532. // remove empty packet
  533. if (pCdp)
  534. delete pCdp;
  535. }
  536. m_pkts.RemoveAll();
  537. }
  538. void CVirtualRegistry::Cancel(int nIndex)
  539. {
  540. int nSize = (int)m_pkts.GetSize();
  541. for (int k = nIndex; k < nSize; k++)
  542. {
  543. m_pkts.SetAt(nIndex, new CDataPacket);
  544. }
  545. }
  546. int CVirtualRegistry::Apply(int nIndex)
  547. {
  548. int err = ERROR_SUCCESS;
  549. int nSize = (int)m_pkts.GetSize();
  550. CDataPacket *pCdp = m_pkts.ElementAt(nIndex);
  551. if (pCdp->IsModified())
  552. err = pCdp -> Apply();
  553. return err;;
  554. }
  555. int CVirtualRegistry::ApplyAll(void)
  556. {
  557. int nSize = (int)m_pkts.GetSize();
  558. // Persist all non-empty data packets
  559. for (int k = 0; k < nSize; k++)
  560. {
  561. Apply(k);
  562. }
  563. return ERROR_SUCCESS;
  564. }
  565. int CVirtualRegistry::Ok(int nIndex)
  566. {
  567. return 0;
  568. }
  569. int CVirtualRegistry::SearchForRegEntry(HKEY hRoot,
  570. TCHAR *szKeyPath,
  571. TCHAR *szValueName)
  572. {
  573. int nSize = (int)m_pkts.GetSize();
  574. for (int k = 0; k < nSize; k++)
  575. {
  576. CDataPacket * pCdp = GetAt(k);
  577. if (pCdp -> IsIdentifiedBy(hRoot, szKeyPath, szValueName))
  578. return k;
  579. }
  580. return -1;
  581. }
  582. int CVirtualRegistry::SearchForLsaEntry(CLSID appid)
  583. {
  584. int nSize = (int)m_pkts.GetSize();
  585. for (int k = 0; k < nSize; k++)
  586. {
  587. CDataPacket * pCdp = GetAt(k);
  588. if (pCdp->m_tagType == Password &&
  589. g_util.IsEqualGuid(pCdp->pkt.pw.appid, appid))
  590. {
  591. return k;
  592. }
  593. }
  594. return -1;
  595. }
  596. int CVirtualRegistry::SearchForSrvEntry(TCHAR *szServiceName)
  597. {
  598. int nSize = (int)m_pkts.GetSize();
  599. for (int k = 0; k < nSize; k++)
  600. {
  601. CDataPacket * pCdp = GetAt(k);
  602. if (pCdp->m_tagType == ServiceIdentity &&
  603. (_tcscmp(pCdp->pkt.si.szServiceName, szServiceName)))
  604. {
  605. return k;
  606. }
  607. }
  608. return -1;
  609. }