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.

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