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.

341 lines
13 KiB

  1. /*
  2. Copyright (c) Microsoft Corporation
  3. */
  4. #include "stdinc.h"
  5. #include "sxsp.h"
  6. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name);
  7. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(versioned);
  8. typedef struct _WINDOW_CLASS_CONTEXT
  9. {
  10. _WINDOW_CLASS_CONTEXT() { }
  11. CSmallStringBuffer m_FileNameBuffer;
  12. bool m_Versioned;
  13. private:
  14. _WINDOW_CLASS_CONTEXT(const _WINDOW_CLASS_CONTEXT &);
  15. void operator =(const _WINDOW_CLASS_CONTEXT &);
  16. } WINDOW_CLASS_CONTEXT, *PWINDOW_CLASS_CONTEXT;
  17. typedef struct _WINDOW_CLASS_ENTRY
  18. {
  19. _WINDOW_CLASS_ENTRY() { }
  20. CSmallStringBuffer m_FileNameBuffer;
  21. CSmallStringBuffer m_VersionSpecificWindowClassNameBuffer;
  22. private:
  23. _WINDOW_CLASS_ENTRY(const _WINDOW_CLASS_ENTRY &);
  24. void operator =(const _WINDOW_CLASS_ENTRY &);
  25. } WINDOW_CLASS_ENTRY, *PWINDOW_CLASS_ENTRY;
  26. VOID
  27. __fastcall
  28. SxspWindowClassRedirectionContributorCallback(
  29. PACTCTXCTB_CALLBACK_DATA Data
  30. )
  31. {
  32. FN_TRACE();
  33. PSTRING_SECTION_GENERATION_CONTEXT SSGenContext = (PSTRING_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
  34. PWINDOW_CLASS_CONTEXT WindowClassContext = NULL;
  35. PWINDOW_CLASS_ENTRY Entry = NULL; // deleted on exit if not NULL
  36. if (SSGenContext != NULL)
  37. WindowClassContext = (PWINDOW_CLASS_CONTEXT) ::SxsGetStringSectionGenerationContextCallbackContext(SSGenContext);
  38. switch (Data->Header.Reason)
  39. {
  40. case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
  41. {
  42. Data->GenBeginning.Success = FALSE;
  43. INTERNAL_ERROR_CHECK(WindowClassContext == NULL);
  44. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  45. {
  46. // NTRAID#NTBUG9 - 590977 - 2002/03/30 - mgrier - use smart pointer class here
  47. IFALLOCFAILED_EXIT(WindowClassContext = new WINDOW_CLASS_CONTEXT);
  48. if (!::SxsInitStringSectionGenerationContext(
  49. &SSGenContext,
  50. ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION_FORMAT_WHISTLER,
  51. TRUE,
  52. &::SxspWindowClassRedirectionStringSectionGenerationCallback,
  53. WindowClassContext))
  54. {
  55. FUSION_DELETE_SINGLETON(WindowClassContext);
  56. WindowClassContext = NULL;
  57. goto Exit;
  58. }
  59. Data->Header.ActCtxGenContext = SSGenContext;
  60. }
  61. Data->GenBeginning.Success = TRUE;
  62. break;
  63. }
  64. case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
  65. if (SSGenContext != NULL)
  66. {
  67. ::SxsDestroyStringSectionGenerationContext(SSGenContext);
  68. SSGenContext = NULL;
  69. }
  70. FUSION_DELETE_SINGLETON(WindowClassContext);
  71. WindowClassContext = NULL;
  72. break;
  73. case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
  74. {
  75. Data->AllParsingDone.Success = FALSE;
  76. if (SSGenContext != NULL)
  77. IFW32FALSE_EXIT(::SxsDoneModifyingStringSectionGenerationContext(SSGenContext));
  78. Data->AllParsingDone.Success = TRUE;
  79. break;
  80. }
  81. case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
  82. {
  83. Data->GetSectionSize.Success = FALSE;
  84. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  85. IFW32FALSE_EXIT(::SxsGetStringSectionGenerationContextSectionSize(SSGenContext, &Data->GetSectionSize.SectionSize));
  86. Data->GetSectionSize.Success = TRUE;
  87. break;
  88. }
  89. case ACTCTXCTB_CBREASON_PCDATAPARSED:
  90. {
  91. Data->PCDATAParsed.Success = FALSE;
  92. if ((Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT) &&
  93. (Data->PCDATAParsed.ParseContext->XMLElementDepth == 3) &&
  94. (::FusionpCompareStrings(
  95. Data->PCDATAParsed.ParseContext->ElementPath,
  96. Data->PCDATAParsed.ParseContext->ElementPathCch,
  97. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass",
  98. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass") - 1,
  99. false) == 0))
  100. {
  101. SIZE_T VersionCch;
  102. PCWSTR pwszVersion = NULL;
  103. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  104. INTERNAL_ERROR_CHECK(WindowClassContext != NULL);
  105. // NTRAID#NTBUG9 - 590977 - 2002/03/30 - mgrier - use smart pointer class here
  106. IFALLOCFAILED_EXIT(Entry = new WINDOW_CLASS_ENTRY);
  107. IFW32FALSE_EXIT(Entry->m_FileNameBuffer.Win32Assign(WindowClassContext->m_FileNameBuffer));
  108. IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(0, Data->ElementParsed.AssemblyContext->AssemblyIdentity, &s_IdentityAttribute_version, &pwszVersion, &VersionCch));
  109. if (WindowClassContext->m_Versioned)
  110. {
  111. IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32Assign(pwszVersion, VersionCch));
  112. IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32Append(L"!", 1));
  113. }
  114. IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32Append(Data->PCDATAParsed.Text, Data->PCDATAParsed.TextCch));
  115. IFW32FALSE_EXIT(
  116. ::SxsAddStringToStringSectionGenerationContext(
  117. (PSTRING_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext,
  118. Data->PCDATAParsed.Text,
  119. Data->PCDATAParsed.TextCch,
  120. Entry,
  121. Data->PCDATAParsed.AssemblyContext->AssemblyRosterIndex,
  122. ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME));
  123. // Prevent deletion in exit path...
  124. Entry = NULL;
  125. }
  126. // Everything's groovy!
  127. Data->PCDATAParsed.Success = TRUE;
  128. break;
  129. }
  130. case ACTCTXCTB_CBREASON_ELEMENTPARSED:
  131. {
  132. Data->ElementParsed.Success = FALSE;
  133. if ((Data->ElementParsed.ParseContext->XMLElementDepth == 2) &&
  134. (::FusionpCompareStrings(
  135. Data->ElementParsed.ParseContext->ElementPath,
  136. Data->ElementParsed.ParseContext->ElementPathCch,
  137. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file",
  138. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file") - 1,
  139. false) == 0))
  140. {
  141. CStringBuffer FileNameBuffer;
  142. bool fFound = false;
  143. SIZE_T cb;
  144. // capture the name of the file we're parsing...
  145. IFW32FALSE_EXIT(
  146. ::SxspGetAttributeValue(
  147. 0,
  148. &s_AttributeName_name,
  149. &Data->ElementParsed,
  150. fFound,
  151. sizeof(FileNameBuffer),
  152. &FileNameBuffer,
  153. cb,
  154. NULL,
  155. 0));
  156. // If there's no NAME attribute, someone else will puke; we'll handle it
  157. // gracefully.
  158. if (fFound)
  159. {
  160. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  161. {
  162. INTERNAL_ERROR_CHECK(WindowClassContext != NULL);
  163. IFW32FALSE_EXIT(WindowClassContext->m_FileNameBuffer.Win32Assign(FileNameBuffer));
  164. }
  165. }
  166. }
  167. else if ((Data->ElementParsed.ParseContext->XMLElementDepth == 3) &&
  168. (::FusionpCompareStrings(
  169. Data->ElementParsed.ParseContext->ElementPath,
  170. Data->ElementParsed.ParseContext->ElementPathCch,
  171. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass",
  172. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^windowClass") - 1,
  173. false) == 0))
  174. {
  175. bool fVersioned = true;
  176. bool fFound = false;
  177. SIZE_T cbBytesWritten;
  178. IFW32FALSE_EXIT(
  179. ::SxspGetAttributeValue(
  180. 0,
  181. &s_AttributeName_versioned,
  182. &Data->ElementParsed,
  183. fFound,
  184. sizeof(fVersioned),
  185. &fVersioned,
  186. cbBytesWritten,
  187. &::SxspValidateBoolAttribute,
  188. 0));
  189. if (!fFound)
  190. fVersioned = true;
  191. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  192. {
  193. INTERNAL_ERROR_CHECK(WindowClassContext != NULL);
  194. WindowClassContext->m_Versioned = fVersioned;
  195. }
  196. }
  197. // Everything's groovy!
  198. Data->ElementParsed.Success = TRUE;
  199. break;
  200. }
  201. case ACTCTXCTB_CBREASON_GETSECTIONDATA:
  202. Data->GetSectionData.Success = FALSE;
  203. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  204. IFW32FALSE_EXIT(
  205. ::SxsGetStringSectionGenerationContextSectionData(
  206. SSGenContext,
  207. Data->GetSectionData.SectionSize,
  208. Data->GetSectionData.SectionDataStart,
  209. NULL));
  210. Data->GetSectionData.Success = TRUE;
  211. break;
  212. }
  213. Exit:
  214. ;
  215. }
  216. BOOL
  217. SxspWindowClassRedirectionStringSectionGenerationCallback(
  218. PVOID Context,
  219. ULONG Reason,
  220. PVOID CallbackData
  221. )
  222. {
  223. BOOL fSuccess = FALSE;
  224. FN_TRACE_WIN32(fSuccess);
  225. switch (Reason)
  226. {
  227. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
  228. {
  229. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData =
  230. (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData;
  231. PWINDOW_CLASS_ENTRY Entry = (PWINDOW_CLASS_ENTRY) CBData->DataContext;
  232. FUSION_DELETE_SINGLETON(Entry);
  233. break;
  234. }
  235. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
  236. {
  237. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData =
  238. (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
  239. PWINDOW_CLASS_ENTRY Entry = (PWINDOW_CLASS_ENTRY) CBData->DataContext;
  240. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION);
  241. CBData->DataSize += ((Entry->m_FileNameBuffer.Cch() + 1 +
  242. Entry->m_VersionSpecificWindowClassNameBuffer.Cch() + 1) * sizeof(WCHAR));
  243. break;
  244. }
  245. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
  246. {
  247. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData =
  248. (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
  249. PWINDOW_CLASS_ENTRY Entry = (PWINDOW_CLASS_ENTRY) CBData->DataContext;
  250. PACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION Info;
  251. SIZE_T BytesLeft = CBData->BufferSize;
  252. SIZE_T BytesWritten = 0;
  253. PWSTR Cursor;
  254. Info = (PACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION) CBData->Buffer;
  255. Cursor = (PWSTR) (Info + 1);
  256. if (BytesLeft < sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION))
  257. {
  258. ::FusionpSetLastWin32Error(ERROR_INSUFFICIENT_BUFFER);
  259. goto Exit;
  260. }
  261. BytesWritten += sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION);
  262. BytesLeft -= sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION);
  263. Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION);
  264. Info->Flags = 0;
  265. IFW32FALSE_EXIT(Entry->m_VersionSpecificWindowClassNameBuffer.Win32CopyIntoBuffer(
  266. &Cursor,
  267. &BytesLeft,
  268. &BytesWritten,
  269. Info,
  270. &Info->VersionSpecificClassNameOffset,
  271. &Info->VersionSpecificClassNameLength));
  272. IFW32FALSE_EXIT(Entry->m_FileNameBuffer.Win32CopyIntoBuffer(
  273. &Cursor,
  274. &BytesLeft,
  275. &BytesWritten,
  276. CBData->SectionHeader,
  277. &Info->DllNameOffset,
  278. &Info->DllNameLength));
  279. CBData->BytesWritten = BytesWritten;
  280. }
  281. }
  282. fSuccess = TRUE;
  283. Exit:
  284. return fSuccess;
  285. }