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.

2302 lines
74 KiB

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