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.

546 lines
14 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. sxsoleaut.cpp
  5. Abstract:
  6. Implementation of helper functions called by oleaut32.dll to
  7. get type library and clsid isolation.
  8. Author:
  9. Michael J. Grier (MGrier) 19-May-2000
  10. Revision History:
  11. Jay Krell (JayKrell) November 2001
  12. fixed typelibrary redirection
  13. key typelibraries by guid only, then verify language
  14. --*/
  15. #include "stdinc.h"
  16. #include <windows.h>
  17. #include "sxsp.h"
  18. #include "fusionhandle.h"
  19. typedef const GUID * PCGUID;
  20. typedef CGenericStringBuffer<1, CUnicodeCharTraits> CSmallestUnicodeStringBuffer;
  21. extern "C"
  22. {
  23. extern const CLSID CLSID_PSDispatch;
  24. extern const CLSID CLSID_PSAutomation;
  25. };
  26. HRESULT
  27. FusionpWin32GetAssemblyDirectory(
  28. PCACTCTX_SECTION_KEYED_DATA askd,
  29. CBaseStringBuffer & rbuf
  30. );
  31. HRESULT
  32. HrFusionpWin32GetAssemblyDirectory(
  33. PCACTCTX_SECTION_KEYED_DATA askd,
  34. CBaseStringBuffer & rbuff
  35. );
  36. BOOL
  37. FusionpHasAssemblyDirectory(
  38. PCACTCTX_SECTION_KEYED_DATA askd
  39. );
  40. HRESULT
  41. HrFusionpOleaut_CopyString(
  42. PWSTR Buffer,
  43. SIZE_T BufferSizeAvailable,
  44. SIZE_T * BufferSizeWrittenOrRequired,
  45. PCWSTR String,
  46. SIZE_T Length
  47. )
  48. {
  49. HRESULT hr;
  50. if (BufferSizeAvailable >= (Length + 1))
  51. {
  52. if (Buffer != NULL)
  53. {
  54. ::memcpy(Buffer, String, (Length * sizeof(WCHAR)));
  55. Buffer[Length] = L'\0';
  56. }
  57. *BufferSizeWrittenOrRequired = Length;
  58. hr = NOERROR;
  59. }
  60. else
  61. {
  62. // Need ... more .... room!
  63. *BufferSizeWrittenOrRequired = (Length + 1);
  64. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  65. goto Exit;
  66. }
  67. Exit:
  68. return hr;
  69. }
  70. HRESULT
  71. HrFusionpOleaut_GetTypeLibraryName(
  72. PCACTCTX_SECTION_KEYED_DATA askd,
  73. PCWSTR * ppsz,
  74. SIZE_T * pcch
  75. )
  76. {
  77. HRESULT hr = E_UNEXPECTED;
  78. FN_TRACE_HR(hr);
  79. ULONG cch = 0;
  80. PCWSTR psz = 0;
  81. if (ppsz != NULL)
  82. *ppsz = NULL;
  83. if (pcch != NULL)
  84. *pcch = 0;
  85. INTERNAL_ERROR_CHECK(askd != NULL);
  86. INTERNAL_ERROR_CHECK(ppsz != NULL);
  87. INTERNAL_ERROR_CHECK(pcch != NULL);
  88. PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION Data = reinterpret_cast<PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION>(askd->lpData);
  89. if (Data->NameOffset == 0)
  90. {
  91. psz = NULL;
  92. cch = 0;
  93. }
  94. else
  95. {
  96. psz = reinterpret_cast<PCWSTR>(reinterpret_cast<ULONG_PTR>(askd->lpSectionBase) + Data->NameOffset);
  97. cch = Data->NameLength / sizeof(WCHAR);
  98. if (cch != 0 && psz[cch - 1] == 0)
  99. cch -= 1;
  100. }
  101. *ppsz = psz;
  102. *pcch = cch;
  103. hr = NOERROR;
  104. Exit:
  105. return hr;
  106. }
  107. HRESULT
  108. HrFusionpOleaut_GetTypeLibraryFullPath(
  109. PCACTCTX_SECTION_KEYED_DATA askd,
  110. CBaseStringBuffer & rbuff
  111. )
  112. {
  113. FN_PROLOG_HR
  114. PCWSTR TypeLibraryName = NULL;
  115. SIZE_T TypeLibraryNameLength = 0;
  116. HANDLE ActivationContextHandle = NULL;
  117. IFCOMFAILED_EXIT(HrFusionpOleaut_GetTypeLibraryName(askd, &TypeLibraryName, &TypeLibraryNameLength));
  118. IFW32FALSE_EXIT(FusionpGetActivationContextFromFindResult(askd, &ActivationContextHandle));
  119. IFW32FALSE_EXIT(FusionpSearchPath(
  120. FUSIONP_SEARCH_PATH_ACTCTX,
  121. NULL, // path to search
  122. TypeLibraryName,
  123. NULL, // extension
  124. rbuff,
  125. NULL, // offset to file part
  126. ActivationContextHandle
  127. ));
  128. FN_EPILOG
  129. }
  130. #define FUSIONP_OLEAUT_HANDLE_FIND_ERROR() \
  131. do { \
  132. const DWORD dwLastError = ::FusionpGetLastWin32Error(); \
  133. \
  134. if ((dwLastError == ERROR_SXS_KEY_NOT_FOUND) || (dwLastError == ERROR_SXS_SECTION_NOT_FOUND)) \
  135. { \
  136. hr = S_FALSE; \
  137. goto Exit; \
  138. } \
  139. \
  140. hr = HRESULT_FROM_WIN32(dwLastError); \
  141. goto Exit; \
  142. } while(0)
  143. EXTERN_C
  144. HRESULT
  145. STDAPICALLTYPE
  146. SxsOleAut32MapReferenceClsidToConfiguredClsid(
  147. REFCLSID rclsidIn,
  148. CLSID *pclsidOut
  149. )
  150. {
  151. HRESULT hr = NOERROR;
  152. FN_TRACE_HR(hr);
  153. ACTCTX_SECTION_KEYED_DATA askd;
  154. PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Data = NULL;
  155. PARAMETER_CHECK(pclsidOut != NULL);
  156. askd.cbSize = sizeof(askd);
  157. if (!::FindActCtxSectionGuid(
  158. 0,
  159. NULL,
  160. ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION,
  161. &rclsidIn,
  162. &askd))
  163. {
  164. FUSIONP_OLEAUT_HANDLE_FIND_ERROR();
  165. }
  166. Data = (PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION) askd.lpData;
  167. if ((askd.ulDataFormatVersion != ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_FORMAT_WHISTLER) ||
  168. (askd.ulLength < sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION)) ||
  169. (Data->Size < sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION)))
  170. {
  171. hr = HRESULT_FROM_WIN32(ERROR_SXS_INVALID_ACTCTXDATA_FORMAT);
  172. goto Exit;
  173. }
  174. // We should be clear to go now.
  175. if (pclsidOut != NULL)
  176. *pclsidOut = Data->ConfiguredClsid;
  177. hr = NOERROR;
  178. Exit:
  179. return hr;
  180. }
  181. HRESULT
  182. SxspOleAut32RedirectTypeLibrary(
  183. LPCOLESTR szGuid,
  184. WORD wMaj,
  185. WORD wMin,
  186. LANGID langid,
  187. SIZE_T *pcchFileName,
  188. LPOLESTR rgFileName
  189. )
  190. {
  191. HRESULT hr = E_UNEXPECTED;
  192. FN_TRACE_HR(hr);
  193. CFusionActCtxHandle ActCtxHandle;
  194. PARAMETER_CHECK(szGuid != NULL);
  195. PARAMETER_CHECK(pcchFileName != NULL);
  196. PARAMETER_CHECK((rgFileName != NULL) || (*pcchFileName));
  197. ACTCTX_SECTION_KEYED_DATA askd;
  198. PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION Data = NULL;
  199. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER AssemblyRosterHeader = NULL;
  200. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY AssemblyRosterEntry = NULL;
  201. askd.cbSize = sizeof(askd);
  202. askd.hActCtx = NULL;
  203. {
  204. GUID Guid;
  205. IFW32FALSE_EXIT(SxspParseGUID(szGuid, ::wcslen(szGuid), Guid));
  206. if (!::FindActCtxSectionGuid(
  207. FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
  208. | FIND_ACTCTX_SECTION_KEY_RETURN_FLAGS
  209. | FIND_ACTCTX_SECTION_KEY_RETURN_ASSEMBLY_METADATA,
  210. NULL,
  211. ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
  212. &Guid,
  213. &askd))
  214. {
  215. FUSIONP_OLEAUT_HANDLE_FIND_ERROR();
  216. }
  217. }
  218. ActCtxHandle = askd.hActCtx; // ReleaseActCtx in destructor
  219. Data = (PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION) askd.lpData;
  220. if ((askd.ulDataFormatVersion != ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_FORMAT_WHISTLER) ||
  221. (askd.ulLength < sizeof(ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION)) ||
  222. (Data->Size < sizeof(ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION)))
  223. {
  224. hr = HRESULT_FROM_WIN32(ERROR_SXS_INVALID_ACTCTXDATA_FORMAT);
  225. goto Exit;
  226. }
  227. if (langid != MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL))
  228. {
  229. ULONG LanguageLength = 0;
  230. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION AssemblyInformation = NULL;
  231. AssemblyInformation = reinterpret_cast<PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION>(askd.AssemblyMetadata.lpInformation);
  232. LanguageLength = (AssemblyInformation->LanguageLength / sizeof(WCHAR));
  233. if (LanguageLength != 0)
  234. {
  235. CSmallestUnicodeStringBuffer Cultures[2];
  236. PCWSTR LanguageString = NULL;
  237. // we should do bounds checking here against AssemblyMetadata.ulSectionLength
  238. LanguageString = reinterpret_cast<PCWSTR>(AssemblyInformation->LanguageOffset + reinterpret_cast<PCBYTE>(askd.AssemblyMetadata.lpSectionBase));
  239. IFW32FALSE_EXIT(SxspMapLANGIDToCultures(langid, Cultures[0], Cultures[1]));
  240. if (LanguageLength != 0 && LanguageString[LanguageLength - 1] == 0)
  241. LanguageLength -= 1;
  242. if ( !FusionpEqualStringsI(LanguageString, LanguageLength, Cultures[0])
  243. && !FusionpEqualStringsI(LanguageString, LanguageLength, Cultures[1])
  244. )
  245. {
  246. hr = S_FALSE;
  247. goto Exit;
  248. }
  249. }
  250. }
  251. if (wMaj != 0 || wMin != 0)
  252. {
  253. if (wMaj != Data->Version.Major)
  254. {
  255. hr = S_FALSE;
  256. goto Exit;
  257. }
  258. if (wMin > Data->Version.Minor)
  259. {
  260. hr = S_FALSE;
  261. goto Exit;
  262. }
  263. }
  264. {
  265. CSmallestUnicodeStringBuffer buff;
  266. IFCOMFAILED_EXIT(HrFusionpOleaut_GetTypeLibraryFullPath(&askd, buff));
  267. IFCOMFAILED_EXIT(
  268. HrFusionpOleaut_CopyString(
  269. rgFileName,
  270. *pcchFileName,
  271. pcchFileName,
  272. static_cast<PCWSTR>(buff),
  273. buff.Cch()
  274. ));
  275. }
  276. hr = NOERROR;
  277. Exit:
  278. return hr;
  279. }
  280. LANGID
  281. FusionpLanguageIdFromLocaleId(
  282. LCID lcid
  283. )
  284. {
  285. //
  286. // LANGIDFROMLCID does not actually remove non default sort.
  287. //
  288. LANGID Language = LANGIDFROMLCID(lcid);
  289. ULONG PrimaryLanguage = PRIMARYLANGID(Language);
  290. ULONG SubLanguage = SUBLANGID(Language);
  291. Language = MAKELANGID(PrimaryLanguage, SubLanguage);
  292. return Language;
  293. }
  294. EXTERN_C
  295. HRESULT
  296. STDAPICALLTYPE
  297. SxsOleAut32RedirectTypeLibrary(
  298. LPCOLESTR szGuid,
  299. WORD wMaj,
  300. WORD wMin,
  301. LCID lcid,
  302. BOOL /*fHighest*/,
  303. SIZE_T *pcchFileName,
  304. LPOLESTR rgFileName
  305. )
  306. {
  307. HRESULT hr = E_UNEXPECTED;
  308. FN_TRACE_HR(hr);
  309. PARAMETER_CHECK(szGuid != NULL);
  310. PARAMETER_CHECK(pcchFileName != NULL);
  311. PARAMETER_CHECK(rgFileName != NULL || *pcchFileName == 0);
  312. IFCOMFAILED_EXIT(hr = ::SxspOleAut32RedirectTypeLibrary(szGuid, wMaj, wMin, FusionpLanguageIdFromLocaleId(lcid), pcchFileName, rgFileName));
  313. Exit:
  314. return hr;
  315. }
  316. HRESULT
  317. HrFusionpOleaut_MapIIDToTLBID(
  318. REFIID riid,
  319. PCGUID* ppctlbid
  320. )
  321. {
  322. HRESULT hr = E_UNEXPECTED;
  323. FN_TRACE_HR(hr);
  324. ACTCTX_SECTION_KEYED_DATA askd;
  325. PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Data = 0;
  326. PARAMETER_CHECK(&riid != NULL);
  327. PARAMETER_CHECK(ppctlbid != NULL);
  328. *ppctlbid = NULL;
  329. askd.cbSize = sizeof(askd);
  330. if (!::FindActCtxSectionGuid(
  331. 0,
  332. NULL,
  333. ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
  334. &riid,
  335. &askd))
  336. {
  337. FUSIONP_OLEAUT_HANDLE_FIND_ERROR();
  338. }
  339. Data = reinterpret_cast<PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION>(askd.lpData);
  340. *ppctlbid = &Data->TypeLibraryId;
  341. hr = NOERROR;
  342. Exit:
  343. return hr;
  344. }
  345. EXTERN_C
  346. HRESULT
  347. STDAPICALLTYPE
  348. SxsOleAut32MapIIDToTLBPath(
  349. REFIID riid,
  350. SIZE_T cchBuffer,
  351. WCHAR *pBuffer,
  352. SIZE_T *pcchWrittenOrRequired
  353. )
  354. {
  355. HRESULT hr = E_UNEXPECTED;
  356. FN_TRACE_HR(hr);
  357. ACTCTX_SECTION_KEYED_DATA askd;
  358. PCGUID pctlbid = NULL;
  359. CSmallStringBuffer buff;
  360. CFusionActCtxHandle ActCtxHandle;
  361. PARAMETER_CHECK(&riid != NULL);
  362. PARAMETER_CHECK(pBuffer != NULL);
  363. PARAMETER_CHECK(pcchWrittenOrRequired != NULL);
  364. PARAMETER_CHECK(cchBuffer != 0);
  365. IFCOMFAILED_EXIT(hr = HrFusionpOleaut_MapIIDToTLBID(riid, &pctlbid));
  366. if (hr == S_FALSE)
  367. {
  368. goto Exit;
  369. }
  370. askd.cbSize = sizeof(askd);
  371. if (!::FindActCtxSectionGuid(
  372. FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
  373. | FIND_ACTCTX_SECTION_KEY_RETURN_FLAGS,
  374. NULL,
  375. ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
  376. pctlbid,
  377. &askd))
  378. {
  379. FUSIONP_OLEAUT_HANDLE_FIND_ERROR();
  380. }
  381. ActCtxHandle = askd.hActCtx; // ReleaseActCtx in destructor
  382. IFCOMFAILED_EXIT(HrFusionpOleaut_GetTypeLibraryFullPath(&askd, buff));
  383. //
  384. // We do not care about version or language in this case.
  385. //
  386. IFCOMFAILED_EXIT(
  387. HrFusionpOleaut_CopyString(
  388. pBuffer,
  389. cchBuffer,
  390. pcchWrittenOrRequired,
  391. static_cast<PCWSTR>(buff),
  392. buff.Cch()
  393. ));
  394. hr = NOERROR;
  395. Exit:
  396. return hr;
  397. }
  398. EXTERN_C
  399. HRESULT
  400. STDAPICALLTYPE
  401. SxsOleAut32MapIIDToProxyStubCLSID(
  402. REFIID riid,
  403. CLSID * pclsidOut
  404. )
  405. {
  406. HRESULT hr = E_UNEXPECTED;
  407. FN_TRACE_HR(hr);
  408. ACTCTX_SECTION_KEYED_DATA askd;
  409. PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Data = 0;
  410. if (pclsidOut != NULL)
  411. *pclsidOut = GUID_NULL;
  412. PARAMETER_CHECK(&riid != NULL);
  413. PARAMETER_CHECK(pclsidOut != NULL);
  414. askd.cbSize = sizeof(askd);
  415. if (!::FindActCtxSectionGuid(
  416. 0,
  417. NULL,
  418. ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
  419. &riid,
  420. &askd))
  421. {
  422. FUSIONP_OLEAUT_HANDLE_FIND_ERROR();
  423. }
  424. Data = reinterpret_cast<PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION>(askd.lpData);
  425. *pclsidOut = Data->ProxyStubClsid32;
  426. //
  427. // There are only USUALLY two acceptable answers here.
  428. // (but there is one bit of code in oleaut32.dll that is
  429. // actually look for anything but these two.)
  430. //
  431. // CLSID_PSDispatch {00020424-0000-0000-C000-000000000046}
  432. // CLSID_PSAutomation {00020420-0000-0000-C000-000000000046}
  433. //
  434. #if DBG
  435. {
  436. ULONG i;
  437. const static struct
  438. {
  439. const GUID * Guid;
  440. STRING Name;
  441. } GuidNameMap[] =
  442. {
  443. { NULL, RTL_CONSTANT_STRING("unknown") },
  444. { &CLSID_PSDispatch, RTL_CONSTANT_STRING("CLSID_PSDispatch") },
  445. { &CLSID_PSAutomation, RTL_CONSTANT_STRING("CLSID_PSAutomation") }
  446. };
  447. for (i = 1 ; i != NUMBER_OF(GuidNameMap) ; ++i)
  448. if (Data->ProxyStubClsid32 == *GuidNameMap[i].Guid)
  449. break;
  450. if (i == NUMBER_OF(GuidNameMap))
  451. i = 0;
  452. ::FusionpDbgPrintEx(
  453. FUSION_DBG_LEVEL_VERBOSE | FUSION_DBG_LEVEL_INFO,
  454. "SXS: %s returning %Z\n",
  455. __FUNCTION__,
  456. &GuidNameMap[i].Name
  457. );
  458. }
  459. #endif
  460. hr = NOERROR;
  461. Exit:
  462. return hr;
  463. }