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.

974 lines
23 KiB

  1. #include "stdinc.h"
  2. #include "fusionbuffer.h"
  3. #include "fusionhash.h"
  4. #include "csecuritymetadata.h"
  5. #include "strongname.h"
  6. #include "hashfile.h"
  7. typedef CCaseInsensitiveSimpleUnicodeStringTableIter<CFusionByteArray, CFileHashTableHelper> CFileHashTableIter;
  8. CMetaDataFileElement::CMetaDataFileElement()
  9. {
  10. }
  11. BOOL
  12. CMetaDataFileElement::WriteToRegistry( CRegKey & hkThisFileNode ) const
  13. {
  14. FN_PROLOG_WIN32
  15. const CFileHashTable &rfileHashTable = *this;
  16. CFileHashTableIter TableIterator( const_cast<CFileHashTable&>(rfileHashTable) );
  17. for ( TableIterator.Reset(); TableIterator.More(); TableIterator.Next() )
  18. {
  19. const PCWSTR &rcbuffAlgName = TableIterator.GetKey();
  20. const CFusionByteArray &rbbuffHashData = TableIterator.GetValue();
  21. IFW32FALSE_EXIT( hkThisFileNode.SetValue(
  22. rcbuffAlgName,
  23. REG_BINARY,
  24. rbbuffHashData.GetArrayPtr(),
  25. rbbuffHashData.GetSize() ) );
  26. }
  27. FN_EPILOG
  28. }
  29. BOOL
  30. CMetaDataFileElement::ReadFromRegistry( CRegKey& hkThisFileNode )
  31. {
  32. /*
  33. Here we take a few shortcuts. We know there is a list of "valid" hash
  34. alg name strings, so we only query for them in the registry. If anything
  35. else is in there, then too bad for them.
  36. */
  37. FN_PROLOG_WIN32
  38. DWORD dwIndex = 0;
  39. DWORD dwLastError;
  40. CFusionByteArray baHashValue;
  41. IFW32FALSE_EXIT(baHashValue.Win32Initialize());
  42. while ( true )
  43. {
  44. CSmallStringBuffer buffHashAlgName;
  45. BOOL fNoMoreItems;
  46. IFW32FALSE_EXIT( ::SxspEnumKnownHashTypes( dwIndex++, buffHashAlgName, fNoMoreItems ) );
  47. //
  48. // There's no more hash types to be enumerated...
  49. //
  50. if (fNoMoreItems)
  51. break;
  52. //
  53. // Get the hash data out of the registry
  54. //
  55. IFW32FALSE_EXIT(
  56. ::FusionpRegQueryBinaryValueEx(
  57. FUSIONP_REG_QUERY_BINARY_NO_FAIL_IF_NON_BINARY,
  58. hkThisFileNode,
  59. buffHashAlgName,
  60. baHashValue,
  61. dwLastError,
  62. 2,
  63. ERROR_PATH_NOT_FOUND,
  64. ERROR_FILE_NOT_FOUND));
  65. if (dwLastError == ERROR_SUCCESS)
  66. IFW32FALSE_EXIT(this->PutHashData(buffHashAlgName, baHashValue));
  67. }
  68. FN_EPILOG
  69. }
  70. BOOL
  71. CMetaDataFileElement::Initialize()
  72. {
  73. FN_PROLOG_WIN32
  74. IFW32FALSE_EXIT( CFileHashTable::Initialize() );
  75. FN_EPILOG
  76. }
  77. BOOL
  78. CMetaDataFileElement::GetHashDataForKind(
  79. IN const ALG_ID aid,
  80. OUT CFusionByteArray& arrHashData,
  81. OUT BOOL &bHadSuchData
  82. ) const
  83. {
  84. FN_PROLOG_WIN32
  85. CSmallStringBuffer buffAlgName;
  86. IFW32FALSE_EXIT( ::SxspHashStringFromAlg(aid, buffAlgName) );
  87. IFW32FALSE_EXIT( this->GetHashDataForKind( buffAlgName, arrHashData, bHadSuchData ) );
  88. FN_EPILOG
  89. }
  90. BOOL
  91. CMetaDataFileElement::GetHashDataForKind(
  92. IN const CBaseStringBuffer& buffId,
  93. OUT CFusionByteArray& arrHashData,
  94. OUT BOOL &bHadSuchData
  95. ) const
  96. {
  97. FN_PROLOG_WIN32
  98. CFusionByteArray *pFoundData = NULL;
  99. IFW32FALSE_EXIT( arrHashData.Win32Reset() );
  100. IFW32FALSE_EXIT( this->Find( buffId, pFoundData ) );
  101. if ( pFoundData != NULL )
  102. {
  103. IFW32FALSE_EXIT(pFoundData->Win32Clone(arrHashData));
  104. bHadSuchData = TRUE;
  105. }
  106. FN_EPILOG
  107. }
  108. BOOL
  109. CMetaDataFileElement::PutHashData(
  110. IN const ALG_ID aid,
  111. IN const CFusionByteArray& arrHashData
  112. )
  113. {
  114. FN_PROLOG_WIN32
  115. CSmallStringBuffer buffTempAlgId;
  116. IFW32FALSE_EXIT( ::SxspHashStringFromAlg( aid, buffTempAlgId ) );
  117. IFW32FALSE_EXIT( this->PutHashData( buffTempAlgId, arrHashData ) );
  118. FN_EPILOG
  119. }
  120. BOOL
  121. CMetaDataFileElement::PutHashData(
  122. IN const CBaseStringBuffer& buffId,
  123. IN const CFusionByteArray& arrHashData
  124. )
  125. {
  126. FN_PROLOG_WIN32
  127. CFusionByteArray *pStoredValue = NULL;
  128. BOOL bFound = FALSE;
  129. IFW32FALSE_EXIT( this->FindOrInsertIfNotPresent(
  130. buffId,
  131. arrHashData,
  132. &pStoredValue,
  133. &bFound ) );
  134. if ( bFound )
  135. {
  136. ASSERT( pStoredValue != NULL );
  137. IFW32FALSE_EXIT(arrHashData.Win32Clone(*pStoredValue));
  138. }
  139. FN_EPILOG
  140. }
  141. BOOL
  142. CSecurityMetaData::GetFileMetaData(
  143. const CBaseStringBuffer& buffFileName,
  144. const CMetaDataFileElement* &pElementData
  145. ) const
  146. {
  147. FN_PROLOG_WIN32
  148. IFW32FALSE_EXIT( m_fitFileDataTable.Find(buffFileName, pElementData) );
  149. FN_EPILOG
  150. }
  151. BOOL
  152. CSecurityMetaData::Initialize()
  153. {
  154. FN_PROLOG_WIN32
  155. IFW32FALSE_EXIT(m_cilCodebases.Win32Initialize());
  156. IFW32FALSE_EXIT(m_baSignerPublicKeyToken.Win32Initialize());
  157. IFW32FALSE_EXIT(m_baManifestSha1Hash.Win32Initialize());
  158. IFW32FALSE_EXIT(m_fitFileDataTable.Initialize());
  159. m_buffShortNameOnDisk.Clear();
  160. m_buffShortCatalogName.Clear();
  161. m_buffShortManifestName.Clear();
  162. FN_EPILOG
  163. }
  164. BOOL
  165. CSecurityMetaData::Initialize(
  166. const CSecurityMetaData &other
  167. )
  168. {
  169. FN_PROLOG_WIN32
  170. #define CLONEFUSIONARRAY( src, dst ) IFW32FALSE_EXIT( (src).Win32Clone( dst ) )
  171. #define CLONESTRING( dst, src ) IFW32FALSE_EXIT( (dst).Win32Assign( (src), (src).Cch() ) )
  172. IFW32FALSE_EXIT( this->Initialize() );
  173. CLONEFUSIONARRAY(other.m_cilCodebases, this->m_cilCodebases);
  174. CLONEFUSIONARRAY(other.m_baSignerPublicKeyToken, this->m_baSignerPublicKeyToken);
  175. CLONEFUSIONARRAY(other.m_baManifestSha1Hash, this->m_baManifestSha1Hash);
  176. CLONESTRING(this->m_buffShortNameOnDisk, other.m_buffShortNameOnDisk);
  177. CLONESTRING(this->m_buffTextualAssemblyIdentity, other.m_buffTextualAssemblyIdentity);
  178. CLONESTRING(this->m_buffShortManifestName, other.m_buffShortManifestName);
  179. CLONESTRING(this->m_buffShortCatalogName, other.m_buffShortCatalogName);
  180. //
  181. // Copy file information table over
  182. //
  183. {
  184. CFileInformationTableIter Iter(const_cast<CFileInformationTable&>(other.m_fitFileDataTable));
  185. for (Iter.Reset(); Iter.More(); Iter.Next())
  186. IFW32FALSE_EXIT( this->m_fitFileDataTable.Insert( Iter.GetKey(), Iter.GetValue() ) );
  187. }
  188. FN_EPILOG
  189. }
  190. BOOL
  191. CSecurityMetaData::AddFileMetaData(
  192. const CBaseStringBuffer &rbuffFileName,
  193. CMetaDataFileElement &rElementData,
  194. CSecurityMetaData::FileAdditionDisposition dispHowToAdd
  195. )
  196. {
  197. FN_PROLOG_WIN32
  198. if (dispHowToAdd == CSecurityMetaData::eFailIfAlreadyExists)
  199. {
  200. IFW32FALSE_EXIT(m_fitFileDataTable.Insert(rbuffFileName, rElementData));
  201. }
  202. else if (dispHowToAdd == CSecurityMetaData::eReplaceIfAlreadyExists)
  203. {
  204. bool fAlreadyExists;
  205. IFW32FALSE_EXIT_UNLESS(
  206. m_fitFileDataTable.Insert(rbuffFileName, rElementData),
  207. (::FusionpGetLastWin32Error() == ERROR_ALREADY_EXISTS),
  208. fAlreadyExists);
  209. if (fAlreadyExists)
  210. {
  211. IFW32FALSE_EXIT(m_fitFileDataTable.Remove(rbuffFileName));
  212. IFW32FALSE_EXIT(m_fitFileDataTable.Insert(rbuffFileName, rElementData));
  213. }
  214. }
  215. else if (dispHowToAdd == CSecurityMetaData::eMergeIfAlreadyExists)
  216. {
  217. IFW32FALSE_EXIT(
  218. m_fitFileDataTable.InsertOrUpdateIf<CSecurityMetaData>(
  219. rbuffFileName,
  220. rElementData,
  221. this,
  222. &CSecurityMetaData::MergeFileDataElement));
  223. }
  224. FN_EPILOG
  225. }
  226. BOOL
  227. CSecurityMetaData::SetSignerPublicKeyTokenBits(
  228. const CFusionByteArray & rcbuffSignerPublicKeyBits
  229. )
  230. {
  231. FN_PROLOG_WIN32
  232. IFW32FALSE_EXIT(rcbuffSignerPublicKeyBits.Win32Clone(this->m_baSignerPublicKeyToken));
  233. FN_EPILOG
  234. }
  235. BOOL
  236. CSecurityMetaData::QuickAddFileHash(
  237. const CBaseStringBuffer &rcbuffFileName,
  238. ALG_ID aidHashAlg,
  239. const CBaseStringBuffer &rcbuffHashValue
  240. )
  241. {
  242. FN_PROLOG_WIN32
  243. CMetaDataFileElement Element;
  244. CFusionByteArray baHashBytes;
  245. //
  246. // Build the element
  247. //
  248. IFW32FALSE_EXIT(Element.Initialize());
  249. IFW32FALSE_EXIT(::SxspHashStringToBytes(rcbuffHashValue, rcbuffHashValue.Cch(), baHashBytes));
  250. IFW32FALSE_EXIT(Element.PutHashData(aidHashAlg, baHashBytes));
  251. //
  252. // And merge it in
  253. //
  254. IFW32FALSE_EXIT(
  255. this->AddFileMetaData(
  256. rcbuffFileName,
  257. Element,
  258. eMergeIfAlreadyExists));
  259. FN_EPILOG
  260. }
  261. BOOL
  262. CSecurityMetaData::WritePrimaryAssemblyInfoIntoRegistryKey(
  263. ULONG Flags,
  264. const CRegKey &rhkRegistryNode
  265. ) const
  266. {
  267. FN_PROLOG_WIN32
  268. CRegKey hkFilesKey;
  269. CRegKey hkCodebases;
  270. ::FusionpDbgPrintEx(
  271. FUSION_DBG_LEVEL_INSTALLATION,
  272. "SXS: %s - starting\n",
  273. __FUNCTION__);
  274. PARAMETER_CHECK((Flags & ~(SXSP_WRITE_PRIMARY_ASSEMBLY_INFO_INTO_REGISTRY_KEY_FLAG_REFRESH)) == 0);
  275. IFW32FALSE_EXIT(
  276. rhkRegistryNode.SetValue(
  277. CSMD_TOPLEVEL_IDENTITY,
  278. this->GetTextualIdentity()));
  279. IFW32FALSE_EXIT( rhkRegistryNode.SetValue(
  280. CSMD_TOPLEVEL_CATALOG,
  281. static_cast<DWORD>(1)));
  282. IFW32FALSE_EXIT( rhkRegistryNode.SetValue(
  283. CSMD_TOPLEVEL_MANIFESTHASH,
  284. REG_BINARY,
  285. this->m_baManifestSha1Hash.GetArrayPtr(),
  286. this->m_baManifestSha1Hash.GetSize() ) );
  287. IFW32FALSE_EXIT(
  288. rhkRegistryNode.OpenOrCreateSubKey(
  289. hkFilesKey,
  290. CSMD_TOPLEVEL_FILES,
  291. KEY_WRITE));
  292. IFW32FALSE_EXIT(this->WriteFilesIntoKey(hkFilesKey));
  293. //
  294. // Write keys into this codebase node
  295. //
  296. if ((Flags & SXSP_WRITE_PRIMARY_ASSEMBLY_INFO_INTO_REGISTRY_KEY_FLAG_REFRESH) == 0)
  297. {
  298. IFW32FALSE_EXIT(
  299. rhkRegistryNode.OpenOrCreateSubKey(
  300. hkCodebases,
  301. CSMD_TOPLEVEL_CODEBASES,
  302. KEY_WRITE));
  303. for (ULONG ulI = 0; ulI < this->m_cilCodebases.GetSize(); ulI++)
  304. {
  305. CRegKey hkSingleCodebaseKey;
  306. const CCodebaseInformation &rcCodebase = m_cilCodebases[ulI];
  307. // Don't attempt to write blank (Darwin) referenced codebases to the
  308. // registry.
  309. if ( rcCodebase.GetReference().Cch() == 0 )
  310. continue;
  311. IFW32FALSE_EXIT(
  312. hkCodebases.OpenOrCreateSubKey(
  313. hkSingleCodebaseKey,
  314. rcCodebase.GetReference(),
  315. KEY_WRITE));
  316. IFW32FALSE_EXIT(rcCodebase.WriteToRegistryKey(hkSingleCodebaseKey));
  317. }
  318. }
  319. #if DBG
  320. else
  321. {
  322. ::FusionpDbgPrintEx(
  323. FUSION_DBG_LEVEL_WFP | FUSION_DBG_LEVEL_INSTALLATION,
  324. "SXS.DLL: %s - recovery, not writing codebase and codebase prompt\n",
  325. __FUNCTION__);
  326. }
  327. #endif
  328. FN_EPILOG
  329. }
  330. BOOL
  331. CSecurityMetaData::WriteSecondaryAssemblyInfoIntoRegistryKey(
  332. const CRegKey &rhkRegistryNode
  333. ) const
  334. {
  335. FN_PROLOG_WIN32
  336. IFW32FALSE_EXIT(rhkRegistryNode.SetValue(CSMD_TOPLEVEL_SHORTNAME, this->GetInstalledDirShortName()));
  337. IFW32FALSE_EXIT(rhkRegistryNode.SetValue(CSMD_TOPLEVEL_SHORTCATALOG, this->GetShortCatalogPath()));
  338. IFW32FALSE_EXIT(rhkRegistryNode.SetValue(CSMD_TOPLEVEL_SHORTMANIFEST, this->GetShortManifestPath()));
  339. IFW32FALSE_EXIT(
  340. rhkRegistryNode.SetValue(
  341. CSMD_TOPLEVEL_PUBLIC_KEY_TOKEN,
  342. REG_BINARY,
  343. this->m_baSignerPublicKeyToken.GetArrayPtr(),
  344. this->m_baSignerPublicKeyToken.GetSize()));
  345. FN_EPILOG
  346. }
  347. BOOL
  348. CSecurityMetaData::WriteFilesIntoKey(
  349. CRegKey & rhkFilesKey
  350. ) const
  351. {
  352. FN_PROLOG_WIN32
  353. CFileInformationTableIter FilesIterator( const_cast<CFileInformationTable&>(m_fitFileDataTable) );
  354. ULONG uliIndex = 0;
  355. for ( FilesIterator.Reset(); FilesIterator.More(); FilesIterator.Next() )
  356. {
  357. const PCWSTR pcwszFileName = FilesIterator.GetKey();
  358. const CMetaDataFileElement& rcmdfeFileData = FilesIterator.GetValue();
  359. CRegKey hkFileSubKey;
  360. CSmallStringBuffer buffKeySubname;
  361. //
  362. // The trick here is that you can't simply create the subkey off this node,
  363. // as it might be "foo\bar\bas\zip.ding".
  364. //
  365. IFW32FALSE_EXIT( buffKeySubname.Win32Format( L"%ld", uliIndex++ ) );
  366. IFW32FALSE_EXIT( rhkFilesKey.OpenOrCreateSubKey(
  367. hkFileSubKey,
  368. buffKeySubname,
  369. KEY_ALL_ACCESS ) );
  370. //
  371. // So instead, we set the default value of the key to be the name of the file.
  372. //
  373. IFW32FALSE_EXIT( buffKeySubname.Win32Assign( pcwszFileName, lstrlenW(pcwszFileName) ) );
  374. IFW32FALSE_EXIT( hkFileSubKey.SetValue(
  375. NULL,
  376. buffKeySubname ) );
  377. IFW32FALSE_EXIT( rcmdfeFileData.WriteToRegistry( hkFileSubKey ) );
  378. }
  379. FN_EPILOG
  380. }
  381. /*
  382. [name of full assembly]
  383. v : Codebase = [meta-url] <string>
  384. v : Catalog = 1 <dword>
  385. v : Shortname = [shortname generated during installation] <string>
  386. v : ManifestHash = [...] <binary>
  387. v : PublicKeyToken = [...] <binary>
  388. k : Files
  389. k : [Filename]
  390. v : SHA1 = [...] <binary>
  391. v : MD5 = [...] <binary>
  392. k : [Filename]
  393. ...
  394. k : Codebases
  395. k : [reference-string]
  396. v : PromptString = [...] <string>
  397. v : Url = [meta-url] <string>
  398. */
  399. BOOL
  400. CSecurityMetaData::LoadFromRegistryKey(
  401. const CRegKey &rhkRegistryNode
  402. )
  403. {
  404. FN_PROLOG_WIN32
  405. CRegKey hkTempStuff;
  406. DWORD dwHasCatalog;
  407. IFW32FALSE_EXIT(
  408. ::FusionpRegQueryDwordValueEx(
  409. 0,
  410. rhkRegistryNode,
  411. CSMD_TOPLEVEL_CATALOG,
  412. &dwHasCatalog,
  413. 0));
  414. ASSERT(dwHasCatalog != 0);
  415. IFW32FALSE_EXIT(
  416. ::FusionpRegQuerySzValueEx(
  417. FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
  418. rhkRegistryNode,
  419. CSMD_TOPLEVEL_IDENTITY,
  420. this->m_buffTextualAssemblyIdentity));
  421. IFW32FALSE_EXIT(
  422. ::FusionpRegQuerySzValueEx(
  423. FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
  424. rhkRegistryNode,
  425. CSMD_TOPLEVEL_SHORTNAME,
  426. this->m_buffShortNameOnDisk));
  427. IFW32FALSE_EXIT(
  428. ::FusionpRegQuerySzValueEx(
  429. FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
  430. rhkRegistryNode,
  431. CSMD_TOPLEVEL_SHORTCATALOG,
  432. this->m_buffShortCatalogName));
  433. IFW32FALSE_EXIT(
  434. ::FusionpRegQuerySzValueEx(
  435. FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
  436. rhkRegistryNode,
  437. CSMD_TOPLEVEL_SHORTMANIFEST,
  438. this->m_buffShortManifestName));
  439. IFW32FALSE_EXIT(
  440. ::FusionpRegQueryBinaryValueEx(
  441. 0,
  442. rhkRegistryNode,
  443. CSMD_TOPLEVEL_MANIFESTHASH,
  444. this->m_baManifestSha1Hash));
  445. IFW32FALSE_EXIT(
  446. ::FusionpRegQueryBinaryValueEx(
  447. 0,
  448. rhkRegistryNode,
  449. CSMD_TOPLEVEL_PUBLIC_KEY_TOKEN,
  450. this->m_baSignerPublicKeyToken));
  451. IFW32FALSE_EXIT(rhkRegistryNode.OpenSubKey(hkTempStuff, CSMD_TOPLEVEL_CODEBASES, KEY_READ));
  452. if (hkTempStuff != CRegKey::GetInvalidValue())
  453. {
  454. IFW32FALSE_EXIT(this->LoadCodebasesFromKey(hkTempStuff));
  455. IFW32FALSE_EXIT(hkTempStuff.Win32Close());
  456. }
  457. IFW32FALSE_EXIT( rhkRegistryNode.OpenSubKey(hkTempStuff, CSMD_TOPLEVEL_FILES, KEY_READ));
  458. if (hkTempStuff != CRegKey::GetInvalidValue())
  459. {
  460. IFW32FALSE_EXIT(this->LoadFilesFromKey(hkTempStuff));
  461. IFW32FALSE_EXIT(hkTempStuff.Win32Close());
  462. }
  463. FN_EPILOG
  464. }
  465. BOOL
  466. CSecurityMetaData::LoadFilesFromKey(
  467. CRegKey &hkTopLevelFileKey
  468. )
  469. {
  470. FN_PROLOG_WIN32
  471. DWORD dwIndex = 0;
  472. while ( true )
  473. {
  474. CSmallStringBuffer buffNextKeyName;
  475. BOOL fNoMoreItems;
  476. CRegKey hkIterator;
  477. IFW32FALSE_EXIT(hkTopLevelFileKey.EnumKey(
  478. dwIndex++,
  479. buffNextKeyName,
  480. NULL,
  481. &fNoMoreItems ) );
  482. if ( fNoMoreItems )
  483. {
  484. break;
  485. }
  486. IFW32FALSE_EXIT( hkTopLevelFileKey.OpenSubKey(
  487. hkIterator,
  488. buffNextKeyName,
  489. KEY_READ ) );
  490. if ( hkIterator != CRegKey::GetInvalidValue() )
  491. {
  492. CMetaDataFileElement SingleFileElement;
  493. IFW32FALSE_EXIT( SingleFileElement.Initialize() );
  494. IFW32FALSE_EXIT( SingleFileElement.ReadFromRegistry( hkIterator ) );
  495. //
  496. // Now read the name of the file from the default
  497. //
  498. IFW32FALSE_EXIT(
  499. ::FusionpRegQuerySzValueEx(
  500. 0,
  501. hkIterator,
  502. NULL,
  503. buffNextKeyName));
  504. IFW32FALSE_EXIT(this->AddFileMetaData( buffNextKeyName, SingleFileElement));
  505. }
  506. }
  507. FN_EPILOG
  508. }
  509. BOOL
  510. CSecurityMetaData::LoadCodebasesFromKey(
  511. IN CRegKey& hkCodebaseSubkey
  512. )
  513. {
  514. FN_PROLOG_WIN32
  515. DWORD dwMaxKeyLength;
  516. CStringBuffer buffKeyNameTemp;
  517. DWORD dwNextIndex = 0;
  518. //
  519. // Find out how big the largest subkey string is, then reset our iterator temp
  520. // to be that big.
  521. //
  522. IFW32FALSE_EXIT(hkCodebaseSubkey.LargestSubItemLengths(&dwMaxKeyLength, NULL));
  523. IFW32FALSE_EXIT(buffKeyNameTemp.Win32ResizeBuffer(dwMaxKeyLength + 1, eDoNotPreserveBufferContents));
  524. //
  525. // Codebases are stored as subkeys and then values under them.
  526. //
  527. for (;;)
  528. {
  529. BOOL fNoMoreItems = FALSE;
  530. IFW32FALSE_EXIT(
  531. hkCodebaseSubkey.EnumKey(
  532. dwNextIndex++,
  533. buffKeyNameTemp,
  534. NULL,
  535. &fNoMoreItems));
  536. if (fNoMoreItems)
  537. break;
  538. CRegKey hkSingleCodebaseKey;
  539. IFW32FALSE_EXIT(
  540. hkCodebaseSubkey.OpenSubKey(
  541. hkSingleCodebaseKey,
  542. buffKeyNameTemp,
  543. KEY_READ));
  544. if (hkSingleCodebaseKey == CRegKey::GetInvalidValue())
  545. continue;
  546. CCodebaseInformation Codebase;
  547. IFW32FALSE_EXIT(Codebase.Initialize());
  548. IFW32FALSE_EXIT(Codebase.SetReference(buffKeyNameTemp));
  549. #if DBG
  550. ::FusionpDbgPrintEx(
  551. FUSION_DBG_LEVEL_INSTALLATION,
  552. "SXS: %s - read codebase %ls %ls\n",
  553. __FUNCTION__,
  554. static_cast<PCWSTR>(buffKeyNameTemp),
  555. static_cast<PCWSTR>(Codebase.GetCodebase())
  556. );
  557. #endif
  558. IFW32FALSE_EXIT(Codebase.ReadFromRegistryKey(hkSingleCodebaseKey));
  559. IFW32FALSE_EXIT(this->m_cilCodebases.Win32Append(Codebase));
  560. }
  561. FN_EPILOG
  562. }
  563. BOOL
  564. CMetaDataFileElement::Initialize(
  565. const CMetaDataFileElement &other
  566. )
  567. {
  568. FN_PROLOG_WIN32
  569. // The lack of a const iterator here is disturbing, so I have to const_cast
  570. // the metadatafileelement
  571. CFileHashTableIter InputTableIter( const_cast<CMetaDataFileElement&>(other) );
  572. //
  573. // Why is this not a bool??
  574. //
  575. this->ClearNoCallback();
  576. for(InputTableIter.Reset(); InputTableIter.More(); InputTableIter.Next())
  577. {
  578. IFW32FALSE_EXIT( this->Insert( InputTableIter.GetKey(), InputTableIter.GetValue() ) );
  579. }
  580. FN_EPILOG
  581. }
  582. BOOL
  583. CFileInformationTableHelper::UpdateValue(
  584. const CMetaDataFileElement &vin,
  585. CMetaDataFileElement &stored
  586. )
  587. {
  588. FN_PROLOG_WIN32
  589. ASSERT( FALSE );
  590. FN_EPILOG
  591. }
  592. BOOL
  593. CCodebaseInformation::Initialize()
  594. {
  595. m_Codebase.Clear();
  596. m_PromptText.Clear();
  597. m_Reference.Clear();
  598. return TRUE;
  599. }
  600. BOOL
  601. CCodebaseInformation::Initialize(
  602. const CCodebaseInformation &other
  603. )
  604. {
  605. FN_PROLOG_WIN32
  606. IFW32FALSE_EXIT(this->SetCodebase(other.GetCodebase()));
  607. IFW32FALSE_EXIT(this->SetPromptText(other.GetPromptText()));
  608. IFW32FALSE_EXIT(this->SetReference(other.GetReference()));
  609. this->m_Type = other.m_Type;
  610. FN_EPILOG
  611. }
  612. BOOL
  613. CCodebaseInformation::WriteToRegistryKey(
  614. const CRegKey &rhkCodebaseKey
  615. ) const
  616. {
  617. FN_PROLOG_WIN32
  618. if (m_PromptText.Cch() != 0)
  619. {
  620. IFW32FALSE_EXIT(
  621. rhkCodebaseKey.SetValue(
  622. CSMD_CODEBASES_PROMPTSTRING,
  623. this->m_PromptText));
  624. }
  625. IFW32FALSE_EXIT(
  626. rhkCodebaseKey.SetValue(
  627. CSMD_CODEBASES_URL,
  628. this->m_Codebase));
  629. FN_EPILOG
  630. }
  631. BOOL
  632. CCodebaseInformation::ReadFromRegistryKey(
  633. const CRegKey &rhkSingleCodebaseKey
  634. )
  635. {
  636. FN_PROLOG_WIN32
  637. //
  638. // Missing prompt is OK
  639. //
  640. IFW32FALSE_EXIT(
  641. ::FusionpRegQuerySzValueEx(
  642. FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
  643. rhkSingleCodebaseKey,
  644. CSMD_CODEBASES_PROMPTSTRING,
  645. m_PromptText));
  646. //
  647. // We don't want to fail just because someone messed up the registry...
  648. //
  649. IFW32FALSE_EXIT(
  650. ::FusionpRegQuerySzValueEx(
  651. FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
  652. rhkSingleCodebaseKey,
  653. CSMD_CODEBASES_URL,
  654. m_Codebase));
  655. FN_EPILOG
  656. }
  657. BOOL
  658. CCodebaseInformationList::FindCodebase(
  659. const CBaseStringBuffer &rbuffReference,
  660. CCodebaseInformation *&rpCodebaseInformation
  661. )
  662. {
  663. FN_PROLOG_WIN32
  664. bool fMatches = false;
  665. SIZE_T i;
  666. rpCodebaseInformation = NULL;
  667. for (i=0; i < m_cElements; i++)
  668. {
  669. IFW32FALSE_EXIT(m_prgtElements[i].GetReference().Win32Equals(rbuffReference, fMatches, true));
  670. if (fMatches)
  671. break;
  672. }
  673. if (fMatches)
  674. {
  675. INTERNAL_ERROR_CHECK(i < m_cElements);
  676. rpCodebaseInformation = &m_prgtElements[i];
  677. }
  678. FN_EPILOG
  679. }
  680. BOOL
  681. CCodebaseInformationList::RemoveCodebase(
  682. const CBaseStringBuffer &rbuffReference,
  683. bool &rfRemoved
  684. )
  685. {
  686. FN_PROLOG_WIN32
  687. bool fMatches = false;
  688. SIZE_T i;
  689. rfRemoved = false;
  690. for (i=0; i < m_cElements; i++)
  691. {
  692. IFW32FALSE_EXIT(m_prgtElements[i].GetReference().Win32Equals(rbuffReference, fMatches, true));
  693. if (fMatches)
  694. {
  695. IFW32FALSE_EXIT(this->Win32Remove(i));
  696. rfRemoved = true;
  697. break;
  698. }
  699. }
  700. FN_EPILOG
  701. }
  702. BOOL
  703. CSecurityMetaData::Initialize(
  704. const CBaseStringBuffer &rcbuffTextualIdentity
  705. )
  706. {
  707. FN_PROLOG_WIN32
  708. IFW32FALSE_EXIT( this->Initialize() );
  709. ASSERT( FALSE );
  710. FN_EPILOG
  711. }
  712. BOOL
  713. SxspValidateAllFileHashes(
  714. IN const CMetaDataFileElement &rmdfeElement,
  715. IN const CBaseStringBuffer &rbuffFileName,
  716. OUT HashValidateResult &rResult
  717. )
  718. {
  719. FN_PROLOG_WIN32
  720. DWORD dwIndex = 0;
  721. CSmallStringBuffer buffHashName;
  722. BOOL fAllHashesMatch = TRUE;
  723. HashValidateResult Results;
  724. CFusionByteArray baFileHashData;
  725. ALG_ID aid;
  726. rResult = HashValidate_OtherProblems;
  727. while ( true && fAllHashesMatch )
  728. {
  729. BOOL fTemp;
  730. IFW32FALSE_EXIT(
  731. ::SxspEnumKnownHashTypes(
  732. dwIndex++,
  733. buffHashName,
  734. fTemp));
  735. if (fTemp)
  736. break;
  737. IFW32FALSE_EXIT( SxspHashAlgFromString( buffHashName, aid ) );
  738. //
  739. // Did the file element have this type of hash data in it?
  740. //
  741. IFW32FALSE_EXIT( rmdfeElement.GetHashDataForKind(
  742. buffHashName,
  743. baFileHashData,
  744. fTemp ));
  745. if ( !fTemp )
  746. {
  747. continue;
  748. }
  749. IFW32FALSE_EXIT( ::SxspVerifyFileHash(
  750. SVFH_RETRY_LOGIC_SIMPLE,
  751. rbuffFileName,
  752. baFileHashData,
  753. aid,
  754. Results ) );
  755. if ( Results != HashValidate_Matches )
  756. {
  757. fAllHashesMatch = FALSE;
  758. }
  759. }
  760. if ( fAllHashesMatch )
  761. {
  762. rResult = HashValidate_Matches;
  763. }
  764. FN_EPILOG
  765. }
  766. BOOL
  767. CSecurityMetaData::RemoveCodebase(
  768. const CBaseStringBuffer &rbuffReference,
  769. bool &rfRemoved
  770. )
  771. {
  772. return m_cilCodebases.RemoveCodebase(rbuffReference, rfRemoved);
  773. }