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.

2314 lines
77 KiB

  1. /*
  2. Copyright (c) Microsoft Corporation
  3. */
  4. #include "stdinc.h"
  5. #include <windows.h>
  6. #include "sxsp.h"
  7. #include <stdio.h>
  8. #include "fusionhandle.h"
  9. #include "sxsapi.h"
  10. #include <limits.h>
  11. typedef const void * PCVOID;
  12. VOID
  13. SxspDbgPrintInstallSourceInfo(
  14. ULONG Level,
  15. PSXS_INSTALL_SOURCE_INFO Info,
  16. CBaseStringBuffer &rbuffPLP
  17. );
  18. VOID
  19. SxspDbgPrintActivationContextDataTocEntry(
  20. ULONG Level,
  21. bool fFull,
  22. PCACTIVATION_CONTEXT_DATA Base,
  23. PCACTIVATION_CONTEXT_DATA_TOC_ENTRY Entry,
  24. CBaseStringBuffer &rbuffPLP
  25. );
  26. VOID
  27. SxspDbgPrintActivationContextDataTocSections(
  28. ULONG Level,
  29. bool fFull,
  30. PCACTIVATION_CONTEXT_DATA Base,
  31. PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data,
  32. const GUID *ExtensionGuid,
  33. CBaseStringBuffer &rbuffPLP
  34. );
  35. VOID
  36. SxspDbgPrintActivationContextDataTocSection(
  37. ULONG Level,
  38. bool fFull,
  39. PVOID Section,
  40. SIZE_T Length,
  41. const GUID *ExtensionGuid,
  42. ULONG SectionId,
  43. PCSTR SectionName,
  44. CBaseStringBuffer &rbuffPLP
  45. );
  46. VOID
  47. SxspDbgPrintActivationContextDataExtendedTocHeader(
  48. ULONG Level,
  49. bool fFull,
  50. PCACTIVATION_CONTEXT_DATA Base,
  51. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data,
  52. CBaseStringBuffer &rbuffPLP
  53. );
  54. VOID
  55. SxspDbgPrintActivationContextDataExtendedTocEntry(
  56. ULONG Level,
  57. bool fFull,
  58. PCACTIVATION_CONTEXT_DATA Base,
  59. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry,
  60. CBaseStringBuffer &rbuffPLP
  61. );
  62. VOID
  63. SxspDbgPrintActivationContextDataExtendedTocSections(
  64. ULONG Level,
  65. bool fFull,
  66. PCACTIVATION_CONTEXT_DATA Base,
  67. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data,
  68. CBaseStringBuffer &rbuffPLP
  69. );
  70. VOID
  71. SxspDbgPrintActivationContextDataExtendedTocEntrySections(
  72. ULONG Level,
  73. bool fFull,
  74. PCACTIVATION_CONTEXT_DATA Base,
  75. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Data,
  76. CBaseStringBuffer &rbuffPLP
  77. );
  78. VOID
  79. SxspDbgPrintActivationContextStringSection(
  80. ULONG Level,
  81. bool fFull,
  82. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Data,
  83. const GUID *ExtensionGuid,
  84. ULONG SectionId,
  85. PCSTR SectionName,
  86. CBaseStringBuffer &rbuffPLP
  87. );
  88. VOID
  89. SxspDbgPrintActivationContextGuidSection(
  90. ULONG Level,
  91. bool fFull,
  92. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Data,
  93. const GUID *ExtensionGuid,
  94. ULONG SectionId,
  95. PCSTR SectionName,
  96. CBaseStringBuffer &rbuffPLP
  97. );
  98. VOID
  99. SxspDbgPrintActivationContextBinarySection(
  100. ULONG Level,
  101. bool fFull,
  102. PVOID Data,
  103. SIZE_T Length,
  104. CBaseStringBuffer &rbuffPLP
  105. );
  106. VOID
  107. SxspDbgPrintAssemblyInformation(
  108. ULONG Level,
  109. bool fFull,
  110. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  111. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION Entry,
  112. SIZE_T Length,
  113. CBaseStringBuffer &rbuffPLP,
  114. CBaseStringBuffer &rbuffBriefOutput
  115. );
  116. VOID
  117. SxspDbgPrintDllRedirection(
  118. ULONG Level,
  119. bool fFull,
  120. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  121. PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION Entry,
  122. SIZE_T Length,
  123. CBaseStringBuffer &rbuffPLP,
  124. CBaseStringBuffer &rbuffBriefOutput
  125. );
  126. VOID
  127. SxspDbgPrintWindowClassRedirection(
  128. ULONG Level,
  129. bool fFull,
  130. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  131. PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION Entry,
  132. SIZE_T Length,
  133. CBaseStringBuffer &rbuffPLP,
  134. CBaseStringBuffer &rbuffBriefOutput
  135. );
  136. VOID
  137. SxspDbgPrintCLRSurrogateTable(
  138. ULONG Level,
  139. bool fFull,
  140. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  141. PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE Entry,
  142. SIZE_T Length,
  143. CBaseStringBuffer &rbuffPLP,
  144. CBaseStringBuffer &rbuffBriefOutput
  145. );
  146. VOID
  147. SxspDbgPrintComServerRedirection(
  148. ULONG Level,
  149. bool fFull,
  150. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  151. PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Entry,
  152. SIZE_T Length,
  153. CBaseStringBuffer &rbuffPLP,
  154. CBaseStringBuffer &rbuffBriefOutput
  155. );
  156. VOID
  157. SxspDbgPrintComProgIdRedirection(
  158. ULONG Level,
  159. bool fFull,
  160. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  161. PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION Entry,
  162. SIZE_T Length,
  163. CBaseStringBuffer &rbuffPLP,
  164. CBaseStringBuffer &rbuffBriefOutput
  165. );
  166. VOID
  167. SxspDbgPrintTypeLibraryRedirection(
  168. ULONG Level,
  169. bool fFull,
  170. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  171. PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION Entry,
  172. SIZE_T Length,
  173. CBaseStringBuffer &rbuffPLP,
  174. CBaseStringBuffer &rbuffBriefOutput
  175. );
  176. VOID
  177. SxspDbgPrintComInterfaceRedirection(
  178. ULONG Level,
  179. bool fFull,
  180. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  181. PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Entry,
  182. SIZE_T Length,
  183. CBaseStringBuffer &rbuffPLP,
  184. CBaseStringBuffer &rbuffBriefOutput
  185. );
  186. VOID
  187. SxspDbgPrintActivationContextDataAssemblyRoster(
  188. ULONG Level,
  189. bool fFull,
  190. PCACTIVATION_CONTEXT_DATA Base,
  191. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER Data,
  192. CBaseStringBuffer &rbuffPLP
  193. );
  194. VOID
  195. SxspDbgPrintActivationContextDataTocHeader(
  196. ULONG Level,
  197. bool fFull,
  198. PCACTIVATION_CONTEXT_DATA Base,
  199. PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data,
  200. CBaseStringBuffer &rbuffPLP
  201. );
  202. VOID
  203. SxsppDbgPrintActivationContextData(
  204. ULONG Level,
  205. bool fFull,
  206. PCACTIVATION_CONTEXT_DATA Data,
  207. CBaseStringBuffer &rbuffPLP
  208. )
  209. {
  210. PCWSTR PLP = rbuffPLP;
  211. //
  212. // ISSUE: jonwis 3/7/2002
  213. // - Parameter checking of Data is noticably absent.
  214. // - Lots of unchecked pointer math here. Not so bad, since this will only
  215. // crash user-mode code, and will only allow reads of this process'
  216. // memory space, but it's correctness. Mitgated by this being debugging-
  217. // related code only.
  218. //
  219. if (fFull)
  220. {
  221. ::FusionpDbgPrintEx(
  222. Level,
  223. "%SActivation Context Data %p\n"
  224. "%S Magic = 0x%08lx (%lu)\n"
  225. "%S HeaderSize = %d (0x%lx)\n"
  226. "%S FormatVersion = %d\n",
  227. PLP, Data,
  228. PLP, Data->Magic, Data->Magic,
  229. PLP, Data->HeaderSize, Data->HeaderSize,
  230. PLP, Data->FormatVersion);
  231. ::FusionpDbgPrintEx(
  232. Level,
  233. "%S TotalSize = %d (0x%lx)\n"
  234. "%S DefaultTocOffset = %d (0x%lx) (-> %p)\n"
  235. "%S ExtendedTocOffset = %d (0x%lx) (-> %p)\n",
  236. PLP, Data->TotalSize, Data->TotalSize,
  237. PLP, Data->DefaultTocOffset, Data->DefaultTocOffset, (Data->DefaultTocOffset == 0) ? NULL : (PVOID) (((ULONG_PTR) Data) + Data->DefaultTocOffset),
  238. PLP, Data->ExtendedTocOffset, Data->ExtendedTocOffset, (Data->ExtendedTocOffset == 0) ? NULL : (PVOID) (((ULONG_PTR) Data) + Data->ExtendedTocOffset));
  239. ::FusionpDbgPrintEx(
  240. Level,
  241. "%S AssemblyRosterOffset = %d (0x%lx) (-> %p)\n",
  242. PLP, Data->AssemblyRosterOffset, Data->AssemblyRosterOffset, (Data->AssemblyRosterOffset == 0) ? NULL : (PVOID) (((ULONG_PTR) Data) + Data->AssemblyRosterOffset));
  243. }
  244. else
  245. {
  246. // !fFull
  247. ::FusionpDbgPrintEx(
  248. Level,
  249. "%SActivation Context Data %p (brief output)\n",
  250. PLP, Data);
  251. }
  252. //
  253. // ISSUE: jonwis 3/7/2002
  254. // - Bad bad BAD form. Use .Win32AppendFill(L' ', 3) instead.
  255. //
  256. rbuffPLP.Win32Append(L" ", 3);
  257. if (Data->AssemblyRosterOffset != 0)
  258. ::SxspDbgPrintActivationContextDataAssemblyRoster(
  259. Level,
  260. fFull,
  261. Data,
  262. (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER) (((ULONG_PTR) Data) + Data->AssemblyRosterOffset),
  263. rbuffPLP);
  264. if (Data->DefaultTocOffset != 0)
  265. ::SxspDbgPrintActivationContextDataTocHeader(
  266. Level,
  267. fFull,
  268. Data,
  269. (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Data) + Data->DefaultTocOffset),
  270. rbuffPLP);
  271. if (Data->ExtendedTocOffset != 0)
  272. ::SxspDbgPrintActivationContextDataExtendedTocHeader(
  273. Level,
  274. fFull,
  275. Data,
  276. (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER) (((ULONG_PTR) Data) + Data->ExtendedTocOffset),
  277. rbuffPLP);
  278. // That's it for the header information. Now start dumping the sections...
  279. if (Data->DefaultTocOffset != 0)
  280. ::SxspDbgPrintActivationContextDataTocSections(
  281. Level,
  282. fFull,
  283. Data,
  284. (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Data) + Data->DefaultTocOffset),
  285. NULL,
  286. rbuffPLP);
  287. if (Data->ExtendedTocOffset != 0)
  288. ::SxspDbgPrintActivationContextDataExtendedTocSections(
  289. Level,
  290. fFull,
  291. Data,
  292. (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER) (((ULONG_PTR) Data) + Data->ExtendedTocOffset),
  293. rbuffPLP);
  294. }
  295. VOID
  296. SxspDbgPrintActivationContextData(
  297. ULONG Level,
  298. PCACTIVATION_CONTEXT_DATA Data,
  299. CBaseStringBuffer &rbuffPLP
  300. )
  301. {
  302. if (::FusionpDbgWouldPrintAtFilterLevel(Level))
  303. {
  304. ::SxsppDbgPrintActivationContextData(Level, ::FusionpDbgWouldPrintAtFilterLevel(FUSION_DBG_LEVEL_FULLACTCTX), Data, rbuffPLP);
  305. }
  306. }
  307. VOID
  308. SxspDbgPrintActivationContextDataAssemblyRoster(
  309. ULONG Level,
  310. bool fFull,
  311. PCACTIVATION_CONTEXT_DATA Base,
  312. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER Data,
  313. CBaseStringBuffer &rbuffPLP
  314. )
  315. {
  316. ULONG i;
  317. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY Entry;
  318. CSmallStringBuffer buffFlags;
  319. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION AssemblyInformation = NULL;
  320. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgAssemblyRosterEntryFlags[] =
  321. {
  322. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_INVALID, "Invalid")
  323. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_ROOT, "Root")
  324. };
  325. PCWSTR PLP = rbuffPLP;
  326. if (fFull)
  327. ::FusionpDbgPrintEx(
  328. Level,
  329. "%SACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER %p\n"
  330. "%S HeaderSize = %lu (0x%lx)\n"
  331. "%S EntryCount = %lu (0x%lx)\n"
  332. "%S FirstEntryOffset = %ld (0x%lx)\n",
  333. PLP, Data,
  334. PLP, Data->HeaderSize, Data->HeaderSize,
  335. PLP, Data->EntryCount, Data->EntryCount,
  336. PLP, Data->FirstEntryOffset, Data->FirstEntryOffset);
  337. else
  338. ::FusionpDbgPrintEx(
  339. Level,
  340. "%SAssembly Roster (%lu assemblies)\n"
  341. "%SIndex | Assembly Name (Flags)\n",
  342. PLP, Data->EntryCount - 1,
  343. PLP);
  344. for (i=0; i<Data->EntryCount; i++)
  345. {
  346. Entry = ((PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset)) + i;
  347. UNICODE_STRING s;
  348. if (Entry->AssemblyNameOffset != 0)
  349. {
  350. s.Length = (USHORT) Entry->AssemblyNameLength;
  351. s.MaximumLength = s.Length;
  352. s.Buffer = (PWSTR) (((ULONG_PTR) Base) + Entry->AssemblyNameOffset);
  353. }
  354. else
  355. {
  356. s.Length = 0;
  357. s.MaximumLength = 0;
  358. s.Buffer = NULL;
  359. }
  360. ::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgAssemblyRosterEntryFlags), s_rgAssemblyRosterEntryFlags, buffFlags);
  361. if (Entry->AssemblyInformationOffset != NULL)
  362. AssemblyInformation = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION) (((ULONG_PTR) Base) + Entry->AssemblyInformationOffset);
  363. else
  364. AssemblyInformation = NULL;
  365. if (fFull)
  366. {
  367. ::FusionpDbgPrintEx(
  368. Level,
  369. "%S ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY %p [#%d]\n"
  370. "%S Flags = 0x%08lx (%S)\n"
  371. "%S PseudoKey = %lu\n",
  372. PLP, Entry, i,
  373. PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags),
  374. PLP, Entry->PseudoKey);
  375. ::FusionpDbgPrintEx(
  376. Level,
  377. "%S AssemblyNameOffset = %lu (0x%lx) \"%wZ\"\n"
  378. "%S AssemblyNameLength = %lu (0x%lx) \n"
  379. "%S AssemblyInformationOffset = %lu (0x%lx) (-> %p)\n"
  380. "%S AssemblyInformationLength = %lu (0x%lx)\n",
  381. PLP, Entry->AssemblyNameOffset, Entry->AssemblyNameOffset, &s,
  382. PLP, Entry->AssemblyNameLength, Entry->AssemblyNameLength,
  383. PLP, Entry->AssemblyInformationOffset, Entry->AssemblyInformationOffset, AssemblyInformation,
  384. PLP, Entry->AssemblyInformationLength, Entry->AssemblyInformationLength);
  385. }
  386. else
  387. {
  388. if (i != 0)
  389. ::FusionpDbgPrintEx(
  390. Level,
  391. "%S%5lu | %wZ (%S)\n",
  392. PLP, i, &s, static_cast<PCWSTR>(buffFlags));
  393. }
  394. }
  395. }
  396. VOID
  397. SxspDbgPrintActivationContextDataTocHeader(
  398. ULONG Level,
  399. bool fFull,
  400. PCACTIVATION_CONTEXT_DATA Base,
  401. PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data,
  402. CBaseStringBuffer &rbuffPLP
  403. )
  404. {
  405. PCWSTR PLP = rbuffPLP;
  406. CSmallStringBuffer buffFlags;
  407. ULONG i;
  408. PCACTIVATION_CONTEXT_DATA_TOC_ENTRY FirstEntry = NULL;
  409. if (PLP == NULL)
  410. PLP = L"";
  411. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgFlags[] =
  412. {
  413. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_TOC_HEADER_DENSE, "Dense")
  414. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_TOC_HEADER_INORDER, "Inorder")
  415. };
  416. ::FusionpFormatFlags(Data->Flags, fFull, NUMBER_OF(s_rgFlags), s_rgFlags, buffFlags);
  417. if (Data->FirstEntryOffset != 0)
  418. FirstEntry = (PCACTIVATION_CONTEXT_DATA_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset);
  419. if (fFull)
  420. {
  421. ::FusionpDbgPrintEx(
  422. Level,
  423. "%SACTIVATION_CONTEXT_DATA_TOC_HEADER %p\n"
  424. "%S HeaderSize = %d (0x%lx)\n"
  425. "%S EntryCount = %d\n"
  426. "%S FirstEntryOffset = %d (0x%lx) (-> %p)\n"
  427. "%S Flags = 0x%08lx (%S)\n",
  428. PLP, Data,
  429. PLP, Data->HeaderSize, Data->HeaderSize,
  430. PLP, Data->EntryCount,
  431. PLP, Data->FirstEntryOffset, Data->FirstEntryOffset, FirstEntry,
  432. PLP, Data->Flags, static_cast<PCWSTR>(buffFlags));
  433. }
  434. if (FirstEntry != NULL)
  435. {
  436. SIZE_T cchSave = rbuffPLP.Cch();
  437. rbuffPLP.Win32Append(L" ", 3);
  438. for (i=0; i<Data->EntryCount; i++)
  439. ::SxspDbgPrintActivationContextDataTocEntry(Level, fFull, Base, &FirstEntry[i], rbuffPLP);
  440. rbuffPLP.Left(cchSave);
  441. }
  442. }
  443. VOID
  444. SxspDbgPrintActivationContextDataTocSections(
  445. ULONG Level,
  446. bool fFull,
  447. PCACTIVATION_CONTEXT_DATA Base,
  448. PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data,
  449. const GUID *ExtensionGuid,
  450. CBaseStringBuffer &rbuffPLP
  451. )
  452. {
  453. PCWSTR PLP = rbuffPLP;
  454. SIZE_T cchPLP = rbuffPLP.Cch();
  455. if (Data->FirstEntryOffset != 0)
  456. {
  457. PCACTIVATION_CONTEXT_DATA_TOC_ENTRY Entries = (PCACTIVATION_CONTEXT_DATA_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset);
  458. ULONG i;
  459. for (i=0; i<Data->EntryCount; i++)
  460. {
  461. if (Entries[i].Offset != 0)
  462. {
  463. //
  464. // ISSUE: jonwis 3/7/2002
  465. // - Why build up the buffSectionId string if we never output it?
  466. //
  467. PVOID Section = (PVOID) (((ULONG_PTR) Base) + Entries[i].Offset);
  468. CSmallStringBuffer buffSectionId;
  469. PCSTR pszSectionName = "<untranslatable>";
  470. if (ExtensionGuid != NULL)
  471. {
  472. //
  473. // ISSUE: jonwis 3/7/2002
  474. // - Stack-based strings are evil. Use .Win32ResizeBuffer along with
  475. // .Win32FormatAppend to get rid of this:
  476. //
  477. // buffSectionId.Win32ResizeBuffer(buffSectionId.Cch() + 1 + (sizeof(LONG)*CHAR_BIT));
  478. // buffSectionId.Win32FormatAppend(L".%u", Entries[i].Id);
  479. //
  480. WCHAR rgchBuff[sizeof(LONG)*CHAR_BIT];
  481. ::SxspFormatGUID(*ExtensionGuid, buffSectionId);
  482. buffSectionId.Win32Append(L".", 1);
  483. swprintf(rgchBuff, L"%u", Entries[i].Id);
  484. buffSectionId.Win32Append(rgchBuff, ::wcslen(rgchBuff));
  485. }
  486. else
  487. {
  488. WCHAR rgchBuff[255];
  489. #define MAP_ENTRY(_x, _y) case _x: if (fFull) pszSectionName = #_x; else pszSectionName = _y; break;
  490. switch (Entries[i].Id)
  491. {
  492. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "Assembly Information")
  493. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "DLL Redirection")
  494. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "Window Class Redirection")
  495. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, "COM Server Redirection")
  496. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, "COM Interface Redirection")
  497. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, "COM Type Library Redirection")
  498. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, "COM ProgId Redirection")
  499. MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE, "Win32 Global Object Name Redirection")
  500. }
  501. //
  502. // ISSUE: jonwis 3/7/2002
  503. // - See above. Use .Win32ResizeBuffer and .Win32FormatAppend
  504. //
  505. if (pszSectionName != NULL)
  506. swprintf(rgchBuff, L"%u (%S)", Entries[i].Id, pszSectionName);
  507. else
  508. swprintf(rgchBuff, L"%u", Entries[i].Id);
  509. buffSectionId.Win32Append(rgchBuff, ::wcslen(rgchBuff));
  510. }
  511. ::SxspDbgPrintActivationContextDataTocSection(
  512. Level,
  513. fFull,
  514. Section,
  515. Entries[i].Length,
  516. ExtensionGuid,
  517. Entries[i].Id,
  518. pszSectionName,
  519. rbuffPLP);
  520. }
  521. }
  522. }
  523. }
  524. VOID
  525. SxspDbgPrintActivationContextDataTocSection(
  526. ULONG Level,
  527. bool fFull,
  528. PVOID Section,
  529. SIZE_T Length,
  530. const GUID *ExtensionGuid,
  531. ULONG SectionId,
  532. PCSTR SectionName,
  533. CBaseStringBuffer &rbuffPLP
  534. )
  535. {
  536. if (Length > sizeof(ULONG))
  537. {
  538. switch (*(ULONG *) Section)
  539. {
  540. case ACTIVATION_CONTEXT_STRING_SECTION_MAGIC:
  541. ::SxspDbgPrintActivationContextStringSection(
  542. Level,
  543. fFull,
  544. (PCACTIVATION_CONTEXT_STRING_SECTION_HEADER) Section,
  545. ExtensionGuid,
  546. SectionId,
  547. SectionName,
  548. rbuffPLP);
  549. break;
  550. case ACTIVATION_CONTEXT_GUID_SECTION_MAGIC:
  551. ::SxspDbgPrintActivationContextGuidSection(
  552. Level,
  553. fFull,
  554. (PCACTIVATION_CONTEXT_GUID_SECTION_HEADER) Section,
  555. ExtensionGuid,
  556. SectionId,
  557. SectionName,
  558. rbuffPLP);
  559. break;
  560. default:
  561. break;
  562. }
  563. }
  564. else if ( SectionId != 0 )
  565. {
  566. ::SxspDbgPrintActivationContextBinarySection(
  567. Level,
  568. fFull,
  569. Section,
  570. Length,
  571. rbuffPLP);
  572. }
  573. }
  574. const STRING *
  575. SxspDbgSectionIdToNtString(
  576. ULONG Id
  577. )
  578. {
  579. switch (Id)
  580. {
  581. #define ENTRY(id, s) id : { const static STRING t = RTL_CONSTANT_STRING(s); return &t; }
  582. ENTRY(default, "<No name associated with id>");
  583. ENTRY(case ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "Assembly Information");
  584. ENTRY(case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "Dll Redirection");
  585. ENTRY(case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "Window Class Redirection");
  586. ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, "COM Server Redirection");
  587. ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, "COM Interface Redirection");
  588. ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, "COM Type Library Redirection");
  589. ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, "COM ProgId Redirection");
  590. ENTRY(case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE, "Win32 Global Object Name Redirection");
  591. ENTRY(case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES, "CLR Surrogate Type Table");
  592. #undef ENTRY
  593. }
  594. }
  595. PCSTR
  596. SxspDbgSectionIdToString(
  597. ULONG Id
  598. )
  599. {
  600. return SxspDbgSectionIdToNtString(Id)->Buffer;
  601. }
  602. VOID
  603. SxspDbgPrintActivationContextDataTocEntry(
  604. ULONG Level,
  605. bool fFull,
  606. PCACTIVATION_CONTEXT_DATA Base,
  607. PCACTIVATION_CONTEXT_DATA_TOC_ENTRY Entry,
  608. CBaseStringBuffer &rbuffPLP
  609. )
  610. {
  611. PVOID SectionData = NULL;
  612. PCSTR pszFormat = "<untranslated format>";
  613. PCWSTR PLP = rbuffPLP;
  614. if (!fFull)
  615. return;
  616. if (PLP == NULL)
  617. PLP = L"";
  618. if (Entry->Offset != 0)
  619. SectionData = (PVOID) (((ULONG_PTR) Base) + Entry->Offset);
  620. #define MAP_FORMAT(_x, _sn) \
  621. case _x: \
  622. if (fFull) \
  623. pszFormat = #_x; \
  624. else \
  625. pszFormat = _sn; \
  626. break;
  627. switch (Entry->Format)
  628. {
  629. default: break;
  630. MAP_FORMAT(ACTIVATION_CONTEXT_SECTION_FORMAT_UNKNOWN, "user defined");
  631. MAP_FORMAT(ACTIVATION_CONTEXT_SECTION_FORMAT_STRING_TABLE, "string table");
  632. MAP_FORMAT(ACTIVATION_CONTEXT_SECTION_FORMAT_GUID_TABLE, "guid table");
  633. }
  634. #undef MAP_FORMAT
  635. if (fFull)
  636. {
  637. ::FusionpDbgPrintEx(
  638. Level,
  639. "%SACTIVATION_CONTEXT_DATA_TOC_ENTRY %p\n"
  640. "%S Id = %Z (%u)\n"
  641. "%S Offset = %lu (0x%lx) (-> %p)\n"
  642. "%S Length = %lu (0x%lx)\n"
  643. "%S Format = %lu (%s)\n",
  644. PLP, Entry,
  645. PLP, SxspDbgSectionIdToNtString(Entry->Id), Entry->Id,
  646. PLP, Entry->Offset, Entry->Offset, SectionData,
  647. PLP, Entry->Length, Entry->Length,
  648. PLP, Entry->Format, pszFormat);
  649. }
  650. else
  651. {
  652. ::FusionpDbgPrintEx(
  653. Level,
  654. "%S%7lu | %Z (%s)\n",
  655. PLP, Entry->Id, SxspDbgSectionIdToNtString(Entry->Id), pszFormat);
  656. }
  657. }
  658. VOID
  659. SxspDbgPrintActivationContextDataExtendedTocHeader(
  660. ULONG Level,
  661. bool fFull,
  662. PCACTIVATION_CONTEXT_DATA Base,
  663. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data,
  664. CBaseStringBuffer &rbuffPLP
  665. )
  666. {
  667. PCWSTR PLP = rbuffPLP;
  668. CSmallStringBuffer buffNewPrefix;
  669. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry = NULL;
  670. ULONG i;
  671. if (PLP == NULL)
  672. PLP = L"";
  673. //
  674. // ISSUE: jonwis 3/7/2002
  675. // - Again , this is really -really- poor practice. Why make our own prefix when
  676. // we can abuse the prefix buffer (stash the prefix depth, work, reset depth)
  677. // - And, the .Win32Append(L"", 3) pattern strikes again.
  678. //
  679. if (Data->FirstEntryOffset != NULL)
  680. {
  681. buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP));
  682. buffNewPrefix.Win32Append(L" ", 3);
  683. Entry = (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset);
  684. }
  685. ::FusionpDbgPrintEx(
  686. Level,
  687. "%SACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER %p\n"
  688. "%S HeaderSize = %d\n"
  689. "%S EntryCount = %d\n"
  690. "%S FirstEntryOffset = %d (->%p)\n"
  691. "%S Flags = 0x%08lx\n",
  692. PLP, Data,
  693. PLP, Data->HeaderSize,
  694. PLP, Data->EntryCount,
  695. PLP, Data->FirstEntryOffset, Entry,
  696. PLP, Data->Flags);
  697. if (Entry != NULL)
  698. {
  699. for (i=0; i<Data->EntryCount; i++)
  700. ::SxspDbgPrintActivationContextDataExtendedTocEntry(
  701. Level,
  702. fFull,
  703. Base,
  704. &Entry[i],
  705. buffNewPrefix);
  706. }
  707. }
  708. VOID
  709. SxspDbgPrintActivationContextDataExtendedTocEntry(
  710. ULONG Level,
  711. bool fFull,
  712. PCACTIVATION_CONTEXT_DATA Base,
  713. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry,
  714. CBaseStringBuffer &rbuffPLP
  715. )
  716. {
  717. PCWSTR PLP = rbuffPLP;
  718. CSmallStringBuffer buffNewPrefix;
  719. CSmallStringBuffer buffFormattedGUID;
  720. PCACTIVATION_CONTEXT_DATA_TOC_HEADER Toc = NULL;
  721. if (PLP == NULL)
  722. PLP = L"";
  723. if (Entry->TocOffset != 0)
  724. {
  725. buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP));
  726. buffNewPrefix.Win32Append(L" ", 3);
  727. Toc = (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Base) + Entry->TocOffset);
  728. }
  729. ::SxspFormatGUID(Entry->ExtensionGuid, buffFormattedGUID);
  730. ::FusionpDbgPrintEx(
  731. Level,
  732. "%SACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY %p\n"
  733. "%S ExtensionGuid = %S\n"
  734. "%S TocOffset = %d (-> %p)\n"
  735. "%S Length = %d\n",
  736. PLP, Entry,
  737. PLP, static_cast<PCWSTR>(buffFormattedGUID),
  738. PLP, Entry->Length);
  739. if (Toc != NULL)
  740. ::SxspDbgPrintActivationContextDataTocHeader(Level, fFull, Base, Toc, buffNewPrefix);
  741. }
  742. VOID
  743. SxspDbgPrintActivationContextDataExtendedTocSections(
  744. ULONG Level,
  745. bool fFull,
  746. PCACTIVATION_CONTEXT_DATA Base,
  747. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data,
  748. CBaseStringBuffer &rbuffPLP
  749. )
  750. {
  751. PCWSTR PLP = rbuffPLP;
  752. CSmallStringBuffer buffNewPrefix;
  753. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry = NULL;
  754. ULONG i;
  755. if (PLP == NULL)
  756. PLP = L"";
  757. if (Data->FirstEntryOffset != NULL)
  758. {
  759. buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP));
  760. buffNewPrefix.Win32Append(L" ", 3);
  761. Entry = (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset);
  762. }
  763. if (Entry != NULL)
  764. {
  765. for (i=0; i<Data->EntryCount; i++)
  766. ::SxspDbgPrintActivationContextDataExtendedTocEntrySections(
  767. Level,
  768. fFull,
  769. Base,
  770. &Entry[i],
  771. buffNewPrefix);
  772. }
  773. }
  774. VOID
  775. SxspDbgPrintActivationContextDataExtendedTocEntrySections(
  776. ULONG Level,
  777. bool fFull,
  778. PCACTIVATION_CONTEXT_DATA Base,
  779. PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry,
  780. CBaseStringBuffer &rbuffPLP
  781. )
  782. {
  783. PCWSTR PLP = rbuffPLP;
  784. CSmallStringBuffer buffNewPrefix;
  785. PCACTIVATION_CONTEXT_DATA_TOC_HEADER Toc = NULL;
  786. if (PLP == NULL)
  787. PLP = L"";
  788. if (Entry->TocOffset != 0)
  789. {
  790. //
  791. // ISSUE: jonwis 3/7/2002
  792. // - Sigh, again, why do this? Why not assign from rbuffPLP, or abuse rbuffPLP?
  793. //
  794. buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP));
  795. buffNewPrefix.Win32Append(L" ", 3);
  796. Toc = (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Base) + Entry->TocOffset);
  797. }
  798. if (Toc != NULL)
  799. {
  800. CSmallStringBuffer buffFormattedGUID;
  801. ::SxspFormatGUID(Entry->ExtensionGuid, buffFormattedGUID);
  802. ::FusionpDbgPrintEx(
  803. Level,
  804. "%SSections for extension GUID %S (Extended TOC entry %p)\n",
  805. PLP, static_cast<PCWSTR>(buffFormattedGUID), Entry);
  806. ::SxspDbgPrintActivationContextDataTocSections(Level, fFull, Base, Toc, &Entry->ExtensionGuid, buffNewPrefix);
  807. }
  808. }
  809. VOID
  810. SxspDbgPrintActivationContextBinarySection(
  811. ULONG Level,
  812. bool fFull,
  813. PVOID Data,
  814. SIZE_T Length,
  815. CBaseStringBuffer &rbuffPLP
  816. )
  817. {
  818. PCWSTR PLP = rbuffPLP;
  819. if (PLP == NULL)
  820. PLP = L"";
  821. ::FusionpDbgPrintEx(
  822. Level,
  823. "%SBinary section %p (%d bytes)\n",
  824. PLP, Data, Length);
  825. if (Length != 0)
  826. {
  827. CSmallStringBuffer buffNewPrefix;
  828. buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP));
  829. buffNewPrefix.Win32Append(L" ", 3);
  830. ::FusionpDbgPrintBlob(Level, Data, Length, buffNewPrefix);
  831. }
  832. }
  833. VOID
  834. SxspDbgPrintActivationContextStringSection(
  835. ULONG Level,
  836. bool fFull,
  837. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Data,
  838. const GUID *ExtensionGuid,
  839. ULONG SectionId,
  840. PCSTR SectionName,
  841. CBaseStringBuffer &rbuffPLP
  842. )
  843. {
  844. PCWSTR PLP = rbuffPLP;
  845. SIZE_T cchPLP = rbuffPLP.Cch();
  846. CSmallStringBuffer buffBriefOutput;
  847. CSmallStringBuffer buffFlags;
  848. SIZE_T cchBriefOutputKey = 3;
  849. PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY ElementList = NULL;
  850. PCACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE SearchStructure = NULL;
  851. PVOID UserData = NULL;
  852. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgStringSectionFlags[] =
  853. {
  854. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_STRING_SECTION_CASE_INSENSITIVE, "Case Insensitive")
  855. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_STRING_SECTION_ENTRIES_IN_PSEUDOKEY_ORDER, "In PseudoKey Order")
  856. };
  857. if (PLP == NULL)
  858. PLP = L"";
  859. if (Data->ElementListOffset != 0)
  860. ElementList = (PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY) (((ULONG_PTR) Data) + Data->ElementListOffset);
  861. if (Data->SearchStructureOffset != 0)
  862. SearchStructure = (PCACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE) (((ULONG_PTR) Data) + Data->SearchStructureOffset);
  863. if (Data->UserDataOffset != 0)
  864. UserData = (PVOID) (((ULONG_PTR) Data) + Data->UserDataOffset);
  865. ::FusionpFormatFlags(Data->Flags, fFull, NUMBER_OF(s_rgStringSectionFlags), s_rgStringSectionFlags, buffFlags);
  866. if (fFull)
  867. {
  868. ::FusionpDbgPrintEx(
  869. Level,
  870. "%SACTIVATION_CONTEXT_STRING_SECTION_HEADER %p\n"
  871. "%S Magic = 0x%08lx\n"
  872. "%S HeaderSize = %lu (0x%lx)\n"
  873. "%S FormatVersion = %lu\n"
  874. "%S DataFormatVersion = %u\n"
  875. "%S Flags = 0x%08lx (%S)\n",
  876. PLP, Data,
  877. PLP, Data->Magic,
  878. PLP, Data->HeaderSize, Data->HeaderSize,
  879. PLP, Data->FormatVersion,
  880. PLP, Data->DataFormatVersion,
  881. PLP, Data->Flags, static_cast<PCWSTR>(buffFlags));
  882. ::FusionpDbgPrintEx(
  883. Level,
  884. "%S ElementCount = %lu\n"
  885. "%S ElementListOffset = %lu (0x%lx) (-> %p)\n"
  886. "%S HashAlgorithm = %lu\n"
  887. "%S SearchStructureOffset = %lu (0x%lx) (-> %p)\n"
  888. "%S UserDataOffset = %lu (0x%lx) (-> %p)\n"
  889. "%S UserDataSize = %lu (0x%lx)\n",
  890. PLP, Data->ElementCount,
  891. PLP, Data->ElementListOffset, Data->ElementListOffset, ElementList,
  892. PLP, Data->HashAlgorithm,
  893. PLP, Data->SearchStructureOffset, Data->SearchStructureOffset, SearchStructure,
  894. PLP, Data->UserDataOffset, Data->UserDataOffset, UserData,
  895. PLP, Data->UserDataSize, Data->UserDataSize);
  896. if (UserData != NULL)
  897. {
  898. ::FusionpDbgPrintEx(
  899. Level,
  900. "%S User data at %p (%d bytes)\n",
  901. PLP, UserData, Data->UserDataSize);
  902. rbuffPLP.Win32Append(L" ", 3);
  903. FusionpDbgPrintBlob(Level, UserData, Data->UserDataSize, rbuffPLP);
  904. rbuffPLP.Left(cchPLP);
  905. PLP = rbuffPLP;
  906. }
  907. }
  908. else
  909. {
  910. // let's figure out the brief output key size
  911. cchBriefOutputKey = 3;
  912. if (ElementList != NULL)
  913. {
  914. ULONG i;
  915. for (i=0; i<Data->ElementCount; i++)
  916. {
  917. SIZE_T cch = ElementList[i].KeyLength / sizeof(WCHAR);
  918. if (cch > cchBriefOutputKey)
  919. cchBriefOutputKey = cch;
  920. }
  921. }
  922. if (cchBriefOutputKey > 64)
  923. cchBriefOutputKey = 64;
  924. // Abuse the brief output buffer temporarily...
  925. buffBriefOutput.Win32Assign(L"Key................................................................", // 64 dots
  926. cchBriefOutputKey);
  927. ::FusionpDbgPrintEx(
  928. Level,
  929. "%S%s string section (%lu entr%s; Flags: %S)\n"
  930. "%S %S | Value\n",
  931. PLP, SectionName, Data->ElementCount, Data->ElementCount == 1 ? "y" : "ies", static_cast<PCWSTR>(buffFlags),
  932. PLP, static_cast<PCWSTR>(buffBriefOutput));
  933. }
  934. if (fFull && (SearchStructure != NULL))
  935. {
  936. PCACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET BucketTable = NULL;
  937. if (SearchStructure->BucketTableOffset != 0)
  938. BucketTable = (PCACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET) (((ULONG_PTR) Data) + SearchStructure->BucketTableOffset);
  939. ::FusionpDbgPrintEx(
  940. Level,
  941. "%S ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE %p\n"
  942. "%S BucketTableEntryCount = %u\n"
  943. "%S BucketTableOffset = %d (-> %p)\n",
  944. PLP, SearchStructure,
  945. PLP, SearchStructure->BucketTableEntryCount,
  946. PLP, SearchStructure->BucketTableOffset, BucketTable);
  947. if (BucketTable != NULL)
  948. {
  949. ULONG i;
  950. for (i=0; i<SearchStructure->BucketTableEntryCount; i++)
  951. {
  952. PLONG Entries = NULL;
  953. if (BucketTable[i].ChainOffset != 0)
  954. Entries = (PLONG) (((ULONG_PTR) Data) + BucketTable[i].ChainOffset);
  955. ::FusionpDbgPrintEx(
  956. Level,
  957. "%S ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET %p\n"
  958. "%S ChainCount = %u\n"
  959. "%S ChainOffset = %d (-> %p)\n",
  960. PLP, &BucketTable[i],
  961. PLP, BucketTable[i].ChainCount,
  962. PLP, BucketTable[i].ChainOffset, Entries);
  963. if (Entries != NULL)
  964. {
  965. ULONG j;
  966. for (j=0; j<BucketTable[i].ChainCount; j++)
  967. {
  968. PVOID Entry = NULL;
  969. if (Entries[j] != 0)
  970. Entry = (PVOID) (((ULONG_PTR) Data) + Entries[j]);
  971. ::FusionpDbgPrintEx(
  972. Level,
  973. "%S Chain[%d] = %d (-> %p)\n",
  974. PLP, j, Entries[j], Entry);
  975. }
  976. }
  977. }
  978. }
  979. }
  980. if (ElementList != NULL)
  981. {
  982. ULONG i;
  983. for (i=0; i<Data->ElementCount; i++)
  984. {
  985. UNICODE_STRING s;
  986. PVOID EntryData = NULL;
  987. s.Length = static_cast<USHORT>(ElementList[i].KeyLength);
  988. s.MaximumLength = s.Length;
  989. s.Buffer = (PWSTR) (((ULONG_PTR) Data) + ElementList[i].KeyOffset);
  990. if (ElementList[i].Offset != 0)
  991. EntryData = (PVOID) (((ULONG_PTR) Data) + ElementList[i].Offset);
  992. if (fFull)
  993. {
  994. ::FusionpDbgPrintEx(
  995. Level,
  996. "%S ACTIVATION_CONTEXT_STRING_SECTION_ENTRY #%d - %p\n"
  997. "%S AssemblyRosterIndex = %u\n"
  998. "%S PseudoKey = %u\n",
  999. PLP, i, &ElementList[i],
  1000. PLP, ElementList[i].AssemblyRosterIndex,
  1001. PLP, ElementList[i].PseudoKey);
  1002. ::FusionpDbgPrintEx(
  1003. Level,
  1004. "%S String = \"%wZ\"\n"
  1005. "%S Offset = %d (-> %p)\n"
  1006. "%S Length = %u\n",
  1007. PLP, &s,
  1008. PLP, ElementList[i].Offset, EntryData,
  1009. PLP, ElementList[i].Length);
  1010. }
  1011. else
  1012. {
  1013. // Abuse the flags buffer so we can truncate the name as necessary...
  1014. SIZE_T cchKey = s.Length / sizeof(WCHAR);
  1015. PCWSTR pszKey = s.Buffer;
  1016. if (cchKey > cchBriefOutputKey)
  1017. {
  1018. pszKey += (cchKey - cchBriefOutputKey);
  1019. cchKey = cchBriefOutputKey;
  1020. }
  1021. buffFlags.Win32AssignFill(L' ', (cchBriefOutputKey - cchKey));
  1022. buffFlags.Win32Append(pszKey, cchKey);
  1023. buffBriefOutput.Win32ResizeBuffer(cchPLP + 3 + cchBriefOutputKey + 4, eDoNotPreserveBufferContents);
  1024. buffBriefOutput.Win32Format(
  1025. L"%s %s | ",
  1026. PLP, static_cast<PCWSTR>(buffFlags));
  1027. }
  1028. if (EntryData != NULL)
  1029. {
  1030. if (ExtensionGuid == NULL)
  1031. {
  1032. rbuffPLP.Win32Append(L" ", 6);
  1033. switch (SectionId)
  1034. {
  1035. default:
  1036. if (fFull)
  1037. ::FusionpDbgPrintBlob(Level, EntryData, ElementList[i].Length, rbuffPLP);
  1038. else
  1039. buffBriefOutput.Win32Append(
  1040. L"<untranslatable value>",
  1041. 22);
  1042. break;
  1043. case ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION:
  1044. ::SxspDbgPrintAssemblyInformation(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1045. break;
  1046. case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION:
  1047. ::SxspDbgPrintDllRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1048. break;
  1049. case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION:
  1050. ::SxspDbgPrintWindowClassRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1051. break;
  1052. case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION:
  1053. ::SxspDbgPrintComProgIdRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1054. break;
  1055. }
  1056. rbuffPLP.Left(cchPLP);
  1057. PLP = rbuffPLP;
  1058. }
  1059. }
  1060. if (!fFull)
  1061. ::FusionpDbgPrintEx(Level, "%S\n", static_cast<PCWSTR>(buffBriefOutput));
  1062. }
  1063. }
  1064. }
  1065. VOID
  1066. SxspDbgPrintActivationContextGuidSection(
  1067. ULONG Level,
  1068. bool fFull,
  1069. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Data,
  1070. const GUID *ExtensionGuid,
  1071. ULONG SectionId,
  1072. PCSTR SectionName,
  1073. CBaseStringBuffer &rbuffPLP
  1074. )
  1075. {
  1076. PCWSTR PLP = rbuffPLP;
  1077. SIZE_T cchPLP = rbuffPLP.Cch();
  1078. CSmallStringBuffer buffFlags;
  1079. CSmallStringBuffer buffBriefOutput;
  1080. PCACTIVATION_CONTEXT_GUID_SECTION_ENTRY ElementList = NULL;
  1081. PCACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE SearchStructure = NULL;
  1082. PVOID UserData = NULL;
  1083. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgGuidSectionFlags[] =
  1084. {
  1085. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_GUID_SECTION_ENTRIES_IN_ORDER, "Inorder")
  1086. };
  1087. if (PLP == NULL)
  1088. PLP = L"";
  1089. if (Data->ElementListOffset != 0)
  1090. ElementList = (PCACTIVATION_CONTEXT_GUID_SECTION_ENTRY) (((ULONG_PTR) Data) + Data->ElementListOffset);
  1091. if (Data->SearchStructureOffset != 0)
  1092. SearchStructure = (PCACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE) (((ULONG_PTR) Data) + Data->SearchStructureOffset);
  1093. if (Data->UserDataOffset != 0)
  1094. UserData = (PVOID) (((ULONG_PTR) Data) + Data->UserDataOffset);
  1095. ::FusionpFormatFlags(Data->Flags, fFull, NUMBER_OF(s_rgGuidSectionFlags), s_rgGuidSectionFlags, buffFlags);
  1096. if (fFull)
  1097. {
  1098. ::FusionpDbgPrintEx(
  1099. Level,
  1100. "%SACTIVATION_CONTEXT_GUID_SECTION_HEADER %p\n"
  1101. "%S Magic = 0x%08lx\n"
  1102. "%S HeaderSize = %u\n"
  1103. "%S FormatVersion = %u\n"
  1104. "%S DataFormatVersion = %u\n"
  1105. "%S Flags = 0x%08lx (%S)\n",
  1106. PLP, Data,
  1107. PLP, Data->Magic,
  1108. PLP, Data->HeaderSize,
  1109. PLP, Data->FormatVersion,
  1110. PLP, Data->DataFormatVersion,
  1111. PLP, Data->Flags, static_cast<PCWSTR>(buffFlags));
  1112. ::FusionpDbgPrintEx(
  1113. Level,
  1114. "%S ElementCount = %u\n"
  1115. "%S ElementListOffset = %d (-> %p)\n"
  1116. "%S SearchStructureOffset = %d (-> %p)\n"
  1117. "%S UserDataOffset = %d (-> %p)\n"
  1118. "%S UserDataSize = %u\n",
  1119. PLP, Data->ElementCount,
  1120. PLP, Data->ElementListOffset, ElementList,
  1121. PLP, Data->SearchStructureOffset, SearchStructure,
  1122. PLP, Data->UserDataOffset, UserData,
  1123. PLP, Data->UserDataSize);
  1124. if (UserData != NULL)
  1125. {
  1126. ::FusionpDbgPrintEx(
  1127. Level,
  1128. "%S User data at %p (%d bytes)\n",
  1129. PLP, UserData, Data->UserDataSize);
  1130. rbuffPLP.Win32Append(L" ", 3);
  1131. FusionpDbgPrintBlob(Level, UserData, Data->UserDataSize, rbuffPLP);
  1132. rbuffPLP.Left(cchPLP);
  1133. PLP = rbuffPLP;
  1134. }
  1135. }
  1136. else
  1137. {
  1138. ::FusionpDbgPrintEx(
  1139. Level,
  1140. "%S%s guid section (%lu entr%s; Flags: %S)\n"
  1141. "%S Key................................... | Value\n",
  1142. PLP, SectionName, Data->ElementCount, Data->ElementCount == 1 ? "y" : "ies", static_cast<PCWSTR>(buffFlags),
  1143. PLP);
  1144. }
  1145. if (fFull && (SearchStructure != NULL))
  1146. {
  1147. PCACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET BucketTable = NULL;
  1148. if (SearchStructure->BucketTableOffset != 0)
  1149. BucketTable = (PCACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET) (((ULONG_PTR) Data) + SearchStructure->BucketTableOffset);
  1150. ::FusionpDbgPrintEx(
  1151. Level,
  1152. "%S ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE %p\n"
  1153. "%S BucketTableEntryCount = %u\n"
  1154. "%S BucketTableOffset = %d (-> %p)\n",
  1155. PLP, SearchStructure,
  1156. PLP, SearchStructure->BucketTableEntryCount,
  1157. PLP, SearchStructure->BucketTableOffset, BucketTable);
  1158. if (BucketTable != NULL)
  1159. {
  1160. ULONG i;
  1161. for (i=0; i<SearchStructure->BucketTableEntryCount; i++)
  1162. {
  1163. PLONG Entries = NULL;
  1164. if (BucketTable[i].ChainOffset != 0)
  1165. Entries = (PLONG) (((ULONG_PTR) Data) + BucketTable[i].ChainOffset);
  1166. ::FusionpDbgPrintEx(
  1167. Level,
  1168. "%S ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET %p\n"
  1169. "%S ChainCount = %u\n"
  1170. "%S ChainOffset = %d (-> %p)\n",
  1171. PLP, &BucketTable[i],
  1172. PLP, BucketTable[i].ChainCount,
  1173. PLP, BucketTable[i].ChainOffset, Entries);
  1174. if (Entries != NULL)
  1175. {
  1176. ULONG j;
  1177. for (j=0; j<BucketTable[i].ChainCount; j++)
  1178. {
  1179. PVOID Entry = NULL;
  1180. if (Entries[j] != 0)
  1181. Entry = (PVOID) (((ULONG_PTR) Data) + Entries[j]);
  1182. ::FusionpDbgPrintEx(
  1183. Level,
  1184. "%S Chain[%d] = %d (-> %p)\n",
  1185. PLP, j, Entries[j], Entry);
  1186. }
  1187. }
  1188. }
  1189. }
  1190. }
  1191. if (ElementList != NULL)
  1192. {
  1193. ULONG i;
  1194. CSmallStringBuffer buffFormattedGuid;
  1195. for (i=0; i<Data->ElementCount; i++)
  1196. {
  1197. PVOID EntryData = NULL;
  1198. ::SxspFormatGUID(ElementList[i].Guid, buffFormattedGuid);
  1199. if (ElementList[i].Offset != 0)
  1200. EntryData = (PVOID) (((ULONG_PTR) Data) + ElementList[i].Offset);
  1201. if (fFull)
  1202. {
  1203. ::FusionpDbgPrintEx(
  1204. Level,
  1205. "%S ACTIVATION_CONTEXT_GUID_SECTION_ENTRY #%d - %p\n"
  1206. "%S Guid = %S\n"
  1207. "%S AssemblyRosterIndex = %u\n",
  1208. PLP, i, &ElementList[i],
  1209. PLP, static_cast<PCWSTR>(buffFormattedGuid),
  1210. PLP, ElementList[i].AssemblyRosterIndex);
  1211. ::FusionpDbgPrintEx(
  1212. Level,
  1213. "%S Offset = %d (-> %p)\n"
  1214. "%S Length = %u\n",
  1215. PLP, ElementList[i].Offset, EntryData,
  1216. PLP, ElementList[i].Length);
  1217. }
  1218. else
  1219. {
  1220. //
  1221. // ISSUE: jonwis 3/7/2002
  1222. // - Augh! It's -like- .Win32FormatAppend, but it's NOT! %s will attempt to append
  1223. // ANSI charcacters, not UNICODE chars like what PLP points to!
  1224. //
  1225. buffBriefOutput.Win32ResizeBuffer(cchPLP + 3 + 38 + 4, eDoNotPreserveBufferContents);
  1226. buffBriefOutput.Win32Format(L"%s %38s | ", PLP, static_cast<PCWSTR>(buffFormattedGuid));
  1227. }
  1228. if (EntryData != NULL)
  1229. {
  1230. if (ExtensionGuid == NULL)
  1231. {
  1232. //
  1233. // ISSUE: jonwis 3/7/2002
  1234. // - wcslen(L" ") != 6
  1235. //
  1236. rbuffPLP.Win32Append(L" ", 6);
  1237. switch (SectionId)
  1238. {
  1239. default:
  1240. ::FusionpDbgPrintBlob(Level, EntryData, ElementList[i].Length, rbuffPLP);
  1241. break;
  1242. case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION:
  1243. ::SxspDbgPrintComServerRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1244. break;
  1245. case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION:
  1246. ::SxspDbgPrintComInterfaceRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1247. break;
  1248. case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION:
  1249. ::SxspDbgPrintTypeLibraryRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1250. break;
  1251. case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES:
  1252. ::SxspDbgPrintCLRSurrogateTable(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE)EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput);
  1253. break;
  1254. }
  1255. rbuffPLP.Left(cchPLP);
  1256. PLP = rbuffPLP;
  1257. }
  1258. }
  1259. if (!fFull)
  1260. ::FusionpDbgPrintEx(Level, "%S\n", static_cast<PCWSTR>(buffBriefOutput));
  1261. }
  1262. }
  1263. }
  1264. VOID
  1265. SxspDbgPrintAssemblyInformation(
  1266. ULONG Level,
  1267. bool fFull,
  1268. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  1269. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION Entry,
  1270. SIZE_T Length,
  1271. CBaseStringBuffer &rbuffPLP,
  1272. CBaseStringBuffer &rbuffBriefOutput
  1273. )
  1274. {
  1275. PCWSTR PLP = rbuffPLP;
  1276. UNICODE_STRING s2, s3, s5, strIdentity;
  1277. CSmallStringBuffer buffManifestLastWriteTime;
  1278. CSmallStringBuffer buffPolicyLastWriteTime;
  1279. CSmallStringBuffer buffFlags;
  1280. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgAssemblyInformationFlags[] =
  1281. {
  1282. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_ASSEMBLY, "Root Assembly")
  1283. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_POLICY_APPLIED, "Policy Applied")
  1284. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ASSEMBLY_POLICY_APPLIED, "Assembly Policy Applied")
  1285. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_POLICY_APPLIED, "Root Policy Applied")
  1286. };
  1287. if (PLP == NULL)
  1288. PLP = L"";
  1289. #define GET_STRING(_var, _elem) \
  1290. if (Entry-> _elem ## Length != 0) \
  1291. { \
  1292. (_var).Length = (_var).MaximumLength = static_cast<USHORT>(Entry-> _elem ## Length); \
  1293. (_var).Buffer = reinterpret_cast<PWSTR>(((LONG_PTR) Header) + Entry-> _elem ## Offset); \
  1294. } \
  1295. else \
  1296. { \
  1297. (_var).Length = (_var).MaximumLength = 0; \
  1298. (_var).Buffer = NULL; \
  1299. }
  1300. GET_STRING(s2, ManifestPath);
  1301. GET_STRING(s3, PolicyPath);
  1302. GET_STRING(s5, AssemblyDirectoryName);
  1303. #undef GET_STRING
  1304. // prepare data for print
  1305. ::SxspFormatFileTime(Entry->ManifestLastWriteTime, buffManifestLastWriteTime);
  1306. ::SxspFormatFileTime(Entry->PolicyLastWriteTime, buffPolicyLastWriteTime);
  1307. ::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgAssemblyInformationFlags), s_rgAssemblyInformationFlags, buffFlags);
  1308. if (Entry->EncodedAssemblyIdentityOffset != 0)
  1309. {
  1310. strIdentity.Buffer = (PWSTR) (((ULONG_PTR) Header) + Entry->EncodedAssemblyIdentityOffset);
  1311. strIdentity.Length = static_cast<USHORT>(Entry->EncodedAssemblyIdentityLength);
  1312. strIdentity.MaximumLength = static_cast<USHORT>(Entry->EncodedAssemblyIdentityLength);
  1313. }
  1314. else
  1315. {
  1316. strIdentity.Buffer = NULL;
  1317. strIdentity.Length = 0;
  1318. strIdentity.MaximumLength = 0;
  1319. }
  1320. if (fFull)
  1321. {
  1322. ::FusionpDbgPrintEx(
  1323. Level,
  1324. "%SACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION %p\n"
  1325. "%S Size = %lu\n"
  1326. "%S Flags = 0x%08lx (%S)\n",
  1327. PLP, Entry,
  1328. PLP, Entry->Size,
  1329. PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags));
  1330. ::FusionpDbgPrintEx(
  1331. Level,
  1332. "%S EncodedIdentity = %wZ\n",
  1333. PLP, &strIdentity);
  1334. ::FusionpDbgPrintEx(
  1335. Level,
  1336. "%S ManifestPathType = %lu\n"
  1337. "%S ManifestPath = \"%wZ\"\n",
  1338. PLP, Entry->ManifestPathType,
  1339. PLP, &s2);
  1340. ::FusionpDbgPrintEx(
  1341. Level,
  1342. "%S ManifestLastWriteTime = %S\n",
  1343. PLP, static_cast<PCWSTR>(buffManifestLastWriteTime));
  1344. ::FusionpDbgPrintEx(
  1345. Level,
  1346. "%S PolicyPathType = %lu\n"
  1347. "%S PolicyPath = \"%wZ\"\n"
  1348. "%S PolicyLastWriteTime = %S\n",
  1349. PLP, Entry->PolicyPathType,
  1350. PLP, &s3,
  1351. PLP, static_cast<PCWSTR>(buffPolicyLastWriteTime));
  1352. ::FusionpDbgPrintEx(
  1353. Level,
  1354. "%S MetadataSatelliteRosterIndex = %lu\n"
  1355. "%S ManifestVersionMajor = %u\n"
  1356. "%S ManifestVersionMinor = %u\n",
  1357. PLP, Entry->MetadataSatelliteRosterIndex,
  1358. PLP, Entry->ManifestVersionMajor,
  1359. PLP, Entry->ManifestVersionMinor);
  1360. ::FusionpDbgPrintEx(
  1361. Level,
  1362. "%S AssemblyDirectoryName = \"%wZ\"\n",
  1363. PLP, &s5);
  1364. }
  1365. else
  1366. {
  1367. // abuse buffManifestLastWriteTime
  1368. buffManifestLastWriteTime.Win32ResizeBuffer(((strIdentity.Length + s2.Length) / sizeof(WCHAR)) + 4, eDoNotPreserveBufferContents);
  1369. buffManifestLastWriteTime.Win32Format(L"%wZ \"%wZ\"", &strIdentity, &s2);
  1370. rbuffBriefOutput.Win32Append(buffManifestLastWriteTime);
  1371. }
  1372. }
  1373. VOID
  1374. SxspDbgPrintDllRedirection(
  1375. ULONG Level,
  1376. bool fFull,
  1377. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  1378. PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION Entry,
  1379. SIZE_T Length,
  1380. CBaseStringBuffer &rbuffPLP,
  1381. CBaseStringBuffer &rbuffBriefOutput
  1382. )
  1383. {
  1384. PCWSTR PLP = rbuffPLP;
  1385. PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT PathSegments = NULL;
  1386. CSmallStringBuffer buffFlags;
  1387. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgDllRedirectionFlags[] =
  1388. {
  1389. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME, "Includes Base Name")
  1390. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT, "Omits Assembly Root")
  1391. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND, "Req. EnvVar Expansion")
  1392. };
  1393. if (PLP == NULL)
  1394. PLP = L"";
  1395. if (Entry->PathSegmentOffset != 0)
  1396. PathSegments = (PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT) (((ULONG_PTR) Header) + Entry->PathSegmentOffset);
  1397. ::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgDllRedirectionFlags), s_rgDllRedirectionFlags, buffFlags);
  1398. if (fFull)
  1399. {
  1400. ::FusionpDbgPrintEx(
  1401. Level,
  1402. "%SACTIVATION_CONTEXT_DATA_DLL_REDIRECTION %p\n"
  1403. "%S Size = %u\n"
  1404. "%S Flags = 0x%08lx (%S)\n"
  1405. "%S TotalPathLength = %u (%u chars)\n"
  1406. "%S PathSegmentCount = %u\n"
  1407. "%S PathSegmentOffset = %d (-> %p)\n",
  1408. PLP, Entry,
  1409. PLP, Entry->Size,
  1410. PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags),
  1411. PLP, Entry->TotalPathLength, Entry->TotalPathLength / sizeof(WCHAR),
  1412. PLP, Entry->PathSegmentCount,
  1413. PLP, Entry->PathSegmentOffset, PathSegments);
  1414. }
  1415. else
  1416. rbuffBriefOutput.Win32Append(L"\"", 1);
  1417. if (PathSegments != NULL)
  1418. {
  1419. ULONG i;
  1420. for (i=0; i<Entry->PathSegmentCount; i++)
  1421. {
  1422. PCWSTR pwch = NULL;
  1423. UNICODE_STRING s;
  1424. if (PathSegments[i].Offset != 0)
  1425. {
  1426. pwch = (PCWSTR) (((ULONG_PTR) Header) + PathSegments[i].Offset);
  1427. s.MaximumLength = static_cast<USHORT>(PathSegments[i].Length);
  1428. s.Length = static_cast<USHORT>(PathSegments[i].Length);
  1429. s.Buffer = (PWSTR) pwch;
  1430. }
  1431. else
  1432. {
  1433. s.MaximumLength = 0;
  1434. s.Length = 0;
  1435. s.Buffer = NULL;
  1436. }
  1437. if (fFull)
  1438. {
  1439. ::FusionpDbgPrintEx(
  1440. Level,
  1441. "%S ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT #%d - %p\n"
  1442. "%S Length = %u (%u chars)\n"
  1443. "%S Offset = %d (-> %p)\n"
  1444. "%S \"%wZ\"\n",
  1445. PLP, i, &PathSegments[i],
  1446. PLP, PathSegments[i].Length, PathSegments[i].Length / sizeof(WCHAR),
  1447. PLP, PathSegments[i].Offset, pwch,
  1448. PLP, &s);
  1449. }
  1450. else
  1451. {
  1452. rbuffBriefOutput.Win32Append(s.Buffer, s.Length / sizeof(WCHAR));
  1453. }
  1454. }
  1455. }
  1456. if (!fFull)
  1457. {
  1458. rbuffBriefOutput.Win32Append(L"\" (Flags: ", 10);
  1459. rbuffBriefOutput.Win32Append(buffFlags);
  1460. rbuffBriefOutput.Win32Append(L")", 1);
  1461. }
  1462. }
  1463. VOID
  1464. SxspDbgPrintWindowClassRedirection(
  1465. ULONG Level,
  1466. bool fFull,
  1467. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  1468. PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION Entry,
  1469. SIZE_T Length,
  1470. CBaseStringBuffer &rbuffPLP,
  1471. CBaseStringBuffer &rbuffBriefOutput
  1472. )
  1473. {
  1474. PCWSTR PLP = rbuffPLP;
  1475. UNICODE_STRING s1, s2;
  1476. CSmallStringBuffer buffFlags;
  1477. if (PLP == NULL)
  1478. PLP = L"";
  1479. //
  1480. // ISSUE: jonwis 3/7/2002 - Ick. Use initializers instead. The compiler is smarter than you are.
  1481. //
  1482. memset(&s1, 0, sizeof(s1));
  1483. memset(&s2, 0, sizeof(s2));
  1484. ::FusionpFormatFlags(
  1485. Entry->Flags,
  1486. fFull,
  1487. 0, NULL,
  1488. buffFlags);
  1489. if (Entry->VersionSpecificClassNameOffset != 0)
  1490. {
  1491. s1.Length = static_cast<USHORT>(Entry->VersionSpecificClassNameLength);
  1492. s1.MaximumLength = s1.Length;
  1493. s1.Buffer = (PWSTR) (((ULONG_PTR) Entry) + Entry->VersionSpecificClassNameOffset);
  1494. }
  1495. if (Entry->DllNameOffset != 0)
  1496. {
  1497. s2.Length = static_cast<USHORT>(Entry->DllNameLength);
  1498. s2.MaximumLength = s2.Length;
  1499. s2.Buffer = (PWSTR) (((ULONG_PTR) Header) + Entry->DllNameOffset);
  1500. }
  1501. if (fFull)
  1502. {
  1503. ::FusionpDbgPrintEx(
  1504. Level,
  1505. "%SACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION %p\n"
  1506. "%S Size = %u\n"
  1507. "%S Flags = 0x%08lx\n"
  1508. "%S VersionSpecificClassNameLength = %u (%u chars)\n"
  1509. "%S VersionSpecificClassNameOffset = %d (-> %p)\n"
  1510. "%S \"%wZ\"\n"
  1511. "%S DllNameLength = %u (%u chars)\n"
  1512. "%S DllNameOffset = %d (-> %p)\n"
  1513. "%S \"%wZ\"\n",
  1514. PLP, Entry,
  1515. PLP, Entry->Size,
  1516. PLP, Entry->Flags,
  1517. PLP, Entry->VersionSpecificClassNameLength, Entry->VersionSpecificClassNameLength / sizeof(WCHAR),
  1518. PLP, Entry->VersionSpecificClassNameOffset, s1.Buffer,
  1519. PLP, &s1,
  1520. PLP, Entry->DllNameLength, Entry->DllNameLength / sizeof(WCHAR),
  1521. PLP, Entry->DllNameOffset, s2.Buffer,
  1522. PLP, &s2);
  1523. }
  1524. else
  1525. {
  1526. //
  1527. // ISSUE: jonwis 3/7/2002
  1528. // - Use Win32FormatAppend or Win32AssignW tead. It's faster, better, cheaper.
  1529. //
  1530. rbuffBriefOutput.Win32Append(s1.Buffer, s1.Length / sizeof(WCHAR));
  1531. rbuffBriefOutput.Win32Append(L" in ", 4);
  1532. rbuffBriefOutput.Win32Append(s2.Buffer, s2.Length / sizeof(WCHAR));
  1533. rbuffBriefOutput.Win32Append(L" (Flags: ", 9);
  1534. rbuffBriefOutput.Win32Append(buffFlags);
  1535. rbuffBriefOutput.Win32Append(L")", 1);
  1536. }
  1537. }
  1538. VOID
  1539. SxspDbgPrintCLRSurrogateTable(
  1540. ULONG Level,
  1541. bool fFull,
  1542. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  1543. PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE Entry,
  1544. SIZE_T Length,
  1545. CBaseStringBuffer &rbuffPLP,
  1546. CBaseStringBuffer &rbuffBriefOutput
  1547. )
  1548. {
  1549. PCWSTR PLP = rbuffPLP;
  1550. CSmallStringBuffer buffGuid;
  1551. UNICODE_STRING RuntimeVersion = RTL_CONSTANT_STRING(L"<No runtime version>");
  1552. UNICODE_STRING TypeName = RTL_CONSTANT_STRING(L"<No type name>");
  1553. if (PLP == NULL)
  1554. PLP = L"";
  1555. ::SxspFormatGUID(Entry->SurrogateIdent, buffGuid);
  1556. if (Entry->VersionOffset != 0)
  1557. {
  1558. RuntimeVersion.MaximumLength = RuntimeVersion.Length = static_cast<USHORT>(Entry->VersionLength);
  1559. RuntimeVersion.Buffer = (PWSTR)(((ULONG_PTR)Entry) + Entry->VersionOffset);
  1560. }
  1561. if (Entry->TypeNameOffset != 0)
  1562. {
  1563. TypeName.MaximumLength = TypeName.Length = static_cast<USHORT>(Entry->TypeNameLength);
  1564. TypeName.Buffer = (PWSTR)(((ULONG_PTR)Entry) + Entry->TypeNameOffset);
  1565. }
  1566. if (fFull)
  1567. {
  1568. ::FusionpDbgPrintEx(
  1569. Level,
  1570. "%SACTIVATION_CONTEXT_DATA_CLR_INTEROP %p\n"
  1571. "%S Size = %u\n"
  1572. "%S Flags = 0x%08lx\n"
  1573. "%S SurrogateIdent = %S\n",
  1574. PLP, Entry,
  1575. PLP, Entry->Size,
  1576. PLP, Entry->Flags,
  1577. PLP, static_cast<PCWSTR>(buffGuid));
  1578. ::FusionpDbgPrintEx(
  1579. Level,
  1580. "%S Typename [Offset %u (-> %p), Length %u] = \"%wZ\"\n"
  1581. "%S RuntimeVersion [Offset %u (-> %p), Length %u] = \"%wZ\"\n",
  1582. PLP, Entry->TypeNameOffset, TypeName.Buffer, Entry->TypeNameLength, &TypeName,
  1583. PLP, Entry->VersionOffset, RuntimeVersion.Buffer, Entry->VersionLength, &RuntimeVersion
  1584. );
  1585. }
  1586. else
  1587. {
  1588. rbuffBriefOutput.Win32Append(buffGuid);
  1589. rbuffBriefOutput.Win32Append(L" runtime: '", NUMBER_OF(L" runtime: '")-1);
  1590. rbuffBriefOutput.Win32Append(&RuntimeVersion);
  1591. rbuffBriefOutput.Win32Append(L"' typename: '", NUMBER_OF(L"' typename: '")-1);
  1592. rbuffBriefOutput.Win32Append(&TypeName);
  1593. rbuffBriefOutput.Win32Append(L"'", 1);
  1594. }
  1595. }
  1596. VOID
  1597. SxspDbgPrintComServerRedirection(
  1598. ULONG Level,
  1599. bool fFull,
  1600. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  1601. PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Entry,
  1602. SIZE_T Length,
  1603. CBaseStringBuffer &rbuffPLP,
  1604. CBaseStringBuffer &rbuffBriefOutput
  1605. )
  1606. {
  1607. PCWSTR PLP = rbuffPLP;
  1608. CSmallStringBuffer buffConfiguredClsid;
  1609. CSmallStringBuffer buffImplementedClsid;
  1610. CSmallStringBuffer buffReferenceClsid;
  1611. CSmallStringBuffer buffTypeLibraryId;
  1612. CSmallStringBuffer buffThreadingModel;
  1613. UNICODE_STRING s;
  1614. UNICODE_STRING progid;
  1615. if (PLP == NULL)
  1616. PLP = L"";
  1617. memset(&s, 0, sizeof(s));
  1618. ::SxspFormatGUID(Entry->ReferenceClsid, buffReferenceClsid);
  1619. ::SxspFormatGUID(Entry->ConfiguredClsid, buffConfiguredClsid);
  1620. ::SxspFormatGUID(Entry->ImplementedClsid, buffImplementedClsid);
  1621. if (Entry->TypeLibraryId == GUID_NULL)
  1622. buffTypeLibraryId.Win32Assign(L"<none>", 6);
  1623. else
  1624. ::SxspFormatGUID(Entry->TypeLibraryId, buffTypeLibraryId);
  1625. ::SxspFormatThreadingModel(Entry->ThreadingModel, buffThreadingModel);
  1626. if (Entry->ModuleOffset != 0)
  1627. {
  1628. s.Length = static_cast<USHORT>(Entry->ModuleLength);
  1629. s.MaximumLength = s.Length;
  1630. s.Buffer = (PWSTR) (((ULONG_PTR) Header) + Entry->ModuleOffset);
  1631. }
  1632. if (Entry->ProgIdOffset != 0)
  1633. {
  1634. progid.Length = static_cast<USHORT>(Entry->ProgIdLength);
  1635. progid.MaximumLength = progid.Length;
  1636. progid.Buffer = (PWSTR) (((ULONG_PTR) Entry) + Entry->ProgIdOffset);
  1637. }
  1638. else
  1639. {
  1640. progid.Length = 0;
  1641. progid.MaximumLength = 0;
  1642. progid.Buffer = NULL;
  1643. }
  1644. if (fFull)
  1645. {
  1646. PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM ShimData = NULL;
  1647. ::FusionpDbgPrintEx(
  1648. Level,
  1649. "%SACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION %p\n"
  1650. "%S Size = %u\n"
  1651. "%S Flags = 0x%08lx\n"
  1652. "%S ThreadingModel = %u (%S)\n"
  1653. "%S ReferenceClsid = %S\n",
  1654. PLP, Entry,
  1655. PLP, Entry->Size,
  1656. PLP, Entry->Flags,
  1657. PLP, Entry->ThreadingModel, static_cast<PCWSTR>(buffThreadingModel),
  1658. PLP, static_cast<PCWSTR>(buffReferenceClsid));
  1659. ::FusionpDbgPrintEx(
  1660. Level,
  1661. "%S ConfiguredClsid = %S\n"
  1662. "%S ImplementedClsid = %S\n"
  1663. "%S TypeLibraryId = %S\n"
  1664. "%S ModuleLength = %u (%u chars)\n"
  1665. "%S ModuleOffset = %d (-> %p)\n"
  1666. "%S \"%wZ\"\n",
  1667. PLP, static_cast<PCWSTR>(buffConfiguredClsid),
  1668. PLP, static_cast<PCWSTR>(buffImplementedClsid),
  1669. PLP, static_cast<PCWSTR>(buffTypeLibraryId),
  1670. PLP, Entry->ModuleLength, Entry->ModuleLength / sizeof(WCHAR),
  1671. PLP, Entry->ModuleOffset, s.Buffer,
  1672. PLP, &s);
  1673. ::FusionpDbgPrintEx(
  1674. Level,
  1675. "%S ProgIdLength = %lu\n"
  1676. "%S ProgIdOffset = %ld (-> %p)\n"
  1677. "%S \"%wZ\"\n",
  1678. PLP, Entry->ProgIdLength,
  1679. PLP, Entry->ProgIdOffset, progid.Buffer,
  1680. PLP, &progid);
  1681. if (Entry->ShimDataOffset != 0)
  1682. ShimData = (PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM) (((ULONG_PTR) Entry) + Entry->ShimDataOffset);
  1683. ::FusionpDbgPrintEx(
  1684. Level,
  1685. "%S ShimDataLength = %lu\n"
  1686. "%S ShimDataOffset = %ld (-> %p)\n",
  1687. PLP, Entry->ShimDataLength,
  1688. PLP, Entry->ShimDataOffset, ShimData);
  1689. if (ShimData != NULL)
  1690. {
  1691. ::FusionpDbgPrintEx(
  1692. Level,
  1693. "%S Size = %lu\n"
  1694. "%S Flags = 0x%08lx\n"
  1695. "%S Type = %lu\n",
  1696. PLP, ShimData->Size,
  1697. PLP, ShimData->Flags,
  1698. PLP, ShimData->Type);
  1699. if (ShimData->ModuleOffset != 0)
  1700. {
  1701. s.Buffer = (PWSTR) (((ULONG_PTR) Header) + ShimData->ModuleOffset);
  1702. s.Length = (USHORT) ShimData->ModuleLength;
  1703. s.MaximumLength = (USHORT) ShimData->ModuleLength;
  1704. }
  1705. else
  1706. {
  1707. s.Buffer = NULL;
  1708. s.Length = 0;
  1709. s.MaximumLength = 0;
  1710. }
  1711. ::FusionpDbgPrintEx(
  1712. Level,
  1713. "%S ModuleLength = %lu\n"
  1714. "%S ModuleOffset = %lu (-> %p)\n"
  1715. "%S \"%wZ\"\n",
  1716. PLP, ShimData->ModuleLength,
  1717. PLP, ShimData->ModuleOffset, s.Buffer,
  1718. PLP, &s);
  1719. if (ShimData->TypeOffset != 0)
  1720. {
  1721. s.Buffer = (PWSTR) (((ULONG_PTR) ShimData) + ShimData->TypeOffset);
  1722. s.Length = (USHORT) ShimData->TypeLength;
  1723. s.MaximumLength = (USHORT) ShimData->TypeLength;
  1724. }
  1725. else
  1726. {
  1727. s.Buffer = NULL;
  1728. s.Length = 0;
  1729. s.MaximumLength = 0;
  1730. }
  1731. ::FusionpDbgPrintEx(
  1732. Level,
  1733. "%S TypeLength = %lu\n"
  1734. "%S TypeOffset = %lu (-> %p)\n"
  1735. "%S \"%wZ\"\n",
  1736. PLP, ShimData->TypeLength,
  1737. PLP, ShimData->TypeOffset, s.Buffer,
  1738. PLP, &s);
  1739. if (ShimData->ShimVersionOffset != 0)
  1740. {
  1741. s.Buffer = (PWSTR) (((ULONG_PTR) ShimData) + ShimData->ShimVersionOffset);
  1742. s.Length = (USHORT) ShimData->ShimVersionLength;
  1743. s.MaximumLength = (USHORT) ShimData->ShimVersionLength;
  1744. }
  1745. else
  1746. {
  1747. s.Buffer = NULL;
  1748. s.Length = 0;
  1749. s.MaximumLength = 0;
  1750. }
  1751. ::FusionpDbgPrintEx(
  1752. Level,
  1753. "%S ShimVersionLength = %lu\n"
  1754. "%S ShimVersionOffset = %lu (-> %p)\n"
  1755. "%S \"%wZ\"\n",
  1756. PLP, ShimData->ShimVersionLength,
  1757. PLP, ShimData->ShimVersionOffset, s.Buffer,
  1758. PLP, &s);
  1759. }
  1760. }
  1761. else
  1762. {
  1763. rbuffBriefOutput.Win32Append(buffConfiguredClsid);
  1764. rbuffBriefOutput.Win32Append(L" ", 1);
  1765. rbuffBriefOutput.Win32Append(s.Buffer, s.Length / sizeof(WCHAR));
  1766. if (progid.Length != 0)
  1767. {
  1768. rbuffBriefOutput.Win32Append(L" progid: ", 9);
  1769. rbuffBriefOutput.Win32Append(progid.Buffer, progid.Length / sizeof(WCHAR));
  1770. }
  1771. }
  1772. }
  1773. VOID
  1774. FusionpDbgPrintStringInUntruncatedChunks(
  1775. ULONG Level,
  1776. PCWSTR String,
  1777. SIZE_T Length
  1778. )
  1779. //
  1780. // in pieces so it does not get truncated by DbgPrint (or we could use OutputDebugString, which
  1781. // does this same work)
  1782. //
  1783. {
  1784. if (!::FusionpDbgWouldPrintAtFilterLevel(Level))
  1785. return;
  1786. while (Length != 0)
  1787. {
  1788. SIZE_T ShortLength = ((Length > 128) ? 128 : Length);
  1789. CUnicodeString UnicodeString(String, ShortLength);
  1790. ::FusionpDbgPrintEx(Level, "%wZ", &UnicodeString);
  1791. Length -= ShortLength;
  1792. String += ShortLength;
  1793. }
  1794. }
  1795. VOID
  1796. FusionpDbgPrintStringInUntruncatedChunks(
  1797. ULONG Level,
  1798. const CBaseStringBuffer &rbuff
  1799. )
  1800. {
  1801. if (!::FusionpDbgWouldPrintAtFilterLevel(Level))
  1802. return;
  1803. FusionpDbgPrintStringInUntruncatedChunks(Level, rbuff, rbuff.Cch());
  1804. }
  1805. VOID
  1806. SxspDbgPrintTypeLibraryRedirection(
  1807. ULONG Level,
  1808. bool fFull,
  1809. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  1810. PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION Entry,
  1811. SIZE_T Length,
  1812. CBaseStringBuffer &rbuffPLP,
  1813. CBaseStringBuffer &rbuffBriefOutput
  1814. )
  1815. {
  1816. if (!::FusionpDbgWouldPrintAtFilterLevel(Level))
  1817. return;
  1818. PCWSTR PLP = rbuffPLP;
  1819. CSmallStringBuffer buff;
  1820. UNICODE_STRING Name = RTL_CONSTANT_STRING(L"");
  1821. UNICODE_STRING HelpDir = RTL_CONSTANT_STRING(L"");
  1822. ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION Version = { 0 };
  1823. if (!buff.Win32ResizeBuffer(4096, eDoNotPreserveBufferContents))
  1824. return;
  1825. #if 1
  1826. #define GET_STRING(ntstr, struc, struc_size, offset_field, length_field, base) \
  1827. do { if (RTL_CONTAINS_FIELD((struc), (struc_size), offset_field) \
  1828. && RTL_CONTAINS_FIELD((struc), (struc_size), length_field) \
  1829. && (struc)->offset_field != 0 \
  1830. && (struc)->length_field != 0) \
  1831. { \
  1832. (ntstr).Length = static_cast<USHORT>(struc->length_field - sizeof((ntstr).Buffer[0])); \
  1833. (ntstr).Buffer = const_cast<PWSTR>(reinterpret_cast<PCWSTR>(struc->offset_field + reinterpret_cast<PCBYTE>(base))); \
  1834. } } while(0)
  1835. GET_STRING(Name, Entry, Entry->Size, NameOffset, NameLength, Header);
  1836. GET_STRING(HelpDir, Entry, Entry->Size, HelpDirOffset, HelpDirLength, Entry);
  1837. #undef GET_STRING
  1838. #else
  1839. if (RTL_CONTAINS_FIELD(Entry, Entry->Size, NameLength)
  1840. && RTL_CONTAINS_FIELD(Entry, Entry->Size, NameOffset)
  1841. && Entry->NameOffset != 0
  1842. )
  1843. {
  1844. Name.Length = static_cast<USHORT>(Entry->NameLength);
  1845. Name.Buffer = const_cast<PWSTR>(reinterpret_cast<PCWSTR>(Entry->NameOffset + reinterpret_cast<PCBYTE>(Header)));
  1846. }
  1847. if (RTL_CONTAINS_FIELD(Entry, Entry->Size, HelpDirLength)
  1848. && RTL_CONTAINS_FIELD(Entry, Entry->Size, HelpDirOffset)
  1849. && Entry->HelpDirOffset != 0
  1850. )
  1851. {
  1852. HelpDir.Length = static_cast<USHORT>(Entry->HelpDirLength);
  1853. HelpDir.Buffer = const_cast<PWSTR>(reinterpret_cast<PCWSTR>(Entry->HelpDirOffset + reinterpret_cast<PCBYTE>(Entry)));
  1854. }
  1855. #endif
  1856. if (RTL_CONTAINS_FIELD(Entry, Entry->Size, Version))
  1857. Version = Entry->Version;
  1858. if (!buff.Win32Format(
  1859. L"%SACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION %p\n"
  1860. L"%S Size = 0x%lx\n"
  1861. L"%S Flags = 0x%lx\n"
  1862. L"%S Name = %wZ (offset 0x%lx + %p = %p)\n"
  1863. L"%S HelpDir = %wZ (offset 0x%lx + %p = %p)\n"
  1864. L"%S Version = 0x%lx.%lx\n",
  1865. PLP, Entry,
  1866. PLP, static_cast<ULONG>(Entry->Size),
  1867. PLP, static_cast<ULONG>(Entry->Flags),
  1868. PLP, &Name, static_cast<ULONG>(Entry->NameOffset), static_cast<PCVOID>(Header), static_cast<PCVOID>(Name.Buffer),
  1869. PLP, &HelpDir, static_cast<ULONG>(Entry->HelpDirOffset), static_cast<PCVOID>(Entry), static_cast<PCVOID>(HelpDir.Buffer),
  1870. PLP, static_cast<ULONG>(Version.Major), static_cast<ULONG>(Version.Minor)
  1871. ))
  1872. return;
  1873. ::FusionpDbgPrintStringInUntruncatedChunks(Level, buff);
  1874. }
  1875. VOID
  1876. SxspDbgPrintComProgIdRedirection(
  1877. ULONG Level,
  1878. bool fFull,
  1879. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header,
  1880. PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION Entry,
  1881. SIZE_T Length,
  1882. CBaseStringBuffer &rbuffPLP,
  1883. CBaseStringBuffer &rbuffBriefOutput
  1884. )
  1885. {
  1886. PCWSTR PLP = rbuffPLP;
  1887. // CSmallStringBuffer buffFlags;
  1888. CSmallStringBuffer buffClsid;
  1889. const GUID *pcguid = NULL;
  1890. if (Entry->ConfiguredClsidOffset != 0)
  1891. {
  1892. pcguid = (const GUID *) (((ULONG_PTR) Header) + Entry->ConfiguredClsidOffset);
  1893. ::SxspFormatGUID(*pcguid, buffClsid);
  1894. }
  1895. if (fFull)
  1896. {
  1897. ::FusionpDbgPrintEx(
  1898. Level,
  1899. "%SACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION %p\n"
  1900. "%S Size = %lu (0x%lx)\n"
  1901. "%S Flags = 0x%08lx\n"
  1902. "%S ConfiguredClsidOffset = %lu (-> %p)\n"
  1903. "%S %S\n",
  1904. PLP, Entry,
  1905. PLP, Entry->Size, Entry->Size,
  1906. PLP, Entry->Flags,
  1907. PLP, Entry->ConfiguredClsidOffset, pcguid,
  1908. PLP, static_cast<PCWSTR>(buffClsid));
  1909. }
  1910. else
  1911. {
  1912. rbuffBriefOutput.Win32Append(buffClsid);
  1913. }
  1914. }
  1915. VOID
  1916. SxspDbgPrintComInterfaceRedirection(
  1917. ULONG Level,
  1918. bool fFull,
  1919. PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header,
  1920. PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Entry,
  1921. SIZE_T Length,
  1922. CBaseStringBuffer &rbuffPLP,
  1923. CBaseStringBuffer &rbuffBriefOutput
  1924. )
  1925. {
  1926. PCWSTR PLP = rbuffPLP;
  1927. CSmallStringBuffer buffProxyStubClsid32;
  1928. CSmallStringBuffer buffBaseInterface;
  1929. CSmallStringBuffer buffFlags;
  1930. CSmallStringBuffer buffTypeLibraryId;
  1931. UNICODE_STRING s;
  1932. static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgComInterfaceFlags[] =
  1933. {
  1934. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_NUM_METHODS_VALID, "NumMethods Valid")
  1935. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_BASE_INTERFACE_VALID, "BaseInterface Valid")
  1936. };
  1937. if (PLP == NULL)
  1938. PLP = L"";
  1939. memset(&s, 0, sizeof(s));
  1940. ::SxspFormatGUID(Entry->ProxyStubClsid32, buffProxyStubClsid32);
  1941. ::SxspFormatGUID(Entry->BaseInterface, buffBaseInterface);
  1942. ::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgComInterfaceFlags), s_rgComInterfaceFlags, buffFlags);
  1943. if (Entry->TypeLibraryId == GUID_NULL)
  1944. buffTypeLibraryId.Win32Assign(L"<none>", 6);
  1945. else
  1946. ::SxspFormatGUID(Entry->TypeLibraryId, buffTypeLibraryId);
  1947. if (Entry->NameOffset != 0)
  1948. {
  1949. s.Length = static_cast<USHORT>(Entry->NameLength);
  1950. s.MaximumLength = s.Length;
  1951. s.Buffer = (PWSTR) (((ULONG_PTR) Entry) + Entry->NameOffset);
  1952. }
  1953. if (fFull)
  1954. {
  1955. ::FusionpDbgPrintEx(
  1956. Level,
  1957. "%SACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION %p\n"
  1958. "%S Size = %lu\n"
  1959. "%S Flags = 0x%08lx (%S)\n",
  1960. PLP, Entry,
  1961. PLP, Entry->Size,
  1962. PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags));
  1963. ::FusionpDbgPrintEx(
  1964. Level,
  1965. "%S ProxyStubClsid32 = %S\n"
  1966. "%S NumMethods = %lu\n"
  1967. "%S TypeLibraryId = %S\n",
  1968. PLP, static_cast<PCWSTR>(buffProxyStubClsid32),
  1969. PLP, Entry->NumMethods,
  1970. PLP, static_cast<PCWSTR>(buffTypeLibraryId));
  1971. ::FusionpDbgPrintEx(
  1972. Level,
  1973. "%S BaseInterface = %S\n"
  1974. "%S NameLength = %lu (%u chars)\n"
  1975. "%S NameOffset = %lu (-> %p)\n",
  1976. PLP, static_cast<PCWSTR>(buffBaseInterface),
  1977. PLP, Entry->NameLength, (Entry->NameLength / sizeof(WCHAR)),
  1978. PLP, Entry->NameOffset, s.Buffer);
  1979. ::FusionpDbgPrintEx(
  1980. Level,
  1981. "%S \"%wZ\"\n",
  1982. PLP, &s);
  1983. }
  1984. else
  1985. {
  1986. rbuffBriefOutput.Win32Append(buffProxyStubClsid32);
  1987. rbuffBriefOutput.Win32Append(L" ", 1);
  1988. rbuffBriefOutput.Win32Append(s.Buffer, s.Length / sizeof(WCHAR));
  1989. }
  1990. }
  1991. VOID
  1992. SxspDbgPrintInstallSourceInfo(
  1993. ULONG Level,
  1994. bool fFull,
  1995. PSXS_INSTALL_SOURCE_INFO Info,
  1996. CBaseStringBuffer &rbuffPLP
  1997. )
  1998. {
  1999. PCWSTR PLP = rbuffPLP;
  2000. if ( !PLP ) PLP = L"SXS.DLL:";
  2001. if ( !Info )
  2002. {
  2003. ::FusionpDbgPrintEx( Level, "%S InstallationInfo is null!\n", PLP );
  2004. }
  2005. else
  2006. {
  2007. DWORD dwFlags = Info->dwFlags;
  2008. ::FusionpDbgPrintEx(
  2009. Level,
  2010. "%S InstallationInfo at 0x%08x - size = %d\n",
  2011. "%S Flag set: %s catalog, %s codebase, %s prompt, %s in setup mode\n"
  2012. "%S Codebase Name: %ls\n"
  2013. "%S Prompt: %ls\n",
  2014. PLP, Info, Info->cbSize,
  2015. PLP,
  2016. dwFlags & SXSINSTALLSOURCE_HAS_CATALOG ? "has" : "no",
  2017. dwFlags & SXSINSTALLSOURCE_HAS_CODEBASE ? "has" : "no",
  2018. dwFlags & SXSINSTALLSOURCE_HAS_PROMPT ? "has" : "no",
  2019. dwFlags & SXSINSTALLSOURCE_INSTALLING_SETUP ? "is" : "not",
  2020. PLP, Info->pcwszCodebaseName,
  2021. PLP, Info->pcwszPromptOnRefresh);
  2022. }
  2023. }