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.

2499 lines
87 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. sxs.c
  5. Abstract:
  6. Side-by-side activation APIs for Win32
  7. Author:
  8. Michael Grier (MGrier) 2/29/2000
  9. Revision History:
  10. Jay Krell (a-JayK) June - July 2000
  11. factored/merged with sxs.c, source code duplication eliminated
  12. moved file opening out of csrss.exe to client process
  13. merged with MGrier: flag per added api struct field, assembly dir support
  14. Jon Wiswall (jonwis) Dec. 2000
  15. Moved code here from csrsxs.c to make csrsxs.c tiny and more in-line with general
  16. csrxxxx.c coding patterns, and to fix when we look in system32 vs. when
  17. we look in syswow64
  18. Jon Wiswall (jonwis) December 2000
  19. ACTCTX's that don't specify what resource ID they want now automagically
  20. search through the sources to find a resource type in the "actctx
  21. source." This requires a gross EnumResourceNamesW call, after a
  22. stomach-churning LoadLibraryExW to load the object.
  23. Jay Krell (JayKrell) May 2001
  24. CreateActCtx now honors "administrative" override for .dlls. (foo.dll.2.manifest)
  25. (not) CreateActCtx now implements ACTCTX_FLAG_LIKE_CREATEPROCESS flag (foo.exe.manifest)
  26. --*/
  27. #include "basedll.h"
  28. #include <sxstypes.h>
  29. #include "SxsApi.h"
  30. #include "winuser.h"
  31. #if !defined(RTL_NUL_TERMINATE_STRING)
  32. #define RTL_NUL_TERMINATE_STRING(x) ((x)->Buffer[(x)->Length / sizeof(*(x)->Buffer)] = 0)
  33. #endif
  34. #define DPFLTR_LEVEL_STATUS(x) ((NT_SUCCESS(x) \
  35. || (x) == STATUS_OBJECT_NAME_NOT_FOUND \
  36. || (x) == STATUS_RESOURCE_DATA_NOT_FOUND \
  37. || (x) == STATUS_RESOURCE_TYPE_NOT_FOUND \
  38. || (x) == STATUS_RESOURCE_NAME_NOT_FOUND \
  39. || (x) == STATUS_RESOURCE_LANG_NOT_FOUND \
  40. || (x) == STATUS_SXS_CANT_GEN_ACTCTX \
  41. ) \
  42. ? DPFLTR_TRACE_LEVEL : DPFLTR_ERROR_LEVEL)
  43. #define ACTCTX_VALID_FLAGS \
  44. ( \
  45. ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID | \
  46. ACTCTX_FLAG_LANGID_VALID | \
  47. ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID | \
  48. ACTCTX_FLAG_RESOURCE_NAME_VALID | \
  49. ACTCTX_FLAG_SET_PROCESS_DEFAULT | \
  50. ACTCTX_FLAG_APPLICATION_NAME_VALID | \
  51. ACTCTX_FLAG_HMODULE_VALID \
  52. /*| ACTCTX_FLAG_LIKE_CREATEPROCESS*/ \
  53. )
  54. // This is the name for the manifest if we are given an assembly root directory but no manifest name is specified.
  55. const WCHAR ManifestDefaultName[] = L"Application.Manifest";
  56. #define MAXSIZE_T (~(SIZE_T)0)
  57. extern const UNICODE_STRING SxsManifestSuffix = RTL_CONSTANT_STRING(L".Manifest");
  58. extern const UNICODE_STRING SxsPolicySuffix = RTL_CONSTANT_STRING(L".Config");
  59. #define MEDIUM_PATH (64)
  60. //#define IsSxsAcceptablePathType(x) (x in (RtlPathTypeUncAbsolute, RtlPathTypeDriveAbsolute, RtlPathTypeLocalDevice))
  61. #define IsSxsAcceptablePathType(x) ((x == RtlPathTypeUncAbsolute) || (x == RtlPathTypeDriveAbsolute) || (x == RtlPathTypeLocalDevice))
  62. VOID
  63. BasepSxsOverrideStreamToMessageStream(
  64. IN PCSXS_OVERRIDE_STREAM OverrideStream,
  65. OUT PBASE_MSG_SXS_STREAM MessageStream
  66. );
  67. HANDLE
  68. WINAPI
  69. CreateActCtxA(
  70. PCACTCTXA pParamsA
  71. )
  72. {
  73. ACTCTXW ParamsW = {sizeof(ParamsW)};
  74. PUNICODE_STRING UnicodeString;
  75. ANSI_STRING AnsiString;
  76. NTSTATUS Status = STATUS_SUCCESS;
  77. HANDLE ActivationContextHandle = INVALID_HANDLE_VALUE;
  78. UNICODE_STRING AssemblyDir = {0};
  79. WCHAR AssemblyDirBuffer[STATIC_UNICODE_BUFFER_LENGTH];
  80. ULONG_PTR MappedResourceName = 0;
  81. const PTEB Teb = NtCurrentTeb();
  82. if (pParamsA == NULL
  83. || !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, lpSource)
  84. ) {
  85. DbgPrintEx(
  86. DPFLTR_SXS_ID,
  87. DPFLTR_ERROR_LEVEL,
  88. "SXS: %s() Null %p or size 0x%lx too small\n",
  89. __FUNCTION__,
  90. pParamsA,
  91. pParamsA->cbSize
  92. );
  93. Status = STATUS_INVALID_PARAMETER;
  94. goto Exit;
  95. }
  96. ParamsW.dwFlags = pParamsA->dwFlags;
  97. if (((ParamsW.dwFlags & ~ACTCTX_VALID_FLAGS) != 0) ||
  98. ((ParamsW.dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID) && !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, wProcessorArchitecture)) ||
  99. ((ParamsW.dwFlags & ACTCTX_FLAG_LANGID_VALID) && !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, wLangId)) ||
  100. ((ParamsW.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) && !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, lpAssemblyDirectory)) ||
  101. ((ParamsW.dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) && !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, lpResourceName)) ||
  102. ((ParamsW.dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID) && !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, lpApplicationName)) ||
  103. ((ParamsW.dwFlags & ACTCTX_FLAG_HMODULE_VALID) && !RTL_CONTAINS_FIELD(pParamsA, pParamsA->cbSize, hModule))) {
  104. DbgPrintEx(
  105. DPFLTR_SXS_ID,
  106. DPFLTR_ERROR_LEVEL,
  107. "SXS: %s() Bad flags/size 0x%lx/0x%lx\n",
  108. __FUNCTION__,
  109. pParamsA->dwFlags,
  110. pParamsA->cbSize);
  111. Status = STATUS_INVALID_PARAMETER;
  112. goto Exit;
  113. }
  114. if (pParamsA->lpSource != NULL) {
  115. UnicodeString = &Teb->StaticUnicodeString;
  116. RtlInitAnsiString(&AnsiString, pParamsA->lpSource);
  117. Status = Basep8BitStringToUnicodeString(UnicodeString, &AnsiString, FALSE);
  118. if (!NT_SUCCESS(Status)) {
  119. if (Status == STATUS_BUFFER_OVERFLOW) {
  120. Status = STATUS_NAME_TOO_LONG;
  121. }
  122. goto Exit;
  123. }
  124. ParamsW.lpSource = UnicodeString->Buffer;
  125. } else {
  126. if ((ParamsW.dwFlags & ACTCTX_FLAG_HMODULE_VALID) == 0) {
  127. Status = STATUS_INVALID_PARAMETER;
  128. goto Exit;
  129. }
  130. ParamsW.lpSource = NULL;
  131. }
  132. if (ParamsW.dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID) {
  133. ParamsW.wProcessorArchitecture = pParamsA->wProcessorArchitecture;
  134. }
  135. if (ParamsW.dwFlags & ACTCTX_FLAG_LANGID_VALID) {
  136. ParamsW.wLangId = pParamsA->wLangId;
  137. }
  138. if (ParamsW.dwFlags & ACTCTX_FLAG_HMODULE_VALID) {
  139. ParamsW.hModule = pParamsA->hModule;
  140. }
  141. if (ParamsW.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) {
  142. RtlInitAnsiString(&AnsiString, pParamsA->lpAssemblyDirectory);
  143. AssemblyDir.MaximumLength = sizeof(AssemblyDirBuffer);
  144. AssemblyDir.Buffer = AssemblyDirBuffer;
  145. Status = Basep8BitStringToUnicodeString(&AssemblyDir, &AnsiString, FALSE);
  146. #if 0 // This is inconsistent. Two string ANSI APIs like MoveFileA are only
  147. // documented to support MAX_PATH. They actually support one of the strings
  148. // being unlimited, but let's stick to what is documented.
  149. if (Status == STATUS_BUFFER_OVERFLOW) {
  150. // Try again, this time with dynamic allocation
  151. Status = Basep8BitStringToUnicodeString(&AssemblyDir, &AnsiString, TRUE);
  152. }
  153. #endif
  154. if (Status == STATUS_BUFFER_OVERFLOW) {
  155. Status = STATUS_NAME_TOO_LONG;
  156. }
  157. if (NT_ERROR(Status))
  158. goto Exit;
  159. ParamsW.lpAssemblyDirectory = AssemblyDir.Buffer;
  160. }
  161. if (ParamsW.dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) {
  162. MappedResourceName = BaseDllMapResourceIdA(pParamsA->lpResourceName);
  163. if (MappedResourceName == -1) {
  164. DbgPrintEx(
  165. DPFLTR_SXS_ID,
  166. DPFLTR_ERROR_LEVEL,
  167. "SXS: %s() BaseDllMapResourceIdA failed\n",
  168. __FUNCTION__);
  169. Status = Teb->LastStatusValue;
  170. goto Exit;
  171. }
  172. ParamsW.lpResourceName = (PCWSTR) MappedResourceName;
  173. }
  174. ActivationContextHandle = CreateActCtxW(&ParamsW);
  175. if (ActivationContextHandle == INVALID_HANDLE_VALUE) {
  176. Status = Teb->LastStatusValue;
  177. }
  178. Exit:
  179. if (AssemblyDir.Buffer != NULL
  180. && AssemblyDir.Buffer != AssemblyDirBuffer) {
  181. RtlFreeUnicodeString(&AssemblyDir);
  182. }
  183. BaseDllFreeResourceId(MappedResourceName);
  184. if (ActivationContextHandle == INVALID_HANDLE_VALUE) {
  185. BaseSetLastNTError(Status);
  186. }
  187. #if DBG
  188. if ( ActivationContextHandle == INVALID_HANDLE_VALUE ) {
  189. DbgPrintEx( DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status),
  190. "SXS: Exiting %s(%s, %p), Handle:%p, Status:0x%lx\n",
  191. __FUNCTION__,
  192. (pParamsA != NULL) ? pParamsA->lpSource : NULL,
  193. (pParamsA != NULL) ? pParamsA->lpResourceName : NULL,
  194. ActivationContextHandle,
  195. Status
  196. );
  197. }
  198. #endif
  199. return ActivationContextHandle;
  200. }
  201. USHORT
  202. BasepSxsGetProcessorArchitecture(
  203. VOID
  204. )
  205. {
  206. //
  207. // Return the processor architecture of the currently executing code/process.
  208. //
  209. USHORT Result;
  210. #if defined(BUILD_WOW6432)
  211. Result = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64;
  212. #elif defined(_M_IX86)
  213. Result = PROCESSOR_ARCHITECTURE_INTEL;
  214. #elif defined(_M_IA64)
  215. Result = PROCESSOR_ARCHITECTURE_IA64;
  216. #elif defined(_M_AMD64)
  217. Result = PROCESSOR_ARCHITECTURE_AMD64;
  218. #else
  219. static USHORT StaticResult;
  220. static BOOL Inited = FALSE;
  221. if (!Inited) {
  222. SYSTEM_INFO SystemInfo;
  223. SystemInfo.wProcessorArchictecure = 0;
  224. GetSystemInfo(&SystemInfo);
  225. StaticResult = SystemInfo.wProcessorArchictecure;
  226. Inited = TRUE;
  227. }
  228. Result = StaticResult;
  229. #endif
  230. return Result;
  231. }
  232. VOID
  233. NTAPI
  234. BasepSxsActivationContextNotification(
  235. IN ULONG NotificationType,
  236. IN PACTIVATION_CONTEXT ActivationContext,
  237. IN const VOID *ActivationContextData,
  238. IN PVOID NotificationContext,
  239. IN PVOID NotificationData,
  240. IN OUT PBOOLEAN DisableNotification
  241. )
  242. {
  243. switch (NotificationType)
  244. {
  245. case ACTIVATION_CONTEXT_NOTIFICATION_DESTROY:
  246. RTL_SOFT_VERIFY(NT_SUCCESS(NtUnmapViewOfSection(NtCurrentProcess(), (PVOID) ActivationContextData)));
  247. break;
  248. default:
  249. // Otherwise, we don't need to see this notification ever again.
  250. *DisableNotification = TRUE;
  251. break;
  252. }
  253. }
  254. #if DBG
  255. VOID
  256. DbgPrintActCtx(
  257. PCSTR FunctionPlus,
  258. PCACTCTXW ActCtx
  259. )
  260. {
  261. // odd but correct
  262. if (NtQueryDebugFilterState(DPFLTR_SXS_ID, DPFLTR_INFO_LEVEL) != TRUE)
  263. return;
  264. DbgPrint("%s Flags 0x%08lx(%s%s%s%s%s%s%s%s%s)\n",
  265. FunctionPlus,
  266. ActCtx->dwFlags,
  267. (ActCtx->dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID ) ? " processor" : "",
  268. (ActCtx->dwFlags & ACTCTX_FLAG_LANGID_VALID ) ? " langid" : "",
  269. (ActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID ) ? " directory" : "",
  270. (ActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID ) ? " resource" : "",
  271. (ActCtx->dwFlags & ACTCTX_FLAG_SET_PROCESS_DEFAULT ) ? " setdefault" : "",
  272. (ActCtx->dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID ) ? " appname" : "",
  273. (ActCtx->dwFlags & ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF ) ? " asmref" : "",
  274. (ActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID ) ? " hmodule" : "",
  275. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  276. (ActCtx->dwFlags & ACTCTX_FLAG_LIKE_CREATEPROCESS ) ? " likecreateprocess" : ""
  277. #else
  278. ""
  279. #endif
  280. );
  281. DbgPrint("%s Source %ls\n", FunctionPlus, ActCtx->lpSource);
  282. if (ActCtx->dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID)
  283. DbgPrint("%s ProcessorArchitecture 0x%08lx\n", FunctionPlus, ActCtx->wProcessorArchitecture);
  284. if (ActCtx->dwFlags & ACTCTX_FLAG_LANGID_VALID)
  285. DbgPrint("%s LangId 0x%08lx\n", FunctionPlus, ActCtx->wLangId);
  286. if (ActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID)
  287. DbgPrint("%s AssemblyDirectory %ls\n", FunctionPlus, ActCtx->lpAssemblyDirectory);
  288. if (ActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID)
  289. DbgPrint("%s ResourceName %p (%Id)\n", FunctionPlus, ActCtx->lpResourceName, (ULONG_PTR) ActCtx->lpResourceName);
  290. if (ActCtx->dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID)
  291. DbgPrint("%s ApplicationName %ls\n", FunctionPlus, ActCtx->lpApplicationName);
  292. if (ActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID)
  293. DbgPrint("%s hModule = %p\n", FunctionPlus, ActCtx->hModule);
  294. }
  295. #else
  296. #define DbgPrintActCtx(FunctionPlus, ActCtx) /* nothing */
  297. #endif
  298. typedef struct EnumResParams {
  299. ULONG_PTR *MappedResourceName;
  300. BOOL FoundManifest;
  301. BOOL ErrorEncountered;
  302. } EnumResParams;
  303. BOOL CALLBACK
  304. BasepSxsSuitableManifestCallback(
  305. HMODULE hModule,
  306. PCWSTR lpszType,
  307. PWSTR lpszName,
  308. LONG_PTR lParam
  309. )
  310. {
  311. EnumResParams *pParams = (EnumResParams*)lParam;
  312. BOOL fContinueEnumeration = FALSE;
  313. #if DBG
  314. DbgPrintEx( DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL,
  315. "Sxs.c: %s(%p, %p, %p, %p)\n",
  316. __FUNCTION__, hModule, lpszType, lpszName, lParam
  317. );
  318. #endif
  319. ASSERT((pParams != NULL) &&
  320. (!pParams->ErrorEncountered) &&
  321. (!pParams->FoundManifest) &&
  322. (pParams->MappedResourceName != NULL));
  323. ASSERT(lpszType == MAKEINTRESOURCEW(RT_MANIFEST));
  324. // Boo! Boooooo!
  325. if ((pParams == NULL) ||
  326. (pParams->ErrorEncountered) ||
  327. (pParams->FoundManifest) ||
  328. (pParams->MappedResourceName == NULL)) {
  329. // None of these should be able to happen except if there is a coding error in the caller
  330. // of EnumResourceNamesW() or in the code for EnumResourceNamesW().
  331. if (pParams != NULL)
  332. pParams->ErrorEncountered = TRUE;
  333. SetLastError(ERROR_INVALID_PARAMETER);
  334. fContinueEnumeration = FALSE;
  335. goto Exit;
  336. }
  337. #if DBG
  338. DbgPrintEx(
  339. DPFLTR_SXS_ID,
  340. DPFLTR_TRACE_LEVEL,
  341. " Params (start): { ResName: *(%p) = %p, Found: %s, Error: %s }",
  342. pParams->MappedResourceName, pParams->MappedResourceName,
  343. pParams->FoundManifest ? "true" : "false",
  344. pParams->ErrorEncountered ? "true" : "false");
  345. #endif
  346. if (lpszType == MAKEINTRESOURCEW(RT_MANIFEST)) {
  347. // We found one - we don't care about others
  348. *pParams->MappedResourceName = BaseDllMapResourceIdW(lpszName);
  349. pParams->FoundManifest = TRUE;
  350. fContinueEnumeration = FALSE;
  351. goto Exit;
  352. }
  353. // This should not be able to happen; we should only be called for
  354. // RT_MANIFEST resources, but in case it somehow does happen, go on to the
  355. // next one.
  356. fContinueEnumeration = TRUE;
  357. Exit:
  358. #if DBG
  359. if ((pParams != NULL) && (pParams->MappedResourceName))
  360. DbgPrintEx(
  361. DPFLTR_SXS_ID,
  362. DPFLTR_TRACE_LEVEL,
  363. " Params (end): { ResName: *(%p) = %p, Found: %s, Error: %s }",
  364. pParams->MappedResourceName, pParams->MappedResourceName,
  365. pParams->FoundManifest ? "true" : "false",
  366. pParams->ErrorEncountered ? "true" : "false");
  367. #endif
  368. return fContinueEnumeration;
  369. }
  370. NTSTATUS
  371. BasepSxsFindSuitableManifestResourceFor(
  372. PCACTCTXW Params,
  373. ULONG_PTR *MappedResourceName,
  374. BOOL *FoundManifest
  375. )
  376. {
  377. NTSTATUS Status = STATUS_SUCCESS;
  378. EnumResParams FinderParameters = { MappedResourceName, FALSE, FALSE };
  379. HMODULE hSourceItem = NULL;
  380. BOOL FreeSourceModule = FALSE;
  381. if (FoundManifest != NULL)
  382. *FoundManifest = FALSE;
  383. if (MappedResourceName != NULL)
  384. *MappedResourceName = 0;
  385. if ((FoundManifest == NULL) ||
  386. (MappedResourceName == NULL)) {
  387. Status = STATUS_INVALID_PARAMETER;
  388. goto Exit;
  389. }
  390. //
  391. // General pattern - open Params->lpSource and attempt to find the first
  392. // resource with type == RT_MANIFEST (24). Stuff its resource name into
  393. // MappedResourceName.
  394. //
  395. if (Params->dwFlags & ACTCTX_FLAG_HMODULE_VALID) {
  396. hSourceItem = Params->hModule;
  397. FreeSourceModule = FALSE;
  398. } else {
  399. //
  400. // Map the dll/exe/etc. If this fails, then there's a good chance that the
  401. // thing isn't a dll or exe, so don't fail out, just indicate that no manifest
  402. // was found.
  403. //
  404. hSourceItem = LoadLibraryExW(Params->lpSource, NULL, LOAD_LIBRARY_AS_DATAFILE);
  405. if ((hSourceItem == NULL) || (hSourceItem == INVALID_HANDLE_VALUE)) {
  406. Status = NtCurrentTeb()->LastStatusValue;
  407. goto Exit;
  408. }
  409. FreeSourceModule = TRUE;
  410. }
  411. //
  412. // If this fails with something other than ERROR_RESOURCE_TYPE_NOT_FOUND
  413. // then we're in an interesting state.
  414. //
  415. if (!EnumResourceNamesW(
  416. hSourceItem,
  417. MAKEINTRESOURCEW(RT_MANIFEST),
  418. &BasepSxsSuitableManifestCallback,
  419. (LONG_PTR) &FinderParameters)) {
  420. DWORD dwError = GetLastError();
  421. if ((dwError != ERROR_SUCCESS) && (dwError != ERROR_RESOURCE_TYPE_NOT_FOUND)) {
  422. Status = NtCurrentTeb()->LastStatusValue;
  423. goto Exit;
  424. }
  425. }
  426. #if DBG
  427. if (FreeSourceModule && *MappedResourceName != 0) {
  428. // Debugging code for mgrier to see what DLLs we're actually using the enum pattern for.
  429. DbgPrint(
  430. "SXS/KERNEL32: Found resource %d in %ls (process %wZ) by enumeration\n",
  431. (INT) *MappedResourceName,
  432. Params->lpSource,
  433. &NtCurrentPeb()->ProcessParameters->ImagePathName);
  434. }
  435. #endif
  436. Status = STATUS_SUCCESS;
  437. Exit:
  438. if ((hSourceItem != NULL) &&
  439. (hSourceItem != INVALID_HANDLE_VALUE) &&
  440. (FreeSourceModule))
  441. FreeLibrary(hSourceItem);
  442. return Status;
  443. }
  444. HANDLE
  445. WINAPI
  446. CreateActCtxW(
  447. PCACTCTXW pParamsW
  448. )
  449. {
  450. HANDLE ActivationContextHandle = INVALID_HANDLE_VALUE;
  451. NTSTATUS Status = STATUS_SUCCESS;
  452. ACTCTXW Params = { sizeof(Params) };
  453. ULONG_PTR MappedResourceName = 0;
  454. PVOID ActivationContextData = NULL;
  455. // lpTempSourcePath is used to hold a pointer to the source path if it needs to be created
  456. // in this function. It should be freed before leaving the function.
  457. LPWSTR lpTempSourcePath = NULL;
  458. PPEB Peb = NULL;
  459. RTL_UNICODE_STRING_BUFFER AssemblyDirectoryFromSourceBuffer = { 0 };
  460. RTL_UNICODE_STRING_BUFFER SourceBuffer = { 0 };
  461. UCHAR StaticBuffer[256];
  462. UCHAR SourceStaticBuffer[256];
  463. BOOLEAN PebLockAcquired = FALSE;
  464. ULONG BasepCreateActCtxFlags = 0;
  465. DbgPrintActCtx(__FUNCTION__ " before munging", pParamsW);
  466. if ((pParamsW == NULL) ||
  467. !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, lpSource)) {
  468. DbgPrintEx(
  469. DPFLTR_SXS_ID,
  470. DPFLTR_ERROR_LEVEL,
  471. "SXS: %s() Null %p or size 0x%lx too small\n",
  472. __FUNCTION__,
  473. pParamsW,
  474. pParamsW->cbSize
  475. );
  476. Status = STATUS_INVALID_PARAMETER;
  477. goto Exit;
  478. }
  479. Params.dwFlags = pParamsW->dwFlags;
  480. if ((Params.dwFlags & ~ACTCTX_VALID_FLAGS) ||
  481. ((Params.dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID) && !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, wProcessorArchitecture)) ||
  482. ((Params.dwFlags & ACTCTX_FLAG_LANGID_VALID) && !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, wLangId)) ||
  483. ((Params.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) && !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, lpAssemblyDirectory)) ||
  484. ((Params.dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) && !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, lpResourceName)) ||
  485. ((Params.dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID) && !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, lpApplicationName)) ||
  486. ((Params.dwFlags & ACTCTX_FLAG_HMODULE_VALID) && !RTL_CONTAINS_FIELD(pParamsW, pParamsW->cbSize, hModule))) {
  487. DbgPrintEx(
  488. DPFLTR_SXS_ID,
  489. DPFLTR_ERROR_LEVEL,
  490. "SXS: %s() Bad flags/size 0x%lx/0x%lx\n",
  491. __FUNCTION__,
  492. pParamsW->dwFlags,
  493. pParamsW->cbSize);
  494. Status = STATUS_INVALID_PARAMETER;
  495. goto Exit;
  496. }
  497. if (Params.dwFlags & ACTCTX_FLAG_SET_PROCESS_DEFAULT) {
  498. Peb = NtCurrentPeb();
  499. if (Peb->ActivationContextData != NULL) {
  500. Status = STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET;
  501. goto Exit;
  502. }
  503. }
  504. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  505. if (Params.dwFlags & ACTCTX_FLAG_LIKE_CREATEPROCESS) {
  506. Status = BasepCreateActCtxLikeCreateProcess(pParamsW);
  507. goto Exit;
  508. }
  509. #endif
  510. Params.lpSource = pParamsW->lpSource;
  511. // We need at least either a source path or an HMODULE.
  512. if ((Params.lpSource == NULL) &&
  513. ((Params.dwFlags & ACTCTX_FLAG_HMODULE_VALID) == 0) &&
  514. ((Params.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) == 0)) {
  515. Status = STATUS_INVALID_PARAMETER;
  516. goto Exit;
  517. }
  518. if (Params.dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID) {
  519. USHORT wProcessorArchitecture = pParamsW->wProcessorArchitecture;
  520. #if defined(BUILD_WOW6432)
  521. if (wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
  522. wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64;
  523. #endif
  524. if ((wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN) &&
  525. (wProcessorArchitecture != BasepSxsGetProcessorArchitecture())) {
  526. DbgPrintEx(
  527. DPFLTR_SXS_ID,
  528. DPFLTR_ERROR_LEVEL,
  529. "SXS: %s() bad wProcessorArchitecture 0x%x\n",
  530. __FUNCTION__,
  531. pParamsW->wProcessorArchitecture);
  532. Status = STATUS_INVALID_PARAMETER;
  533. goto Exit;
  534. }
  535. Params.wProcessorArchitecture = wProcessorArchitecture;
  536. } else {
  537. Params.wProcessorArchitecture = BasepSxsGetProcessorArchitecture();
  538. Params.dwFlags |= ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID;
  539. }
  540. if (Params.dwFlags & ACTCTX_FLAG_LANGID_VALID) {
  541. Params.wLangId = pParamsW->wLangId;
  542. } else {
  543. Params.wLangId = GetUserDefaultUILanguage();
  544. Params.dwFlags |= ACTCTX_FLAG_LANGID_VALID;
  545. }
  546. if (Params.dwFlags & ACTCTX_FLAG_HMODULE_VALID)
  547. Params.hModule = pParamsW->hModule;
  548. // If the assembly root dir is specified, then the valid values for lpSource are
  549. // NULL - This implies that we look for a file called "application.manifest" in the assembly root dir.
  550. // Relative FilePath - if lpSource is relative then we combine it with the assembly root dir to get the path.
  551. // Absolute path - used unmodified.
  552. Params.lpAssemblyDirectory = pParamsW->lpAssemblyDirectory;
  553. if (Params.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) {
  554. RTL_PATH_TYPE AssemblyPathType;
  555. RTL_PATH_TYPE SourcePathType;
  556. // if this is true, implies we will make the source path from the assembly dir.
  557. BOOL MakeSourcePath = FALSE ;
  558. LPCWSTR RelativePath = NULL;
  559. if ((Params.lpAssemblyDirectory == NULL) ||
  560. (Params.lpAssemblyDirectory[0] == 0)) {
  561. DbgPrintEx(
  562. DPFLTR_SXS_ID,
  563. DPFLTR_ERROR_LEVEL,
  564. "SXS: %s() Bad lpAssemblyDirectory %ls\n",
  565. __FUNCTION__,
  566. Params.lpAssemblyDirectory);
  567. Status = STATUS_INVALID_PARAMETER;
  568. goto Exit;
  569. }
  570. // Next check that the assembly dir is an absolute file name.
  571. AssemblyPathType = RtlDetermineDosPathNameType_U(Params.lpAssemblyDirectory);
  572. if (!IsSxsAcceptablePathType(AssemblyPathType)) {
  573. DbgPrintEx(
  574. DPFLTR_SXS_ID,
  575. DPFLTR_ERROR_LEVEL,
  576. "SXS: %s() Bad lpAssemblyDirectory PathType %ls, 0x%lx\n",
  577. Params.lpAssemblyDirectory,
  578. (LONG) AssemblyPathType);
  579. Status = STATUS_INVALID_PARAMETER;
  580. goto Exit;
  581. }
  582. if (Params.lpSource != NULL) {
  583. SourcePathType = RtlDetermineDosPathNameType_U(Params.lpSource);
  584. if (IsSxsAcceptablePathType(SourcePathType)){
  585. MakeSourcePath = FALSE ; // We don't need to mess with lpSource in this case.
  586. } else if ( SourcePathType == RtlPathTypeRelative ) {
  587. MakeSourcePath = TRUE ;
  588. RelativePath = Params.lpSource;
  589. } else {
  590. DbgPrintEx(
  591. DPFLTR_SXS_ID,
  592. DPFLTR_ERROR_LEVEL,
  593. "SXS: %s() Bad lpSource PathType %ls, 0x%lx\n",
  594. Params.lpSource,
  595. (LONG)SourcePathType);
  596. Status = STATUS_INVALID_PARAMETER;
  597. goto Exit;
  598. }
  599. }
  600. else {
  601. MakeSourcePath = TRUE;
  602. RelativePath = ManifestDefaultName;
  603. }
  604. if (MakeSourcePath) {
  605. ULONG LengthAssemblyDir;
  606. ULONG LengthRelativePath ;
  607. ULONG Length ; // Will hold total number of characters we
  608. BOOL AddTrailingSlash = FALSE;
  609. LPWSTR lpCurrent;
  610. LengthAssemblyDir = wcslen(Params.lpAssemblyDirectory);
  611. AddTrailingSlash = (Params.lpAssemblyDirectory[LengthAssemblyDir - 1] != L'\\');
  612. LengthRelativePath = wcslen(RelativePath);
  613. Length = LengthAssemblyDir + (AddTrailingSlash ? 1 : 0) + LengthRelativePath;
  614. Length++ ; // For NULL terminator
  615. lpTempSourcePath = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG(TMP_TAG),
  616. Length * sizeof(WCHAR));
  617. if (lpTempSourcePath == NULL) {
  618. Status = STATUS_NO_MEMORY;
  619. goto Exit;
  620. }
  621. lpCurrent = lpTempSourcePath;
  622. memcpy(lpCurrent, Params.lpAssemblyDirectory, LengthAssemblyDir * sizeof(WCHAR));
  623. lpCurrent += LengthAssemblyDir;
  624. if (AddTrailingSlash) {
  625. *lpCurrent = L'\\';
  626. lpCurrent++;
  627. }
  628. memcpy(lpCurrent, RelativePath, LengthRelativePath * sizeof(WCHAR));
  629. lpCurrent += LengthRelativePath;
  630. *lpCurrent = L'\0';
  631. // make this the new lpSource member.
  632. Params.lpSource = lpTempSourcePath;
  633. }
  634. } else {
  635. SIZE_T SourceLength;
  636. //
  637. // Ensure that this is a full absolute path. If it's relative, then this
  638. // must be expanded out to the full path before we use it to default the
  639. // lpAssemblyDirectory member.
  640. //
  641. // There is no precedent for using the peb lock this way, but it is the correct
  642. // thing. FullPaths can change as the current working directory is modified
  643. // on other threads. The behavior isn't predictable either way, but our
  644. // code works better.
  645. //
  646. RtlAcquirePebLock();
  647. __try {
  648. RtlInitUnicodeStringBuffer(&SourceBuffer, SourceStaticBuffer, sizeof(SourceStaticBuffer));
  649. SourceLength = RtlGetFullPathName_U( Params.lpSource, (ULONG)SourceBuffer.ByteBuffer.Size, SourceBuffer.String.Buffer, NULL );
  650. if (SourceLength == 0) {
  651. Status = STATUS_NO_MEMORY;
  652. goto Exit;
  653. } else if (SourceLength > SourceBuffer.ByteBuffer.Size) {
  654. Status = RtlEnsureUnicodeStringBufferSizeBytes(&SourceBuffer, SourceLength);
  655. if ( !NT_SUCCESS(Status) )
  656. goto Exit;
  657. SourceLength = RtlGetFullPathName_U( Params.lpSource, (ULONG)SourceBuffer.ByteBuffer.Size, SourceBuffer.String.Buffer, NULL );
  658. if (SourceLength == 0) {
  659. Status = STATUS_NO_MEMORY;
  660. goto Exit;
  661. }
  662. }
  663. SourceBuffer.String.Length = (USHORT)SourceLength;
  664. Params.lpSource = SourceBuffer.String.Buffer;
  665. } __finally {
  666. RtlReleasePebLock();
  667. }
  668. // This would be a nice place to use
  669. // RtlTakeRemainingStaticBuffer(&SourceBuffer, &DirectoryBuffer, &DirectoryBufferSize);
  670. // RtlInitUnicodeStringBuffer(&DirectoryBuffer, &DirectoryBuffer, &DirectoryBufferSize);
  671. // but RtlTakeRemainingStaticBuffer has not yet been tested.
  672. RtlInitUnicodeStringBuffer(&AssemblyDirectoryFromSourceBuffer, StaticBuffer, sizeof(StaticBuffer));
  673. Status = RtlAssignUnicodeStringBuffer(&AssemblyDirectoryFromSourceBuffer, &SourceBuffer.String);
  674. if (!NT_SUCCESS(Status)) {
  675. goto Exit;
  676. }
  677. Status = RtlRemoveLastFullDosOrNtPathElement(0, &AssemblyDirectoryFromSourceBuffer);
  678. if (!NT_SUCCESS(Status)) {
  679. goto Exit;
  680. }
  681. RTL_NUL_TERMINATE_STRING(&AssemblyDirectoryFromSourceBuffer.String);
  682. Params.lpAssemblyDirectory = AssemblyDirectoryFromSourceBuffer.String.Buffer;
  683. Params.dwFlags |= ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
  684. }
  685. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  686. if (Params.dwFlags & ACTCTX_FLAG_LIKE_CREATEPROCESS) {
  687. Params.dwFlags |= ACTCTX_FLAG_RESOURCE_NAME_VALID;
  688. MappedResourceName = (LONG_PTR)CREATEPROCESS_MANIFEST_RESOURCE_ID;
  689. if (MappedResourceName == -1) {
  690. DbgPrintEx(
  691. DPFLTR_SXS_ID,
  692. DPFLTR_ERROR_LEVEL,
  693. "SXS: %s() BaseDllMapResourceIdW(1) failed\n",
  694. __FUNCTION__
  695. );
  696. Status = NtCurrentTeb()->LastStatusValue;
  697. goto Exit;
  698. }
  699. Params.lpResourceName = (PCWSTR) MappedResourceName;
  700. }
  701. else
  702. #endif
  703. if (Params.dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) {
  704. if (pParamsW->lpResourceName == 0) {
  705. DbgPrintEx(
  706. DPFLTR_SXS_ID,
  707. DPFLTR_ERROR_LEVEL,
  708. "SXS: %s() ACTCTX_FLAG_RESOURCE_NAME_VALID set but lpResourceName == 0\n",
  709. __FUNCTION__
  710. );
  711. Status = STATUS_INVALID_PARAMETER;
  712. goto Exit;
  713. }
  714. MappedResourceName = BaseDllMapResourceIdW(pParamsW->lpResourceName);
  715. if (MappedResourceName == -1) {
  716. DbgPrintEx(
  717. DPFLTR_SXS_ID,
  718. DPFLTR_ERROR_LEVEL,
  719. "SXS: %s() BaseDllMapResourceIdW failed\n",
  720. __FUNCTION__
  721. );
  722. Status = NtCurrentTeb()->LastStatusValue;
  723. goto Exit;
  724. }
  725. Params.lpResourceName = (PCWSTR) MappedResourceName;
  726. } else {
  727. BOOL ProbeFoundManifestResource;
  728. //
  729. // Otherwise, probe through the filename that was passed in via the resource
  730. // enumeration functions to find the first suitable manifest.
  731. //
  732. Status = BasepSxsFindSuitableManifestResourceFor(&Params, &MappedResourceName, &ProbeFoundManifestResource);
  733. if ((!NT_SUCCESS(Status)) &&
  734. (Status != STATUS_INVALID_IMAGE_FORMAT))
  735. goto Exit;
  736. if (ProbeFoundManifestResource) {
  737. Params.lpResourceName = (PCWSTR) MappedResourceName;
  738. Params.dwFlags |= ACTCTX_FLAG_RESOURCE_NAME_VALID;
  739. }
  740. BasepCreateActCtxFlags = BASEP_CREATE_ACTCTX_FLAG_NO_ADMIN_OVERRIDE;
  741. }
  742. DbgPrintActCtx(__FUNCTION__ " after munging", &Params);
  743. Status = BasepCreateActCtx(BasepCreateActCtxFlags, &Params, &ActivationContextData);
  744. if (!NT_SUCCESS(Status)) {
  745. goto Exit;
  746. }
  747. if (Params.dwFlags & ACTCTX_FLAG_SET_PROCESS_DEFAULT) {
  748. if (Peb->ActivationContextData != NULL) {
  749. Status = STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET;
  750. goto Exit;
  751. }
  752. if (InterlockedCompareExchangePointer(
  753. (PVOID*)&Peb->ActivationContextData,
  754. ActivationContextData,
  755. NULL
  756. )
  757. != NULL) {
  758. Status = STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET;
  759. goto Exit;
  760. }
  761. ActivationContextData = NULL; // don't unmap it
  762. ActivationContextHandle = NULL; // unusual success value, INVALID_HANDLE_VALUE is failure
  763. // and we don't need to return anything to be cleaned up
  764. Status = STATUS_SUCCESS;
  765. goto Exit;
  766. }
  767. Status = RtlCreateActivationContext(
  768. 0,
  769. ActivationContextData,
  770. 0, // no extra bytes required today
  771. BasepSxsActivationContextNotification,
  772. NULL,
  773. (PACTIVATION_CONTEXT *) &ActivationContextHandle);
  774. if (!NT_SUCCESS(Status)) {
  775. DbgPrintEx(
  776. DPFLTR_SXS_ID,
  777. DPFLTR_LEVEL_STATUS(Status),
  778. "SXS: RtlCreateActivationContext() failed 0x%08lx\n", Status);
  779. // Just in case RtlCreateActivationContext() set it to NULL...
  780. ActivationContextHandle = INVALID_HANDLE_VALUE;
  781. goto Exit;
  782. }
  783. ActivationContextData = NULL; // Don't unmap in exit if we actually succeeded.
  784. Status = STATUS_SUCCESS;
  785. Exit:
  786. if (ActivationContextData != NULL) {
  787. NtUnmapViewOfSection(NtCurrentProcess(), ActivationContextData);
  788. }
  789. BaseDllFreeResourceId(MappedResourceName);
  790. if (!NT_SUCCESS(Status)) {
  791. BaseSetLastNTError(Status);
  792. ActivationContextHandle = INVALID_HANDLE_VALUE;
  793. }
  794. #if DBG
  795. if (ActivationContextHandle == INVALID_HANDLE_VALUE) {
  796. DbgPrintEx(
  797. DPFLTR_SXS_ID,
  798. DPFLTR_LEVEL_STATUS(Status),
  799. "SXS: Exiting %s(%ls / %ls, %p), ActivationContextHandle:%p, Status:0x%lx\n",
  800. __FUNCTION__,
  801. Params.lpSource, pParamsW->lpSource,
  802. Params.lpResourceName,
  803. ActivationContextHandle,
  804. Status
  805. );
  806. }
  807. #endif
  808. // Do these after DbgPrintEx because at least one of them can get printed.
  809. RtlFreeUnicodeStringBuffer(&AssemblyDirectoryFromSourceBuffer);
  810. RtlFreeUnicodeStringBuffer(&SourceBuffer);
  811. if (lpTempSourcePath != NULL) {
  812. // Set the lpSource value back to the original so we don't access freed memory.
  813. Params.lpSource = pParamsW->lpSource;
  814. RtlFreeHeap(RtlProcessHeap(), 0, lpTempSourcePath);
  815. }
  816. return ActivationContextHandle;
  817. }
  818. VOID
  819. WINAPI
  820. AddRefActCtx(
  821. HANDLE hActCtx
  822. )
  823. {
  824. RtlAddRefActivationContext((PACTIVATION_CONTEXT) hActCtx);
  825. }
  826. VOID
  827. WINAPI
  828. ReleaseActCtx(
  829. HANDLE hActCtx
  830. )
  831. {
  832. RtlReleaseActivationContext((PACTIVATION_CONTEXT) hActCtx);
  833. }
  834. BOOL
  835. WINAPI
  836. ZombifyActCtx(
  837. HANDLE hActCtx
  838. )
  839. {
  840. NTSTATUS Status = RtlZombifyActivationContext((PACTIVATION_CONTEXT) hActCtx);
  841. if (!NT_SUCCESS(Status))
  842. {
  843. BaseSetLastNTError(Status);
  844. return FALSE;
  845. }
  846. return TRUE;
  847. }
  848. BOOL
  849. WINAPI
  850. ActivateActCtx(
  851. HANDLE hActCtx,
  852. ULONG_PTR *lpCookie
  853. )
  854. {
  855. NTSTATUS Status;
  856. if (hActCtx == INVALID_HANDLE_VALUE) {
  857. BaseSetLastNTError(STATUS_INVALID_PARAMETER);
  858. return FALSE;
  859. }
  860. Status = RtlActivateActivationContext(0, (PACTIVATION_CONTEXT) hActCtx, lpCookie);
  861. if (!NT_SUCCESS(Status)) {
  862. BaseSetLastNTError(Status);
  863. return FALSE;
  864. }
  865. return TRUE;
  866. }
  867. BOOL
  868. DeactivateActCtx(
  869. DWORD dwFlags,
  870. ULONG_PTR ulCookie
  871. )
  872. {
  873. DWORD dwFlagsDown = 0;
  874. if ((dwFlags & ~(DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION)) != 0) {
  875. BaseSetLastNTError(STATUS_INVALID_PARAMETER);
  876. return FALSE;
  877. }
  878. if (dwFlags & DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION)
  879. dwFlagsDown |= RTL_DEACTIVATE_ACTIVATION_CONTEXT_FLAG_FORCE_EARLY_DEACTIVATION;
  880. // The Rtl function does not fail...
  881. RtlDeactivateActivationContext(dwFlagsDown, ulCookie);
  882. return TRUE;
  883. }
  884. BOOL
  885. WINAPI
  886. GetCurrentActCtx(
  887. HANDLE *lphActCtx)
  888. {
  889. NTSTATUS Status;
  890. BOOL fSuccess = FALSE;
  891. if (lphActCtx == NULL) {
  892. BaseSetLastNTError(STATUS_INVALID_PARAMETER);
  893. goto Exit;
  894. }
  895. Status = RtlGetActiveActivationContext((PACTIVATION_CONTEXT *) lphActCtx);
  896. if (!NT_SUCCESS(Status))
  897. {
  898. BaseSetLastNTError(Status);
  899. goto Exit;
  900. }
  901. fSuccess = TRUE;
  902. Exit:
  903. return fSuccess;
  904. }
  905. NTSTATUS
  906. BasepAllocateActivationContextActivationBlock(
  907. IN DWORD Flags,
  908. IN PVOID Callback,
  909. IN PVOID CallbackContext,
  910. OUT PBASE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK *ActivationBlock
  911. )
  912. {
  913. NTSTATUS Status;
  914. ACTIVATION_CONTEXT_BASIC_INFORMATION acbi = {0};
  915. if (ActivationBlock != NULL)
  916. *ActivationBlock = NULL;
  917. if ((Flags & ~(
  918. BASEP_ALLOCATE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK_FLAG_DO_NOT_FREE_AFTER_CALLBACK |
  919. BASEP_ALLOCATE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK_FLAG_DO_NOT_ALLOCATE_IF_PROCESS_DEFAULT)) != 0) {
  920. Status = STATUS_INVALID_PARAMETER_1;
  921. goto Exit;
  922. }
  923. if (ActivationBlock == NULL) {
  924. Status = STATUS_INVALID_PARAMETER_4;
  925. goto Exit;
  926. }
  927. Status =
  928. RtlQueryInformationActivationContext(
  929. RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT,
  930. NULL,
  931. 0,
  932. ActivationContextBasicInformation,
  933. &acbi,
  934. sizeof(acbi),
  935. NULL);
  936. if (!NT_SUCCESS(Status)) {
  937. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s - Failure getting active activation context; ntstatus %08lx\n", __FUNCTION__, Status);
  938. goto Exit;
  939. }
  940. if (acbi.Flags & ACTIVATION_CONTEXT_FLAG_NO_INHERIT) {
  941. RtlReleaseActivationContext(acbi.ActivationContext);
  942. acbi.ActivationContext = NULL;
  943. }
  944. // If the activation context is non-NULL or the caller always wants the block allocated
  945. if (((Flags & BASEP_ALLOCATE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK_FLAG_DO_NOT_ALLOCATE_IF_PROCESS_DEFAULT) == 0) ||
  946. (acbi.ActivationContext != NULL)) {
  947. *ActivationBlock = (PBASE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK) RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG(TMP_TAG), sizeof(BASE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK));
  948. if (*ActivationBlock == NULL) {
  949. Status = STATUS_NO_MEMORY;
  950. goto Exit;
  951. }
  952. (*ActivationBlock)->Flags = 0;
  953. (*ActivationBlock)->ActivationContext = acbi.ActivationContext;
  954. acbi.ActivationContext = NULL; // don't release in exit path...
  955. if (Flags & BASEP_ALLOCATE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK_FLAG_DO_NOT_FREE_AFTER_CALLBACK)
  956. (*ActivationBlock)->Flags |= BASE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK_FLAG_DO_NOT_FREE_AFTER_CALLBACK;
  957. (*ActivationBlock)->CallbackFunction = Callback;
  958. (*ActivationBlock)->CallbackContext = CallbackContext;
  959. }
  960. Status = STATUS_SUCCESS;
  961. Exit:
  962. if (acbi.ActivationContext != NULL)
  963. RtlReleaseActivationContext(acbi.ActivationContext);
  964. return Status;
  965. }
  966. VOID
  967. BasepFreeActivationContextActivationBlock(
  968. PBASE_ACTIVATION_CONTEXT_ACTIVATION_BLOCK ActivationBlock
  969. )
  970. {
  971. if (ActivationBlock != NULL) {
  972. if (ActivationBlock->ActivationContext != NULL) {
  973. RtlReleaseActivationContext(ActivationBlock->ActivationContext);
  974. ActivationBlock->ActivationContext = NULL;
  975. }
  976. RtlFreeHeap(RtlProcessHeap(), 0, ActivationBlock);
  977. }
  978. }
  979. VOID
  980. BasepSxsCloseHandles(
  981. IN PCBASE_MSG_SXS_HANDLES Handles
  982. )
  983. {
  984. NTSTATUS Status;
  985. if (Handles->File != NULL) {
  986. Status = NtClose(Handles->File);
  987. ASSERT(NT_SUCCESS(Status));
  988. }
  989. if (Handles->Section != NULL) {
  990. Status = NtClose(Handles->Section);
  991. ASSERT(NT_SUCCESS(Status));
  992. }
  993. if (Handles->ViewBase != NULL) {
  994. HANDLE Process = Handles->Process;
  995. if (Process == NULL) {
  996. Process = NtCurrentProcess();
  997. }
  998. Status = NtUnmapViewOfSection(Process, Handles->ViewBase);
  999. ASSERT(NT_SUCCESS(Status));
  1000. }
  1001. }
  1002. NTSTATUS
  1003. BasepCreateActCtx(
  1004. ULONG Flags,
  1005. IN PCACTCTXW ActParams,
  1006. OUT PVOID* ActivationContextData
  1007. )
  1008. {
  1009. RTL_PATH_TYPE PathType = RtlPathTypeUnknown;
  1010. IO_STATUS_BLOCK IoStatusBlock;
  1011. UCHAR Win32PolicyPathStaticBuffer[MEDIUM_PATH * sizeof(WCHAR)];
  1012. UCHAR NtPolicyPathStaticBuffer[MEDIUM_PATH * sizeof(WCHAR)];
  1013. UNICODE_STRING Win32ManifestPath;
  1014. UNICODE_STRING NtManifestPath;
  1015. CONST SXS_CONSTANT_WIN32_NT_PATH_PAIR ManifestPathPair = { &Win32ManifestPath, &NtManifestPath };
  1016. RTL_UNICODE_STRING_BUFFER Win32PolicyPath;
  1017. RTL_UNICODE_STRING_BUFFER NtPolicyPath;
  1018. CONST SXS_CONSTANT_WIN32_NT_PATH_PAIR PolicyPathPair = { &Win32PolicyPath.String, &NtPolicyPath.String };
  1019. USHORT RemoveManifestExtensionFromPolicy = 0;
  1020. BASE_SXS_CREATE_ACTIVATION_CONTEXT_MSG Message;
  1021. NTSTATUS Status = STATUS_SUCCESS;
  1022. UNICODE_STRING PolicyPathPieces[3];
  1023. WCHAR PolicyManifestResourceId[sizeof(".65535\0")];
  1024. BOOL IsImage = FALSE;
  1025. BOOL IsExe = FALSE;
  1026. PIMAGE_NT_HEADERS ImageNtHeader = NULL;
  1027. OBJECT_ATTRIBUTES Obja;
  1028. SIZE_T ViewSize = 0;
  1029. PBASE_MSG_SXS_HANDLES ManifestFileHandles = NULL;
  1030. PBASE_MSG_SXS_HANDLES ManifestImageHandles = NULL;
  1031. BASE_MSG_SXS_HANDLES ManifestHandles = { 0 };
  1032. BASE_MSG_SXS_HANDLES ManifestHandles2 = { 0 };
  1033. BASE_MSG_SXS_HANDLES PolicyHandles = { 0 };
  1034. BOOL CloseManifestImageHandles = TRUE;
  1035. PCWSTR ManifestExtension = NULL;
  1036. ULONG LdrCreateOutOfProcessImageFlags = 0;
  1037. UCHAR Win32ManifestAdminOverridePathStaticBuffer[MEDIUM_PATH * sizeof(WCHAR)];
  1038. UCHAR NtManifestAdminOverridePathStaticBuffer[MEDIUM_PATH * sizeof(WCHAR)];
  1039. RTL_UNICODE_STRING_BUFFER Win32ManifestAdminOverridePath;
  1040. RTL_UNICODE_STRING_BUFFER NtManifestAdminOverridePath;
  1041. UNICODE_STRING ManifestAdminOverridePathPieces[3];
  1042. CONST SXS_CONSTANT_WIN32_NT_PATH_PAIR ManifestAdminOverridePathPair =
  1043. { &Win32ManifestAdminOverridePath.String, &NtManifestAdminOverridePath.String };
  1044. BOOL PassFilePair = FALSE;
  1045. PCSXS_CONSTANT_WIN32_NT_PATH_PAIR FilePairToPass = NULL;
  1046. ULONG BasepSxsCreateStreamsFlags = 0;
  1047. #if DBG
  1048. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() beginning\n", __FUNCTION__);
  1049. ASSERT(ActParams != NULL);
  1050. ASSERT(ActParams->cbSize == sizeof(*ActParams));
  1051. ASSERT(ActParams->dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID);
  1052. ASSERT(ActParams->dwFlags & ACTCTX_FLAG_LANGID_VALID);
  1053. ASSERT(ActParams->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID);
  1054. ASSERT(ActivationContextData != NULL);
  1055. ASSERT(*ActivationContextData == NULL);
  1056. #endif
  1057. RtlZeroMemory(&Message, sizeof(Message));
  1058. RtlInitUnicodeStringBuffer(&Win32PolicyPath, Win32PolicyPathStaticBuffer, sizeof(Win32PolicyPathStaticBuffer));
  1059. RtlInitUnicodeStringBuffer(&NtPolicyPath, NtPolicyPathStaticBuffer, sizeof(NtPolicyPathStaticBuffer));
  1060. RtlInitUnicodeStringBuffer(&Win32ManifestAdminOverridePath, Win32ManifestAdminOverridePathStaticBuffer, sizeof(Win32ManifestAdminOverridePathStaticBuffer));
  1061. RtlInitUnicodeStringBuffer(&NtManifestAdminOverridePath, NtManifestAdminOverridePathStaticBuffer, sizeof(NtManifestAdminOverridePathStaticBuffer));
  1062. NtManifestPath.Buffer = NULL;
  1063. Message.ProcessorArchitecture = ActParams->wProcessorArchitecture;
  1064. Message.LangId = ActParams->wLangId;
  1065. RtlInitUnicodeString(&Message.AssemblyDirectory, RTL_CONST_CAST(PWSTR)(ActParams->lpAssemblyDirectory));
  1066. if (Message.AssemblyDirectory.Length != 0) {
  1067. ASSERT(RTL_STRING_IS_NUL_TERMINATED(&Message.AssemblyDirectory));
  1068. if (!RTL_STRING_IS_NUL_TERMINATED(&Message.AssemblyDirectory)) {
  1069. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_ERROR_LEVEL, "SXS: %s() AssemblyDirectory is not null terminated\n", __FUNCTION__);
  1070. Status = STATUS_INVALID_PARAMETER;
  1071. goto Exit;
  1072. }
  1073. }
  1074. if (ActParams->lpSource == NULL || ActParams->lpSource[0] == 0) {
  1075. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_ERROR_LEVEL, "SXS: %s() empty lpSource %ls\n", __FUNCTION__, ActParams->lpSource);
  1076. Status = STATUS_INVALID_PARAMETER;
  1077. goto Exit;
  1078. }
  1079. if ((ActParams->dwFlags & ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF) != 0) {
  1080. Message.Flags = BASE_MSG_SXS_SYSTEM_DEFAULT_TEXTUAL_ASSEMBLY_IDENTITY_PRESENT;
  1081. RtlInitUnicodeString(&Message.TextualAssemblyIdentity, ActParams->lpSource);
  1082. // no streams, no handles, no manifest
  1083. // no policy, no last modified time
  1084. // no paths
  1085. goto CsrMessageFilledIn;
  1086. }
  1087. RtlInitUnicodeString(&Win32ManifestPath, ActParams->lpSource);
  1088. PathType = RtlDetermineDosPathNameType_U(ActParams->lpSource);
  1089. if (!RtlDosPathNameToNtPathName_U(
  1090. Win32ManifestPath.Buffer,
  1091. &NtManifestPath,
  1092. NULL,
  1093. NULL)) {
  1094. //
  1095. // NTRAID#NTBUG9-147881-2000/7/21-a-JayK errors mutated into bools in ntdll
  1096. //
  1097. Status = STATUS_OBJECT_PATH_NOT_FOUND;
  1098. goto Exit;
  1099. }
  1100. // If there's an explicitly set HMODULE, we need to verify that the HMODULE came from the lpSource
  1101. // specified and then we can avoid opening/mapping the file.
  1102. if (ActParams->dwFlags & ACTCTX_FLAG_HMODULE_VALID) {
  1103. ManifestHandles.File = NULL;
  1104. ManifestHandles.Section = NULL;
  1105. ManifestHandles.ViewBase = ActParams->hModule;
  1106. if (LDR_IS_DATAFILE(ActParams->hModule))
  1107. LdrCreateOutOfProcessImageFlags = LDR_DLL_MAPPED_AS_DATA;
  1108. else
  1109. LdrCreateOutOfProcessImageFlags = LDR_DLL_MAPPED_AS_IMAGE;
  1110. // Don't try to close the handles or unmap the view on exit of this function...
  1111. CloseManifestImageHandles = FALSE;
  1112. } else {
  1113. InitializeObjectAttributes(
  1114. &Obja,
  1115. &NtManifestPath,
  1116. OBJ_CASE_INSENSITIVE,
  1117. NULL,
  1118. NULL);
  1119. Status =
  1120. NtOpenFile(
  1121. &ManifestHandles.File,
  1122. FILE_GENERIC_READ | FILE_EXECUTE,
  1123. &Obja,
  1124. &IoStatusBlock,
  1125. FILE_SHARE_READ,
  1126. FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
  1127. );
  1128. if (!NT_SUCCESS(Status)) {
  1129. if (DPFLTR_LEVEL_STATUS(Status) == DPFLTR_ERROR_LEVEL) {
  1130. DbgPrintEx(
  1131. DPFLTR_SXS_ID,
  1132. DPFLTR_LEVEL_STATUS(Status),
  1133. "SXS: %s() NtOpenFile(%wZ) failed\n",
  1134. __FUNCTION__,
  1135. Obja.ObjectName
  1136. );
  1137. }
  1138. goto Exit;
  1139. }
  1140. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() NtOpenFile(%wZ) succeeded\n", __FUNCTION__, Obja.ObjectName));
  1141. Status =
  1142. NtCreateSection(
  1143. &ManifestHandles.Section,
  1144. SECTION_MAP_READ,
  1145. NULL, // ObjectAttributes
  1146. NULL, // MaximumSize (whole file)
  1147. PAGE_READONLY, // SectionPageProtection
  1148. SEC_COMMIT, // AllocationAttributes
  1149. ManifestHandles.File
  1150. );
  1151. if (!NT_SUCCESS(Status)) {
  1152. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() NtCreateSection() failed\n", __FUNCTION__);
  1153. goto Exit;
  1154. }
  1155. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() NtCreateSection() succeeded\n", __FUNCTION__));
  1156. Status =
  1157. NtMapViewOfSection(
  1158. ManifestHandles.Section,
  1159. NtCurrentProcess(),
  1160. &ManifestHandles.ViewBase,
  1161. 0, // ZeroBits,
  1162. 0, // CommitSize,
  1163. NULL, // SectionOffset,
  1164. &ViewSize, // ViewSize,
  1165. ViewShare, // InheritDisposition,
  1166. 0, // AllocationType,
  1167. PAGE_READONLY // Protect
  1168. );
  1169. if (!NT_SUCCESS(Status)) {
  1170. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() NtMapViewOfSection failed\n", __FUNCTION__);
  1171. goto Exit;
  1172. }
  1173. LdrCreateOutOfProcessImageFlags = LDR_DLL_MAPPED_AS_DATA;
  1174. }
  1175. ImageNtHeader = RtlImageNtHeader(LDR_DATAFILE_TO_VIEW(ManifestHandles.ViewBase));
  1176. IsImage = (ImageNtHeader != NULL);
  1177. if (IsImage) {
  1178. IsExe = ((ImageNtHeader->FileHeader.Characteristics & IMAGE_FILE_DLL) == 0);
  1179. ManifestImageHandles = &ManifestHandles;
  1180. ManifestFileHandles = &ManifestHandles2;
  1181. } else {
  1182. IsExe = FALSE;
  1183. ManifestFileHandles = &ManifestHandles;
  1184. ManifestImageHandles = NULL;
  1185. }
  1186. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  1187. if ((ActParams->dwFlags & ACTCTX_FLAG_LIKE_CREATEPROCESS) != 0 && !IsExe) {
  1188. //
  1189. // We want to be like CreateProcess(foo.dll), which does:
  1190. // SetLastError(ERROR_BAD_EXE_FORMAT), there are a few mappings from ntstatus
  1191. // to this error.
  1192. //
  1193. Status = STATUS_INVALID_IMAGE_FORMAT;
  1194. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() bad flags/file combo\n", __FUNCTION__);
  1195. goto Exit;
  1196. }
  1197. #endif
  1198. // See if someone's trying to load a resource from something that is not an EXE
  1199. if ((!IsImage) && (ActParams->lpResourceName != NULL)) {
  1200. // Yup...
  1201. Status = STATUS_INVALID_IMAGE_FORMAT;
  1202. goto Exit;
  1203. }
  1204. // or if an exe but no resource (and none found by probing earlier)
  1205. else if (IsImage && (ActParams->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) == 0) {
  1206. Status = STATUS_RESOURCE_TYPE_NOT_FOUND;
  1207. goto Exit;
  1208. }
  1209. //
  1210. // form up the policy path
  1211. // foo.manifest => foo.policy
  1212. // foo.dll, resourceid == n, resourceid != 1 => foo.dll.n.policy
  1213. // foo.dll, resourceid == 1 => foo.dll.policy
  1214. // foo.dll, resourceid == "bar" => foo.dll.bar.policy
  1215. //
  1216. PolicyPathPieces[0] = Win32ManifestPath;
  1217. PolicyPathPieces[1].Length = 0;
  1218. PolicyPathPieces[1].MaximumLength = 0;
  1219. PolicyPathPieces[1].Buffer = NULL;
  1220. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  1221. if (ActParams->dwFlags & ACTCTX_FLAG_LIKE_CREATEPROCESS) {
  1222. ; /* nothing */
  1223. } else
  1224. #endif
  1225. if (ActParams->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) {
  1226. if (IS_INTRESOURCE(ActParams->lpResourceName)) {
  1227. if (ActParams->lpResourceName != MAKEINTRESOURCEW(CREATEPROCESS_MANIFEST_RESOURCE_ID)) {
  1228. PolicyPathPieces[1].Length = (USHORT) (_snwprintf(PolicyManifestResourceId, RTL_NUMBER_OF(PolicyManifestResourceId), L".%lu", (ULONG)(ULONG_PTR)ActParams->lpResourceName) * sizeof(WCHAR));
  1229. PolicyPathPieces[1].MaximumLength = sizeof(PolicyManifestResourceId);
  1230. PolicyPathPieces[1].Buffer = PolicyManifestResourceId;
  1231. }
  1232. } else {
  1233. RtlInitUnicodeString(&PolicyPathPieces[1], ActParams->lpResourceName);
  1234. }
  1235. }
  1236. PolicyPathPieces[2] = SxsPolicySuffix;
  1237. ManifestExtension = wcsrchr(Win32ManifestPath.Buffer, L'.');
  1238. if (ManifestExtension != NULL && _wcsicmp(ManifestExtension, SxsManifestSuffix.Buffer) == 0) {
  1239. RemoveManifestExtensionFromPolicy = SxsManifestSuffix.Length;
  1240. PolicyPathPieces[0].Length -= RemoveManifestExtensionFromPolicy;
  1241. }
  1242. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(&Win32PolicyPath, RTL_NUMBER_OF(PolicyPathPieces), PolicyPathPieces))) {
  1243. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() RtlMultiAppendUnicodeStringBuffer failed\n", __FUNCTION__);
  1244. goto Exit;
  1245. }
  1246. PolicyPathPieces[0] = NtManifestPath;
  1247. PolicyPathPieces[0].Length -= RemoveManifestExtensionFromPolicy;
  1248. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(&NtPolicyPath, RTL_NUMBER_OF(PolicyPathPieces), PolicyPathPieces))) {
  1249. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() RtlMultiAppendUnicodeStringBuffer failed\n", __FUNCTION__);
  1250. goto Exit;
  1251. }
  1252. //
  1253. // form up the path to the administrative override file for manifests in resources
  1254. //
  1255. // not an image => no override
  1256. // manifest=foo.dll, resourceid=n, n != 1 => foo.dll.n.manifest
  1257. // manifest=foo.dll, resourceid=n, n == 1 => foo.dll.manifest
  1258. //
  1259. // the second to last element is the same as for the policy file
  1260. //
  1261. if (IsImage) {
  1262. ManifestAdminOverridePathPieces[0] = Win32ManifestPath;
  1263. ManifestAdminOverridePathPieces[1] = PolicyPathPieces[1];
  1264. ManifestAdminOverridePathPieces[2] = SxsManifestSuffix;
  1265. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(
  1266. &Win32ManifestAdminOverridePath,
  1267. RTL_NUMBER_OF(ManifestAdminOverridePathPieces),
  1268. ManifestAdminOverridePathPieces))
  1269. ) {
  1270. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() RtlMultiAppendUnicodeStringBuffer failed\n", __FUNCTION__);
  1271. goto Exit;
  1272. }
  1273. ManifestAdminOverridePathPieces[0] = NtManifestPath;
  1274. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(
  1275. &NtManifestAdminOverridePath,
  1276. RTL_NUMBER_OF(ManifestAdminOverridePathPieces),
  1277. ManifestAdminOverridePathPieces))
  1278. ) {
  1279. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() RtlMultiAppendUnicodeStringBuffer failed\n", __FUNCTION__);
  1280. goto Exit;
  1281. }
  1282. }
  1283. Message.ActivationContextData = ActivationContextData;
  1284. ManifestHandles.Process = NtCurrentProcess();
  1285. #if DBG
  1286. if (NtQueryDebugFilterState(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL) == TRUE)
  1287. {
  1288. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: Win32ManifestPath: \"%wZ\"\n", __FUNCTION__, &Win32ManifestPath);
  1289. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: NtManifestPath: \"%wZ\"\n", __FUNCTION__, &NtManifestPath);
  1290. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: Win32ManifestAdminPath: \"%wZ\"\n", __FUNCTION__, &Win32ManifestAdminOverridePath);
  1291. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: NtManifestAdminPath: \"%wZ\"\n", __FUNCTION__, &NtManifestAdminOverridePath);
  1292. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: Win32PolicyPath: \"%wZ\"\n", __FUNCTION__, &Win32PolicyPath);
  1293. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: Nt32PolicyPath: \"%wZ\"\n", __FUNCTION__, &NtPolicyPath);
  1294. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: ManifestHandles.Process: %p\n", __FUNCTION__, ManifestHandles.Process);
  1295. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: ManifestHandles.File: %p\n", __FUNCTION__, ManifestHandles.File);
  1296. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: ManifestHandles.Section: %p\n", __FUNCTION__, ManifestHandles.Section);
  1297. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: ManifestHandles.ViewBase: %p\n", __FUNCTION__, ManifestHandles.ViewBase);
  1298. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s: IsImage: %lu\n", __FUNCTION__, (ULONG) IsImage);
  1299. }
  1300. #endif
  1301. PassFilePair = (!IsImage || (Flags & BASEP_CREATE_ACTCTX_FLAG_NO_ADMIN_OVERRIDE) == 0);
  1302. FilePairToPass = IsImage ? &ManifestAdminOverridePathPair : &ManifestPathPair;
  1303. Status =
  1304. BasepSxsCreateStreams(
  1305. BasepSxsCreateStreamsFlags,
  1306. LdrCreateOutOfProcessImageFlags,
  1307. FILE_GENERIC_READ | FILE_EXECUTE, // AccessMask,
  1308. NULL, // override manifest
  1309. NULL, // override policy
  1310. PassFilePair ? FilePairToPass : NULL,
  1311. ManifestFileHandles,
  1312. IsImage ? &ManifestPathPair : NULL,
  1313. ManifestImageHandles,
  1314. (ULONG_PTR)(ActParams->lpResourceName),
  1315. &PolicyPathPair,
  1316. &PolicyHandles,
  1317. &Message.Flags,
  1318. &Message.Manifest,
  1319. &Message.Policy
  1320. );
  1321. CsrMessageFilledIn:
  1322. if (Message.Flags == 0) {
  1323. ASSERT(!NT_SUCCESS(Status));
  1324. //
  1325. // BasepSxsCreateStreams doesn't DbgPrint for the file not found, but
  1326. // we want to.
  1327. //
  1328. DbgPrintEx(
  1329. DPFLTR_SXS_ID,
  1330. DPFLTR_LEVEL_STATUS(Status),
  1331. "SXS: %s() BasepSxsCreateStreams() failed\n",
  1332. __FUNCTION__
  1333. );
  1334. goto Exit;
  1335. }
  1336. ASSERT(Message.Flags & (BASE_MSG_SXS_MANIFEST_PRESENT | BASE_MSG_SXS_TEXTUAL_ASSEMBLY_IDENTITY_PRESENT));
  1337. //
  1338. // file not found for .policy is ok
  1339. //
  1340. if (((Message.Flags & BASE_MSG_SXS_POLICY_PRESENT) == 0) &&
  1341. BasepSxsIsStatusFileNotFoundEtc(Status)) {
  1342. Status = STATUS_SUCCESS;
  1343. }
  1344. if (!NT_SUCCESS(Status)) {
  1345. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() BasepSxsCreateStreams() failed\n", __FUNCTION__);
  1346. goto Exit;
  1347. }
  1348. // Fly my pretties, fly!
  1349. Status = CsrBasepCreateActCtx( &Message );
  1350. if (!NT_SUCCESS(Status)) {
  1351. ASSERT(*ActivationContextData == NULL);
  1352. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() Calling csrss server failed\n", __FUNCTION__);
  1353. goto Exit;
  1354. }
  1355. Status = STATUS_SUCCESS;
  1356. Exit:
  1357. if (ManifestFileHandles != NULL) {
  1358. BasepSxsCloseHandles(ManifestFileHandles);
  1359. }
  1360. if (ManifestImageHandles != NULL && CloseManifestImageHandles) {
  1361. BasepSxsCloseHandles(ManifestImageHandles);
  1362. }
  1363. BasepSxsCloseHandles(&PolicyHandles);
  1364. RtlFreeHeap(RtlProcessHeap(), 0, NtManifestPath.Buffer);
  1365. RtlFreeUnicodeStringBuffer(&Win32PolicyPath);
  1366. RtlFreeUnicodeStringBuffer(&NtPolicyPath);
  1367. RtlFreeUnicodeStringBuffer(&Win32ManifestAdminOverridePath);
  1368. RtlFreeUnicodeStringBuffer(&NtManifestAdminOverridePath);
  1369. if (ActivationContextData != NULL) {
  1370. NtUnmapViewOfSection(NtCurrentProcess(), ActivationContextData);
  1371. }
  1372. #if DBG
  1373. DbgPrintEx(
  1374. DPFLTR_SXS_ID,
  1375. DPFLTR_LEVEL_STATUS(Status),
  1376. "SXS: %s(%ls) exiting 0x%08lx\n",
  1377. __FUNCTION__,
  1378. (ActParams != NULL ? ActParams->lpSource : NULL),
  1379. Status
  1380. );
  1381. #endif
  1382. return Status;
  1383. }
  1384. NTSTATUS
  1385. BasepSxsCreateResourceStream(
  1386. IN ULONG LdrCreateOutOfProcessImageFlags,
  1387. PCSXS_CONSTANT_WIN32_NT_PATH_PAIR Win32NtPathPair,
  1388. IN OUT PBASE_MSG_SXS_HANDLES Handles,
  1389. IN ULONG_PTR MappedResourceName,
  1390. OUT PBASE_MSG_SXS_STREAM MessageStream
  1391. )
  1392. {
  1393. //
  1394. // Any handles passed in, we do not close.
  1395. // Any handles we open, we close, except the ones passed out in MessageStream.
  1396. //
  1397. IO_STATUS_BLOCK IoStatusBlock;
  1398. IMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
  1399. FILE_BASIC_INFORMATION FileBasicInfo;
  1400. NTSTATUS Status = STATUS_SUCCESS;
  1401. LDR_OUT_OF_PROCESS_IMAGE OutOfProcessImage = {0};
  1402. ULONG_PTR ResourcePath[] = { ((ULONG_PTR)RT_MANIFEST), 0, 0 };
  1403. PVOID ResourceAddress = 0;
  1404. ULONG ResourceSize = 0;
  1405. KdPrintEx((
  1406. DPFLTR_SXS_ID,
  1407. DPFLTR_TRACE_LEVEL,
  1408. "SXS: %s(%wZ) beginning\n",
  1409. __FUNCTION__,
  1410. (Win32NtPathPair != NULL) ? Win32NtPathPair->Win32 : (PCUNICODE_STRING)NULL
  1411. ));
  1412. ASSERT(Handles != NULL);
  1413. ASSERT(Handles->Process != NULL);
  1414. ASSERT(MessageStream != NULL);
  1415. ASSERT(Win32NtPathPair != NULL);
  1416. // LdrFindOutOfProcessResource currently does not search on id or langid, just type.
  1417. // If you give it a nonzero id, it will only find it if is the first one.
  1418. // Another approach would be to have LdrFindOutOfProcessResource return the id it found.
  1419. ASSERT((MappedResourceName == (ULONG_PTR)CREATEPROCESS_MANIFEST_RESOURCE_ID) || (Handles->Process == NtCurrentProcess()));
  1420. //
  1421. // We could open any null handles like CreateFileStream does, but we happen to know
  1422. // that our clients open all of them.
  1423. //
  1424. // CreateActCtx maps the view earlier to determine if it starts MZ.
  1425. // CreateProcess gives us the view from the peb.
  1426. // .policy files are never resources.
  1427. ASSERT(Handles->ViewBase != NULL);
  1428. Status =
  1429. LdrCreateOutOfProcessImage(
  1430. LdrCreateOutOfProcessImageFlags,
  1431. Handles->Process,
  1432. Handles->ViewBase,
  1433. &OutOfProcessImage
  1434. );
  1435. if (!NT_SUCCESS(Status)) {
  1436. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() LdrCreateOutOfProcessImage failed\n", __FUNCTION__);
  1437. goto Exit;
  1438. }
  1439. ResourcePath[1] = MappedResourceName;
  1440. Status =
  1441. LdrFindCreateProcessManifest(
  1442. 0, // flags
  1443. &OutOfProcessImage,
  1444. ResourcePath,
  1445. RTL_NUMBER_OF(ResourcePath),
  1446. &ResourceDataEntry
  1447. );
  1448. if (!NT_SUCCESS(Status)) {
  1449. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() LdrFindOutOfProcessResource failed; nt status = %08lx\n", __FUNCTION__, Status);
  1450. goto Exit;
  1451. }
  1452. Status =
  1453. LdrAccessOutOfProcessResource(
  1454. 0, // flags
  1455. &OutOfProcessImage,
  1456. &ResourceDataEntry,
  1457. &ResourceAddress,
  1458. &ResourceSize);
  1459. if (!NT_SUCCESS(Status)) {
  1460. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() LdrAccessOutOfProcessResource failed; nt status = %08lx\n", __FUNCTION__, Status);
  1461. goto Exit;
  1462. }
  1463. MessageStream->Handle = Handles->Process;
  1464. MessageStream->FileHandle = Handles->File;
  1465. MessageStream->PathType = BASE_MSG_PATHTYPE_FILE;
  1466. MessageStream->FileType = BASE_MSG_FILETYPE_XML;
  1467. MessageStream->Path = *Win32NtPathPair->Win32; // it will be put in the csr capture buffer later
  1468. MessageStream->HandleType = BASE_MSG_HANDLETYPE_PROCESS;
  1469. MessageStream->Offset = (ULONGLONG) ResourceAddress;
  1470. MessageStream->Size = ResourceSize;
  1471. #if DBG
  1472. if (NtQueryDebugFilterState(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL) == TRUE) {
  1473. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() ResourceAddress:%p\n", __FUNCTION__, ResourceAddress);
  1474. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() OutOfProcessImage.DllHandle:%p\n", __FUNCTION__, OutOfProcessImage.DllHandle);
  1475. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() MessageStream->Offset:0x%I64x\n", __FUNCTION__, MessageStream->Offset);
  1476. }
  1477. #endif
  1478. Status = STATUS_SUCCESS;
  1479. Exit:
  1480. LdrDestroyOutOfProcessImage(&OutOfProcessImage);
  1481. #if DBG
  1482. DbgPrintEx(
  1483. DPFLTR_SXS_ID,
  1484. DPFLTR_LEVEL_STATUS(Status),
  1485. "SXS: %s(%wZ) exiting 0x%08lx\n",
  1486. __FUNCTION__,
  1487. (Win32NtPathPair != NULL) ? Win32NtPathPair->Win32 : (PCUNICODE_STRING)NULL,
  1488. Status
  1489. );
  1490. #endif
  1491. return Status;
  1492. }
  1493. VOID
  1494. BasepSxsOverrideStreamToMessageStream(
  1495. IN PCSXS_OVERRIDE_STREAM OverrideStream,
  1496. OUT PBASE_MSG_SXS_STREAM MessageStream
  1497. )
  1498. {
  1499. MessageStream->FileType = BASE_MSG_FILETYPE_XML;
  1500. MessageStream->PathType = BASE_MSG_PATHTYPE_OVERRIDE;
  1501. MessageStream->Path = OverrideStream->Name;
  1502. MessageStream->FileHandle = NULL;
  1503. MessageStream->HandleType = BASE_MSG_HANDLETYPE_CLIENT_PROCESS;
  1504. MessageStream->Handle = NULL;
  1505. MessageStream->Offset = (ULONGLONG)OverrideStream->Address;
  1506. MessageStream->Size = OverrideStream->Size;
  1507. }
  1508. NTSTATUS
  1509. BasepSxsCreateStreams(
  1510. IN ULONG Flags,
  1511. IN ULONG LdrCreateOutOfProcessImageFlags,
  1512. IN ACCESS_MASK AccessMask,
  1513. IN PCSXS_OVERRIDE_STREAM OverrideManifest OPTIONAL,
  1514. IN PCSXS_OVERRIDE_STREAM OverridePolicy OPTIONAL,
  1515. IN PCSXS_CONSTANT_WIN32_NT_PATH_PAIR ManifestFilePathPair,
  1516. IN OUT PBASE_MSG_SXS_HANDLES ManifestFileHandles,
  1517. IN PCSXS_CONSTANT_WIN32_NT_PATH_PAIR ManifestExePathPair,
  1518. IN OUT PBASE_MSG_SXS_HANDLES ManifestExeHandles,
  1519. IN ULONG_PTR MappedManifestResourceName OPTIONAL,
  1520. IN PCSXS_CONSTANT_WIN32_NT_PATH_PAIR PolicyPathPair,
  1521. IN OUT PBASE_MSG_SXS_HANDLES PolicyHandles,
  1522. OUT PULONG MessageFlags,
  1523. OUT PBASE_MSG_SXS_STREAM ManifestMessageStream,
  1524. OUT PBASE_MSG_SXS_STREAM PolicyMessageStream OPTIONAL
  1525. )
  1526. /*
  1527. A mismash of combined code for CreateActCtx and CreateProcess.
  1528. */
  1529. {
  1530. NTSTATUS Status = STATUS_SUCCESS;
  1531. BOOLEAN LookForPolicy = TRUE;
  1532. #if DBG
  1533. ASSERT(MessageFlags != NULL);
  1534. ASSERT(ManifestMessageStream != NULL);
  1535. ASSERT((ManifestFilePathPair != NULL) || (ManifestExePathPair != NULL));
  1536. ASSERT((MappedManifestResourceName == 0) || (ManifestExePathPair != NULL));
  1537. ASSERT((PolicyPathPair != NULL) == (PolicyMessageStream != NULL));
  1538. if (ManifestFilePathPair != NULL) {
  1539. ASSERT(ManifestFilePathPair->Win32 != NULL);
  1540. ASSERT(ManifestFilePathPair->Nt != NULL);
  1541. }
  1542. if (ManifestExePathPair != NULL) {
  1543. ASSERT(ManifestExePathPair->Win32 != NULL);
  1544. ASSERT(ManifestExePathPair->Nt != NULL);
  1545. }
  1546. if (PolicyPathPair != NULL) {
  1547. ASSERT(PolicyPathPair->Win32 != NULL);
  1548. ASSERT(PolicyPathPair->Nt != NULL);
  1549. }
  1550. if (OverrideManifest != NULL && OverrideManifest->Size != 0) {
  1551. ASSERT(OverrideManifest->Address != NULL);
  1552. }
  1553. if (OverridePolicy != NULL && OverridePolicy->Size != 0) {
  1554. ASSERT(OverridePolicy->Address != NULL);
  1555. }
  1556. DbgPrintEx(
  1557. DPFLTR_SXS_ID,
  1558. DPFLTR_TRACE_LEVEL,
  1559. "SXS: %s(ManifestFilePath:%wZ, ManifestExePath:%wZ, PolicyPath:%wZ) beginning\n",
  1560. __FUNCTION__,
  1561. (ManifestFilePathPair != NULL) ? ManifestFilePathPair->Win32 : (PCUNICODE_STRING)NULL,
  1562. (ManifestExePathPair != NULL) ? ManifestExePathPair->Win32 : (PCUNICODE_STRING)NULL,
  1563. (PolicyPathPair != NULL) ? PolicyPathPair->Win32 : (PCUNICODE_STRING)NULL
  1564. );
  1565. #endif
  1566. if (OverrideManifest != NULL) {
  1567. BasepSxsOverrideStreamToMessageStream(OverrideManifest, ManifestMessageStream);
  1568. Status = STATUS_SUCCESS;
  1569. //
  1570. // When appcompat provides a manifest, do not look for a policy.
  1571. // This let's us fix the Matrix DVD.
  1572. //
  1573. LookForPolicy = FALSE;
  1574. goto ManifestFound;
  1575. }
  1576. if (ManifestFilePathPair != NULL) {
  1577. Status =
  1578. BasepSxsCreateFileStream(
  1579. AccessMask,
  1580. ManifestFilePathPair,
  1581. ManifestFileHandles,
  1582. ManifestMessageStream);
  1583. if (NT_SUCCESS(Status)) {
  1584. goto ManifestFound;
  1585. }
  1586. if (!BasepSxsIsStatusFileNotFoundEtc(Status)) {
  1587. goto Exit;
  1588. }
  1589. }
  1590. if (ManifestExePathPair != NULL) {
  1591. Status =
  1592. BasepSxsCreateResourceStream(
  1593. LdrCreateOutOfProcessImageFlags,
  1594. ManifestExePathPair,
  1595. ManifestExeHandles,
  1596. MappedManifestResourceName,
  1597. ManifestMessageStream);
  1598. if (NT_SUCCESS(Status)) {
  1599. goto ManifestFound;
  1600. }
  1601. }
  1602. ASSERT(!NT_SUCCESS(Status)); // otherwise this should be unreachable
  1603. goto Exit;
  1604. ManifestFound:
  1605. // indicate partial success even if policy file not found
  1606. *MessageFlags |= BASE_MSG_SXS_MANIFEST_PRESENT;
  1607. if (OverridePolicy != NULL) {
  1608. BasepSxsOverrideStreamToMessageStream(OverridePolicy, PolicyMessageStream);
  1609. *MessageFlags |= BASE_MSG_SXS_POLICY_PRESENT;
  1610. Status = STATUS_SUCCESS;
  1611. } else if (LookForPolicy && PolicyPathPair != NULL) {
  1612. Status = BasepSxsCreateFileStream(AccessMask, PolicyPathPair, PolicyHandles, PolicyMessageStream);
  1613. if (!NT_SUCCESS(Status)) {
  1614. goto Exit; // our caller knows this is not necessarily fatal
  1615. }
  1616. *MessageFlags |= BASE_MSG_SXS_POLICY_PRESENT;
  1617. }
  1618. Status = STATUS_SUCCESS;
  1619. Exit:
  1620. #if DBG
  1621. DbgPrintEx(
  1622. DPFLTR_SXS_ID,
  1623. DPFLTR_LEVEL_STATUS(Status),
  1624. "SXS: %s(MessageFlags=%lu) exiting 0x%08lx\n",
  1625. __FUNCTION__,
  1626. *MessageFlags,
  1627. Status);
  1628. #endif // DBG
  1629. return Status;
  1630. }
  1631. BOOL
  1632. BasepSxsIsStatusFileNotFoundEtc(
  1633. NTSTATUS Status
  1634. )
  1635. {
  1636. DWORD Error;
  1637. if (NT_SUCCESS(Status)) {
  1638. return FALSE;
  1639. }
  1640. // First check the most obvious sounding, probably the most common.
  1641. if (
  1642. Status == STATUS_OBJECT_PATH_NOT_FOUND
  1643. || Status == STATUS_OBJECT_NAME_NOT_FOUND
  1644. || Status == STATUS_NO_SUCH_FILE
  1645. )
  1646. {
  1647. return TRUE;
  1648. }
  1649. // Then get the eight or so less obvious ones by their mapping
  1650. // to the two obvious Win32 values and the two inobvious Win32 values.
  1651. Error = RtlNtStatusToDosErrorNoTeb(Status);
  1652. // REVIEW
  1653. // STATUS_PATH_NOT_COVERED, ERROR_HOST_UNREACHABLE,
  1654. if ( Error == ERROR_FILE_NOT_FOUND
  1655. || Error == ERROR_PATH_NOT_FOUND
  1656. || Error == ERROR_BAD_NETPATH // \\a\b
  1657. || Error == ERROR_BAD_NET_NAME // \\a-jayk2\b
  1658. )
  1659. {
  1660. return TRUE;
  1661. }
  1662. return FALSE;
  1663. }
  1664. BOOL
  1665. BasepSxsIsStatusResourceNotFound(
  1666. NTSTATUS Status
  1667. )
  1668. {
  1669. if (NT_SUCCESS(Status))
  1670. return FALSE;
  1671. if (
  1672. Status == STATUS_RESOURCE_DATA_NOT_FOUND
  1673. || Status == STATUS_RESOURCE_TYPE_NOT_FOUND
  1674. || Status == STATUS_RESOURCE_NAME_NOT_FOUND
  1675. || Status == STATUS_RESOURCE_LANG_NOT_FOUND
  1676. )
  1677. {
  1678. return TRUE;
  1679. }
  1680. return FALSE;
  1681. }
  1682. NTSTATUS
  1683. BasepSxsGetProcessImageBaseAddress(
  1684. HANDLE Process,
  1685. PVOID* ImageBaseAddress
  1686. )
  1687. {
  1688. PROCESS_BASIC_INFORMATION ProcessBasicInfo;
  1689. NTSTATUS Status;
  1690. C_ASSERT(RTL_FIELD_SIZE(PEB, ImageBaseAddress) == sizeof(*ImageBaseAddress));
  1691. Status =
  1692. NtQueryInformationProcess(
  1693. Process,
  1694. ProcessBasicInformation,
  1695. &ProcessBasicInfo,
  1696. sizeof(ProcessBasicInfo),
  1697. NULL
  1698. );
  1699. if (!NT_SUCCESS(Status)) {
  1700. goto Exit;
  1701. }
  1702. Status =
  1703. NtReadVirtualMemory(
  1704. Process,
  1705. ((PUCHAR)ProcessBasicInfo.PebBaseAddress) + FIELD_OFFSET(PEB, ImageBaseAddress),
  1706. ImageBaseAddress,
  1707. sizeof(*ImageBaseAddress),
  1708. NULL
  1709. );
  1710. Exit:
  1711. return Status;
  1712. }
  1713. extern const SXS_OVERRIDE_STREAM SxsForceEmptyPolicy =
  1714. {
  1715. RTL_CONSTANT_STRING(L"SxsForceEmptyPolicy"),
  1716. NULL,
  1717. 0
  1718. };
  1719. #if defined(ACTCTX_FLAG_LIKE_CREATEPROCESS)
  1720. NTSTATUS
  1721. BasepCreateActCtxLikeCreateProcess(
  1722. PCACTCXW pParams
  1723. )
  1724. {
  1725. //
  1726. // We could allow processor architecture, as long as it matches the client and the file,
  1727. // modulo x86 vs. x86-on-ia64, we can smooth over that difference.
  1728. //
  1729. BASE_MSG_SXS_HANDLES ExeHandles = { 0 };
  1730. BASE_MSG_SXS_HANDLES AdminOverrideHandles = { 0 };
  1731. const ULONG OkFlags = (ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID | ACTCTX_FLAG_LANGID_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT | ACTCTX_FLAG_LIKE_CREATEPROCESS);
  1732. const ULONG BadFlags = (ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID | ACTCTX_FLAG_APPLICATION_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID);
  1733. ACTCXW Params;
  1734. Params.dwFlags = pParams->dwFlags;
  1735. if (Params.dwFlags & BadFlags) {
  1736. DbgPrintEx(
  1737. DPFLTR_SXS_ID,
  1738. DPFLTR_ERROR_LEVEL,
  1739. "SXS: %s() Bad flags (yourFlags: okFlags : 0x%lx, badFlags; )",
  1740. __FUNCTION__,
  1741. Params.dwFlags,
  1742. OkFlags
  1743. );
  1744. Status = STATUS_INVALID_PARAMETER;
  1745. goto Exit;
  1746. }
  1747. }
  1748. #endif
  1749. NTSTATUS
  1750. BasepSxsCreateProcessCsrMessage(
  1751. IN PCSXS_OVERRIDE_STREAM OverrideManifest OPTIONAL,
  1752. IN PCSXS_OVERRIDE_STREAM OverridePolicy OPTIONAL,
  1753. IN OUT PCSXS_WIN32_NT_PATH_PAIR ManifestPathPair,
  1754. IN OUT PBASE_MSG_SXS_HANDLES ManifestFileHandles,
  1755. IN PCSXS_CONSTANT_WIN32_NT_PATH_PAIR ExePathPair,
  1756. IN OUT PBASE_MSG_SXS_HANDLES ManifestExeHandles,
  1757. IN OUT PCSXS_WIN32_NT_PATH_PAIR PolicyPathPair,
  1758. IN OUT PBASE_MSG_SXS_HANDLES PolicyHandles,
  1759. IN OUT PRTL_UNICODE_STRING_BUFFER Win32AssemblyDirectoryBuffer,
  1760. OUT PBASE_SXS_CREATEPROCESS_MSG Message
  1761. )
  1762. {
  1763. UNICODE_STRING PathPieces[2];
  1764. NTSTATUS Status = STATUS_SUCCESS;
  1765. CONST SXS_CONSTANT_WIN32_NT_PATH_PAIR ConstantManifestPathPair =
  1766. { &ManifestPathPair->Win32->String, &ManifestPathPair->Nt->String };
  1767. CONST SXS_CONSTANT_WIN32_NT_PATH_PAIR ConstantPolicyPathPair =
  1768. { &PolicyPathPair->Win32->String, &PolicyPathPair->Nt->String };
  1769. #if DBG
  1770. //
  1771. // assertions are anded to avoid access violating
  1772. //
  1773. ASSERT(ExePathPair != NULL
  1774. && ExePathPair->Win32 != NULL
  1775. && NT_SUCCESS(RtlValidateUnicodeString(0, ExePathPair->Win32))
  1776. && (ExePathPair->Win32->Buffer[1] == '\\'
  1777. || ExePathPair->Win32->Buffer[1] == ':')
  1778. && ExePathPair->Nt != NULL
  1779. && ExePathPair->Nt->Buffer[0] == '\\'
  1780. && NT_SUCCESS(RtlValidateUnicodeString(0, ExePathPair->Nt)));
  1781. ASSERT(ManifestPathPair != NULL
  1782. && ManifestPathPair->Win32 != NULL
  1783. && NT_SUCCESS(RtlValidateUnicodeString(0, &ManifestPathPair->Win32->String))
  1784. && ManifestPathPair->Nt != NULL
  1785. && NT_SUCCESS(RtlValidateUnicodeString(0, &ManifestPathPair->Nt->String)));
  1786. ASSERT(PolicyPathPair != NULL
  1787. && PolicyPathPair->Win32 != NULL
  1788. && NT_SUCCESS(RtlValidateUnicodeString(0, &PolicyPathPair->Win32->String))
  1789. && PolicyPathPair->Nt != NULL
  1790. && NT_SUCCESS(RtlValidateUnicodeString(0, &PolicyPathPair->Nt->String)));
  1791. ASSERT(Win32AssemblyDirectoryBuffer != NULL
  1792. && NT_SUCCESS(RtlValidateUnicodeString(0, &Win32AssemblyDirectoryBuffer->String)));
  1793. ASSERT(ManifestExeHandles != NULL
  1794. && ManifestExeHandles->Process != NULL
  1795. && ManifestExeHandles->ViewBase == NULL);
  1796. ASSERT(Message != NULL);
  1797. DbgPrintEx(
  1798. DPFLTR_SXS_ID,
  1799. DPFLTR_TRACE_LEVEL,
  1800. "SXS: %s(%wZ) beginning\n",
  1801. __FUNCTION__,
  1802. (ExePathPair != NULL) ? ExePathPair->Win32 : (PCUNICODE_STRING)NULL
  1803. );
  1804. #endif
  1805. // C_ASSERT didn't work.
  1806. ASSERT(BASE_MSG_FILETYPE_NONE == 0);
  1807. ASSERT(BASE_MSG_PATHTYPE_NONE == 0);
  1808. RtlZeroMemory(Message, sizeof(*Message));
  1809. Status = BasepSxsGetProcessImageBaseAddress(ManifestExeHandles->Process, &ManifestExeHandles->ViewBase);
  1810. if (!NT_SUCCESS(Status)) {
  1811. goto Exit;
  1812. }
  1813. //
  1814. // form up foo.exe.manifest and foo.exe.policy, nt and win32 flavors
  1815. //
  1816. PathPieces[0] = *ExePathPair->Win32;
  1817. PathPieces[1] = SxsManifestSuffix;
  1818. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(ManifestPathPair->Win32, 2, PathPieces)))
  1819. goto Exit;
  1820. PathPieces[1] = SxsPolicySuffix;
  1821. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(PolicyPathPair->Win32, 2, PathPieces)))
  1822. goto Exit;
  1823. PathPieces[0] = *ExePathPair->Nt;
  1824. PathPieces[1] = SxsManifestSuffix;
  1825. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(ManifestPathPair->Nt, 2, PathPieces)))
  1826. goto Exit;
  1827. PathPieces[1] = SxsPolicySuffix;
  1828. if (!NT_SUCCESS(Status = RtlMultiAppendUnicodeStringBuffer(PolicyPathPair->Nt, 2, PathPieces)))
  1829. goto Exit;
  1830. Status =
  1831. BasepSxsCreateStreams(
  1832. 0,
  1833. LDR_DLL_MAPPED_AS_UNFORMATED_IMAGE, // LdrCreateOutOfProcessImageFlags
  1834. FILE_GENERIC_READ | FILE_EXECUTE,
  1835. OverrideManifest,
  1836. OverridePolicy,
  1837. &ConstantManifestPathPair,
  1838. ManifestFileHandles,
  1839. ExePathPair,
  1840. ManifestExeHandles,
  1841. (ULONG_PTR)CREATEPROCESS_MANIFEST_RESOURCE_ID,
  1842. &ConstantPolicyPathPair,
  1843. PolicyHandles,
  1844. &Message->Flags,
  1845. &Message->Manifest,
  1846. &Message->Policy
  1847. );
  1848. //
  1849. // did we find manifest and policy
  1850. // it's ok to find neither but if either then always manifest
  1851. //
  1852. if (BasepSxsIsStatusFileNotFoundEtc(Status)
  1853. || BasepSxsIsStatusResourceNotFound(Status)) {
  1854. Status = STATUS_SUCCESS;
  1855. }
  1856. if (!NT_SUCCESS(Status)) {
  1857. goto Exit;
  1858. }
  1859. if (Message->Flags == 0) {
  1860. Status = STATUS_SUCCESS;
  1861. goto Exit;
  1862. }
  1863. //
  1864. // Set the assembly directory. Use a copy to not violate const.
  1865. // We can't just shorten the path because basesrv expects the string to be nul
  1866. // terminated, and better to meet that expection here than there.
  1867. //
  1868. Status = RtlAssignUnicodeStringBuffer(Win32AssemblyDirectoryBuffer, ExePathPair->Win32);
  1869. if (!NT_SUCCESS(Status))
  1870. goto Exit;
  1871. Status = RtlRemoveLastFullDosOrNtPathElement(0, Win32AssemblyDirectoryBuffer);
  1872. if (!NT_SUCCESS(Status))
  1873. goto Exit;
  1874. RTL_NUL_TERMINATE_STRING(&Win32AssemblyDirectoryBuffer->String);
  1875. Message->AssemblyDirectory = Win32AssemblyDirectoryBuffer->String;
  1876. Status = STATUS_SUCCESS;
  1877. Exit:
  1878. #if DBG
  1879. if (NtQueryDebugFilterState(DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL) == TRUE) {
  1880. DbgPrintEx(
  1881. DPFLTR_SXS_ID,
  1882. DPFLTR_TRACE_LEVEL,
  1883. "SXS: %s() Message {\n"
  1884. "SXS: Flags:(%s | %s | %s)\n"
  1885. "SXS: }\n",
  1886. __FUNCTION__,
  1887. (Message->Flags & BASE_MSG_SXS_MANIFEST_PRESENT) ? "MANIFEST_PRESENT" : "0",
  1888. (Message->Flags & BASE_MSG_SXS_POLICY_PRESENT) ? "POLICY_PRESENT" : "0",
  1889. (Message->Flags & BASE_MSG_SXS_TEXTUAL_ASSEMBLY_IDENTITY_PRESENT) ? "TEXTUAL_ASSEMBLY_IDENTITY_PRESENT" : "0"
  1890. );
  1891. if (Message->Flags & BASE_MSG_SXS_MANIFEST_PRESENT) {
  1892. BasepSxsDbgPrintMessageStream(__FUNCTION__, "Manifest", &Message->Manifest);
  1893. }
  1894. if (Message->Flags & BASE_MSG_SXS_POLICY_PRESENT) {
  1895. BasepSxsDbgPrintMessageStream(__FUNCTION__, "Policy", &Message->Policy);
  1896. }
  1897. //
  1898. // CreateProcess does not support textual identities.
  1899. //
  1900. ASSERT((Message->Flags & BASE_MSG_SXS_TEXTUAL_ASSEMBLY_IDENTITY_PRESENT) == 0);
  1901. }
  1902. DbgPrintEx(
  1903. DPFLTR_SXS_ID,
  1904. DPFLTR_LEVEL_STATUS(Status),
  1905. "SXS: %s(%wZ) exiting 0x%08lx\n",
  1906. __FUNCTION__,
  1907. (ExePathPair != NULL) ? ExePathPair->Win32 : (PCUNICODE_STRING)NULL,
  1908. Status
  1909. );
  1910. #endif
  1911. return Status;
  1912. }
  1913. NTSTATUS
  1914. BasepSxsCreateFileStream(
  1915. IN ACCESS_MASK AccessMask,
  1916. PCSXS_CONSTANT_WIN32_NT_PATH_PAIR Win32NtPathPair,
  1917. IN OUT PBASE_MSG_SXS_HANDLES Handles,
  1918. PBASE_MSG_SXS_STREAM MessageStream
  1919. )
  1920. {
  1921. OBJECT_ATTRIBUTES Obja;
  1922. IO_STATUS_BLOCK IoStatusBlock;
  1923. NTSTATUS Status = STATUS_SUCCESS;
  1924. NTSTATUS Status1 = STATUS_SUCCESS;
  1925. FILE_STANDARD_INFORMATION FileBasicInformation;
  1926. #if DBG
  1927. ASSERT(Win32NtPathPair != NULL);
  1928. if (Win32NtPathPair != NULL) {
  1929. ASSERT(Win32NtPathPair->Win32 != NULL);
  1930. ASSERT(Win32NtPathPair->Nt != NULL);
  1931. }
  1932. ASSERT(MessageStream != NULL);
  1933. DbgPrintEx(
  1934. DPFLTR_SXS_ID,
  1935. DPFLTR_TRACE_LEVEL,
  1936. "SXS: %s(Path:%wZ, Handles:%p(Process:%p, File:%p, Section:%p), MessageStream:%p) beginning\n",
  1937. __FUNCTION__,
  1938. (Win32NtPathPair != NULL) ? Win32NtPathPair->Win32 : (PCUNICODE_STRING)NULL,
  1939. Handles,
  1940. (Handles != NULL) ? Handles->Process : NULL,
  1941. (Handles != NULL) ? Handles->File : NULL,
  1942. (Handles != NULL) ? Handles->Section : NULL,
  1943. MessageStream
  1944. );
  1945. #endif
  1946. if (Handles->File == NULL) {
  1947. CONST PCUNICODE_STRING NtPath = Win32NtPathPair->Nt;
  1948. InitializeObjectAttributes(
  1949. &Obja,
  1950. RTL_CONST_CAST(PUNICODE_STRING)(NtPath),
  1951. OBJ_CASE_INSENSITIVE,
  1952. NULL,
  1953. NULL
  1954. );
  1955. Status =
  1956. NtOpenFile(
  1957. &Handles->File,
  1958. AccessMask,
  1959. &Obja,
  1960. &IoStatusBlock,
  1961. FILE_SHARE_READ,
  1962. FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE
  1963. );
  1964. if (!NT_SUCCESS(Status)) {
  1965. if (DPFLTR_LEVEL_STATUS(Status) == DPFLTR_ERROR_LEVEL) {
  1966. DbgPrintEx(
  1967. DPFLTR_SXS_ID,
  1968. DPFLTR_LEVEL_STATUS(Status),
  1969. "SXS: %s() NtOpenFile(%wZ) failed\n",
  1970. __FUNCTION__,
  1971. Obja.ObjectName
  1972. );
  1973. }
  1974. goto Exit;
  1975. }
  1976. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() NtOpenFile(%wZ) succeeded\n", __FUNCTION__, Obja.ObjectName));
  1977. }
  1978. if (Handles->Section == NULL) {
  1979. Status =
  1980. NtCreateSection(
  1981. &Handles->Section,
  1982. SECTION_MAP_READ,
  1983. NULL, // ObjectAttributes
  1984. NULL, // MaximumSize (whole file)
  1985. PAGE_READONLY, // SectionPageProtection
  1986. SEC_COMMIT, // AllocationAttributes
  1987. Handles->File
  1988. );
  1989. if (!NT_SUCCESS(Status)) {
  1990. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_ERROR_LEVEL, "SXS: %s() NtCreateSection() failed\n", __FUNCTION__);
  1991. goto Exit;
  1992. }
  1993. KdPrintEx((DPFLTR_SXS_ID, DPFLTR_TRACE_LEVEL, "SXS: %s() NtCreateSection() succeeded\n", __FUNCTION__));
  1994. }
  1995. Status =
  1996. NtQueryInformationFile(
  1997. Handles->File,
  1998. &IoStatusBlock,
  1999. &FileBasicInformation,
  2000. sizeof(FileBasicInformation),
  2001. FileStandardInformation
  2002. );
  2003. if (!NT_SUCCESS(Status)) {
  2004. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_ERROR_LEVEL, "SXS: %s() NtQueryInformationFile failed\n", __FUNCTION__);
  2005. goto Exit;
  2006. }
  2007. // clamp >4gig on 32bit to 4gig (instead of modulo)
  2008. // we should get an error later like STATUS_SECTION_TOO_BIG
  2009. if (FileBasicInformation.EndOfFile.QuadPart > MAXSIZE_T) {
  2010. FileBasicInformation.EndOfFile.QuadPart = MAXSIZE_T;
  2011. }
  2012. MessageStream->FileHandle = Handles->File;
  2013. MessageStream->PathType = BASE_MSG_PATHTYPE_FILE;
  2014. MessageStream->FileType = BASE_MSG_FILETYPE_XML;
  2015. MessageStream->Path = *Win32NtPathPair->Win32; // it will be put in the csr capture buffer later
  2016. MessageStream->HandleType = BASE_MSG_HANDLETYPE_SECTION;
  2017. MessageStream->Handle = Handles->Section;
  2018. MessageStream->Offset = 0;
  2019. // cast to 32bits on 32bit platform
  2020. MessageStream->Size = (SIZE_T)FileBasicInformation.EndOfFile.QuadPart;
  2021. Status = STATUS_SUCCESS;
  2022. Exit:
  2023. #if DBG
  2024. DbgPrintEx(DPFLTR_SXS_ID, DPFLTR_LEVEL_STATUS(Status), "SXS: %s() exiting 0x%08lx\n", __FUNCTION__, Status);
  2025. #endif // DBG
  2026. return Status;
  2027. }
  2028. WINBASEAPI
  2029. BOOL
  2030. WINAPI
  2031. QueryActCtxW(
  2032. IN DWORD dwFlags,
  2033. IN HANDLE hActCtx,
  2034. IN PVOID pvSubInstance,
  2035. IN ULONG ulInfoClass,
  2036. OUT PVOID pvBuffer,
  2037. IN SIZE_T cbBuffer OPTIONAL,
  2038. OUT SIZE_T *pcbWrittenOrRequired OPTIONAL
  2039. )
  2040. {
  2041. NTSTATUS Status;
  2042. BOOL fSuccess = FALSE;
  2043. ULONG FlagsToRtl = 0;
  2044. ULONG ValidFlags =
  2045. QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX
  2046. | QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE
  2047. | QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS
  2048. | QUERY_ACTCTX_FLAG_NO_ADDREF
  2049. ;
  2050. if (pcbWrittenOrRequired != NULL)
  2051. *pcbWrittenOrRequired = 0;
  2052. //
  2053. // compatibility with old values
  2054. // define QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX (0x00000001)
  2055. // define QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE (0x00000002)
  2056. // define QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS (0x00000003)
  2057. //
  2058. // 80000003 is in heavy use by -DISOLATION_AWARE_ENABLED.
  2059. //
  2060. switch (dwFlags & 3)
  2061. {
  2062. case 0: break; // It is legal to pass none of the flags, like if a real hActCtx is passed.
  2063. case 1: dwFlags |= QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX; break;
  2064. case 2: dwFlags |= QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE; break;
  2065. case 3: dwFlags |= QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS; break;
  2066. }
  2067. dwFlags &= ~3; // These bits have been abandoned.
  2068. if (dwFlags & ~ValidFlags) {
  2069. #if DBG
  2070. DbgPrintEx(
  2071. DPFLTR_SXS_ID,
  2072. DPFLTR_ERROR_LEVEL,
  2073. "SXS: %s() bad flags(passed: 0x%lx, allowed: 0x%lx, bad: 0x%lx)\n",
  2074. __FUNCTION__,
  2075. dwFlags,
  2076. ValidFlags,
  2077. (dwFlags & ~ValidFlags)
  2078. );
  2079. #endif
  2080. BaseSetLastNTError(STATUS_INVALID_PARAMETER_1);
  2081. goto Exit;
  2082. }
  2083. switch (ulInfoClass)
  2084. {
  2085. default:
  2086. #if DBG
  2087. DbgPrintEx(
  2088. DPFLTR_SXS_ID,
  2089. DPFLTR_ERROR_LEVEL,
  2090. "SXS: %s() bad InfoClass(0x%lx)\n",
  2091. __FUNCTION__,
  2092. ulInfoClass
  2093. );
  2094. #endif
  2095. BaseSetLastNTError(STATUS_INVALID_PARAMETER_2);
  2096. goto Exit;
  2097. case ActivationContextBasicInformation:
  2098. case ActivationContextDetailedInformation:
  2099. break;
  2100. case AssemblyDetailedInformationInActivationContext:
  2101. case FileInformationInAssemblyOfAssemblyInActivationContext:
  2102. if (pvSubInstance == NULL)
  2103. {
  2104. #if DBG
  2105. DbgPrintEx(
  2106. DPFLTR_SXS_ID,
  2107. DPFLTR_ERROR_LEVEL,
  2108. "SXS: %s() InfoClass 0x%lx requires SubInstance != NULL\n",
  2109. __FUNCTION__,
  2110. ulInfoClass
  2111. );
  2112. #endif
  2113. BaseSetLastNTError(STATUS_INVALID_PARAMETER_3);
  2114. goto Exit;
  2115. }
  2116. }
  2117. if ((pvBuffer == NULL) && (cbBuffer != 0)) {
  2118. // This probably means that they forgot to check for a failed allocation so we'll
  2119. // attribute the failure to parameter 3.
  2120. #if DBG
  2121. DbgPrintEx(
  2122. DPFLTR_SXS_ID,
  2123. DPFLTR_ERROR_LEVEL,
  2124. "SXS: %s() (pvBuffer == NULL) && ((cbBuffer=0x%lu) != 0)\n",
  2125. __FUNCTION__,
  2126. cbBuffer
  2127. );
  2128. #endif
  2129. BaseSetLastNTError(STATUS_INVALID_PARAMETER_4);
  2130. goto Exit;
  2131. }
  2132. if ((pvBuffer == NULL) && (pcbWrittenOrRequired == NULL)) {
  2133. #if DBG
  2134. DbgPrintEx(
  2135. DPFLTR_SXS_ID,
  2136. DPFLTR_ERROR_LEVEL,
  2137. "SXS: %s() (pvBuffer == NULL) && (pcbWrittenOrRequired == NULL)\n",
  2138. __FUNCTION__
  2139. );
  2140. #endif
  2141. BaseSetLastNTError(STATUS_INVALID_PARAMETER_5);
  2142. goto Exit;
  2143. }
  2144. ValidFlags =
  2145. QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX
  2146. | QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE
  2147. | QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS
  2148. ;
  2149. switch (dwFlags & ValidFlags)
  2150. {
  2151. default:
  2152. #if DBG
  2153. DbgPrintEx(
  2154. DPFLTR_SXS_ID,
  2155. DPFLTR_ERROR_LEVEL,
  2156. "SXS: %s(dwFlags=0x%lx) more than one flag in 0x%lx was passed\n",
  2157. __FUNCTION__,
  2158. dwFlags,
  2159. ValidFlags
  2160. );
  2161. #endif
  2162. BaseSetLastNTError(STATUS_INVALID_PARAMETER_1);
  2163. goto Exit;
  2164. case 0: // It is legal to pass none of the flags, like if a real hActCtx is passed.
  2165. break;
  2166. case QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX:
  2167. FlagsToRtl |= RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT;
  2168. break;
  2169. case QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE:
  2170. FlagsToRtl |= RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_MODULE;
  2171. break;
  2172. case QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS:
  2173. FlagsToRtl |= RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_ADDRESS;
  2174. break;
  2175. }
  2176. if ((dwFlags & QUERY_ACTCTX_FLAG_NO_ADDREF) != 0)
  2177. FlagsToRtl |= RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_NO_ADDREF;
  2178. Status = RtlQueryInformationActivationContext(FlagsToRtl, (PACTIVATION_CONTEXT) hActCtx, pvSubInstance, ulInfoClass, pvBuffer, cbBuffer, pcbWrittenOrRequired);
  2179. if (!NT_SUCCESS(Status)) {
  2180. BaseSetLastNTError(Status);
  2181. goto Exit;
  2182. }
  2183. fSuccess = TRUE;
  2184. Exit:
  2185. return fSuccess;
  2186. }
  2187. NTSTATUS
  2188. NTAPI
  2189. BasepProbeForDllManifest(
  2190. IN PVOID DllBase,
  2191. IN PCWSTR FullDllPath,
  2192. OUT PVOID *ActivationContextOut
  2193. )
  2194. {
  2195. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  2196. PACTIVATION_CONTEXT ActivationContext = NULL;
  2197. ACTCTXW acw = { sizeof(acw) };
  2198. static const ULONG_PTR ResourceIdPath[2] = { (ULONG_PTR) RT_MANIFEST, (ULONG_PTR) ISOLATIONAWARE_MANIFEST_RESOURCE_ID };
  2199. PIMAGE_RESOURCE_DIRECTORY ResourceDirectory = NULL;
  2200. if (ActivationContextOut != NULL)
  2201. *ActivationContextOut = NULL;
  2202. ASSERT(ActivationContextOut != NULL);
  2203. if (ActivationContextOut == NULL) {
  2204. Status = STATUS_INVALID_PARAMETER;
  2205. goto Exit;
  2206. }
  2207. Status = LdrFindResourceDirectory_U(DllBase, ResourceIdPath, RTL_NUMBER_OF(ResourceIdPath), &ResourceDirectory);
  2208. if (!NT_SUCCESS(Status))
  2209. goto Exit;
  2210. acw.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
  2211. acw.lpSource = FullDllPath;
  2212. acw.lpResourceName = MAKEINTRESOURCEW(ISOLATIONAWARE_MANIFEST_RESOURCE_ID);
  2213. acw.hModule = DllBase;
  2214. ActivationContext = (PACTIVATION_CONTEXT) CreateActCtxW(&acw);
  2215. if (ActivationContext == INVALID_HANDLE_VALUE) {
  2216. Status = NtCurrentTeb()->LastStatusValue;
  2217. goto Exit;
  2218. }
  2219. *ActivationContextOut = ActivationContext;
  2220. Status = STATUS_SUCCESS;
  2221. Exit:
  2222. return Status;
  2223. }