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
22 KiB

  1. #using <mscorlib.dll>
  2. #using "assm.netmodule"
  3. #include <stdio.h>
  4. #include <windows.h>
  5. #include <fusenet.h>
  6. #include <util.h>
  7. #include <shlwapi.h>
  8. #include <sxsapi.h>
  9. #include <wchar.h>
  10. #include "cor.h"
  11. using namespace System;
  12. using namespace Microsoft::Fusion::ADF;
  13. using System::Runtime::InteropServices::Marshal;
  14. #define ASM_MANIFEST_IMPORT_DEFAULT_ARRAY_SIZE 32
  15. #define MAX_PKT_LEN 33
  16. typedef HRESULT (*pfnGetAssemblyMDImport)(LPCWSTR szFileName, REFIID riid, LPVOID *ppv);
  17. typedef BOOL (*pfnStrongNameTokenFromPublicKey)(LPBYTE, DWORD, LPBYTE*, LPDWORD);
  18. typedef HRESULT (*pfnStrongNameErrorInfo)();
  19. typedef VOID (*pfnStrongNameFreeBuffer)(LPBYTE);
  20. //#pragma unmanaged
  21. pfnGetAssemblyMDImport g_pfnGetAssemblyMDImport = NULL;
  22. pfnStrongNameTokenFromPublicKey g_pfnStrongNameTokenFromPublicKey = NULL;
  23. pfnStrongNameErrorInfo g_pfnStrongNameErrorInfo = NULL;
  24. pfnStrongNameFreeBuffer g_pfnStrongNameFreeBuffer = NULL;
  25. //--------------------------------------------------------------------
  26. // BinToUnicodeHex
  27. //--------------------------------------------------------------------
  28. HRESULT BinToUnicodeHex(LPBYTE pSrc, UINT cSrc, LPWSTR pDst)
  29. {
  30. UINT x;
  31. UINT y;
  32. #define TOHEX(a) ((a)>=10 ? L'a'+(a)-10 : L'0'+(a))
  33. for ( x = 0, y = 0 ; x < cSrc ; ++x )
  34. {
  35. UINT v;
  36. v = pSrc[x]>>4;
  37. pDst[y++] = TOHEX( v );
  38. v = pSrc[x] & 0x0f;
  39. pDst[y++] = TOHEX( v );
  40. }
  41. pDst[y] = '\0';
  42. return S_OK;
  43. }
  44. // ---------------------------------------------------------------------------
  45. // DeAllocateAssemblyMetaData
  46. //-------------------------------------------------------------------
  47. STDAPI DeAllocateAssemblyMetaData(ASSEMBLYMETADATA *pamd)
  48. {
  49. // NOTE - do not 0 out counts
  50. // since struct may be reused.
  51. pamd->cbLocale = 0;
  52. SAFEDELETEARRAY(pamd->szLocale);
  53. SAFEDELETEARRAY(pamd->rProcessor);
  54. SAFEDELETEARRAY(pamd->rOS);
  55. return S_OK;
  56. }
  57. // ---------------------------------------------------------------------------
  58. // InitializeEEShim
  59. //-------------------------------------------------------------------
  60. HRESULT InitializeEEShim()
  61. {
  62. HRESULT hr = S_OK;
  63. MAKE_ERROR_MACROS_STATIC(hr);
  64. HMODULE hMod;
  65. // BUGBUG - mscoree.dll never gets unloaded with increasing ref count.
  66. // what does URT do?
  67. hMod = LoadLibrary(TEXT("mscoree.dll"));
  68. IF_WIN32_FALSE_EXIT(hMod);
  69. g_pfnGetAssemblyMDImport = (pfnGetAssemblyMDImport)GetProcAddress(hMod, "GetAssemblyMDImport");
  70. g_pfnStrongNameTokenFromPublicKey = (pfnStrongNameTokenFromPublicKey)GetProcAddress(hMod, "StrongNameTokenFromPublicKey");
  71. g_pfnStrongNameErrorInfo = (pfnStrongNameErrorInfo)GetProcAddress(hMod, "StrongNameErrorInfo");
  72. g_pfnStrongNameFreeBuffer = (pfnStrongNameFreeBuffer)GetProcAddress(hMod, "StrongNameFreeBuffer");
  73. if (!g_pfnGetAssemblyMDImport || !g_pfnStrongNameTokenFromPublicKey || !g_pfnStrongNameErrorInfo
  74. || !g_pfnStrongNameFreeBuffer)
  75. {
  76. hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
  77. goto exit;
  78. }
  79. exit:
  80. return hr;
  81. }
  82. // ---------------------------------------------------------------------------
  83. // CreateMetaDataImport
  84. //-------------------------------------------------------------------
  85. HRESULT CreateMetaDataImport(LPCOLESTR pszFilename, IMetaDataAssemblyImport **ppImport)
  86. {
  87. HRESULT hr= S_OK;
  88. MAKE_ERROR_MACROS_STATIC(hr);
  89. IF_FAILED_EXIT(InitializeEEShim());
  90. hr = (*g_pfnGetAssemblyMDImport)(pszFilename, IID_IMetaDataAssemblyImport, (void **)ppImport);
  91. IF_TRUE_EXIT(hr == HRESULT_FROM_WIN32(ERROR_BAD_FORMAT), hr); // do not assert
  92. IF_FAILED_EXIT(hr);
  93. exit:
  94. return hr;
  95. }
  96. // ---------------------------------------------------------------------------
  97. // AllocateAssemblyMetaData
  98. //-------------------------------------------------------------------
  99. STDAPI AllocateAssemblyMetaData(ASSEMBLYMETADATA *pamd)
  100. {
  101. HRESULT hr = S_OK;
  102. MAKE_ERROR_MACROS_STATIC(hr);
  103. // Re/Allocate Locale array
  104. SAFEDELETEARRAY(pamd->szLocale);
  105. if (pamd->cbLocale) {
  106. IF_ALLOC_FAILED_EXIT(pamd->szLocale = new(WCHAR[pamd->cbLocale]));
  107. }
  108. // Re/Allocate Processor array
  109. SAFEDELETEARRAY(pamd->rProcessor);
  110. IF_ALLOC_FAILED_EXIT(pamd->rProcessor = new(DWORD[pamd->ulProcessor]));
  111. // Re/Allocate OS array
  112. SAFEDELETEARRAY(pamd->rOS);
  113. IF_ALLOC_FAILED_EXIT(pamd->rOS = new(OSINFO[pamd->ulOS]));
  114. exit:
  115. if (FAILED(hr) && pamd)
  116. DeAllocateAssemblyMetaData(pamd);
  117. return hr;
  118. }
  119. // ---------------------------------------------------------------------------
  120. // ByteArrayMaker
  121. // ---------------------------------------------------------------------------
  122. HRESULT ByteArrayMaker(LPVOID pvOriginator, DWORD dwOriginator, LPBYTE *ppbPublicKeyToken, DWORD *pcbPublicKeyToken)
  123. {
  124. //LPBYTE pbPublicKeyToken;
  125. //DWORD cbPublicKeyToken;
  126. if (!(g_pfnStrongNameTokenFromPublicKey((LPBYTE)pvOriginator, dwOriginator, ppbPublicKeyToken, pcbPublicKeyToken)))
  127. {
  128. return g_pfnStrongNameErrorInfo();
  129. }
  130. //*ppbPublicKeyToken = pbPublicKeyToken;
  131. //*pcbPublicKeyToken = cbPublicKeyToken;
  132. return S_OK;
  133. }
  134. // ---------------------------------------------------------------------------
  135. // ByteArrayFreer
  136. // ---------------------------------------------------------------------------
  137. void ByteArrayFreer(LPBYTE pbPublicKeyToken)
  138. {
  139. g_pfnStrongNameFreeBuffer(pbPublicKeyToken);
  140. }
  141. //#pragma managed
  142. namespace FusionADF
  143. {
  144. __gc public class AssemblyManifestParser
  145. {
  146. public:
  147. // ---------------------------------------------------------------------------
  148. // AssemblyManifestParser constructor
  149. // ---------------------------------------------------------------------------
  150. AssemblyManifestParser()
  151. {
  152. _dwSig = 'INAM';
  153. _pMDImport = NULL;
  154. _rAssemblyRefTokens = NULL;
  155. _cAssemblyRefTokens = 0;
  156. _rAssemblyModuleTokens = NULL;
  157. _cAssemblyModuleTokens = 0;
  158. *_szManifestFilePath = TEXT('\0');
  159. _ccManifestFilePath = 0;
  160. *_szAssemblyName = TEXT('\0');
  161. _pvOriginator = NULL;
  162. _dwOriginator = 0;
  163. _name = NULL;
  164. _version = NULL;
  165. *_szPubKeyTokStr = TEXT('\0');
  166. _pktString = NULL;
  167. _procArch = NULL;
  168. _language = NULL;
  169. _hr = S_OK;
  170. instanceValid = false;
  171. initCalledOnce = false;
  172. }
  173. // ---------------------------------------------------------------------------
  174. // AssemblyManifestParser destructor
  175. // ---------------------------------------------------------------------------
  176. ~AssemblyManifestParser()
  177. {
  178. SAFERELEASE(_pMDImport);
  179. SAFEDELETEARRAY(_rAssemblyRefTokens);
  180. SAFEDELETEARRAY(_rAssemblyModuleTokens);
  181. }
  182. bool InitFromFile(String* filePath)
  183. {
  184. LPCOLESTR lstr = 0;
  185. HRESULT hr;
  186. if(initCalledOnce) return false;
  187. initCalledOnce = true;
  188. try
  189. {
  190. lstr = static_cast<LPCOLESTR>(const_cast<void*>(static_cast<const void*>(Marshal::StringToHGlobalAuto(filePath))));
  191. }
  192. catch(ArgumentException *e)
  193. {
  194. // handle the exception
  195. return false;
  196. }
  197. catch (OutOfMemoryException *e)
  198. {
  199. // handle the exception
  200. return false;
  201. }
  202. hr = Init(lstr);
  203. if(hr != S_OK) return false;
  204. instanceValid = true;
  205. return true;
  206. }
  207. bool IsInstanceValid()
  208. {
  209. return instanceValid;
  210. }
  211. bool HasInitBeenCalled()
  212. {
  213. return initCalledOnce;
  214. }
  215. // ---------------------------------------------------------------------------
  216. // GetAssemblyIdentity
  217. // ---------------------------------------------------------------------------
  218. AssemblyIdentity* GetAssemblyIdentity()
  219. {
  220. return new AssemblyIdentity(_name, _version, _pktString, _procArch, _language);
  221. }
  222. // ---------------------------------------------------------------------------
  223. // GetNumDependentAssemblies
  224. // ---------------------------------------------------------------------------
  225. int GetNumDependentAssemblies()
  226. {
  227. return _cAssemblyRefTokens;
  228. }
  229. // ---------------------------------------------------------------------------
  230. // GetDependentAssemblyInfo
  231. // ---------------------------------------------------------------------------
  232. DependentAssemblyInfo* GetDependentAssemblyInfo(int nIndex)
  233. {
  234. WCHAR szAssemblyName[MAX_PATH];
  235. const VOID* pvOriginator = 0;
  236. const VOID* pvHashValue = NULL;
  237. DWORD ccAssemblyName = MAX_PATH,
  238. cbOriginator = 0,
  239. ccLocation = MAX_PATH,
  240. cbHashValue = 0,
  241. dwRefFlags = 0;
  242. INT i;
  243. LPWSTR pwz=NULL;
  244. mdAssemblyRef mdmar;
  245. ASSEMBLYMETADATA amd = {0};
  246. String *name = NULL, *pktString = NULL, *procArch = NULL, *language = NULL;
  247. Version *version = NULL;
  248. // Verify the index passed in.
  249. if (nIndex >= _cAssemblyRefTokens)
  250. {
  251. _hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  252. goto exit;
  253. }
  254. // Reference indexed dep assembly ref token.
  255. mdmar = _rAssemblyRefTokens[nIndex];
  256. // Default allocation sizes.
  257. amd.ulProcessor = amd.ulOS = 32;
  258. amd.cbLocale = MAX_PATH;
  259. // Loop max 2 (try/retry)
  260. for (i = 0; i < 2; i++)
  261. {
  262. // Allocate ASSEMBLYMETADATA instance.
  263. IF_FAILED_EXIT(AllocateAssemblyMetaData(&amd));
  264. // Get the properties for the refrenced assembly.
  265. IF_FAILED_EXIT(_pMDImport->GetAssemblyRefProps(
  266. mdmar, // [IN] The AssemblyRef for which to get the properties.
  267. &pvOriginator, // [OUT] Pointer to the PublicKeyToken blob.
  268. &cbOriginator, // [OUT] Count of bytes in the PublicKeyToken Blob.
  269. szAssemblyName, // [OUT] Buffer to fill with name.
  270. MAX_PATH, // [IN] Size of buffer in wide chars.
  271. &ccAssemblyName, // [OUT] Actual # of wide chars in name.
  272. &amd, // [OUT] Assembly MetaData.
  273. &pvHashValue, // [OUT] Hash blob.
  274. &cbHashValue, // [OUT] Count of bytes in the hash blob.
  275. &dwRefFlags // [OUT] Flags.
  276. ));
  277. // Check if retry necessary.
  278. if (!i)
  279. {
  280. if (amd.ulProcessor <= 32
  281. && amd.ulOS <= 32)
  282. {
  283. break;
  284. }
  285. else
  286. DeAllocateAssemblyMetaData(&amd);
  287. }
  288. // Retry with updated sizes
  289. }
  290. // Allow for funky null locale convention
  291. // in metadata - cbLocale == 0 means szLocale ==L'\0'
  292. if (!amd.cbLocale)
  293. {
  294. amd.cbLocale = 1;
  295. }
  296. else if (amd.szLocale)
  297. {
  298. WCHAR *ptr;
  299. ptr = StrChrW(amd.szLocale, L';');
  300. if (ptr)
  301. {
  302. (*ptr) = L'\0';
  303. amd.cbLocale = ((DWORD) (ptr - amd.szLocale) + sizeof(WCHAR));
  304. }
  305. }
  306. else
  307. {
  308. _hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
  309. goto exit;
  310. }
  311. //Name
  312. name = new String(szAssemblyName);
  313. //Version
  314. version = new Version(amd.usMajorVersion, amd.usMinorVersion, amd.usBuildNumber, amd.usRevisionNumber);
  315. //Public Key Token
  316. if (cbOriginator)
  317. {
  318. IF_ALLOC_FAILED_EXIT(pwz = new WCHAR[cbOriginator*2 +1]);
  319. IF_FAILED_EXIT(BinToUnicodeHex((LPBYTE)pvOriginator, cbOriginator, pwz));
  320. pktString = new String(pwz);
  321. SAFEDELETEARRAY(pwz);
  322. }
  323. //Architecture
  324. procArch = S"x86";
  325. //Language
  326. if (!(*amd.szLocale)) language = S"*";
  327. else language = new String(amd.szLocale);
  328. _hr = S_OK;
  329. exit:
  330. DeAllocateAssemblyMetaData(&amd);
  331. SAFEDELETEARRAY(pwz);
  332. if(_hr != S_OK) return NULL;
  333. else return new DependentAssemblyInfo(new AssemblyIdentity(name, version, pktString, procArch, language), NULL);
  334. }
  335. // ---------------------------------------------------------------------------
  336. // GetNumDependentFiles
  337. // ---------------------------------------------------------------------------
  338. int GetNumDependentFiles()
  339. {
  340. return _cAssemblyModuleTokens;
  341. }
  342. // ---------------------------------------------------------------------------
  343. // GetDependentFileInfo
  344. // ---------------------------------------------------------------------------
  345. DependentFileInfo* GetDependentFileInfo(int nIndex)
  346. {
  347. LPWSTR pszName = NULL;
  348. DWORD ccPath = 0;
  349. WCHAR szModulePath[MAX_PATH];
  350. mdFile mdf;
  351. WCHAR szModuleName[MAX_PATH];
  352. DWORD ccModuleName = MAX_PATH;
  353. const VOID* pvHashValue = NULL;
  354. DWORD cbHashValue = 0;
  355. DWORD dwFlags = 0;
  356. LPWSTR pwz=NULL;
  357. String *name = NULL, *hash = NULL;
  358. // Verify the index.
  359. if (nIndex >= _cAssemblyModuleTokens)
  360. {
  361. _hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  362. goto exit;
  363. }
  364. // Reference indexed dep assembly ref token.
  365. mdf = _rAssemblyModuleTokens[nIndex];
  366. // Get the properties for the refrenced assembly.
  367. IF_FAILED_EXIT(_pMDImport->GetFileProps(
  368. mdf, // [IN] The File for which to get the properties.
  369. szModuleName, // [OUT] Buffer to fill with name.
  370. MAX_CLASS_NAME, // [IN] Size of buffer in wide chars.
  371. &ccModuleName, // [OUT] Actual # of wide chars in name.
  372. &pvHashValue, // [OUT] Pointer to the Hash Value Blob.
  373. &cbHashValue, // [OUT] Count of bytes in the Hash Value Blob.
  374. &dwFlags)); // [OUT] Flags.
  375. //name
  376. name = new String(szModuleName);
  377. //hash
  378. if (cbHashValue)
  379. {
  380. IF_ALLOC_FAILED_EXIT(pwz = new WCHAR[cbHashValue*2 +1]);
  381. IF_FAILED_EXIT(_hr = BinToUnicodeHex((LPBYTE)pvHashValue, cbHashValue, pwz));
  382. hash = new String(pwz);
  383. SAFEDELETEARRAY(pwz);
  384. }
  385. _hr = S_OK;
  386. exit:
  387. SAFEDELETEARRAY(pwz);
  388. if(_hr != S_OK) return NULL;
  389. else return new DependentFileInfo(name, hash);
  390. }
  391. private:
  392. DWORD _dwSig;
  393. HRESULT _hr;
  394. WCHAR _szManifestFilePath __nogc[MAX_PATH];
  395. DWORD _ccManifestFilePath;
  396. WCHAR _szAssemblyName __nogc[MAX_CLASS_NAME];
  397. IMetaDataAssemblyImport *_pMDImport;
  398. PBYTE _pMap;
  399. mdAssembly *_rAssemblyRefTokens;
  400. DWORD _cAssemblyRefTokens;
  401. mdFile *_rAssemblyModuleTokens;
  402. DWORD _cAssemblyModuleTokens;
  403. LPVOID _pvOriginator;
  404. DWORD _dwOriginator;
  405. String* _name;
  406. Version* _version;
  407. WCHAR _szPubKeyTokStr __nogc[MAX_PKT_LEN];
  408. String* _pktString;
  409. String* _procArch;
  410. String* _language;
  411. bool instanceValid;
  412. bool initCalledOnce;
  413. // ---------------------------------------------------------------------------
  414. // Init
  415. // ---------------------------------------------------------------------------
  416. HRESULT Init(LPCOLESTR szManifestFilePath)
  417. {
  418. WCHAR __pin *tempFP = _szManifestFilePath;
  419. WCHAR __pin *temp_szAssemblyName = _szAssemblyName;
  420. WCHAR __pin *temp_szPubKeyTokStr = _szPubKeyTokStr;
  421. LPBYTE pbPublicKeyToken = NULL;
  422. DWORD cbPublicKeyToken = 0;
  423. DWORD dwFlags = 0, dwSize = 0, dwHashAlgId = 0;
  424. INT i;
  425. ASSEMBLYMETADATA amd = {0};
  426. const cElems = ASM_MANIFEST_IMPORT_DEFAULT_ARRAY_SIZE;
  427. // ********** First, work on getting metadata from file.
  428. // ********** ------------------------------------------
  429. IF_NULL_EXIT(szManifestFilePath, E_INVALIDARG);
  430. _ccManifestFilePath = lstrlenW(szManifestFilePath) + 1;
  431. memcpy(tempFP, szManifestFilePath, _ccManifestFilePath * sizeof(WCHAR));
  432. IF_ALLOC_FAILED_EXIT(_rAssemblyRefTokens = new(mdAssemblyRef[cElems]));
  433. IF_ALLOC_FAILED_EXIT(_rAssemblyModuleTokens = new(mdFile[cElems]));
  434. // Create meta data importer if necessary.
  435. if (!_pMDImport)
  436. {
  437. IMetaDataAssemblyImport *temp_pMDImport;
  438. // Create meta data importer
  439. _hr = CreateMetaDataImport((LPCOLESTR)tempFP, &temp_pMDImport);
  440. IF_TRUE_EXIT(_hr == HRESULT_FROM_WIN32(ERROR_BAD_FORMAT), _hr);
  441. IF_FAILED_EXIT(_hr);
  442. _pMDImport = temp_pMDImport;
  443. }
  444. // ********** Next, get the assembly identity fields.
  445. // ********** ---------------------------------------
  446. mdAssembly mda;
  447. // Get the assembly token.
  448. if(FAILED(_hr = _pMDImport->GetAssemblyFromScope(&mda)))
  449. {
  450. // This fails when called with managed module and not manifest. mg does such things.
  451. _hr = S_FALSE; // this will convert CLDB_E_RECORD_NOTFOUND (0x80131130) to S_FALSE;
  452. goto exit;
  453. }
  454. // Default allocation sizes.
  455. amd.ulProcessor = amd.ulOS = 32;
  456. amd.cbLocale = MAX_PATH;
  457. // Loop max 2 (try/retry)
  458. for (i = 0; i < 2; i++)
  459. {
  460. // Create an ASSEMBLYMETADATA instance.
  461. IF_FAILED_EXIT(AllocateAssemblyMetaData(&amd));
  462. LPVOID temp_pvOriginator;
  463. DWORD temp_dwOriginator;
  464. // Get name and metadata
  465. IF_FAILED_EXIT(_pMDImport->GetAssemblyProps(
  466. mda, // [IN] The Assembly for which to get the properties.
  467. (const void **)&temp_pvOriginator, // [OUT] Pointer to the Originator blob.
  468. &temp_dwOriginator, // [OUT] Count of bytes in the Originator Blob.
  469. &dwHashAlgId, // [OUT] Hash Algorithm.
  470. temp_szAssemblyName, // [OUT] Buffer to fill with name.
  471. MAX_CLASS_NAME, // [IN] Size of buffer in wide chars.
  472. &dwSize, // [OUT] Actual # of wide chars in name.
  473. &amd, // [OUT] Assembly MetaData.
  474. &dwFlags // [OUT] Flags.
  475. ));
  476. _pvOriginator = temp_pvOriginator;
  477. _dwOriginator = temp_dwOriginator;
  478. // Check if retry necessary.
  479. if (!i)
  480. {
  481. if (amd.ulProcessor <= 32 && amd.ulOS <= 32)
  482. break;
  483. else
  484. DeAllocateAssemblyMetaData(&amd);
  485. }
  486. }
  487. // Allow for funky null locale convention
  488. // in metadata - cbLocale == 0 means szLocale ==L'\0'
  489. if (!amd.cbLocale)
  490. {
  491. amd.cbLocale = 1;
  492. }
  493. else if (amd.szLocale)
  494. {
  495. WCHAR *ptr;
  496. ptr = StrChrW(amd.szLocale, L';');
  497. if (ptr)
  498. {
  499. (*ptr) = L'\0';
  500. amd.cbLocale = ((DWORD) (ptr - amd.szLocale) + sizeof(WCHAR));
  501. }
  502. }
  503. else
  504. {
  505. _hr = E_FAIL;
  506. goto exit;
  507. }
  508. // NAME is _szAssemblyName, pinned in temp_szAssemblyName, set to _name using the following code:
  509. _name = new String(temp_szAssemblyName);
  510. // VERSION is _version, set using the following code:
  511. _version = new Version(amd.usMajorVersion, amd.usMinorVersion, amd.usBuildNumber, amd.usRevisionNumber);
  512. // PUBLICKEYTOKEN is being figured out
  513. if (_dwOriginator)
  514. {
  515. if(FAILED(_hr = ByteArrayMaker(_pvOriginator, _dwOriginator, &pbPublicKeyToken, &cbPublicKeyToken)))
  516. {
  517. goto exit;
  518. }
  519. if(FAILED(_hr = BinToUnicodeHex(pbPublicKeyToken, cbPublicKeyToken, temp_szPubKeyTokStr)))
  520. {
  521. goto exit;
  522. }
  523. ByteArrayFreer(pbPublicKeyToken);
  524. _pktString = new String(temp_szPubKeyTokStr);
  525. }
  526. // LANGUAGE is _language, set using the following code:
  527. if (!(*amd.szLocale)) _language = S"*";
  528. else _language = new String(amd.szLocale);
  529. // PROCESSOR ARCHITECTURE is _procArch, set using the following code:
  530. _procArch = S"x86";
  531. // ********** Next, get the dependent assemblies.
  532. // ********** -----------------------------------
  533. if (!_cAssemblyRefTokens)
  534. {
  535. DWORD cTokensMax = 0;
  536. HCORENUM hEnum = 0;
  537. // Attempt to get token array. If we have insufficient space
  538. // in the default array we will re-allocate it.
  539. if (FAILED(_hr = _pMDImport->EnumAssemblyRefs(
  540. &hEnum,
  541. _rAssemblyRefTokens,
  542. ASM_MANIFEST_IMPORT_DEFAULT_ARRAY_SIZE,
  543. &cTokensMax)))
  544. {
  545. goto exit;
  546. }
  547. // Number of tokens known. close enum.
  548. _pMDImport->CloseEnum(hEnum);
  549. hEnum = 0;
  550. // Insufficient array size. Grow array.
  551. if (cTokensMax > ASM_MANIFEST_IMPORT_DEFAULT_ARRAY_SIZE)
  552. {
  553. // Re-allocate space for tokens.
  554. SAFEDELETEARRAY(_rAssemblyRefTokens);
  555. _cAssemblyRefTokens = cTokensMax;
  556. _rAssemblyRefTokens = new(mdAssemblyRef[_cAssemblyRefTokens]);
  557. if (!_rAssemblyRefTokens)
  558. {
  559. _hr = E_OUTOFMEMORY;
  560. goto exit;
  561. }
  562. DWORD temp_cART;
  563. // Re-get tokens.
  564. if (FAILED(_hr = _pMDImport->EnumAssemblyRefs(
  565. &hEnum,
  566. _rAssemblyRefTokens,
  567. cTokensMax,
  568. &temp_cART)))
  569. {
  570. goto exit;
  571. }
  572. _cAssemblyRefTokens = temp_cART;
  573. // Close enum.
  574. _pMDImport->CloseEnum(hEnum);
  575. hEnum = 0;
  576. }
  577. // Otherwise, the default array size was sufficient.
  578. else
  579. {
  580. _cAssemblyRefTokens = cTokensMax;
  581. }
  582. }
  583. // ********** Next, get the dependent files / modules.
  584. // ********** ----------------------------------------
  585. if (!_cAssemblyModuleTokens)
  586. {
  587. DWORD cTokensMax = 0;
  588. HCORENUM hEnum = 0;
  589. // Attempt to get token array. If we have insufficient space
  590. // in the default array we will re-allocate it.
  591. if (FAILED(_hr = _pMDImport->EnumFiles(&hEnum, _rAssemblyModuleTokens,
  592. ASM_MANIFEST_IMPORT_DEFAULT_ARRAY_SIZE, &cTokensMax)))
  593. {
  594. goto exit;
  595. }
  596. // Number of tokens known. close enum.
  597. _pMDImport->CloseEnum(hEnum);
  598. hEnum = 0;
  599. if (cTokensMax > ASM_MANIFEST_IMPORT_DEFAULT_ARRAY_SIZE)
  600. {
  601. // Insufficient array size. Grow array.
  602. _cAssemblyModuleTokens = cTokensMax;
  603. SAFEDELETEARRAY(_rAssemblyModuleTokens);
  604. _rAssemblyModuleTokens = new(mdFile[_cAssemblyModuleTokens]);
  605. if(_hr == S_OK) Console::WriteLine(S"Still OK 3");
  606. if (!_rAssemblyModuleTokens)
  607. {
  608. _hr = E_OUTOFMEMORY;
  609. //Console::WriteLine(S"2 HR set, failure, going to exit");
  610. goto exit;
  611. }
  612. DWORD temp_cAMT;
  613. // Re-get tokens.
  614. if (FAILED(_hr = _pMDImport->EnumFiles(
  615. &hEnum,
  616. _rAssemblyModuleTokens,
  617. cTokensMax,
  618. &temp_cAMT)))
  619. {
  620. //Console::WriteLine(S"3 HR set, failure, going to exit");
  621. goto exit;
  622. }
  623. _cAssemblyModuleTokens = temp_cAMT;
  624. // Close enum.
  625. _pMDImport->CloseEnum(hEnum);
  626. hEnum = 0;
  627. }
  628. // Otherwise, the default array size was sufficient.
  629. else _cAssemblyModuleTokens = cTokensMax;
  630. }
  631. _hr = S_OK;
  632. exit:
  633. // ********** If everything worked, _hr will be S_OK. That is for caller to determine.
  634. // ********** ------------------------------------------------------------------------
  635. DeAllocateAssemblyMetaData(&amd);
  636. return _hr;
  637. }
  638. //Functions not implemented
  639. HRESULT GetSubscriptionInfo(IManifestInfo **ppSubsInfo)
  640. {
  641. return E_NOTIMPL;
  642. }
  643. HRESULT GetNextPlatform(DWORD nIndex, IManifestData **ppPlatformInfo)
  644. {
  645. return E_NOTIMPL;
  646. }
  647. HRESULT GetManifestApplicationInfo(IManifestInfo **ppAppInfo)
  648. {
  649. return E_NOTIMPL;
  650. }
  651. HRESULT CQueryFile(LPCOLESTR pwzFileName,IManifestInfo **ppAssemblyFile)
  652. {
  653. return E_NOTIMPL;
  654. }
  655. };
  656. }