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.

2292 lines
74 KiB

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