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.

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