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.

460 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: StoreRSOP.cpp
  7. //
  8. // Contents: Implementation of CCertStoreRSOP
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <gpedit.h>
  13. #include "cookie.h"
  14. #include "StoreRSOP.h"
  15. #include "certifct.h"
  16. USE_HANDLE_MACROS("CERTMGR(StoreRSOP.cpp)")
  17. #ifdef _DEBUG
  18. #ifndef ALPHA
  19. #define new DEBUG_NEW
  20. #endif
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. extern GUID g_guidExtension;
  25. extern GUID g_guidRegExt;
  26. extern GUID g_guidSnapin;
  27. ///////////////////////////////////////////////////////////////////////////////
  28. ///////////////////////////////////////////////////////////////////////////////
  29. CCertStoreRSOP::CCertStoreRSOP (
  30. DWORD dwFlags,
  31. LPCWSTR lpcszMachineName,
  32. LPCWSTR objectName,
  33. const CString & pcszLogStoreName,
  34. const CString & pcszPhysStoreName,
  35. CRSOPObjectArray& rsopObjectArray,
  36. const GUID& compDataGUID,
  37. IConsole* pConsole)
  38. : CCertStore (CERTMGR_LOG_STORE_RSOP,
  39. CERT_STORE_PROV_SYSTEM, dwFlags, lpcszMachineName, objectName,
  40. pcszLogStoreName, pcszPhysStoreName,
  41. StoreNameToType (pcszLogStoreName),
  42. 0,
  43. pConsole),
  44. m_fIsComputerType (false),
  45. m_fIsNullEFSPolicy (true) // assume NULL policy until proven otherwise
  46. {
  47. _TRACE (1, L"Entering CCertStoreRSOP::CCertStoreRSOP - %s\n",
  48. (LPCWSTR) pcszLogStoreName);
  49. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  50. if ( ::IsEqualGUID (compDataGUID, NODEID_User) )
  51. {
  52. m_fIsComputerType = false;
  53. m_dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
  54. }
  55. else if ( ::IsEqualGUID (compDataGUID, NODEID_Machine) )
  56. {
  57. m_fIsComputerType = true;
  58. m_dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
  59. }
  60. else
  61. ASSERT (0);
  62. int nIndex = 0;
  63. INT_PTR nUpperBound = rsopObjectArray.GetUpperBound ();
  64. bool bFound = false;
  65. CString storePath = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
  66. storePath += L"\\";
  67. storePath += m_pcszStoreName;
  68. size_t nStoreLen = storePath.GetLength ();
  69. while ( nUpperBound >= nIndex )
  70. {
  71. CRSOPObject* pObject = rsopObjectArray.GetAt (nIndex);
  72. if ( pObject )
  73. {
  74. // Only add if
  75. // 1. Precedence is 1
  76. // 2. The object belongs to this store
  77. // 3. The valueName is not empty
  78. if ( 1 == pObject->GetPrecedence () )
  79. {
  80. // Consider only entries from this store
  81. if ( !wcsncmp (storePath, pObject->GetRegistryKey (), nStoreLen) )
  82. {
  83. bFound = true;
  84. if ( !pObject->GetValueName ().IsEmpty () )
  85. {
  86. CRSOPObject* pNewObject = new CRSOPObject (*pObject);
  87. if ( pNewObject )
  88. m_rsopObjectArray.Add (pNewObject);
  89. }
  90. }
  91. else if ( bFound )
  92. {
  93. // Since the list is sorted, and we've already found the
  94. // desired RSOP objects and no longer are finding them,
  95. // there aren't any more. We can optimize and break here.
  96. break;
  97. }
  98. }
  99. }
  100. else
  101. break;
  102. nIndex++;
  103. }
  104. _TRACE (-1, L"Leaving CCertStoreRSOP::CCertStoreRSOP - %s\n",
  105. (LPCWSTR) pcszLogStoreName);
  106. }
  107. CCertStoreRSOP::~CCertStoreRSOP ()
  108. {
  109. _TRACE (1, L"Entering CCertStoreRSOP::~CCertStoreRSOP - %s\n",
  110. (LPCWSTR) m_pcszStoreName);
  111. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  112. INT_PTR nUpperBound = m_rsopObjectArray.GetUpperBound ();
  113. int nIndex = 0;
  114. while (nUpperBound >= nIndex)
  115. {
  116. CRSOPObject* pObject = m_rsopObjectArray.GetAt (nIndex);
  117. if ( pObject )
  118. {
  119. delete pObject;
  120. }
  121. else
  122. break;
  123. nIndex++;
  124. }
  125. _TRACE (-1, L"Leaving CCertStoreRSOP::~CCertStoreRSOP - %s\n",
  126. (LPCWSTR) m_pcszStoreName);
  127. }
  128. HCERTSTORE CCertStoreRSOP::GetStoreHandle (BOOL bSilent /*= FALSE*/, HRESULT* phr /* = 0*/)
  129. {
  130. _TRACE (1, L"Entering CCertStoreRSOP::GetStoreHandle - %s\n",
  131. (LPCWSTR) m_pcszStoreName);
  132. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  133. if ( !m_hCertStore )
  134. {
  135. DWORD dwErr = 0;
  136. //open a generic memory store
  137. m_hCertStore = ::CertOpenStore (CERT_STORE_PROV_MEMORY,
  138. 0, NULL,
  139. CERT_STORE_SET_LOCALIZED_NAME_FLAG | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  140. NULL);
  141. if ( m_hCertStore )
  142. {
  143. // Certificates, CTLs and other objects are either stored integrally in a
  144. // value called "Blob" or broken up into multiple parts. In this case, we'll
  145. // first see "BlobCount", which tells us how many parts there are, then
  146. // "BlobLength" which tells us the total byte length and finally
  147. // "Blob0", "Blob1", etc. to "Blob<BlobCount-1>"
  148. // Check for Certificates
  149. GetBlobs ();
  150. }
  151. else
  152. {
  153. dwErr = GetLastError ();
  154. if ( phr )
  155. *phr = HRESULT_FROM_WIN32 (dwErr);
  156. _TRACE (0, L"CertOpenStore (CERT_STORE_PROV_MEMORY) failed: 0x%x\n", dwErr);
  157. }
  158. if ( !m_hCertStore && !m_bUnableToOpenMsgDisplayed
  159. && !bSilent &&
  160. (USERDS_STORE != GetStoreType ()) )
  161. {
  162. m_bUnableToOpenMsgDisplayed = true;
  163. CString caption;
  164. CString text;
  165. int iRetVal = 0;
  166. VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
  167. text.FormatMessage (IDS_UNABLE_TO_OPEN_STORE, GetStoreName (),
  168. GetSystemMessage (dwErr));
  169. if ( m_pConsole )
  170. m_pConsole->MessageBox (text, caption, MB_OK, &iRetVal);
  171. }
  172. }
  173. _TRACE (-1, L"Leaving CCertStoreRSOP::GetStoreHandle - %s\n",
  174. (LPCWSTR) m_pcszStoreName);
  175. return m_hCertStore;
  176. }
  177. HRESULT CCertStoreRSOP::GetBlobs ()
  178. {
  179. HRESULT hr = S_OK;
  180. INT_PTR nUpperBound = m_rsopObjectArray.GetUpperBound ();
  181. int nIndex = 0;
  182. while (nUpperBound >= nIndex)
  183. {
  184. CRSOPObject* pObject = m_rsopObjectArray.GetAt (nIndex);
  185. if ( pObject )
  186. {
  187. if ( STR_BLOB == pObject->GetValueName () )
  188. {
  189. // If this is a single, serialized cert, get it and
  190. // add it to the store
  191. BYTE* pByte = pObject->GetBlob ();
  192. ASSERT (pByte);
  193. if ( pByte )
  194. {
  195. if ( !CertAddSerializedElementToStore (
  196. m_hCertStore,
  197. pByte,
  198. (DWORD) pObject->GetBlobLength (),
  199. CERT_STORE_ADD_ALWAYS,
  200. 0,
  201. CERT_STORE_ALL_CONTEXT_FLAG,
  202. NULL,
  203. NULL) )
  204. {
  205. _TRACE (0, L"CertAddSerializedElementToStore () failed: 0x%x\n",
  206. GetLastError ());
  207. }
  208. }
  209. }
  210. else if ( STR_BLOBCOUNT == pObject->GetValueName () )
  211. {
  212. CString szBaseRegKey = pObject->GetRegistryKey ();
  213. DWORD dwBlobCount = pObject->GetDWORDValue ();
  214. if ( dwBlobCount > 0 )
  215. {
  216. nIndex++;
  217. if (nUpperBound >= nIndex)
  218. {
  219. // Get the blob length
  220. pObject = m_rsopObjectArray.GetAt (nIndex);
  221. if ( pObject )
  222. {
  223. if ( STR_BLOBLENGTH == pObject->GetValueName () )
  224. {
  225. DWORD dwBlobLength = pObject->GetDWORDValue ();
  226. if ( dwBlobLength )
  227. {
  228. BYTE* pbyLob = new BYTE[dwBlobLength];
  229. if ( pbyLob )
  230. {
  231. size_t nTotalBlobLength = 0;
  232. BYTE* pbyLobPtr = pbyLob;
  233. for (DWORD dwBlob = 0; dwBlob < dwBlobCount; dwBlob++)
  234. {
  235. nIndex++;
  236. if ( nUpperBound >= nIndex )
  237. {
  238. WCHAR szName[16];
  239. wsprintf (szName, L"%s%d", STR_BLOB, dwBlob);
  240. CString szRegKey = szBaseRegKey;
  241. szRegKey += L"\\";
  242. szRegKey += szName;
  243. pObject = m_rsopObjectArray.GetAt (nIndex);
  244. if ( pObject )
  245. {
  246. if ( szRegKey == pObject->GetRegistryKey () &&
  247. STR_BLOB == pObject->GetValueName () )
  248. {
  249. BYTE* pByte = pObject->GetBlob ();
  250. if ( pByte )
  251. {
  252. memcpy (pbyLobPtr, pByte, pObject->GetBlobLength ());
  253. pbyLobPtr += pObject->GetBlobLength ();
  254. nTotalBlobLength += pObject->GetBlobLength ();
  255. }
  256. else
  257. {
  258. ASSERT (0);
  259. hr = E_UNEXPECTED;
  260. break;
  261. }
  262. }
  263. else
  264. {
  265. ASSERT (0);
  266. hr = E_UNEXPECTED;
  267. break;
  268. }
  269. }
  270. else
  271. {
  272. ASSERT (0);
  273. hr = E_UNEXPECTED;
  274. break;
  275. }
  276. }
  277. else
  278. {
  279. ASSERT (0);
  280. hr = E_UNEXPECTED;
  281. break;
  282. }
  283. }
  284. if ( SUCCEEDED (hr) && nTotalBlobLength == (size_t) dwBlobLength )
  285. {
  286. if ( !CertAddSerializedElementToStore (
  287. m_hCertStore,
  288. pbyLob,
  289. dwBlobLength,
  290. CERT_STORE_ADD_ALWAYS,
  291. 0,
  292. CERT_STORE_ALL_CONTEXT_FLAG,
  293. NULL,
  294. NULL) )
  295. {
  296. _TRACE (0, L"CertAddSerializedElementToStore () failed: 0x%x\n",
  297. GetLastError ());
  298. }
  299. }
  300. delete [] pbyLob;
  301. }
  302. else
  303. {
  304. hr = E_OUTOFMEMORY;
  305. break;
  306. }
  307. }
  308. else
  309. {
  310. ASSERT (0);
  311. hr = E_UNEXPECTED;
  312. break;
  313. }
  314. }
  315. else
  316. {
  317. ASSERT (0);
  318. hr = E_UNEXPECTED;
  319. break;
  320. }
  321. }
  322. else
  323. {
  324. ASSERT (0);
  325. hr = E_UNEXPECTED;
  326. break;
  327. }
  328. }
  329. else
  330. {
  331. ASSERT (0);
  332. hr = E_UNEXPECTED;
  333. break;
  334. }
  335. }
  336. }
  337. }
  338. else
  339. break;
  340. nIndex++;
  341. }
  342. return hr;
  343. }
  344. bool CCertStoreRSOP::CanContain(CertificateManagerObjectType nodeType)
  345. {
  346. _TRACE (1, L"Entering CCertStoreRSOP::CanContain - %s\n",
  347. (LPCWSTR) m_pcszStoreName);
  348. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  349. bool bCanContain = false;
  350. switch (nodeType)
  351. {
  352. case CERTMGR_CERTIFICATE:
  353. if ( ROOT_STORE == GetStoreType () ||
  354. EFS_STORE == GetStoreType () )
  355. {
  356. bCanContain = true;
  357. }
  358. break;
  359. case CERTMGR_CTL:
  360. if ( TRUST_STORE == GetStoreType () )
  361. {
  362. bCanContain = true;
  363. }
  364. break;
  365. default:
  366. break;
  367. }
  368. _TRACE (-1, L"Leaving CCertStoreRSOP::CanContain - %s\n",
  369. (LPCWSTR) m_pcszStoreName);
  370. return bCanContain;
  371. }
  372. bool CCertStoreRSOP::IsMachineStore()
  373. {
  374. _TRACE (0, L"Entering and leaving CCertStoreRSOP::IsMachineStore - %s\n",
  375. (LPCWSTR) m_pcszStoreName);
  376. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  377. if (m_dwFlags & CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY)
  378. return true;
  379. else
  380. return false;
  381. }
  382. void CCertStoreRSOP::FinalCommit()
  383. {
  384. _TRACE (1, L"Entering CCertStoreRSOP::FinalCommit - %s\n",
  385. (LPCWSTR) m_pcszStoreName);
  386. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  387. // Called only from destructor
  388. // Cannot commit here for GPT: GPT has already freed all pertinent data
  389. _TRACE (-1, L"Leaving CCertStoreRSOP::FinalCommit - %s\n",
  390. (LPCWSTR) m_pcszStoreName);
  391. }
  392. bool CCertStoreRSOP::IsNullEFSPolicy()
  393. {
  394. _TRACE (1, L"Entering CCertStoreRSOP::IsNullEFSPolicy - %s\n",
  395. (LPCWSTR) m_pcszStoreName);
  396. GetStoreHandle (); // to initialize
  397. Close ();
  398. _TRACE (-1, L"Leaving CCertStoreRSOP::IsNullEFSPolicy - %s\n",
  399. (LPCWSTR) m_pcszStoreName);
  400. return m_fIsNullEFSPolicy;
  401. }
  402. void CCertStoreRSOP::AllowEmptyEFSPolicy()
  403. {
  404. _TRACE (1, L"Entering CCertStoreRSOP::AllowEmptyEFSPolicy - %s\n",
  405. (LPCWSTR) m_pcszStoreName);
  406. m_fIsNullEFSPolicy = false;
  407. _TRACE (-1, L"Leaving CCertStoreRSOP::AllowEmptyEFSPolicy - %s\n",
  408. (LPCWSTR) m_pcszStoreName);
  409. }
  410. PCCERT_CONTEXT CCertStoreRSOP::EnumCertificates (PCCERT_CONTEXT pPrevCertContext)
  411. {
  412. PCCERT_CONTEXT pCertContext = CCertStore::EnumCertificates (pPrevCertContext);
  413. if ( pCertContext )
  414. m_fIsNullEFSPolicy = false;
  415. return pCertContext;
  416. }