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.

815 lines
25 KiB

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