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.

502 lines
15 KiB

  1. #include <fusenetincludes.h>
  2. #include <msxml2.h>
  3. #include <assemblyidentity.h>
  4. #include <shlwapi.h>
  5. //*****************************************************************************
  6. //NTRAID#NTBUG9-577183-2002/03/14-adriaanc
  7. //
  8. // The code in this file needs to be completely rewritten to provide complete identity support
  9. // including generate filesystem names for the application cache correctly. It is currently for
  10. // prototype purposes only.
  11. //
  12. //*****************************************************************************
  13. // ---------------------------------------------------------------------------
  14. // CreateAssemblyIdentity
  15. // ---------------------------------------------------------------------------
  16. STDAPI
  17. CreateAssemblyIdentity(
  18. LPASSEMBLY_IDENTITY *ppAssemblyId,
  19. DWORD dwFlags)
  20. {
  21. HRESULT hr = S_OK;
  22. MAKE_ERROR_MACROS_STATIC(hr);
  23. CAssemblyIdentity *pAssemblyId = NULL;
  24. pAssemblyId = new(CAssemblyIdentity);
  25. IF_ALLOC_FAILED_EXIT(pAssemblyId);
  26. IF_FAILED_EXIT(pAssemblyId->Init());
  27. exit:
  28. if (FAILED(hr))
  29. {
  30. SAFERELEASE(pAssemblyId);
  31. *ppAssemblyId = NULL;
  32. }
  33. else
  34. *ppAssemblyId = pAssemblyId;
  35. return hr;
  36. }
  37. STDAPI
  38. CreateAssemblyIdentityEx(
  39. LPASSEMBLY_IDENTITY *ppAssemblyId,
  40. DWORD dwFlags,
  41. LPWSTR wzDisplayName)
  42. {
  43. HRESULT hr = S_OK;
  44. MAKE_ERROR_MACROS_STATIC(hr);
  45. CAssemblyIdentity *pAssemblyId = NULL;
  46. pAssemblyId = new(CAssemblyIdentity);
  47. IF_ALLOC_FAILED_EXIT(pAssemblyId);
  48. IF_FAILED_EXIT(hr = pAssemblyId->Init());
  49. if (wzDisplayName)
  50. {
  51. LPWSTR pwzStart, pwzEnd;
  52. CString Temp[4];
  53. CString sDirName;
  54. int i=0;
  55. IF_FAILED_EXIT(sDirName.Assign(wzDisplayName));
  56. pwzStart = sDirName._pwz;
  57. pwzEnd = sDirName._pwz;
  58. while (pwzEnd = StrChr(pwzEnd, L'_'))
  59. {
  60. *pwzEnd = L'\0';
  61. IF_FAILED_EXIT(Temp[i++].Assign(pwzStart));
  62. pwzStart = ++pwzEnd;
  63. }
  64. IF_FAILED_EXIT(pAssemblyId->SetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE,
  65. (LPCOLESTR)pwzStart, lstrlen(pwzStart) + 1));
  66. IF_FAILED_EXIT(pAssemblyId->SetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION,
  67. (LPCOLESTR)Temp[3]._pwz, lstrlen(Temp[3]._pwz) + 1));
  68. IF_FAILED_EXIT(pAssemblyId->SetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN,
  69. (LPCOLESTR)Temp[2]._pwz, lstrlen(Temp[2]._pwz) + 1));
  70. IF_FAILED_EXIT(pAssemblyId->SetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME,
  71. (LPCOLESTR)Temp[1]._pwz, lstrlen(Temp[1]._pwz) + 1));
  72. IF_FAILED_EXIT(pAssemblyId->SetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PROCESSOR_ARCHITECTURE,
  73. (LPCOLESTR)Temp[0]._pwz, lstrlen(Temp[0]._pwz) + 1));
  74. }
  75. exit:
  76. if (FAILED(hr))
  77. {
  78. SAFERELEASE(pAssemblyId);
  79. *ppAssemblyId = NULL;
  80. }
  81. else
  82. *ppAssemblyId = pAssemblyId;
  83. return hr;
  84. }
  85. // ---------------------------------------------------------------------------
  86. // CloneAssemblyIdentity
  87. // ---------------------------------------------------------------------------
  88. STDAPI
  89. CloneAssemblyIdentity(
  90. LPASSEMBLY_IDENTITY pSrcAssemblyId,
  91. LPASSEMBLY_IDENTITY *ppDestAssemblyId)
  92. {
  93. HRESULT hr = S_OK;
  94. MAKE_ERROR_MACROS_STATIC(hr);
  95. LPWSTR pwz = NULL;
  96. DWORD cc = 0;
  97. LPWSTR rpwzAttrNames[5] =
  98. {
  99. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PROCESSOR_ARCHITECTURE,
  100. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME,
  101. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN,
  102. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION,
  103. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE,
  104. };
  105. CAssemblyIdentity *pAssemblyId = NULL;
  106. IF_FALSE_EXIT((pSrcAssemblyId && ppDestAssemblyId), E_INVALIDARG);
  107. *ppDestAssemblyId = NULL;
  108. IF_FAILED_EXIT(CreateAssemblyIdentity((LPASSEMBLY_IDENTITY*) &pAssemblyId, 0));
  109. for (DWORD i = 0; i < (sizeof(rpwzAttrNames) /sizeof(rpwzAttrNames[0])); i++)
  110. {
  111. CString sValue;
  112. hr = pSrcAssemblyId->GetAttribute(rpwzAttrNames[i], &pwz, &cc);
  113. hr = (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) ? S_FALSE : hr;
  114. IF_FAILED_EXIT(hr);
  115. if (hr == S_OK)
  116. {
  117. IF_FAILED_EXIT(sValue.TakeOwnership(pwz));
  118. IF_FAILED_EXIT(pAssemblyId->SetAttribute(rpwzAttrNames[i], sValue._pwz, cc));
  119. }
  120. }
  121. hr = S_OK;
  122. *ppDestAssemblyId = pAssemblyId;
  123. pAssemblyId = NULL;
  124. exit:
  125. SAFERELEASE(pAssemblyId);
  126. return hr;
  127. }
  128. // ---------------------------------------------------------------------------
  129. // ctor
  130. // ---------------------------------------------------------------------------
  131. CAssemblyIdentity::CAssemblyIdentity()
  132. : _dwSig('TNDI'), _cRef(1), _hr(S_OK)
  133. {}
  134. // ---------------------------------------------------------------------------
  135. // dtor
  136. // ---------------------------------------------------------------------------
  137. CAssemblyIdentity::~CAssemblyIdentity()
  138. {}
  139. // ---------------------------------------------------------------------------
  140. // Init
  141. // ---------------------------------------------------------------------------
  142. HRESULT CAssemblyIdentity::Init()
  143. {
  144. _hr = _AttributeTable.Init(ATTRIBUTE_TABLE_ARRAY_SIZE);
  145. return _hr;
  146. }
  147. // ---------------------------------------------------------------------------
  148. // SetAttribute
  149. // ---------------------------------------------------------------------------
  150. HRESULT CAssemblyIdentity::SetAttribute(LPCOLESTR pwzName,
  151. LPCOLESTR pwzValue, DWORD ccValue)
  152. {
  153. CString sName;
  154. CString sValue;
  155. IF_FAILED_EXIT(sName.Assign((LPWSTR) pwzName));
  156. IF_FAILED_EXIT(sValue.Assign((LPWSTR) pwzValue));
  157. IF_FAILED_EXIT(_AttributeTable.Insert(sName, sValue));
  158. exit:
  159. return _hr;
  160. }
  161. // ---------------------------------------------------------------------------
  162. // GetAttribute
  163. // ---------------------------------------------------------------------------
  164. HRESULT CAssemblyIdentity::GetAttribute(LPCOLESTR pwzName,
  165. LPOLESTR *ppwzValue, LPDWORD pccValue)
  166. {
  167. CString sName;
  168. CString sValue;
  169. CString *psTableValue;
  170. IF_FAILED_EXIT(sName.Assign((LPWSTR) pwzName));
  171. IF_FAILED_EXIT(_AttributeTable.Retrieve(sName, &psTableValue));
  172. if (_hr == S_OK)
  173. {
  174. IF_FAILED_EXIT(sValue.Assign(*psTableValue));
  175. *pccValue = sValue.CharCount();
  176. sValue.ReleaseOwnership(ppwzValue);
  177. }
  178. exit:
  179. _hr = (_hr == S_FALSE) ? HRESULT_FROM_WIN32(ERROR_NOT_FOUND) : _hr;
  180. return _hr;
  181. }
  182. // ---------------------------------------------------------------------------
  183. // IsEqual
  184. // ---------------------------------------------------------------------------
  185. HRESULT CAssemblyIdentity::IsEqual (IAssemblyIdentity *pAssemblyId)
  186. {
  187. LPWSTR pwzBuf;
  188. DWORD ccBuf;
  189. CString sLang1, sVersion1, sToken1, sName1, sArch1;
  190. CString sLang2, sVersion2, sToken2, sName2, sArch2;
  191. // Compare architectures
  192. IF_FAILED_EXIT(pAssemblyId->GetAttribute(
  193. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PROCESSOR_ARCHITECTURE, &pwzBuf, &ccBuf));
  194. IF_FAILED_EXIT(sArch1.TakeOwnership(pwzBuf, ccBuf));
  195. IF_FAILED_EXIT(GetAttribute(
  196. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PROCESSOR_ARCHITECTURE, &pwzBuf, &ccBuf));
  197. IF_FAILED_EXIT(sArch2.TakeOwnership(pwzBuf, ccBuf));
  198. if (StrCmp (sArch1._pwz, sArch2._pwz))
  199. {
  200. _hr = S_FALSE;
  201. goto exit;
  202. }
  203. // Compare names
  204. IF_FAILED_EXIT(pAssemblyId->GetAttribute(
  205. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME, &pwzBuf, &ccBuf));
  206. IF_FAILED_EXIT(sName1.TakeOwnership(pwzBuf, ccBuf));
  207. IF_FAILED_EXIT(GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME, &pwzBuf, &ccBuf));
  208. IF_FAILED_EXIT(sName2.TakeOwnership(pwzBuf, ccBuf));
  209. if (StrCmp (sName1._pwz, sName2._pwz))
  210. {
  211. _hr = S_FALSE;
  212. goto exit;
  213. }
  214. // Compare Public Key Tokens
  215. _hr = (pAssemblyId->GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN, &pwzBuf, &ccBuf));
  216. _hr = (_hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) ? S_FALSE : _hr;
  217. IF_FAILED_EXIT(_hr);
  218. if (_hr == S_OK)
  219. IF_FAILED_EXIT(sToken1.TakeOwnership(pwzBuf, ccBuf));
  220. else
  221. IF_FAILED_EXIT(sToken1.Assign(L""));
  222. _hr = (GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN, &pwzBuf, &ccBuf));
  223. _hr = (_hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) ? S_FALSE : _hr;
  224. IF_FAILED_EXIT(_hr);
  225. if (_hr == S_OK)
  226. IF_FAILED_EXIT(sToken2.TakeOwnership(pwzBuf, ccBuf));
  227. else
  228. IF_FAILED_EXIT(sToken2.Assign(L""));
  229. if (StrCmp (sToken1._pwz, sToken2._pwz))
  230. {
  231. _hr = S_FALSE;
  232. goto exit;
  233. }
  234. // Compare Versions
  235. IF_FAILED_EXIT(pAssemblyId->GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION, &pwzBuf, &ccBuf));
  236. IF_FAILED_EXIT(sVersion1.TakeOwnership(pwzBuf, ccBuf));
  237. IF_FAILED_EXIT(GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION, &pwzBuf, &ccBuf));
  238. IF_FAILED_EXIT(sVersion2.TakeOwnership(pwzBuf, ccBuf));
  239. if (StrCmp (sVersion1._pwz, sVersion2._pwz))
  240. {
  241. _hr = S_FALSE;
  242. goto exit;
  243. }
  244. // Compare Languages
  245. IF_FAILED_EXIT(pAssemblyId->GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE, &pwzBuf, &ccBuf));
  246. IF_FAILED_EXIT(sLang1.TakeOwnership(pwzBuf, ccBuf));
  247. IF_FAILED_EXIT(GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE, &pwzBuf, &ccBuf));
  248. IF_FAILED_EXIT(sLang2.TakeOwnership(pwzBuf, ccBuf));
  249. if (StrCmp (sLang1._pwz, sLang2._pwz))
  250. {
  251. _hr = S_FALSE;
  252. goto exit;
  253. }
  254. _hr = S_OK;
  255. exit:
  256. return _hr;
  257. }
  258. #define WZ_WILDCARDSTRING L"*"
  259. // ---------------------------------------------------------------------------
  260. // GetDisplayName
  261. // ---------------------------------------------------------------------------
  262. HRESULT CAssemblyIdentity::GetDisplayName(DWORD dwFlags, LPOLESTR *ppwzDisplayName, LPDWORD pccDisplayName)
  263. {
  264. LPWSTR rpwzAttrNames[5] =
  265. {
  266. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PROCESSOR_ARCHITECTURE,
  267. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME,
  268. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN,
  269. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION,
  270. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE,
  271. };
  272. LPWSTR pwzBuf = NULL;
  273. DWORD ccBuf = 0;
  274. CString sDisplayName;
  275. for (int i = 0; i < 5; i++)
  276. {
  277. CString sBuffer;
  278. if (FAILED(_hr = GetAttribute(rpwzAttrNames[i], &pwzBuf, &ccBuf))
  279. && _hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  280. goto exit;
  281. // append anyway to keep the number of underscore constant
  282. if (i)
  283. sDisplayName.Append(L"_");
  284. if (dwFlags == ASMID_DISPLAYNAME_WILDCARDED
  285. && _hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  286. {
  287. sDisplayName.Append(WZ_WILDCARDSTRING);
  288. _hr = S_OK;
  289. }
  290. else if (_hr == S_OK)
  291. {
  292. sBuffer.TakeOwnership(pwzBuf, ccBuf);
  293. sDisplayName.Append(sBuffer);
  294. }
  295. }
  296. _hr = S_OK; // ignore missing attributes
  297. *pccDisplayName = sDisplayName.CharCount();
  298. sDisplayName.ReleaseOwnership(ppwzDisplayName);
  299. exit:
  300. return _hr;
  301. }
  302. // ---------------------------------------------------------------------------
  303. // GetCLRDisplayName
  304. // ---------------------------------------------------------------------------
  305. HRESULT CAssemblyIdentity::GetCLRDisplayName(DWORD dwFlags, LPOLESTR *ppwzDisplayName, LPDWORD pccDisplayName)
  306. {
  307. LPWSTR pwzBuf = NULL;
  308. DWORD ccBuf=0;
  309. CString sBuffer, sCLRDisplayName;
  310. if (FAILED(_hr = GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME, &pwzBuf, &ccBuf)))
  311. goto exit;
  312. sCLRDisplayName.TakeOwnership(pwzBuf, ccBuf);
  313. if (FAILED(_hr = GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_TOKEN, &pwzBuf, &ccBuf))
  314. && _hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  315. goto exit;
  316. else if ( _hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  317. _hr = S_OK;
  318. else
  319. {
  320. sBuffer.TakeOwnership(pwzBuf, ccBuf);
  321. sCLRDisplayName.Append(L",PublicKeyToken=\"");
  322. sCLRDisplayName.Append(sBuffer);
  323. sCLRDisplayName.Append(L"\"");
  324. }
  325. if (FAILED(_hr = GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_VERSION, &pwzBuf, &ccBuf))
  326. && _hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  327. goto exit;
  328. else if ( _hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  329. _hr = S_OK;
  330. else
  331. {
  332. sBuffer.TakeOwnership(pwzBuf, ccBuf);
  333. sCLRDisplayName.Append(L",Version=\"");
  334. sCLRDisplayName.Append(sBuffer);
  335. sCLRDisplayName.Append(L"\"");
  336. }
  337. if (FAILED(_hr = GetAttribute(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_LANGUAGE, &pwzBuf, &ccBuf))
  338. && _hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
  339. goto exit;
  340. else if ( _hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) || !StrCmp(pwzBuf, L"x-ww"))
  341. {
  342. _hr = S_OK;
  343. sCLRDisplayName.Append(L",Culture=\"neutral\"");
  344. }
  345. else
  346. {
  347. sBuffer.TakeOwnership(pwzBuf, ccBuf);
  348. sCLRDisplayName.Append(L",Culture=\"");
  349. sCLRDisplayName.Append(sBuffer);
  350. sCLRDisplayName.Append(L"\"");
  351. }
  352. *pccDisplayName = sCLRDisplayName.CharCount();
  353. sCLRDisplayName.ReleaseOwnership(ppwzDisplayName);
  354. exit:
  355. return _hr;
  356. }
  357. // IUnknown Boilerplate
  358. // ---------------------------------------------------------------------------
  359. // CAssemblyIdentity::QI
  360. // ---------------------------------------------------------------------------
  361. STDMETHODIMP
  362. CAssemblyIdentity::QueryInterface(REFIID riid, void** ppvObj)
  363. {
  364. if ( IsEqualIID(riid, IID_IUnknown)
  365. || IsEqualIID(riid, IID_IAssemblyIdentity)
  366. )
  367. {
  368. *ppvObj = static_cast<IAssemblyIdentity*> (this);
  369. AddRef();
  370. return S_OK;
  371. }
  372. else
  373. {
  374. *ppvObj = NULL;
  375. return E_NOINTERFACE;
  376. }
  377. }
  378. // ---------------------------------------------------------------------------
  379. // CAssemblyIdentity::AddRef
  380. // ---------------------------------------------------------------------------
  381. STDMETHODIMP_(ULONG)
  382. CAssemblyIdentity::AddRef()
  383. {
  384. return InterlockedIncrement ((LONG*) &_cRef);
  385. }
  386. // ---------------------------------------------------------------------------
  387. // CAssemblyIdentity::Release
  388. // ---------------------------------------------------------------------------
  389. STDMETHODIMP_(ULONG)
  390. CAssemblyIdentity::Release()
  391. {
  392. ULONG lRet = InterlockedDecrement ((LONG*) &_cRef);
  393. if (!lRet)
  394. delete this;
  395. return lRet;
  396. }