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.

334 lines
12 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. query.cpp
  5. Abstract:
  6. Information querying functions for sxs.dll
  7. Author:
  8. Michael J. Grier (MGrier) 22-May-2001
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include <windows.h>
  13. #include "sxsp.h"
  14. BOOL
  15. SxspQueryManifestInformationBasic(
  16. IN DWORD dwFlags,
  17. IN PCWSTR pszSource,
  18. IN DWORD dwInfoClassSpecificFlags,
  19. IN SIZE_T cbBuffer,
  20. OUT PVOID lpBuffer,
  21. OUT PSIZE_T cbWrittenOrRequired OPTIONAL
  22. );
  23. BOOL
  24. SxsQueryManifestInformation(
  25. IN DWORD dwFlags,
  26. IN PCWSTR pszSource,
  27. IN ULONG ulInfoClass,
  28. IN DWORD dwInfoClassSpecificFlags,
  29. IN SIZE_T cbBuffer,
  30. OUT PVOID lpBuffer,
  31. OUT PSIZE_T pcbWrittenOrRequired OPTIONAL
  32. )
  33. {
  34. FN_PROLOG_WIN32
  35. if (pcbWrittenOrRequired != NULL)
  36. *pcbWrittenOrRequired = 0;
  37. PARAMETER_CHECK((dwFlags & ~SXS_QUERY_MANIFEST_INFORMATION_FLAG_SOURCE_IS_DLL) == 0);
  38. PARAMETER_CHECK(pszSource != NULL);
  39. PARAMETER_CHECK(ulInfoClass == SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC);
  40. // ignore infoclass specific flags
  41. PARAMETER_CHECK((cbBuffer == 0) || (lpBuffer != NULL)); // can't have a nonzero-sized buffer with a NULL pointer to it
  42. PARAMETER_CHECK((cbBuffer != 0) || (pcbWrittenOrRequired != NULL));
  43. switch (ulInfoClass)
  44. {
  45. default:
  46. INTERNAL_ERROR_CHECK(
  47. (ulInfoClass == SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC)
  48. );
  49. ORIGINATE_WIN32_FAILURE_AND_EXIT(InternalErrorNoCaseForInfoClass, ERROR_INTERNAL_ERROR);
  50. break;
  51. case SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC:
  52. IFW32FALSE_EXIT(
  53. ::SxspQueryManifestInformationBasic(
  54. dwFlags,
  55. pszSource,
  56. dwInfoClassSpecificFlags,
  57. cbBuffer,
  58. lpBuffer,
  59. pcbWrittenOrRequired));
  60. break;
  61. }
  62. FN_EPILOG
  63. }
  64. BOOL
  65. SxspQueryManifestInformationBasic(
  66. IN DWORD dwFlags,
  67. IN PCWSTR pszSource,
  68. IN DWORD dwInfoClassSpecificFlags,
  69. IN SIZE_T cbBuffer,
  70. OUT PVOID lpBuffer,
  71. OUT PSIZE_T pcbWrittenOrRequired OPTIONAL
  72. )
  73. {
  74. FN_PROLOG_WIN32
  75. ACTCTXGENCTX ActCtxGenCtx;
  76. ULONG ManifestFlags;
  77. CImpersonationData ImpersonationData;
  78. PCWSTR Slash = NULL;
  79. CSmartRef<ASSEMBLY> Asm;
  80. CStringBuffer buffManifestPath;
  81. USHORT ProcessorArchitecture = ::SxspGetSystemProcessorArchitecture();
  82. LANGID LangId = ::GetUserDefaultUILanguage();
  83. SIZE_T cch, cchRequired;
  84. SIZE_T cbRequired, cbLeft, cbWritten;
  85. PCASSEMBLY_IDENTITY AssemblyIdentity = NULL;
  86. CStringBuffer buffShortName;
  87. PWSTR Cursor;
  88. PSXS_MANIFEST_INFORMATION_BASIC psmib;
  89. CResourceStream DllStream;
  90. CFileStream FileStream;
  91. IStream* pStream = NULL;
  92. if (pcbWrittenOrRequired != NULL)
  93. *pcbWrittenOrRequired = 0;
  94. PARAMETER_CHECK(dwFlags == 0);
  95. PARAMETER_CHECK(pszSource != NULL);
  96. PARAMETER_CHECK((dwInfoClassSpecificFlags & ~(
  97. SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_IDENTITY |
  98. SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_SHORTNAME)) == 0);
  99. PARAMETER_CHECK((cbBuffer == 0) || (lpBuffer != NULL));
  100. PARAMETER_CHECK((cbBuffer != 0) || (pcbWrittenOrRequired != NULL));
  101. //
  102. // If this is a DLL source, then ensure that the flags are zero (in this rev, that's all that's allowed).
  103. //
  104. if (dwFlags & SXS_QUERY_MANIFEST_INFORMATION_FLAG_SOURCE_IS_DLL)
  105. {
  106. PCSXS_MANIFEST_INFORMATION_SOURCE_DLL pDllSource = (PCSXS_MANIFEST_INFORMATION_SOURCE_DLL)pszSource;
  107. const DWORD dwValidFlags =
  108. SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_LANGUAGE_VALID |
  109. SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_TYPE_VALID |
  110. SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_ID_VALID;
  111. PARAMETER_CHECK((pDllSource->dwFlags & ~dwValidFlags) == 0);
  112. PARAMETER_CHECK(pDllSource->pcwszDllPath != NULL);
  113. PARAMETER_CHECK(((pDllSource->dwFlags & SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_LANGUAGE_VALID) == 0) || (pDllSource->Language != 0));
  114. PARAMETER_CHECK(((pDllSource->dwFlags & SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_TYPE_VALID) == 0) || (pDllSource->pcwszResourceType != NULL));
  115. PARAMETER_CHECK(((pDllSource->dwFlags & SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_ID_VALID) == 0) || (pDllSource->pcwszResourceName != NULL));
  116. }
  117. //
  118. // Smarter than the average bear - knows how to handle string buffers and full
  119. // paths.
  120. //
  121. IFW32FALSE_EXIT(::SxspGetFullPathName(pszSource, buffManifestPath, NULL));
  122. IFW32FALSE_EXIT(
  123. ::SxspInitActCtxGenCtx(
  124. &ActCtxGenCtx, // context out
  125. MANIFEST_OPERATION_VALIDATE_SYNTAX,
  126. 0,
  127. 0,
  128. ImpersonationData,
  129. ProcessorArchitecture,
  130. LangId,
  131. ACTIVATION_CONTEXT_PATH_TYPE_NONE,
  132. 0,
  133. NULL));
  134. IFALLOCFAILED_EXIT(Asm = new ASSEMBLY);
  135. {
  136. CProbedAssemblyInformation AssemblyInformation;
  137. //
  138. // For DLL sources, tease apart the version and whatnot from the
  139. // structure passed in.
  140. //
  141. if (dwFlags & SXS_QUERY_MANIFEST_INFORMATION_FLAG_SOURCE_IS_DLL)
  142. {
  143. PCSXS_MANIFEST_INFORMATION_SOURCE_DLL pcSourceInfo = (PCSXS_MANIFEST_INFORMATION_SOURCE_DLL)pszSource;
  144. IFW32FALSE_EXIT(SxspGetFullPathName(pcSourceInfo->pcwszDllPath, buffManifestPath, NULL));
  145. //
  146. // Default action... just go use the normal "find the first in the dll" thing
  147. //
  148. if (pcSourceInfo->dwFlags == 0)
  149. {
  150. IFW32FALSE_EXIT(DllStream.Initialize(buffManifestPath, (PCWSTR)RT_MANIFEST));
  151. }
  152. else
  153. {
  154. IFW32FALSE_EXIT(
  155. DllStream.Initialize(
  156. buffManifestPath,
  157. ((pcSourceInfo->dwFlags & SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_TYPE_VALID) ? pcSourceInfo->pcwszResourceType : (PCWSTR)RT_MANIFEST),
  158. ((pcSourceInfo->dwFlags & SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_ID_VALID) ? pcSourceInfo->pcwszResourceName : NULL),
  159. ((pcSourceInfo->dwFlags & SXS_QUERY_MANIFEST_INFORMATION_DLL_SOURCE_FLAG_RESOURCE_LANGUAGE_VALID) ? (WORD)pcSourceInfo->Language : (WORD)MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL))));
  160. }
  161. pStream = &DllStream;
  162. }
  163. //
  164. // Otherwise, dumb file.
  165. //
  166. else
  167. {
  168. IFW32FALSE_EXIT(SxspGetFullPathName(pszSource, buffManifestPath, NULL));
  169. IFW32FALSE_EXIT(
  170. FileStream.OpenForRead(
  171. buffManifestPath,
  172. CImpersonationData(),
  173. FILE_SHARE_READ,
  174. OPEN_EXISTING,
  175. FILE_ATTRIBUTE_NORMAL));
  176. pStream = &FileStream;
  177. }
  178. ManifestFlags = ASSEMBLY_MANIFEST_FILETYPE_STREAM;
  179. IFW32FALSE_EXIT(AssemblyInformation.Initialize(&ActCtxGenCtx));
  180. IFW32FALSE_EXIT(AssemblyInformation.SetManifestFlags(ManifestFlags));
  181. IFW32FALSE_EXIT(AssemblyInformation.SetManifestStream(pStream));
  182. IFW32FALSE_EXIT(AssemblyInformation.SetManifestPath(ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE, buffManifestPath));
  183. IFW32FALSE_EXIT(AssemblyInformation.SetManifestLastWriteTime(ImpersonationData));
  184. IFW32FALSE_EXIT(SxspInitAssembly(Asm, AssemblyInformation));
  185. //
  186. // The assembly information now owns the stream
  187. //
  188. pStream->Release();
  189. }
  190. Asm->m_AssemblyRosterIndex = 1; // set it to be the root...
  191. IFW32FALSE_EXIT(::SxspIncorporateAssembly(&ActCtxGenCtx, Asm));
  192. IFW32FALSE_EXIT(::SxspFireActCtxGenEnding(&ActCtxGenCtx));
  193. AssemblyIdentity = Asm->m_ProbedAssemblyInformation.GetAssemblyIdentity();
  194. cchRequired = 0;
  195. if ((dwInfoClassSpecificFlags & SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_IDENTITY) == 0)
  196. {
  197. SIZE_T TextuallyEncodedIdentityBufferBytes = 0;
  198. IFW32FALSE_EXIT(
  199. ::SxsComputeAssemblyIdentityEncodedSize(
  200. 0,
  201. AssemblyIdentity,
  202. NULL,
  203. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  204. &TextuallyEncodedIdentityBufferBytes));
  205. INTERNAL_ERROR_CHECK((TextuallyEncodedIdentityBufferBytes % sizeof(WCHAR)) == 0);
  206. cchRequired += ((TextuallyEncodedIdentityBufferBytes / sizeof(WCHAR)) + 1);
  207. }
  208. if ((dwInfoClassSpecificFlags & SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_SHORTNAME) == 0)
  209. {
  210. IFW32FALSE_EXIT(
  211. ::SxspGenerateSxsPath(
  212. SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT,
  213. SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
  214. NULL, 0,
  215. AssemblyIdentity,
  216. NULL,
  217. buffShortName));
  218. cchRequired += (buffShortName.Cch() + 1);
  219. }
  220. // GENERAL REVIEW: What does this do with alignment on ia64? Shouldn't we pad out to
  221. // the next N bytes?
  222. //
  223. cbRequired = sizeof(SXS_MANIFEST_INFORMATION_BASIC) + (cchRequired * sizeof(WCHAR));
  224. if (cbRequired > cbBuffer)
  225. {
  226. if (pcbWrittenOrRequired != NULL)
  227. *pcbWrittenOrRequired = cbRequired;
  228. ORIGINATE_WIN32_FAILURE_AND_EXIT(BufferTooSmall, ERROR_INSUFFICIENT_BUFFER);
  229. }
  230. psmib = (PSXS_MANIFEST_INFORMATION_BASIC) lpBuffer;
  231. psmib->lpIdentity = NULL;
  232. psmib->lpShortName = NULL;
  233. psmib->ulFileCount = ActCtxGenCtx.m_ulFileCount;
  234. Cursor = (PWSTR) (psmib + 1);
  235. cbLeft = (cbBuffer - sizeof(SXS_MANIFEST_INFORMATION_BASIC));
  236. cbWritten = sizeof(SXS_MANIFEST_INFORMATION_BASIC);
  237. if ((dwInfoClassSpecificFlags & SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_IDENTITY) == 0)
  238. {
  239. SIZE_T cbActual;
  240. IFW32FALSE_EXIT(
  241. ::SxsEncodeAssemblyIdentity(
  242. 0,
  243. AssemblyIdentity,
  244. NULL,
  245. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  246. cbLeft,
  247. Cursor,
  248. &cbActual));
  249. INTERNAL_ERROR_CHECK((cbActual % sizeof(WCHAR)) == 0);
  250. INTERNAL_ERROR_CHECK(cbLeft >= cbActual);
  251. psmib->lpIdentity = Cursor;
  252. cbLeft -= cbActual;
  253. cbWritten += cbActual;
  254. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + cbActual);
  255. INTERNAL_ERROR_CHECK(cbLeft >= sizeof(WCHAR));
  256. *Cursor++ = L'\0';
  257. cbLeft -= sizeof(WCHAR);
  258. cbWritten += sizeof(WCHAR);
  259. }
  260. if ((dwInfoClassSpecificFlags & SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_SHORTNAME) == 0)
  261. {
  262. cch = buffShortName.Cch();
  263. INTERNAL_ERROR_CHECK(cbLeft >= ((cch + 1) * sizeof(WCHAR)));
  264. memcpy(Cursor, static_cast<PCWSTR>(buffShortName), (cch + 1) * sizeof(WCHAR));
  265. psmib->lpShortName = Cursor;
  266. cbLeft -= ((cch + 1) * sizeof(WCHAR));
  267. cbWritten += ((cch + 1) * sizeof(WCHAR));
  268. Cursor += (cch + 1);
  269. }
  270. if (pcbWrittenOrRequired != NULL)
  271. *pcbWrittenOrRequired = cbWritten;
  272. FN_EPILOG
  273. }