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.

632 lines
19 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. sxsasmname.cpp
  5. Abstract:
  6. CAssemblyName implementation for installation
  7. Author:
  8. Xiaoyu Wu (xiaoyuw) May 2000
  9. Revision History:
  10. xiaoyuw 09/20000 rewrite the code to use Assembly Identity
  11. --*/
  12. #include "stdinc.h"
  13. #include "sxsasmname.h"
  14. #include "fusionparser.h"
  15. #include "parse.h"
  16. #include "sxsp.h"
  17. #include "sxsid.h"
  18. #include "sxsidp.h"
  19. #include "sxsapi.h"
  20. #include "fusiontrace.h"
  21. // ---------------------------------------------------------------------------
  22. // CreateAssemblyNameObject
  23. // ---------------------------------------------------------------------------
  24. STDAPI
  25. CreateAssemblyNameObject(
  26. LPASSEMBLYNAME *ppAssemblyName,
  27. LPCOLESTR szAssemblyName,
  28. DWORD dwFlags,
  29. LPVOID pvReserved
  30. )
  31. {
  32. HRESULT hr = S_OK;
  33. FN_TRACE_HR(hr);
  34. CSmartRef<CAssemblyName> pName;
  35. if (ppAssemblyName)
  36. *ppAssemblyName = NULL ;
  37. // validate dwFlags
  38. // BUGBUG : the valid value of dwFlags are CANOF_PARSE_DISPLAY_NAME and CANOF_SET_DEFAULT_VALUES, but CANOF_SET_DEFAULT_VALUES
  39. // is never used...
  40. // xiaoyuw@10/02/2000
  41. //
  42. PARAMETER_CHECK(dwFlags == CANOF_PARSE_DISPLAY_NAME);
  43. PARAMETER_CHECK(ppAssemblyName != NULL);
  44. PARAMETER_CHECK(pvReserved == NULL);
  45. IFALLOCFAILED_EXIT(pName = new CAssemblyName);
  46. if (dwFlags & CANOF_PARSE_DISPLAY_NAME)
  47. IFCOMFAILED_EXIT(pName->Parse((LPWSTR)szAssemblyName));
  48. *ppAssemblyName = pName.Disown();
  49. FN_EPILOG
  50. }
  51. // ---------------------------------------------------------------------------
  52. // CAssemblyName::SetProperty
  53. // ---------------------------------------------------------------------------
  54. STDMETHODIMP
  55. CAssemblyName::SetProperty(DWORD PropertyId,
  56. LPVOID pvProperty, DWORD cbProperty)
  57. {
  58. HRESULT hr = NOERROR;
  59. FN_TRACE_HR(hr);
  60. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE Attribute = NULL;
  61. // this function is only called inside fusion, so this fucntion has no impact on Darwin
  62. // maybe more should be added for Assembly Identity, such as StrongName, or random policies
  63. //
  64. if ((!pvProperty) || ((PropertyId != SXS_ASM_NAME_NAME) &&
  65. (PropertyId != SXS_ASM_NAME_VERSION) &&
  66. (PropertyId != SXS_ASM_NAME_PROCESSORARCHITECTURE) &&
  67. (PropertyId != SXS_ASM_NAME_LANGUAGE))){
  68. hr = E_INVALIDARG;
  69. goto Exit;
  70. }
  71. // Fail if finalized.
  72. if (m_fIsFinalized){
  73. hr = E_UNEXPECTED;
  74. goto Exit;
  75. }
  76. switch (PropertyId)
  77. {
  78. case SXS_ASM_NAME_NAME: Attribute = &s_IdentityAttribute_name; break;
  79. case SXS_ASM_NAME_VERSION: Attribute = &s_IdentityAttribute_version; break;
  80. case SXS_ASM_NAME_PROCESSORARCHITECTURE: Attribute = &s_IdentityAttribute_processorArchitecture; break;
  81. case SXS_ASM_NAME_LANGUAGE: Attribute = &s_IdentityAttribute_language; break;
  82. }
  83. INTERNAL_ERROR_CHECK(Attribute != NULL);
  84. IFW32FALSE_EXIT(::SxspSetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, Attribute, (PCWSTR) pvProperty, cbProperty / sizeof(WCHAR)));
  85. hr = NOERROR;
  86. Exit:
  87. return hr;
  88. }
  89. // ---------------------------------------------------------------------------
  90. // CAssemblyName::GetProperty
  91. // ---------------------------------------------------------------------------
  92. STDMETHODIMP
  93. CAssemblyName::GetProperty(DWORD PropertyId,
  94. /* [in] */ LPVOID pvProperty,
  95. /* [out][in] */ LPDWORD pcbProperty)
  96. {
  97. HRESULT hr = NOERROR;
  98. FN_TRACE_HR(hr);
  99. PCWSTR pszAttributeValue = NULL;
  100. SIZE_T CchAttributeValue = 0;
  101. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE Attribute = NULL;
  102. if ((!pvProperty) || (!pcbProperty) || ((PropertyId != SXS_ASM_NAME_NAME) &&
  103. (PropertyId != SXS_ASM_NAME_VERSION) &&
  104. (PropertyId != SXS_ASM_NAME_PROCESSORARCHITECTURE) &&
  105. (PropertyId != SXS_ASM_NAME_LANGUAGE))){
  106. hr = E_INVALIDARG;
  107. goto Exit;
  108. }
  109. switch (PropertyId)
  110. {
  111. case SXS_ASM_NAME_NAME: Attribute = &s_IdentityAttribute_name; break;
  112. case SXS_ASM_NAME_VERSION: Attribute = &s_IdentityAttribute_version; break;
  113. case SXS_ASM_NAME_PROCESSORARCHITECTURE: Attribute = &s_IdentityAttribute_processorArchitecture; break;
  114. case SXS_ASM_NAME_LANGUAGE: Attribute = &s_IdentityAttribute_language; break;
  115. }
  116. INTERNAL_ERROR_CHECK(Attribute != NULL);
  117. IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, Attribute, &pszAttributeValue, &CchAttributeValue));
  118. // check whether we have valid attributes
  119. if (pszAttributeValue == NULL){ // attributes not set yet
  120. hr = E_UNEXPECTED;
  121. goto Exit;
  122. }
  123. if (CchAttributeValue * sizeof(WCHAR) > *pcbProperty) { // buffer size is not big enough
  124. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  125. *pcbProperty = static_cast<DWORD>(CchAttributeValue * sizeof(WCHAR));
  126. goto Exit;
  127. }
  128. // copy the string into the output buffer
  129. memcpy(pvProperty, pszAttributeValue, CchAttributeValue *sizeof(WCHAR));
  130. if (pcbProperty)
  131. *pcbProperty = static_cast<DWORD>(CchAttributeValue * sizeof(WCHAR));
  132. hr = NOERROR;
  133. Exit:
  134. return hr;
  135. }
  136. // ---------------------------------------------------------------------------
  137. // CAssemblyName::GetName
  138. // ---------------------------------------------------------------------------
  139. STDMETHODIMP
  140. CAssemblyName::GetName(
  141. /* [out][in] */ LPDWORD lpcwBuffer,
  142. /* [out] */ WCHAR *pwzName)
  143. {
  144. HRESULT hr = NOERROR;
  145. FN_TRACE_HR(hr);
  146. if (!lpcwBuffer || !pwzName){
  147. hr = E_INVALIDARG;
  148. goto Exit;
  149. }
  150. IFCOMFAILED_EXIT(this->GetProperty(SXS_ASM_NAME_NAME, pwzName, lpcwBuffer));
  151. FN_EPILOG
  152. }
  153. // ---------------------------------------------------------------------------
  154. // CAssemblyName::GetVersion
  155. // ---------------------------------------------------------------------------
  156. STDMETHODIMP
  157. CAssemblyName::GetVersion(
  158. /* [out] */ LPDWORD pdwVersionHi,
  159. /* [out] */ LPDWORD pdwVersionLow)
  160. {
  161. HRESULT hr = NOERROR;
  162. FN_TRACE_HR(hr);
  163. PCWSTR pszAttributeValue = NULL;
  164. SIZE_T CchAttributeValue = 0;
  165. ASSEMBLY_VERSION ver;
  166. bool fSyntaxValid = false;
  167. if ((!pdwVersionHi) || (!pdwVersionLow)){
  168. hr = E_INVALIDARG;
  169. goto Exit;
  170. }
  171. IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, &s_IdentityAttribute_version, &pszAttributeValue, &CchAttributeValue));
  172. if (pszAttributeValue == NULL)
  173. {
  174. hr = E_UNEXPECTED;
  175. goto Exit;
  176. }
  177. IFW32FALSE_EXIT(CFusionParser::ParseVersion(ver, pszAttributeValue, CchAttributeValue, fSyntaxValid));
  178. if (!fSyntaxValid)
  179. {
  180. hr = HRESULT_FROM_WIN32(ERROR_SXS_MANIFEST_PARSE_ERROR);
  181. goto Exit;
  182. }
  183. *pdwVersionHi = MAKELONG(ver.Minor, ver.Major);
  184. *pdwVersionLow = MAKELONG(ver.Build, ver.Revision);
  185. FN_EPILOG
  186. }
  187. // ---------------------------------------------------------------------------
  188. // CAssemblyName::IsEqual
  189. // ---------------------------------------------------------------------------
  190. STDMETHODIMP
  191. CAssemblyName::IsEqual(LPASSEMBLYNAME pName, DWORD dwCmpFlags)
  192. {
  193. HRESULT hr = NOERROR;
  194. FN_TRACE_HR(hr);
  195. BOOL fEqual = FALSE;
  196. PARAMETER_CHECK(pName != NULL);
  197. IFW32FALSE_EXIT(::SxsAreAssemblyIdentitiesEqual(0, m_pAssemblyIdentity, static_cast<CAssemblyName *>(pName)->m_pAssemblyIdentity, &fEqual));
  198. if (fEqual == TRUE)
  199. hr = S_OK;
  200. else
  201. hr = E_FAIL; // not acurrate, however, it depends on Darwin caller.
  202. Exit:
  203. return hr;
  204. }
  205. // ---------------------------------------------------------------------------
  206. // CAssemblyName constructor
  207. // ---------------------------------------------------------------------------
  208. CAssemblyName::CAssemblyName():m_cRef(0),
  209. m_fIsFinalized(FALSE),
  210. m_pAssemblyIdentity(NULL)
  211. {
  212. }
  213. // ---------------------------------------------------------------------------
  214. // CAssemblyName destructor
  215. // ---------------------------------------------------------------------------
  216. CAssemblyName::~CAssemblyName()
  217. {
  218. ASSERT_NTC(m_cRef == 0 );
  219. if (m_pAssemblyIdentity)
  220. {
  221. CSxsPreserveLastError ple;
  222. ::SxsDestroyAssemblyIdentity(m_pAssemblyIdentity);
  223. ple.Restore();
  224. }
  225. }
  226. // ---------------------------------------------------------------------------
  227. // CAssemblyName::Init
  228. // ---------------------------------------------------------------------------
  229. HRESULT
  230. CAssemblyName::Init(LPCWSTR pszAssemblyName, PVOID pamd)
  231. {
  232. HRESULT hr = S_OK;
  233. FN_TRACE_HR(hr);
  234. SIZE_T CchAssemblyName = 0;
  235. UNUSED(pamd);
  236. //ASSERT(m_pAssemblyIdentity == NULL);
  237. if (m_pAssemblyIdentity)
  238. {
  239. hr = E_UNEXPECTED;
  240. goto Exit;
  241. }
  242. IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &m_pAssemblyIdentity, 0, NULL));
  243. // set name if present
  244. if (pszAssemblyName != NULL)
  245. {
  246. CchAssemblyName = wcslen(pszAssemblyName);
  247. IFW32FALSE_EXIT(::SxspSetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, &s_IdentityAttribute_name, pszAssemblyName, wcslen(pszAssemblyName)));
  248. }
  249. hr = NOERROR;
  250. Exit:
  251. return hr;
  252. }
  253. // ---------------------------------------------------------------------------
  254. // CAssemblyName::Init
  255. // ---------------------------------------------------------------------------
  256. HRESULT CAssemblyName::Clone(IAssemblyName **ppName)
  257. {
  258. HRESULT hr = NOERROR;
  259. FN_TRACE_HR(hr);
  260. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  261. CAssemblyName *pName= NULL;
  262. if (ppName)
  263. *ppName = NULL;
  264. if (!ppName){
  265. hr = E_INVALIDARG ;
  266. goto Exit;
  267. }
  268. if (m_pAssemblyIdentity)
  269. {
  270. IFW32FALSE_EXIT(
  271. ::SxsDuplicateAssemblyIdentity(
  272. 0, // DWORD Flags,
  273. m_pAssemblyIdentity, // PCASSEMBLY_IDENTITY Source,
  274. &pAssemblyIdentity)); // PASSEMBLY_IDENTITY *Destination
  275. }
  276. IFALLOCFAILED_EXIT(pName = new CAssemblyName);
  277. pName->m_pAssemblyIdentity = pAssemblyIdentity;
  278. pAssemblyIdentity = NULL;
  279. *ppName = pName;
  280. pName = NULL;
  281. hr = NOERROR;
  282. Exit:
  283. if (pAssemblyIdentity)
  284. SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  285. if (pName)
  286. FUSION_DELETE_SINGLETON(pName);
  287. return hr;
  288. }
  289. // ---------------------------------------------------------------------------
  290. // CAssemblyName::BindToObject
  291. // ---------------------------------------------------------------------------
  292. STDMETHODIMP
  293. CAssemblyName::BindToObject(
  294. /* in */ REFIID refIID,
  295. /* in */ IAssemblyBindSink *pAsmBindSink,
  296. /* in */ IApplicationContext *pAppCtx,
  297. /* in */ LPCOLESTR szCodebase,
  298. /* in */ LONGLONG llFlags,
  299. /* in */ LPVOID pvReserved,
  300. /* in */ DWORD cbReserved,
  301. /* out */ VOID **ppv)
  302. {
  303. if (!ppv)
  304. return E_INVALIDARG ;
  305. *ppv = NULL;
  306. return E_NOTIMPL;
  307. }
  308. // ---------------------------------------------------------------------------
  309. // CAssemblyName::Finalize
  310. // ---------------------------------------------------------------------------
  311. STDMETHODIMP
  312. CAssemblyName::Finalize()
  313. {
  314. m_fIsFinalized = TRUE;
  315. return NOERROR;
  316. }
  317. BOOL SxspIsAssemblyNameAttributeInAssemblyIdentity(PASSEMBLY_IDENTITY_ATTRIBUTE pAttribute)
  318. {
  319. if( pAttribute == NULL)
  320. return FALSE;
  321. //compare namespace
  322. if (::FusionpCompareStrings(
  323. pAttribute->Namespace,
  324. pAttribute->NamespaceCch,
  325. SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE,
  326. NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1,
  327. false) == 0 ){ // case-sensitive comparison
  328. if (::FusionpCompareStrings(
  329. pAttribute->Name,
  330. pAttribute->NameCch,
  331. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME,
  332. NUMBER_OF(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME) - 1,
  333. false) == 0 ){ // case-sensitive comparison
  334. return TRUE;
  335. }
  336. else
  337. return FALSE;
  338. }
  339. else
  340. return FALSE;
  341. }
  342. //-----------------------------------------------------------------------------------
  343. // CAssemblyName::GetDisplayName
  344. // it would be name,ns1:n1="v1",ns2:n2="v2",ns3:n3="v3",ns4:n4="v4"
  345. // I have to put name first in order not to change Darwin's code
  346. //
  347. // xiaoyuw@09/29/2000
  348. //-----------------------------------------------------------------------------------
  349. STDMETHODIMP
  350. CAssemblyName::GetDisplayName(LPOLESTR szDisplayName,
  351. LPDWORD pccDisplayName, DWORD dwDisplayFlags)
  352. {
  353. HRESULT hr = NOERROR;
  354. FN_TRACE_HR(hr);
  355. SIZE_T BufferSize;
  356. SIZE_T BytesWrittenOrRequired = 0;
  357. PARAMETER_CHECK(pccDisplayName != NULL);
  358. PARAMETER_CHECK((szDisplayName != NULL) || (*pccDisplayName == 0));
  359. PARAMETER_CHECK(dwDisplayFlags == 0);
  360. // Need buffer size in bytes...
  361. BufferSize = (*pccDisplayName) * sizeof(WCHAR);
  362. IFW32FALSE_EXIT(
  363. ::SxsEncodeAssemblyIdentity(
  364. 0,
  365. m_pAssemblyIdentity,
  366. NULL,
  367. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  368. BufferSize,
  369. szDisplayName,
  370. &BytesWrittenOrRequired));
  371. if ((BufferSize - BytesWrittenOrRequired) < sizeof(WCHAR))
  372. {
  373. // We actually could fit everything but the trailing null character...
  374. // the BytesWrittenOrRequired actually has the right value for the exit path below;
  375. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  376. goto Exit;
  377. }else // add the trailing NULL
  378. {
  379. szDisplayName[BytesWrittenOrRequired / sizeof (*szDisplayName)] = L'\0';
  380. }
  381. hr = NOERROR;
  382. Exit:
  383. if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
  384. *pccDisplayName = static_cast<DWORD>((BytesWrittenOrRequired / sizeof(WCHAR)) + 1);
  385. return hr;
  386. }
  387. HRESULT CAssemblyName::Parse(LPCWSTR szDisplayName)
  388. {
  389. HRESULT hr = NOERROR;
  390. FN_TRACE_HR(hr);
  391. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  392. // Verify display name passed in.
  393. PARAMETER_CHECK(szDisplayName != NULL);
  394. PARAMETER_CHECK(szDisplayName[0] != L'\0');
  395. IFW32FALSE_EXIT(
  396. ::SxspCreateAssemblyIdentityFromTextualString(
  397. szDisplayName,
  398. &pAssemblyIdentity));
  399. if (m_pAssemblyIdentity != NULL)
  400. ::SxsDestroyAssemblyIdentity(m_pAssemblyIdentity);
  401. m_pAssemblyIdentity = pAssemblyIdentity;
  402. pAssemblyIdentity = NULL;
  403. hr = NOERROR;
  404. Exit:
  405. if (pAssemblyIdentity != NULL)
  406. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  407. return hr;
  408. }
  409. // ---------------------------------------------------------------------------
  410. // CAssemblyName::GetInstalledAssemblyName
  411. // ---------------------------------------------------------------------------
  412. HRESULT
  413. CAssemblyName::GetInstalledAssemblyName(
  414. IN DWORD Flags,
  415. IN ULONG PathType,
  416. CBaseStringBuffer &rBufInstallPath
  417. )
  418. {
  419. HRESULT hr = NOERROR;
  420. FN_TRACE_HR(hr);
  421. BOOL fIsPolicy;
  422. IFCOMFAILED_EXIT(this->DetermineAssemblyType(fIsPolicy));
  423. Flags |= (fIsPolicy ? SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION : 0);
  424. if (Flags & SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT)
  425. {
  426. IFW32FALSE_EXIT(
  427. ::SxspGenerateSxsPath(
  428. Flags,
  429. PathType,
  430. NULL,
  431. 0,
  432. m_pAssemblyIdentity,
  433. rBufInstallPath));
  434. ::FusionpDbgPrintEx(
  435. FUSION_DBG_LEVEL_MSI_INSTALL,
  436. "SXS: %s - Generated %Iu character (root omitted) installation path:\n"
  437. " \"%ls\"\n",
  438. __FUNCTION__, rBufInstallPath.Cch(),
  439. static_cast<PCWSTR>(rBufInstallPath));
  440. }
  441. else
  442. {
  443. CStringBuffer bufRootDir;
  444. IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(bufRootDir));
  445. IFW32FALSE_EXIT(bufRootDir.Win32EnsureTrailingPathSeparator());
  446. IFW32FALSE_EXIT(
  447. ::SxspGenerateSxsPath(
  448. Flags,
  449. PathType,
  450. bufRootDir,
  451. bufRootDir.Cch(),
  452. m_pAssemblyIdentity,
  453. rBufInstallPath));
  454. ::FusionpDbgPrintEx(
  455. FUSION_DBG_LEVEL_MSI_INSTALL,
  456. "SXS: %s - Generated %Iu character installation path:\n"
  457. " \"%ls\"\n",
  458. __FUNCTION__, rBufInstallPath.Cch(),
  459. static_cast<PCWSTR>(rBufInstallPath));
  460. }
  461. FN_EPILOG
  462. }
  463. // TODO :
  464. // 1) this function just check the existence of the directory W/O compare the files under the directory
  465. // 2) this API would return FALSE if something in the middle is wrong, maybe not appropriate
  466. // xiaoyuw@09/29/2000
  467. //
  468. HRESULT CAssemblyName::IsAssemblyInstalled(BOOL &fInstalled)
  469. {
  470. HRESULT hr = NOERROR;
  471. FN_TRACE_HR(hr);
  472. CStringBuffer buffInstalledDir;
  473. fInstalled = FALSE;
  474. IFCOMFAILED_EXIT(
  475. this->GetInstalledAssemblyName(
  476. 0,
  477. SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
  478. buffInstalledDir));
  479. if (::GetFileAttributesW(buffInstalledDir) == INVALID_FILE_ATTRIBUTES)
  480. {
  481. const DWORD dwLastError = ::GetLastError();
  482. if (dwLastError != ERROR_FILE_NOT_FOUND)
  483. ORIGINATE_WIN32_FAILURE_AND_EXIT(GetFileAttributesW, dwLastError);
  484. }
  485. else
  486. fInstalled = TRUE;
  487. FN_EPILOG
  488. }
  489. // IUnknown methods
  490. // ---------------------------------------------------------------------------
  491. // CAssemblyName::AddRef
  492. // ---------------------------------------------------------------------------
  493. STDMETHODIMP_(ULONG)
  494. CAssemblyName::AddRef()
  495. {
  496. return InterlockedIncrement((LONG*) &m_cRef);
  497. }
  498. // ---------------------------------------------------------------------------
  499. // CAssemblyName::Release
  500. // ---------------------------------------------------------------------------
  501. STDMETHODIMP_(ULONG)
  502. CAssemblyName::Release()
  503. {
  504. ULONG lRet = InterlockedDecrement ((PLONG)&m_cRef);
  505. if (!lRet)
  506. FUSION_DELETE_SINGLETON(this);
  507. return lRet;
  508. }
  509. // ---------------------------------------------------------------------------
  510. // CAssemblyName::QueryInterface
  511. // ---------------------------------------------------------------------------
  512. STDMETHODIMP
  513. CAssemblyName::QueryInterface(REFIID riid, void** ppv)
  514. {
  515. if ( IsEqualIID(riid, IID_IUnknown)
  516. || IsEqualIID(riid, IID_IAssemblyName)){
  517. *ppv = static_cast<IAssemblyName*> (this);
  518. AddRef();
  519. return S_OK;
  520. }
  521. else{
  522. *ppv = NULL;
  523. return E_NOINTERFACE;
  524. }
  525. }
  526. HRESULT
  527. CAssemblyName::DetermineAssemblyType( BOOL &fIsPolicy )
  528. {
  529. HRESULT hr = E_FAIL;
  530. FN_TRACE_HR(hr);
  531. INTERNAL_ERROR_CHECK( m_pAssemblyIdentity != NULL );
  532. IFW32FALSE_EXIT(::SxspDetermineAssemblyType(m_pAssemblyIdentity, fIsPolicy));
  533. hr = S_OK;
  534. Exit:
  535. return hr;
  536. }