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.

283 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. sxsactctx.cpp
  5. Abstract:
  6. Implement SxsGenerateActivationContext, called from csrss.exe.
  7. Author:
  8. Michael J. Grier (MGrier)
  9. Revision History:
  10. Jay Krell (a-JayK) June 2000
  11. moved file opening from here (sxs.dll) to csrss.exe client process,
  12. pass ISequentialStreams to sxs.dll.
  13. --*/
  14. #include "stdinc.h"
  15. #include <windows.h>
  16. #include "sxsapi.h"
  17. #include "sxsp.h"
  18. #include "fusioneventlog.h"
  19. #include "filestream.h"
  20. // temporary dbprint reduction until we fix setup/comctl
  21. static ULONG DbgPrintReduceLevel(ULONG FilterLevel)
  22. {
  23. if (FilterLevel != FUSION_DBG_LEVEL_ERROR)
  24. return FilterLevel;
  25. LONG Error = ::FusionpGetLastWin32Error();
  26. if (Error == ERROR_FILE_NOT_FOUND || Error == ERROR_PATH_NOT_FOUND)
  27. return FUSION_DBG_LEVEL_ENTEREXIT;
  28. return FilterLevel;
  29. }
  30. static
  31. VOID
  32. DbgPrintSxsGenerateActivationContextParameters(
  33. ULONG FilterLevel,
  34. PSXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS Parameters,
  35. PCSTR Function
  36. )
  37. {
  38. FilterLevel = DbgPrintReduceLevel(FilterLevel);
  39. #if !DBG
  40. if (FilterLevel != FUSION_DBG_LEVEL_ERROR)
  41. return;
  42. #endif
  43. FusionpDbgPrintEx(
  44. FilterLevel,
  45. "SXS: %s() failed Parameters %p{\n"
  46. "SXS: Flags: 0x%lx\n"
  47. "SXS: ProcessorArchitecture: 0x%lx\n"
  48. "SXS: LangId: 0x%lx\n"
  49. "SXS: AssemblyDirectory: %ls\n"
  50. "SXS: TextualIdentity: %ls\n"
  51. "SXS: Manifest: { %p, %ls }\n"
  52. "SXS: Policy: { %p, %ls }\n"
  53. "SXS: }\n",
  54. Function,
  55. Parameters,
  56. (Parameters != NULL) ? ULONG(Parameters->Flags) : 0,
  57. (Parameters != NULL) ? ULONG(Parameters->ProcessorArchitecture) : NULL,
  58. (Parameters != NULL) ? ULONG(Parameters->LangId) : NULL,
  59. (Parameters != NULL) ? Parameters->AssemblyDirectory : NULL,
  60. (Parameters != NULL) ? Parameters->TextualAssemblyIdentity : NULL,
  61. (Parameters != NULL) ? Parameters->Manifest.Stream : NULL,
  62. (Parameters != NULL) ? Parameters->Manifest.Path : NULL,
  63. (Parameters != NULL) ? Parameters->Policy.Stream : NULL,
  64. (Parameters != NULL) ? Parameters->Policy.Path : NULL);
  65. }
  66. extern "C"
  67. BOOL
  68. WINAPI
  69. SxsGenerateActivationContext(
  70. PSXS_GENERATE_ACTIVATION_CONTEXT_PARAMETERS Parameters
  71. )
  72. {
  73. BOOL fSuccess = FALSE;
  74. FN_TRACE_WIN32(fSuccess);
  75. RTL_PATH_TYPE PathType;
  76. BOOL fSxspCloseManifestGraph = FALSE;
  77. CStringBuffer sbAssemblyDirectory;
  78. SMARTPTR(CFileStream) SystemDefaultManifestFileStream;
  79. ACTCTXGENCTX *pActCtxGenCtx = NULL;
  80. CSmallStringBuffer sbManifestFileName; // rarely used, mainly for system compatible assembly
  81. DWORD dwWin32Error;
  82. #define IS_NT_DOS_PATH(_x) (((_x)[0] == L'\\') && ((_x)[1] == L'?') && ((_x)[2] == L'?') && ((_x)[3] == L'\\'))
  83. ::DbgPrintSxsGenerateActivationContextParameters(
  84. FUSION_DBG_LEVEL_ENTEREXIT,
  85. Parameters,
  86. __FUNCTION__);
  87. PARAMETER_CHECK(Parameters != NULL);
  88. IFALLOCFAILED_EXIT(pActCtxGenCtx = new ACTCTXGENCTX);
  89. {
  90. CImpersonationData ImpersonationData(Parameters->ImpersonationCallback, Parameters->ImpersonationContext);
  91. Parameters->SectionObjectHandle = NULL;
  92. IFINVALID_FLAGS_EXIT_WIN32(Parameters->Flags,
  93. SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_SYSTEM_DEFAULT_TEXTUAL_ASSEMBLY_IDENTITY |
  94. SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_TEXTUAL_ASSEMBLY_IDENTITY);
  95. PARAMETER_CHECK(Parameters->AssemblyDirectory != NULL);
  96. HARD_VERIFY(IS_NT_DOS_PATH(Parameters->AssemblyDirectory) == FALSE);
  97. if (Parameters->Flags &
  98. (SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_TEXTUAL_ASSEMBLY_IDENTITY
  99. | SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_SYSTEM_DEFAULT_TEXTUAL_ASSEMBLY_IDENTITY))
  100. {
  101. PARAMETER_CHECK(Parameters->TextualAssemblyIdentity != NULL);
  102. PARAMETER_CHECK(Parameters->Manifest.Stream == NULL);
  103. PARAMETER_CHECK(Parameters->Policy.Stream == NULL);
  104. //
  105. // If basesrv passes in a textual assembly identity, we have to create stream for manifest from here !
  106. //
  107. BOOL fOpenManifestFailed = FALSE;
  108. IFW32FALSE_EXIT(sbAssemblyDirectory.Win32Assign(Parameters->AssemblyDirectory, ::wcslen(Parameters->AssemblyDirectory)));
  109. IFW32FALSE_EXIT(::SxspCreateManifestFileNameFromTextualString(
  110. 0,
  111. SXSP_GENERATE_SXS_PATH_PATHTYPE_MANIFEST,
  112. sbAssemblyDirectory,
  113. Parameters->TextualAssemblyIdentity,
  114. sbManifestFileName));
  115. IFW32FALSE_EXIT(SystemDefaultManifestFileStream.Win32Allocate(__FILE__, __LINE__));
  116. IFW32FALSE_EXIT(SystemDefaultManifestFileStream->OpenForRead(
  117. sbManifestFileName,
  118. CImpersonationData(),FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, // default value for parameters
  119. dwWin32Error,
  120. 4,
  121. ERROR_FILE_NOT_FOUND,
  122. ERROR_PATH_NOT_FOUND,
  123. ERROR_BAD_NETPATH,
  124. ERROR_BAD_NET_NAME));
  125. if (dwWin32Error != ERROR_SUCCESS)
  126. {
  127. Parameters->SystemDefaultActCxtGenerationResult = BASESRV_SXS_RETURN_RESULT_SYSTEM_DEFAULT_NOT_FOUND;
  128. FN_SUCCESSFUL_EXIT();
  129. }
  130. if (Parameters->Manifest.Path == NULL)
  131. Parameters->Manifest.Path = sbManifestFileName;
  132. Parameters->Manifest.Stream = SystemDefaultManifestFileStream;
  133. }
  134. else
  135. {
  136. PARAMETER_CHECK(Parameters->Manifest.Stream != NULL);
  137. }
  138. if (Parameters->Manifest.Path != NULL)
  139. {
  140. HARD_VERIFY(IS_NT_DOS_PATH(Parameters->Manifest.Path) == FALSE);
  141. }
  142. if (Parameters->Policy.Path != NULL)
  143. {
  144. HARD_VERIFY(IS_NT_DOS_PATH(Parameters->Policy.Path) == FALSE);
  145. }
  146. PathType = ::SxspDetermineDosPathNameType(Parameters->AssemblyDirectory);
  147. PARAMETER_CHECK((PathType == RtlPathTypeUncAbsolute) ||
  148. (PathType == RtlPathTypeLocalDevice) ||
  149. (PathType == RtlPathTypeDriveAbsolute) ||
  150. (PathType == RtlPathTypeDriveRelative));
  151. // Ensure that there's a trailing slash...
  152. IFW32FALSE_EXIT(sbAssemblyDirectory.Win32Assign(Parameters->AssemblyDirectory, ::wcslen(Parameters->AssemblyDirectory)));
  153. IFW32FALSE_EXIT(sbAssemblyDirectory.Win32EnsureTrailingPathSeparator());
  154. Parameters->AssemblyDirectory = sbAssemblyDirectory;
  155. // Allocate and initialize the activation context generation context
  156. IFW32FALSE_EXIT(
  157. ::SxspInitActCtxGenCtx(
  158. pActCtxGenCtx, // context out
  159. MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT,
  160. 0, // general flags
  161. 0, // operation-specific flags
  162. ImpersonationData,
  163. Parameters->ProcessorArchitecture,
  164. Parameters->LangId,
  165. ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
  166. ::wcslen(Parameters->AssemblyDirectory),
  167. Parameters->AssemblyDirectory));
  168. if (Parameters->Policy.Stream != NULL)
  169. {
  170. SIZE_T cchPolicyPath = (Parameters->Policy.Path != NULL) ? ::wcslen(Parameters->Policy.Path): 0;
  171. // Do the policy thing...
  172. IFW32FALSE_EXIT(
  173. ::SxspParseApplicationPolicy(
  174. 0,
  175. pActCtxGenCtx,
  176. ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE,
  177. Parameters->Policy.Path,
  178. cchPolicyPath,
  179. Parameters->Policy.Stream));
  180. }
  181. // Add this manifest (and its policy file) to the context
  182. IFW32FALSE_EXIT(
  183. ::SxspAddRootManifestToActCtxGenCtx(
  184. pActCtxGenCtx,
  185. Parameters));
  186. // Add its dependencies, and their dependencies, etc. until there's nothing more to add
  187. IFW32FALSE_EXIT_UNLESS(
  188. ::SxspCloseManifestGraph(pActCtxGenCtx),
  189. ((Parameters->Flags & SXS_GENERATE_ACTIVATION_CONTEXT_FLAG_SYSTEM_DEFAULT_TEXTUAL_ASSEMBLY_IDENTITY) && (::FusionpGetLastWin32Error() == ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED)),
  190. fSxspCloseManifestGraph);
  191. if (fSxspCloseManifestGraph)
  192. {
  193. Parameters->SystemDefaultActCxtGenerationResult |= BASESRV_SXS_RETURN_RESULT_SYSTEM_DEFAULT_DEPENDENCY_ASSEMBLY_NOT_FOUND;
  194. fSuccess = TRUE;
  195. goto Exit;
  196. }
  197. // Build the activation context data blob.
  198. IFW32FALSE_EXIT(::SxspBuildActCtxData(pActCtxGenCtx, &Parameters->SectionObjectHandle));
  199. fSuccess = TRUE;
  200. }
  201. Exit:
  202. #undef IS_NT_DOS_PATH
  203. // for system default stream,
  204. if (Parameters->Manifest.Stream == SystemDefaultManifestFileStream)
  205. Parameters->Manifest.Stream = NULL;
  206. if (pActCtxGenCtx)
  207. FUSION_DELETE_SINGLETON(pActCtxGenCtx);
  208. if (!fSuccess) // put a win32-error-message into eventlog
  209. {
  210. #if !DBG // misindented to reduce fiff
  211. BOOL fAreWeInOSSetupMode = FALSE;
  212. //
  213. // If we can't determine this, then let the first error through.
  214. //
  215. if (!::FusionpAreWeInOSSetupMode(&fAreWeInOSSetupMode) || !fAreWeInOSSetupMode)
  216. #endif
  217. {
  218. CSxsPreserveLastError ple;
  219. ::FusionpLogError(
  220. MSG_SXS_FUNCTION_CALL_FAIL,
  221. CEventLogString(L"Generate Activation Context"),
  222. (Parameters->Manifest.Path != NULL) ? CEventLogString(static_cast<PCWSTR>(Parameters->Manifest.Path)) : CEventLogString(L"Manifest Filename Unknown"),
  223. CEventLogLastError());
  224. #if DBG
  225. ::DbgPrintSxsGenerateActivationContextParameters(
  226. FUSION_DBG_LEVEL_ERROR,
  227. Parameters,
  228. __FUNCTION__);
  229. #endif
  230. ple.Restore();
  231. }
  232. }
  233. return fSuccess;
  234. }