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.

332 lines
12 KiB

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