|
|
/*
Copyright (c) Microsoft Corporation */ #include "stdinc.h"
#include <windows.h>
#include "sxsp.h"
#include <stdio.h>
#include "fusionhandle.h"
#include "sxsapi.h"
#include <limits.h>
typedef const void * PCVOID;
VOID SxspDbgPrintInstallSourceInfo( ULONG Level, PSXS_INSTALL_SOURCE_INFO Info, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataTocEntry( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_TOC_ENTRY Entry, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataTocSections( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data, const GUID *ExtensionGuid, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataTocSection( ULONG Level, bool fFull, PVOID Section, SIZE_T Length, const GUID *ExtensionGuid, ULONG SectionId, PCSTR SectionName, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataExtendedTocHeader( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataExtendedTocEntry( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataExtendedTocSections( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataExtendedTocEntrySections( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Data, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextStringSection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Data, const GUID *ExtensionGuid, ULONG SectionId, PCSTR SectionName, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextGuidSection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Data, const GUID *ExtensionGuid, ULONG SectionId, PCSTR SectionName, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextBinarySection( ULONG Level, bool fFull, PVOID Data, SIZE_T Length, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintAssemblyInformation( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintDllRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintWindowClassRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintCLRSurrogateTable( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintComServerRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintComProgIdRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintTypeLibraryRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintComInterfaceRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput );
VOID SxspDbgPrintActivationContextDataAssemblyRoster( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER Data, CBaseStringBuffer &rbuffPLP );
VOID SxspDbgPrintActivationContextDataTocHeader( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data, CBaseStringBuffer &rbuffPLP );
VOID SxsppDbgPrintActivationContextData( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Data, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP;
//
// ISSUE: jonwis 3/7/2002
// - Parameter checking of Data is noticably absent.
// - Lots of unchecked pointer math here. Not so bad, since this will only
// crash user-mode code, and will only allow reads of this process'
// memory space, but it's correctness. Mitgated by this being debugging-
// related code only.
//
if (fFull) { ::FusionpDbgPrintEx( Level, "%SActivation Context Data %p\n" "%S Magic = 0x%08lx (%lu)\n" "%S HeaderSize = %d (0x%lx)\n" "%S FormatVersion = %d\n", PLP, Data, PLP, Data->Magic, Data->Magic, PLP, Data->HeaderSize, Data->HeaderSize, PLP, Data->FormatVersion);
::FusionpDbgPrintEx( Level, "%S TotalSize = %d (0x%lx)\n" "%S DefaultTocOffset = %d (0x%lx) (-> %p)\n" "%S ExtendedTocOffset = %d (0x%lx) (-> %p)\n", PLP, Data->TotalSize, Data->TotalSize, PLP, Data->DefaultTocOffset, Data->DefaultTocOffset, (Data->DefaultTocOffset == 0) ? NULL : (PVOID) (((ULONG_PTR) Data) + Data->DefaultTocOffset), PLP, Data->ExtendedTocOffset, Data->ExtendedTocOffset, (Data->ExtendedTocOffset == 0) ? NULL : (PVOID) (((ULONG_PTR) Data) + Data->ExtendedTocOffset));
::FusionpDbgPrintEx( Level, "%S AssemblyRosterOffset = %d (0x%lx) (-> %p)\n", PLP, Data->AssemblyRosterOffset, Data->AssemblyRosterOffset, (Data->AssemblyRosterOffset == 0) ? NULL : (PVOID) (((ULONG_PTR) Data) + Data->AssemblyRosterOffset)); } else { // !fFull
::FusionpDbgPrintEx( Level, "%SActivation Context Data %p (brief output)\n", PLP, Data); }
//
// ISSUE: jonwis 3/7/2002
// - Bad bad BAD form. Use .Win32AppendFill(L' ', 3) instead.
//
rbuffPLP.Win32Append(L" ", 3);
if (Data->AssemblyRosterOffset != 0) ::SxspDbgPrintActivationContextDataAssemblyRoster( Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER) (((ULONG_PTR) Data) + Data->AssemblyRosterOffset), rbuffPLP);
if (Data->DefaultTocOffset != 0) ::SxspDbgPrintActivationContextDataTocHeader( Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Data) + Data->DefaultTocOffset), rbuffPLP);
if (Data->ExtendedTocOffset != 0) ::SxspDbgPrintActivationContextDataExtendedTocHeader( Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER) (((ULONG_PTR) Data) + Data->ExtendedTocOffset), rbuffPLP);
// That's it for the header information. Now start dumping the sections...
if (Data->DefaultTocOffset != 0) ::SxspDbgPrintActivationContextDataTocSections( Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Data) + Data->DefaultTocOffset), NULL, rbuffPLP);
if (Data->ExtendedTocOffset != 0) ::SxspDbgPrintActivationContextDataExtendedTocSections( Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER) (((ULONG_PTR) Data) + Data->ExtendedTocOffset), rbuffPLP); }
VOID SxspDbgPrintActivationContextData( ULONG Level, PCACTIVATION_CONTEXT_DATA Data, CBaseStringBuffer &rbuffPLP ) { if (::FusionpDbgWouldPrintAtFilterLevel(Level)) { ::SxsppDbgPrintActivationContextData(Level, ::FusionpDbgWouldPrintAtFilterLevel(FUSION_DBG_LEVEL_FULLACTCTX), Data, rbuffPLP); } }
VOID SxspDbgPrintActivationContextDataAssemblyRoster( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER Data, CBaseStringBuffer &rbuffPLP ) { ULONG i; PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY Entry; CSmallStringBuffer buffFlags; PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION AssemblyInformation = NULL;
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgAssemblyRosterEntryFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_INVALID, "Invalid") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_ROOT, "Root") };
PCWSTR PLP = rbuffPLP;
if (fFull) ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER %p\n" "%S HeaderSize = %lu (0x%lx)\n" "%S EntryCount = %lu (0x%lx)\n" "%S FirstEntryOffset = %ld (0x%lx)\n", PLP, Data, PLP, Data->HeaderSize, Data->HeaderSize, PLP, Data->EntryCount, Data->EntryCount, PLP, Data->FirstEntryOffset, Data->FirstEntryOffset); else ::FusionpDbgPrintEx( Level, "%SAssembly Roster (%lu assemblies)\n" "%SIndex | Assembly Name (Flags)\n", PLP, Data->EntryCount - 1, PLP);
for (i=0; i<Data->EntryCount; i++) { Entry = ((PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset)) + i;
UNICODE_STRING s;
if (Entry->AssemblyNameOffset != 0) { s.Length = (USHORT) Entry->AssemblyNameLength; s.MaximumLength = s.Length; s.Buffer = (PWSTR) (((ULONG_PTR) Base) + Entry->AssemblyNameOffset); } else { s.Length = 0; s.MaximumLength = 0; s.Buffer = NULL; }
::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgAssemblyRosterEntryFlags), s_rgAssemblyRosterEntryFlags, buffFlags);
if (Entry->AssemblyInformationOffset != NULL) AssemblyInformation = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION) (((ULONG_PTR) Base) + Entry->AssemblyInformationOffset); else AssemblyInformation = NULL;
if (fFull) { ::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY %p [#%d]\n" "%S Flags = 0x%08lx (%S)\n" "%S PseudoKey = %lu\n", PLP, Entry, i, PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags), PLP, Entry->PseudoKey);
::FusionpDbgPrintEx( Level, "%S AssemblyNameOffset = %lu (0x%lx) \"%wZ\"\n" "%S AssemblyNameLength = %lu (0x%lx) \n" "%S AssemblyInformationOffset = %lu (0x%lx) (-> %p)\n" "%S AssemblyInformationLength = %lu (0x%lx)\n", PLP, Entry->AssemblyNameOffset, Entry->AssemblyNameOffset, &s, PLP, Entry->AssemblyNameLength, Entry->AssemblyNameLength, PLP, Entry->AssemblyInformationOffset, Entry->AssemblyInformationOffset, AssemblyInformation, PLP, Entry->AssemblyInformationLength, Entry->AssemblyInformationLength); } else { if (i != 0) ::FusionpDbgPrintEx( Level, "%S%5lu | %wZ (%S)\n", PLP, i, &s, static_cast<PCWSTR>(buffFlags)); } } }
VOID SxspDbgPrintActivationContextDataTocHeader( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffFlags; ULONG i; PCACTIVATION_CONTEXT_DATA_TOC_ENTRY FirstEntry = NULL;
if (PLP == NULL) PLP = L"";
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_TOC_HEADER_DENSE, "Dense") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_TOC_HEADER_INORDER, "Inorder") };
::FusionpFormatFlags(Data->Flags, fFull, NUMBER_OF(s_rgFlags), s_rgFlags, buffFlags);
if (Data->FirstEntryOffset != 0) FirstEntry = (PCACTIVATION_CONTEXT_DATA_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset);
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_TOC_HEADER %p\n" "%S HeaderSize = %d (0x%lx)\n" "%S EntryCount = %d\n" "%S FirstEntryOffset = %d (0x%lx) (-> %p)\n" "%S Flags = 0x%08lx (%S)\n", PLP, Data, PLP, Data->HeaderSize, Data->HeaderSize, PLP, Data->EntryCount, PLP, Data->FirstEntryOffset, Data->FirstEntryOffset, FirstEntry, PLP, Data->Flags, static_cast<PCWSTR>(buffFlags)); }
if (FirstEntry != NULL) { SIZE_T cchSave = rbuffPLP.Cch();
rbuffPLP.Win32Append(L" ", 3);
for (i=0; i<Data->EntryCount; i++) ::SxspDbgPrintActivationContextDataTocEntry(Level, fFull, Base, &FirstEntry[i], rbuffPLP);
rbuffPLP.Left(cchSave); }
}
VOID SxspDbgPrintActivationContextDataTocSections( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_TOC_HEADER Data, const GUID *ExtensionGuid, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; SIZE_T cchPLP = rbuffPLP.Cch();
if (Data->FirstEntryOffset != 0) { PCACTIVATION_CONTEXT_DATA_TOC_ENTRY Entries = (PCACTIVATION_CONTEXT_DATA_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset); ULONG i;
for (i=0; i<Data->EntryCount; i++) { if (Entries[i].Offset != 0) { //
// ISSUE: jonwis 3/7/2002
// - Why build up the buffSectionId string if we never output it?
//
PVOID Section = (PVOID) (((ULONG_PTR) Base) + Entries[i].Offset); CSmallStringBuffer buffSectionId; PCSTR pszSectionName = "<untranslatable>";
if (ExtensionGuid != NULL) { //
// ISSUE: jonwis 3/7/2002
// - Stack-based strings are evil. Use .Win32ResizeBuffer along with
// .Win32FormatAppend to get rid of this:
//
// buffSectionId.Win32ResizeBuffer(buffSectionId.Cch() + 1 + (sizeof(LONG)*CHAR_BIT));
// buffSectionId.Win32FormatAppend(L".%u", Entries[i].Id);
//
WCHAR rgchBuff[sizeof(LONG)*CHAR_BIT];
::SxspFormatGUID(*ExtensionGuid, buffSectionId); buffSectionId.Win32Append(L".", 1); swprintf(rgchBuff, L"%u", Entries[i].Id); buffSectionId.Win32Append(rgchBuff, ::wcslen(rgchBuff)); } else { WCHAR rgchBuff[255];
#define MAP_ENTRY(_x, _y) case _x: if (fFull) pszSectionName = #_x; else pszSectionName = _y; break;
switch (Entries[i].Id) { MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "Assembly Information") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "DLL Redirection") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "Window Class Redirection") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, "COM Server Redirection") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, "COM Interface Redirection") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, "COM Type Library Redirection") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, "COM ProgId Redirection") MAP_ENTRY(ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE, "Win32 Global Object Name Redirection") }
//
// ISSUE: jonwis 3/7/2002
// - See above. Use .Win32ResizeBuffer and .Win32FormatAppend
//
if (pszSectionName != NULL) swprintf(rgchBuff, L"%u (%S)", Entries[i].Id, pszSectionName); else swprintf(rgchBuff, L"%u", Entries[i].Id);
buffSectionId.Win32Append(rgchBuff, ::wcslen(rgchBuff)); }
::SxspDbgPrintActivationContextDataTocSection( Level, fFull, Section, Entries[i].Length, ExtensionGuid, Entries[i].Id, pszSectionName, rbuffPLP); } } } }
VOID SxspDbgPrintActivationContextDataTocSection( ULONG Level, bool fFull, PVOID Section, SIZE_T Length, const GUID *ExtensionGuid, ULONG SectionId, PCSTR SectionName, CBaseStringBuffer &rbuffPLP ) { if (Length > sizeof(ULONG)) { switch (*(ULONG *) Section) { case ACTIVATION_CONTEXT_STRING_SECTION_MAGIC: ::SxspDbgPrintActivationContextStringSection( Level, fFull, (PCACTIVATION_CONTEXT_STRING_SECTION_HEADER) Section, ExtensionGuid, SectionId, SectionName, rbuffPLP); break; case ACTIVATION_CONTEXT_GUID_SECTION_MAGIC: ::SxspDbgPrintActivationContextGuidSection( Level, fFull, (PCACTIVATION_CONTEXT_GUID_SECTION_HEADER) Section, ExtensionGuid, SectionId, SectionName, rbuffPLP); break; default: break; } } else if ( SectionId != 0 ) { ::SxspDbgPrintActivationContextBinarySection( Level, fFull, Section, Length, rbuffPLP); } }
const STRING * SxspDbgSectionIdToNtString( ULONG Id ) { switch (Id) { #define ENTRY(id, s) id : { const static STRING t = RTL_CONSTANT_STRING(s); return &t; }
ENTRY(default, "<No name associated with id>"); ENTRY(case ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "Assembly Information"); ENTRY(case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "Dll Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "Window Class Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, "COM Server Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, "COM Interface Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, "COM Type Library Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, "COM ProgId Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE, "Win32 Global Object Name Redirection"); ENTRY(case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES, "CLR Surrogate Type Table"); #undef ENTRY
} }
PCSTR SxspDbgSectionIdToString( ULONG Id ) { return SxspDbgSectionIdToNtString(Id)->Buffer; }
VOID SxspDbgPrintActivationContextDataTocEntry( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_TOC_ENTRY Entry, CBaseStringBuffer &rbuffPLP ) { PVOID SectionData = NULL; PCSTR pszFormat = "<untranslated format>"; PCWSTR PLP = rbuffPLP;
if (!fFull) return;
if (PLP == NULL) PLP = L"";
if (Entry->Offset != 0) SectionData = (PVOID) (((ULONG_PTR) Base) + Entry->Offset);
#define MAP_FORMAT(_x, _sn) \
case _x: \ if (fFull) \ pszFormat = #_x; \ else \ pszFormat = _sn; \ break;
switch (Entry->Format) { default: break; MAP_FORMAT(ACTIVATION_CONTEXT_SECTION_FORMAT_UNKNOWN, "user defined"); MAP_FORMAT(ACTIVATION_CONTEXT_SECTION_FORMAT_STRING_TABLE, "string table"); MAP_FORMAT(ACTIVATION_CONTEXT_SECTION_FORMAT_GUID_TABLE, "guid table"); } #undef MAP_FORMAT
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_TOC_ENTRY %p\n" "%S Id = %Z (%u)\n" "%S Offset = %lu (0x%lx) (-> %p)\n" "%S Length = %lu (0x%lx)\n" "%S Format = %lu (%s)\n", PLP, Entry, PLP, SxspDbgSectionIdToNtString(Entry->Id), Entry->Id, PLP, Entry->Offset, Entry->Offset, SectionData, PLP, Entry->Length, Entry->Length, PLP, Entry->Format, pszFormat); } else { ::FusionpDbgPrintEx( Level, "%S%7lu | %Z (%s)\n", PLP, Entry->Id, SxspDbgSectionIdToNtString(Entry->Id), pszFormat); } }
VOID SxspDbgPrintActivationContextDataExtendedTocHeader( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffNewPrefix; PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry = NULL; ULONG i;
if (PLP == NULL) PLP = L"";
//
// ISSUE: jonwis 3/7/2002
// - Again , this is really -really- poor practice. Why make our own prefix when
// we can abuse the prefix buffer (stash the prefix depth, work, reset depth)
// - And, the .Win32Append(L"", 3) pattern strikes again.
//
if (Data->FirstEntryOffset != NULL) { buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP)); buffNewPrefix.Win32Append(L" ", 3); Entry = (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset); }
::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER %p\n" "%S HeaderSize = %d\n" "%S EntryCount = %d\n" "%S FirstEntryOffset = %d (->%p)\n" "%S Flags = 0x%08lx\n", PLP, Data, PLP, Data->HeaderSize, PLP, Data->EntryCount, PLP, Data->FirstEntryOffset, Entry, PLP, Data->Flags);
if (Entry != NULL) { for (i=0; i<Data->EntryCount; i++) ::SxspDbgPrintActivationContextDataExtendedTocEntry( Level, fFull, Base, &Entry[i], buffNewPrefix); } }
VOID SxspDbgPrintActivationContextDataExtendedTocEntry( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffNewPrefix; CSmallStringBuffer buffFormattedGUID; PCACTIVATION_CONTEXT_DATA_TOC_HEADER Toc = NULL;
if (PLP == NULL) PLP = L"";
if (Entry->TocOffset != 0) { buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP)); buffNewPrefix.Win32Append(L" ", 3); Toc = (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Base) + Entry->TocOffset); }
::SxspFormatGUID(Entry->ExtensionGuid, buffFormattedGUID);
::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY %p\n" "%S ExtensionGuid = %S\n" "%S TocOffset = %d (-> %p)\n" "%S Length = %d\n", PLP, Entry, PLP, static_cast<PCWSTR>(buffFormattedGUID), PLP, Entry->Length);
if (Toc != NULL) ::SxspDbgPrintActivationContextDataTocHeader(Level, fFull, Base, Toc, buffNewPrefix); }
VOID SxspDbgPrintActivationContextDataExtendedTocSections( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER Data, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffNewPrefix; PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry = NULL; ULONG i;
if (PLP == NULL) PLP = L"";
if (Data->FirstEntryOffset != NULL) { buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP)); buffNewPrefix.Win32Append(L" ", 3); Entry = (PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY) (((ULONG_PTR) Base) + Data->FirstEntryOffset); }
if (Entry != NULL) { for (i=0; i<Data->EntryCount; i++) ::SxspDbgPrintActivationContextDataExtendedTocEntrySections( Level, fFull, Base, &Entry[i], buffNewPrefix); } }
VOID SxspDbgPrintActivationContextDataExtendedTocEntrySections( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_DATA Base, PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY Entry, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffNewPrefix; PCACTIVATION_CONTEXT_DATA_TOC_HEADER Toc = NULL;
if (PLP == NULL) PLP = L"";
if (Entry->TocOffset != 0) { //
// ISSUE: jonwis 3/7/2002
// - Sigh, again, why do this? Why not assign from rbuffPLP, or abuse rbuffPLP?
//
buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP)); buffNewPrefix.Win32Append(L" ", 3); Toc = (PCACTIVATION_CONTEXT_DATA_TOC_HEADER) (((ULONG_PTR) Base) + Entry->TocOffset); }
if (Toc != NULL) { CSmallStringBuffer buffFormattedGUID;
::SxspFormatGUID(Entry->ExtensionGuid, buffFormattedGUID); ::FusionpDbgPrintEx( Level, "%SSections for extension GUID %S (Extended TOC entry %p)\n", PLP, static_cast<PCWSTR>(buffFormattedGUID), Entry);
::SxspDbgPrintActivationContextDataTocSections(Level, fFull, Base, Toc, &Entry->ExtensionGuid, buffNewPrefix); } }
VOID SxspDbgPrintActivationContextBinarySection( ULONG Level, bool fFull, PVOID Data, SIZE_T Length, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; if (PLP == NULL) PLP = L"";
::FusionpDbgPrintEx( Level, "%SBinary section %p (%d bytes)\n", PLP, Data, Length);
if (Length != 0) { CSmallStringBuffer buffNewPrefix;
buffNewPrefix.Win32Assign(PLP, ::wcslen(PLP)); buffNewPrefix.Win32Append(L" ", 3); ::FusionpDbgPrintBlob(Level, Data, Length, buffNewPrefix); } }
VOID SxspDbgPrintActivationContextStringSection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Data, const GUID *ExtensionGuid, ULONG SectionId, PCSTR SectionName, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; SIZE_T cchPLP = rbuffPLP.Cch(); CSmallStringBuffer buffBriefOutput; CSmallStringBuffer buffFlags; SIZE_T cchBriefOutputKey = 3;
PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY ElementList = NULL; PCACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE SearchStructure = NULL; PVOID UserData = NULL;
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgStringSectionFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_STRING_SECTION_CASE_INSENSITIVE, "Case Insensitive") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_STRING_SECTION_ENTRIES_IN_PSEUDOKEY_ORDER, "In PseudoKey Order") };
if (PLP == NULL) PLP = L"";
if (Data->ElementListOffset != 0) ElementList = (PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY) (((ULONG_PTR) Data) + Data->ElementListOffset);
if (Data->SearchStructureOffset != 0) SearchStructure = (PCACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE) (((ULONG_PTR) Data) + Data->SearchStructureOffset);
if (Data->UserDataOffset != 0) UserData = (PVOID) (((ULONG_PTR) Data) + Data->UserDataOffset);
::FusionpFormatFlags(Data->Flags, fFull, NUMBER_OF(s_rgStringSectionFlags), s_rgStringSectionFlags, buffFlags);
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_STRING_SECTION_HEADER %p\n" "%S Magic = 0x%08lx\n" "%S HeaderSize = %lu (0x%lx)\n" "%S FormatVersion = %lu\n" "%S DataFormatVersion = %u\n" "%S Flags = 0x%08lx (%S)\n", PLP, Data, PLP, Data->Magic, PLP, Data->HeaderSize, Data->HeaderSize, PLP, Data->FormatVersion, PLP, Data->DataFormatVersion, PLP, Data->Flags, static_cast<PCWSTR>(buffFlags));
::FusionpDbgPrintEx( Level, "%S ElementCount = %lu\n" "%S ElementListOffset = %lu (0x%lx) (-> %p)\n" "%S HashAlgorithm = %lu\n" "%S SearchStructureOffset = %lu (0x%lx) (-> %p)\n" "%S UserDataOffset = %lu (0x%lx) (-> %p)\n" "%S UserDataSize = %lu (0x%lx)\n", PLP, Data->ElementCount, PLP, Data->ElementListOffset, Data->ElementListOffset, ElementList, PLP, Data->HashAlgorithm, PLP, Data->SearchStructureOffset, Data->SearchStructureOffset, SearchStructure, PLP, Data->UserDataOffset, Data->UserDataOffset, UserData, PLP, Data->UserDataSize, Data->UserDataSize);
if (UserData != NULL) { ::FusionpDbgPrintEx( Level, "%S User data at %p (%d bytes)\n", PLP, UserData, Data->UserDataSize);
rbuffPLP.Win32Append(L" ", 3); FusionpDbgPrintBlob(Level, UserData, Data->UserDataSize, rbuffPLP); rbuffPLP.Left(cchPLP); PLP = rbuffPLP; } } else { // let's figure out the brief output key size
cchBriefOutputKey = 3;
if (ElementList != NULL) { ULONG i;
for (i=0; i<Data->ElementCount; i++) { SIZE_T cch = ElementList[i].KeyLength / sizeof(WCHAR);
if (cch > cchBriefOutputKey) cchBriefOutputKey = cch; } }
if (cchBriefOutputKey > 64) cchBriefOutputKey = 64;
// Abuse the brief output buffer temporarily...
buffBriefOutput.Win32Assign(L"Key................................................................", // 64 dots
cchBriefOutputKey);
::FusionpDbgPrintEx( Level, "%S%s string section (%lu entr%s; Flags: %S)\n" "%S %S | Value\n", PLP, SectionName, Data->ElementCount, Data->ElementCount == 1 ? "y" : "ies", static_cast<PCWSTR>(buffFlags), PLP, static_cast<PCWSTR>(buffBriefOutput)); }
if (fFull && (SearchStructure != NULL)) { PCACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET BucketTable = NULL;
if (SearchStructure->BucketTableOffset != 0) BucketTable = (PCACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET) (((ULONG_PTR) Data) + SearchStructure->BucketTableOffset);
::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE %p\n" "%S BucketTableEntryCount = %u\n" "%S BucketTableOffset = %d (-> %p)\n", PLP, SearchStructure, PLP, SearchStructure->BucketTableEntryCount, PLP, SearchStructure->BucketTableOffset, BucketTable);
if (BucketTable != NULL) { ULONG i;
for (i=0; i<SearchStructure->BucketTableEntryCount; i++) { PLONG Entries = NULL;
if (BucketTable[i].ChainOffset != 0) Entries = (PLONG) (((ULONG_PTR) Data) + BucketTable[i].ChainOffset);
::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET %p\n" "%S ChainCount = %u\n" "%S ChainOffset = %d (-> %p)\n", PLP, &BucketTable[i], PLP, BucketTable[i].ChainCount, PLP, BucketTable[i].ChainOffset, Entries);
if (Entries != NULL) { ULONG j;
for (j=0; j<BucketTable[i].ChainCount; j++) { PVOID Entry = NULL;
if (Entries[j] != 0) Entry = (PVOID) (((ULONG_PTR) Data) + Entries[j]);
::FusionpDbgPrintEx( Level, "%S Chain[%d] = %d (-> %p)\n", PLP, j, Entries[j], Entry); } } } } }
if (ElementList != NULL) { ULONG i;
for (i=0; i<Data->ElementCount; i++) { UNICODE_STRING s; PVOID EntryData = NULL;
s.Length = static_cast<USHORT>(ElementList[i].KeyLength); s.MaximumLength = s.Length; s.Buffer = (PWSTR) (((ULONG_PTR) Data) + ElementList[i].KeyOffset);
if (ElementList[i].Offset != 0) EntryData = (PVOID) (((ULONG_PTR) Data) + ElementList[i].Offset);
if (fFull) { ::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_STRING_SECTION_ENTRY #%d - %p\n" "%S AssemblyRosterIndex = %u\n" "%S PseudoKey = %u\n", PLP, i, &ElementList[i], PLP, ElementList[i].AssemblyRosterIndex, PLP, ElementList[i].PseudoKey);
::FusionpDbgPrintEx( Level, "%S String = \"%wZ\"\n" "%S Offset = %d (-> %p)\n" "%S Length = %u\n", PLP, &s, PLP, ElementList[i].Offset, EntryData, PLP, ElementList[i].Length); } else { // Abuse the flags buffer so we can truncate the name as necessary...
SIZE_T cchKey = s.Length / sizeof(WCHAR); PCWSTR pszKey = s.Buffer;
if (cchKey > cchBriefOutputKey) { pszKey += (cchKey - cchBriefOutputKey); cchKey = cchBriefOutputKey; }
buffFlags.Win32AssignFill(L' ', (cchBriefOutputKey - cchKey)); buffFlags.Win32Append(pszKey, cchKey);
buffBriefOutput.Win32ResizeBuffer(cchPLP + 3 + cchBriefOutputKey + 4, eDoNotPreserveBufferContents);
buffBriefOutput.Win32Format( L"%s %s | ", PLP, static_cast<PCWSTR>(buffFlags)); }
if (EntryData != NULL) {
if (ExtensionGuid == NULL) { rbuffPLP.Win32Append(L" ", 6);
switch (SectionId) { default: if (fFull) ::FusionpDbgPrintBlob(Level, EntryData, ElementList[i].Length, rbuffPLP); else buffBriefOutput.Win32Append( L"<untranslatable value>", 22); break;
case ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION: ::SxspDbgPrintAssemblyInformation(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break;
case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION: ::SxspDbgPrintDllRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break;
case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION: ::SxspDbgPrintWindowClassRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break;
case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION: ::SxspDbgPrintComProgIdRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break; }
rbuffPLP.Left(cchPLP); PLP = rbuffPLP; } }
if (!fFull) ::FusionpDbgPrintEx(Level, "%S\n", static_cast<PCWSTR>(buffBriefOutput)); } } }
VOID SxspDbgPrintActivationContextGuidSection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Data, const GUID *ExtensionGuid, ULONG SectionId, PCSTR SectionName, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; SIZE_T cchPLP = rbuffPLP.Cch(); CSmallStringBuffer buffFlags; CSmallStringBuffer buffBriefOutput;
PCACTIVATION_CONTEXT_GUID_SECTION_ENTRY ElementList = NULL; PCACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE SearchStructure = NULL; PVOID UserData = NULL;
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgGuidSectionFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_GUID_SECTION_ENTRIES_IN_ORDER, "Inorder") };
if (PLP == NULL) PLP = L"";
if (Data->ElementListOffset != 0) ElementList = (PCACTIVATION_CONTEXT_GUID_SECTION_ENTRY) (((ULONG_PTR) Data) + Data->ElementListOffset);
if (Data->SearchStructureOffset != 0) SearchStructure = (PCACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE) (((ULONG_PTR) Data) + Data->SearchStructureOffset);
if (Data->UserDataOffset != 0) UserData = (PVOID) (((ULONG_PTR) Data) + Data->UserDataOffset);
::FusionpFormatFlags(Data->Flags, fFull, NUMBER_OF(s_rgGuidSectionFlags), s_rgGuidSectionFlags, buffFlags);
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_GUID_SECTION_HEADER %p\n" "%S Magic = 0x%08lx\n" "%S HeaderSize = %u\n" "%S FormatVersion = %u\n" "%S DataFormatVersion = %u\n" "%S Flags = 0x%08lx (%S)\n", PLP, Data, PLP, Data->Magic, PLP, Data->HeaderSize, PLP, Data->FormatVersion, PLP, Data->DataFormatVersion, PLP, Data->Flags, static_cast<PCWSTR>(buffFlags));
::FusionpDbgPrintEx( Level, "%S ElementCount = %u\n" "%S ElementListOffset = %d (-> %p)\n" "%S SearchStructureOffset = %d (-> %p)\n" "%S UserDataOffset = %d (-> %p)\n" "%S UserDataSize = %u\n", PLP, Data->ElementCount, PLP, Data->ElementListOffset, ElementList, PLP, Data->SearchStructureOffset, SearchStructure, PLP, Data->UserDataOffset, UserData, PLP, Data->UserDataSize);
if (UserData != NULL) { ::FusionpDbgPrintEx( Level, "%S User data at %p (%d bytes)\n", PLP, UserData, Data->UserDataSize);
rbuffPLP.Win32Append(L" ", 3); FusionpDbgPrintBlob(Level, UserData, Data->UserDataSize, rbuffPLP); rbuffPLP.Left(cchPLP); PLP = rbuffPLP; } } else { ::FusionpDbgPrintEx( Level, "%S%s guid section (%lu entr%s; Flags: %S)\n" "%S Key................................... | Value\n", PLP, SectionName, Data->ElementCount, Data->ElementCount == 1 ? "y" : "ies", static_cast<PCWSTR>(buffFlags), PLP); }
if (fFull && (SearchStructure != NULL)) { PCACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET BucketTable = NULL;
if (SearchStructure->BucketTableOffset != 0) BucketTable = (PCACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET) (((ULONG_PTR) Data) + SearchStructure->BucketTableOffset);
::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE %p\n" "%S BucketTableEntryCount = %u\n" "%S BucketTableOffset = %d (-> %p)\n", PLP, SearchStructure, PLP, SearchStructure->BucketTableEntryCount, PLP, SearchStructure->BucketTableOffset, BucketTable);
if (BucketTable != NULL) { ULONG i;
for (i=0; i<SearchStructure->BucketTableEntryCount; i++) { PLONG Entries = NULL;
if (BucketTable[i].ChainOffset != 0) Entries = (PLONG) (((ULONG_PTR) Data) + BucketTable[i].ChainOffset);
::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET %p\n" "%S ChainCount = %u\n" "%S ChainOffset = %d (-> %p)\n", PLP, &BucketTable[i], PLP, BucketTable[i].ChainCount, PLP, BucketTable[i].ChainOffset, Entries);
if (Entries != NULL) { ULONG j;
for (j=0; j<BucketTable[i].ChainCount; j++) { PVOID Entry = NULL;
if (Entries[j] != 0) Entry = (PVOID) (((ULONG_PTR) Data) + Entries[j]);
::FusionpDbgPrintEx( Level, "%S Chain[%d] = %d (-> %p)\n", PLP, j, Entries[j], Entry); } } } } }
if (ElementList != NULL) { ULONG i; CSmallStringBuffer buffFormattedGuid;
for (i=0; i<Data->ElementCount; i++) { PVOID EntryData = NULL;
::SxspFormatGUID(ElementList[i].Guid, buffFormattedGuid);
if (ElementList[i].Offset != 0) EntryData = (PVOID) (((ULONG_PTR) Data) + ElementList[i].Offset);
if (fFull) { ::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_GUID_SECTION_ENTRY #%d - %p\n" "%S Guid = %S\n" "%S AssemblyRosterIndex = %u\n", PLP, i, &ElementList[i], PLP, static_cast<PCWSTR>(buffFormattedGuid), PLP, ElementList[i].AssemblyRosterIndex);
::FusionpDbgPrintEx( Level, "%S Offset = %d (-> %p)\n" "%S Length = %u\n", PLP, ElementList[i].Offset, EntryData, PLP, ElementList[i].Length); } else { //
// ISSUE: jonwis 3/7/2002
// - Augh! It's -like- .Win32FormatAppend, but it's NOT! %s will attempt to append
// ANSI charcacters, not UNICODE chars like what PLP points to!
//
buffBriefOutput.Win32ResizeBuffer(cchPLP + 3 + 38 + 4, eDoNotPreserveBufferContents); buffBriefOutput.Win32Format(L"%s %38s | ", PLP, static_cast<PCWSTR>(buffFormattedGuid)); }
if (EntryData != NULL) { if (ExtensionGuid == NULL) { //
// ISSUE: jonwis 3/7/2002
// - wcslen(L" ") != 6
//
rbuffPLP.Win32Append(L" ", 6);
switch (SectionId) { default: ::FusionpDbgPrintBlob(Level, EntryData, ElementList[i].Length, rbuffPLP); break;
case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION: ::SxspDbgPrintComServerRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break;
case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION: ::SxspDbgPrintComInterfaceRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break;
case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION: ::SxspDbgPrintTypeLibraryRedirection(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION) EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break;
case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES: ::SxspDbgPrintCLRSurrogateTable(Level, fFull, Data, (PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE)EntryData, ElementList[i].Length, rbuffPLP, buffBriefOutput); break; }
rbuffPLP.Left(cchPLP); PLP = rbuffPLP; } }
if (!fFull) ::FusionpDbgPrintEx(Level, "%S\n", static_cast<PCWSTR>(buffBriefOutput)); } } }
VOID SxspDbgPrintAssemblyInformation( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; UNICODE_STRING s2, s3, s5, strIdentity; CSmallStringBuffer buffManifestLastWriteTime; CSmallStringBuffer buffPolicyLastWriteTime; CSmallStringBuffer buffFlags;
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgAssemblyInformationFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_ASSEMBLY, "Root Assembly") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_POLICY_APPLIED, "Policy Applied") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ASSEMBLY_POLICY_APPLIED, "Assembly Policy Applied") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_POLICY_APPLIED, "Root Policy Applied") };
if (PLP == NULL) PLP = L"";
#define GET_STRING(_var, _elem) \
if (Entry-> _elem ## Length != 0) \ { \ (_var).Length = (_var).MaximumLength = static_cast<USHORT>(Entry-> _elem ## Length); \ (_var).Buffer = reinterpret_cast<PWSTR>(((LONG_PTR) Header) + Entry-> _elem ## Offset); \ } \ else \ { \ (_var).Length = (_var).MaximumLength = 0; \ (_var).Buffer = NULL; \ }
GET_STRING(s2, ManifestPath); GET_STRING(s3, PolicyPath); GET_STRING(s5, AssemblyDirectoryName);
#undef GET_STRING
// prepare data for print
::SxspFormatFileTime(Entry->ManifestLastWriteTime, buffManifestLastWriteTime); ::SxspFormatFileTime(Entry->PolicyLastWriteTime, buffPolicyLastWriteTime);
::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgAssemblyInformationFlags), s_rgAssemblyInformationFlags, buffFlags);
if (Entry->EncodedAssemblyIdentityOffset != 0) { strIdentity.Buffer = (PWSTR) (((ULONG_PTR) Header) + Entry->EncodedAssemblyIdentityOffset); strIdentity.Length = static_cast<USHORT>(Entry->EncodedAssemblyIdentityLength); strIdentity.MaximumLength = static_cast<USHORT>(Entry->EncodedAssemblyIdentityLength); } else { strIdentity.Buffer = NULL; strIdentity.Length = 0; strIdentity.MaximumLength = 0; }
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION %p\n" "%S Size = %lu\n" "%S Flags = 0x%08lx (%S)\n", PLP, Entry, PLP, Entry->Size, PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags));
::FusionpDbgPrintEx( Level, "%S EncodedIdentity = %wZ\n", PLP, &strIdentity);
::FusionpDbgPrintEx( Level, "%S ManifestPathType = %lu\n" "%S ManifestPath = \"%wZ\"\n", PLP, Entry->ManifestPathType, PLP, &s2);
::FusionpDbgPrintEx( Level, "%S ManifestLastWriteTime = %S\n", PLP, static_cast<PCWSTR>(buffManifestLastWriteTime));
::FusionpDbgPrintEx( Level, "%S PolicyPathType = %lu\n" "%S PolicyPath = \"%wZ\"\n" "%S PolicyLastWriteTime = %S\n", PLP, Entry->PolicyPathType, PLP, &s3, PLP, static_cast<PCWSTR>(buffPolicyLastWriteTime));
::FusionpDbgPrintEx( Level, "%S MetadataSatelliteRosterIndex = %lu\n" "%S ManifestVersionMajor = %u\n" "%S ManifestVersionMinor = %u\n", PLP, Entry->MetadataSatelliteRosterIndex, PLP, Entry->ManifestVersionMajor, PLP, Entry->ManifestVersionMinor);
::FusionpDbgPrintEx( Level, "%S AssemblyDirectoryName = \"%wZ\"\n", PLP, &s5); } else { // abuse buffManifestLastWriteTime
buffManifestLastWriteTime.Win32ResizeBuffer(((strIdentity.Length + s2.Length) / sizeof(WCHAR)) + 4, eDoNotPreserveBufferContents); buffManifestLastWriteTime.Win32Format(L"%wZ \"%wZ\"", &strIdentity, &s2); rbuffBriefOutput.Win32Append(buffManifestLastWriteTime); } }
VOID SxspDbgPrintDllRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT PathSegments = NULL; CSmallStringBuffer buffFlags;
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgDllRedirectionFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME, "Includes Base Name") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT, "Omits Assembly Root") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND, "Req. EnvVar Expansion") };
if (PLP == NULL) PLP = L"";
if (Entry->PathSegmentOffset != 0) PathSegments = (PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT) (((ULONG_PTR) Header) + Entry->PathSegmentOffset);
::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgDllRedirectionFlags), s_rgDllRedirectionFlags, buffFlags);
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_DLL_REDIRECTION %p\n" "%S Size = %u\n" "%S Flags = 0x%08lx (%S)\n" "%S TotalPathLength = %u (%u chars)\n" "%S PathSegmentCount = %u\n" "%S PathSegmentOffset = %d (-> %p)\n", PLP, Entry, PLP, Entry->Size, PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags), PLP, Entry->TotalPathLength, Entry->TotalPathLength / sizeof(WCHAR), PLP, Entry->PathSegmentCount, PLP, Entry->PathSegmentOffset, PathSegments); } else rbuffBriefOutput.Win32Append(L"\"", 1);
if (PathSegments != NULL) { ULONG i;
for (i=0; i<Entry->PathSegmentCount; i++) { PCWSTR pwch = NULL; UNICODE_STRING s;
if (PathSegments[i].Offset != 0) { pwch = (PCWSTR) (((ULONG_PTR) Header) + PathSegments[i].Offset);
s.MaximumLength = static_cast<USHORT>(PathSegments[i].Length); s.Length = static_cast<USHORT>(PathSegments[i].Length); s.Buffer = (PWSTR) pwch; } else { s.MaximumLength = 0; s.Length = 0; s.Buffer = NULL; }
if (fFull) { ::FusionpDbgPrintEx( Level, "%S ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT #%d - %p\n" "%S Length = %u (%u chars)\n" "%S Offset = %d (-> %p)\n" "%S \"%wZ\"\n", PLP, i, &PathSegments[i], PLP, PathSegments[i].Length, PathSegments[i].Length / sizeof(WCHAR), PLP, PathSegments[i].Offset, pwch, PLP, &s); } else { rbuffBriefOutput.Win32Append(s.Buffer, s.Length / sizeof(WCHAR)); } } }
if (!fFull) { rbuffBriefOutput.Win32Append(L"\" (Flags: ", 10); rbuffBriefOutput.Win32Append(buffFlags); rbuffBriefOutput.Win32Append(L")", 1); } }
VOID SxspDbgPrintWindowClassRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; UNICODE_STRING s1, s2; CSmallStringBuffer buffFlags;
if (PLP == NULL) PLP = L"";
//
// ISSUE: jonwis 3/7/2002 - Ick. Use initializers instead. The compiler is smarter than you are.
//
memset(&s1, 0, sizeof(s1)); memset(&s2, 0, sizeof(s2));
::FusionpFormatFlags( Entry->Flags, fFull, 0, NULL, buffFlags);
if (Entry->VersionSpecificClassNameOffset != 0) { s1.Length = static_cast<USHORT>(Entry->VersionSpecificClassNameLength); s1.MaximumLength = s1.Length; s1.Buffer = (PWSTR) (((ULONG_PTR) Entry) + Entry->VersionSpecificClassNameOffset); }
if (Entry->DllNameOffset != 0) { s2.Length = static_cast<USHORT>(Entry->DllNameLength); s2.MaximumLength = s2.Length; s2.Buffer = (PWSTR) (((ULONG_PTR) Header) + Entry->DllNameOffset); }
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION %p\n" "%S Size = %u\n" "%S Flags = 0x%08lx\n" "%S VersionSpecificClassNameLength = %u (%u chars)\n" "%S VersionSpecificClassNameOffset = %d (-> %p)\n" "%S \"%wZ\"\n" "%S DllNameLength = %u (%u chars)\n" "%S DllNameOffset = %d (-> %p)\n" "%S \"%wZ\"\n", PLP, Entry, PLP, Entry->Size, PLP, Entry->Flags, PLP, Entry->VersionSpecificClassNameLength, Entry->VersionSpecificClassNameLength / sizeof(WCHAR), PLP, Entry->VersionSpecificClassNameOffset, s1.Buffer, PLP, &s1, PLP, Entry->DllNameLength, Entry->DllNameLength / sizeof(WCHAR), PLP, Entry->DllNameOffset, s2.Buffer, PLP, &s2); } else { //
// ISSUE: jonwis 3/7/2002
// - Use Win32FormatAppend or Win32AssignW tead. It's faster, better, cheaper.
//
rbuffBriefOutput.Win32Append(s1.Buffer, s1.Length / sizeof(WCHAR)); rbuffBriefOutput.Win32Append(L" in ", 4); rbuffBriefOutput.Win32Append(s2.Buffer, s2.Length / sizeof(WCHAR)); rbuffBriefOutput.Win32Append(L" (Flags: ", 9); rbuffBriefOutput.Win32Append(buffFlags); rbuffBriefOutput.Win32Append(L")", 1); } }
VOID SxspDbgPrintCLRSurrogateTable( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffGuid; UNICODE_STRING RuntimeVersion = RTL_CONSTANT_STRING(L"<No runtime version>"); UNICODE_STRING TypeName = RTL_CONSTANT_STRING(L"<No type name>");
if (PLP == NULL) PLP = L"";
::SxspFormatGUID(Entry->SurrogateIdent, buffGuid);
if (Entry->VersionOffset != 0) { RuntimeVersion.MaximumLength = RuntimeVersion.Length = static_cast<USHORT>(Entry->VersionLength); RuntimeVersion.Buffer = (PWSTR)(((ULONG_PTR)Entry) + Entry->VersionOffset); }
if (Entry->TypeNameOffset != 0) { TypeName.MaximumLength = TypeName.Length = static_cast<USHORT>(Entry->TypeNameLength); TypeName.Buffer = (PWSTR)(((ULONG_PTR)Entry) + Entry->TypeNameOffset); }
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_CLR_INTEROP %p\n" "%S Size = %u\n" "%S Flags = 0x%08lx\n" "%S SurrogateIdent = %S\n", PLP, Entry, PLP, Entry->Size, PLP, Entry->Flags, PLP, static_cast<PCWSTR>(buffGuid));
::FusionpDbgPrintEx( Level, "%S Typename [Offset %u (-> %p), Length %u] = \"%wZ\"\n" "%S RuntimeVersion [Offset %u (-> %p), Length %u] = \"%wZ\"\n", PLP, Entry->TypeNameOffset, TypeName.Buffer, Entry->TypeNameLength, &TypeName, PLP, Entry->VersionOffset, RuntimeVersion.Buffer, Entry->VersionLength, &RuntimeVersion ); } else { rbuffBriefOutput.Win32Append(buffGuid); rbuffBriefOutput.Win32Append(L" runtime: '", NUMBER_OF(L" runtime: '")-1); rbuffBriefOutput.Win32Append(&RuntimeVersion); rbuffBriefOutput.Win32Append(L"' typename: '", NUMBER_OF(L"' typename: '")-1); rbuffBriefOutput.Win32Append(&TypeName); rbuffBriefOutput.Win32Append(L"'", 1); } }
VOID SxspDbgPrintComServerRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffConfiguredClsid; CSmallStringBuffer buffImplementedClsid; CSmallStringBuffer buffReferenceClsid; CSmallStringBuffer buffTypeLibraryId; CSmallStringBuffer buffThreadingModel; UNICODE_STRING s; UNICODE_STRING progid;
if (PLP == NULL) PLP = L"";
memset(&s, 0, sizeof(s));
::SxspFormatGUID(Entry->ReferenceClsid, buffReferenceClsid); ::SxspFormatGUID(Entry->ConfiguredClsid, buffConfiguredClsid); ::SxspFormatGUID(Entry->ImplementedClsid, buffImplementedClsid);
if (Entry->TypeLibraryId == GUID_NULL) buffTypeLibraryId.Win32Assign(L"<none>", 6); else ::SxspFormatGUID(Entry->TypeLibraryId, buffTypeLibraryId);
::SxspFormatThreadingModel(Entry->ThreadingModel, buffThreadingModel);
if (Entry->ModuleOffset != 0) { s.Length = static_cast<USHORT>(Entry->ModuleLength); s.MaximumLength = s.Length; s.Buffer = (PWSTR) (((ULONG_PTR) Header) + Entry->ModuleOffset); }
if (Entry->ProgIdOffset != 0) { progid.Length = static_cast<USHORT>(Entry->ProgIdLength); progid.MaximumLength = progid.Length; progid.Buffer = (PWSTR) (((ULONG_PTR) Entry) + Entry->ProgIdOffset); } else { progid.Length = 0; progid.MaximumLength = 0; progid.Buffer = NULL; }
if (fFull) { PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM ShimData = NULL;
::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION %p\n" "%S Size = %u\n" "%S Flags = 0x%08lx\n" "%S ThreadingModel = %u (%S)\n" "%S ReferenceClsid = %S\n", PLP, Entry, PLP, Entry->Size, PLP, Entry->Flags, PLP, Entry->ThreadingModel, static_cast<PCWSTR>(buffThreadingModel), PLP, static_cast<PCWSTR>(buffReferenceClsid));
::FusionpDbgPrintEx( Level, "%S ConfiguredClsid = %S\n" "%S ImplementedClsid = %S\n" "%S TypeLibraryId = %S\n" "%S ModuleLength = %u (%u chars)\n" "%S ModuleOffset = %d (-> %p)\n" "%S \"%wZ\"\n", PLP, static_cast<PCWSTR>(buffConfiguredClsid), PLP, static_cast<PCWSTR>(buffImplementedClsid), PLP, static_cast<PCWSTR>(buffTypeLibraryId), PLP, Entry->ModuleLength, Entry->ModuleLength / sizeof(WCHAR), PLP, Entry->ModuleOffset, s.Buffer, PLP, &s);
::FusionpDbgPrintEx( Level, "%S ProgIdLength = %lu\n" "%S ProgIdOffset = %ld (-> %p)\n" "%S \"%wZ\"\n", PLP, Entry->ProgIdLength, PLP, Entry->ProgIdOffset, progid.Buffer, PLP, &progid);
if (Entry->ShimDataOffset != 0) ShimData = (PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM) (((ULONG_PTR) Entry) + Entry->ShimDataOffset);
::FusionpDbgPrintEx( Level, "%S ShimDataLength = %lu\n" "%S ShimDataOffset = %ld (-> %p)\n", PLP, Entry->ShimDataLength, PLP, Entry->ShimDataOffset, ShimData);
if (ShimData != NULL) { ::FusionpDbgPrintEx( Level, "%S Size = %lu\n" "%S Flags = 0x%08lx\n" "%S Type = %lu\n", PLP, ShimData->Size, PLP, ShimData->Flags, PLP, ShimData->Type);
if (ShimData->ModuleOffset != 0) { s.Buffer = (PWSTR) (((ULONG_PTR) Header) + ShimData->ModuleOffset); s.Length = (USHORT) ShimData->ModuleLength; s.MaximumLength = (USHORT) ShimData->ModuleLength; } else { s.Buffer = NULL; s.Length = 0; s.MaximumLength = 0; }
::FusionpDbgPrintEx( Level, "%S ModuleLength = %lu\n" "%S ModuleOffset = %lu (-> %p)\n" "%S \"%wZ\"\n", PLP, ShimData->ModuleLength, PLP, ShimData->ModuleOffset, s.Buffer, PLP, &s);
if (ShimData->TypeOffset != 0) { s.Buffer = (PWSTR) (((ULONG_PTR) ShimData) + ShimData->TypeOffset); s.Length = (USHORT) ShimData->TypeLength; s.MaximumLength = (USHORT) ShimData->TypeLength; } else { s.Buffer = NULL; s.Length = 0; s.MaximumLength = 0; }
::FusionpDbgPrintEx( Level, "%S TypeLength = %lu\n" "%S TypeOffset = %lu (-> %p)\n" "%S \"%wZ\"\n", PLP, ShimData->TypeLength, PLP, ShimData->TypeOffset, s.Buffer, PLP, &s);
if (ShimData->ShimVersionOffset != 0) { s.Buffer = (PWSTR) (((ULONG_PTR) ShimData) + ShimData->ShimVersionOffset); s.Length = (USHORT) ShimData->ShimVersionLength; s.MaximumLength = (USHORT) ShimData->ShimVersionLength; } else { s.Buffer = NULL; s.Length = 0; s.MaximumLength = 0; }
::FusionpDbgPrintEx( Level, "%S ShimVersionLength = %lu\n" "%S ShimVersionOffset = %lu (-> %p)\n" "%S \"%wZ\"\n", PLP, ShimData->ShimVersionLength, PLP, ShimData->ShimVersionOffset, s.Buffer, PLP, &s); } } else { rbuffBriefOutput.Win32Append(buffConfiguredClsid);
rbuffBriefOutput.Win32Append(L" ", 1); rbuffBriefOutput.Win32Append(s.Buffer, s.Length / sizeof(WCHAR)); if (progid.Length != 0) { rbuffBriefOutput.Win32Append(L" progid: ", 9); rbuffBriefOutput.Win32Append(progid.Buffer, progid.Length / sizeof(WCHAR)); } }
}
VOID FusionpDbgPrintStringInUntruncatedChunks( ULONG Level, PCWSTR String, SIZE_T Length ) //
// in pieces so it does not get truncated by DbgPrint (or we could use OutputDebugString, which
// does this same work)
//
{ if (!::FusionpDbgWouldPrintAtFilterLevel(Level)) return; while (Length != 0) { SIZE_T ShortLength = ((Length > 128) ? 128 : Length);
CUnicodeString UnicodeString(String, ShortLength); ::FusionpDbgPrintEx(Level, "%wZ", &UnicodeString);
Length -= ShortLength; String += ShortLength; } }
VOID FusionpDbgPrintStringInUntruncatedChunks( ULONG Level, const CBaseStringBuffer &rbuff ) { if (!::FusionpDbgWouldPrintAtFilterLevel(Level)) return;
FusionpDbgPrintStringInUntruncatedChunks(Level, rbuff, rbuff.Cch()); }
VOID SxspDbgPrintTypeLibraryRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { if (!::FusionpDbgWouldPrintAtFilterLevel(Level)) return;
PCWSTR PLP = rbuffPLP; CSmallStringBuffer buff;
UNICODE_STRING Name = RTL_CONSTANT_STRING(L""); UNICODE_STRING HelpDir = RTL_CONSTANT_STRING(L""); ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION Version = { 0 };
if (!buff.Win32ResizeBuffer(4096, eDoNotPreserveBufferContents)) return;
#if 1
#define GET_STRING(ntstr, struc, struc_size, offset_field, length_field, base) \
do { if (RTL_CONTAINS_FIELD((struc), (struc_size), offset_field) \ && RTL_CONTAINS_FIELD((struc), (struc_size), length_field) \ && (struc)->offset_field != 0 \ && (struc)->length_field != 0) \ { \ (ntstr).Length = static_cast<USHORT>(struc->length_field - sizeof((ntstr).Buffer[0])); \ (ntstr).Buffer = const_cast<PWSTR>(reinterpret_cast<PCWSTR>(struc->offset_field + reinterpret_cast<PCBYTE>(base))); \ } } while(0)
GET_STRING(Name, Entry, Entry->Size, NameOffset, NameLength, Header); GET_STRING(HelpDir, Entry, Entry->Size, HelpDirOffset, HelpDirLength, Entry);
#undef GET_STRING
#else
if (RTL_CONTAINS_FIELD(Entry, Entry->Size, NameLength) && RTL_CONTAINS_FIELD(Entry, Entry->Size, NameOffset) && Entry->NameOffset != 0 ) { Name.Length = static_cast<USHORT>(Entry->NameLength); Name.Buffer = const_cast<PWSTR>(reinterpret_cast<PCWSTR>(Entry->NameOffset + reinterpret_cast<PCBYTE>(Header))); }
if (RTL_CONTAINS_FIELD(Entry, Entry->Size, HelpDirLength) && RTL_CONTAINS_FIELD(Entry, Entry->Size, HelpDirOffset) && Entry->HelpDirOffset != 0 ) { HelpDir.Length = static_cast<USHORT>(Entry->HelpDirLength); HelpDir.Buffer = const_cast<PWSTR>(reinterpret_cast<PCWSTR>(Entry->HelpDirOffset + reinterpret_cast<PCBYTE>(Entry))); }
#endif
if (RTL_CONTAINS_FIELD(Entry, Entry->Size, Version)) Version = Entry->Version;
if (!buff.Win32Format( L"%SACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION %p\n" L"%S Size = 0x%lx\n" L"%S Flags = 0x%lx\n" L"%S Name = %wZ (offset 0x%lx + %p = %p)\n" L"%S HelpDir = %wZ (offset 0x%lx + %p = %p)\n" L"%S Version = 0x%lx.%lx\n", PLP, Entry, PLP, static_cast<ULONG>(Entry->Size), PLP, static_cast<ULONG>(Entry->Flags), PLP, &Name, static_cast<ULONG>(Entry->NameOffset), static_cast<PCVOID>(Header), static_cast<PCVOID>(Name.Buffer), PLP, &HelpDir, static_cast<ULONG>(Entry->HelpDirOffset), static_cast<PCVOID>(Entry), static_cast<PCVOID>(HelpDir.Buffer), PLP, static_cast<ULONG>(Version.Major), static_cast<ULONG>(Version.Minor) )) return;
::FusionpDbgPrintStringInUntruncatedChunks(Level, buff); }
VOID SxspDbgPrintComProgIdRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; // CSmallStringBuffer buffFlags;
CSmallStringBuffer buffClsid; const GUID *pcguid = NULL;
if (Entry->ConfiguredClsidOffset != 0) { pcguid = (const GUID *) (((ULONG_PTR) Header) + Entry->ConfiguredClsidOffset); ::SxspFormatGUID(*pcguid, buffClsid); }
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION %p\n" "%S Size = %lu (0x%lx)\n" "%S Flags = 0x%08lx\n" "%S ConfiguredClsidOffset = %lu (-> %p)\n" "%S %S\n", PLP, Entry, PLP, Entry->Size, Entry->Size, PLP, Entry->Flags, PLP, Entry->ConfiguredClsidOffset, pcguid, PLP, static_cast<PCWSTR>(buffClsid)); } else { rbuffBriefOutput.Win32Append(buffClsid); } }
VOID SxspDbgPrintComInterfaceRedirection( ULONG Level, bool fFull, PCACTIVATION_CONTEXT_GUID_SECTION_HEADER Header, PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Entry, SIZE_T Length, CBaseStringBuffer &rbuffPLP, CBaseStringBuffer &rbuffBriefOutput ) { PCWSTR PLP = rbuffPLP; CSmallStringBuffer buffProxyStubClsid32; CSmallStringBuffer buffBaseInterface; CSmallStringBuffer buffFlags; CSmallStringBuffer buffTypeLibraryId; UNICODE_STRING s;
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgComInterfaceFlags[] = { DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_NUM_METHODS_VALID, "NumMethods Valid") DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_BASE_INTERFACE_VALID, "BaseInterface Valid") };
if (PLP == NULL) PLP = L"";
memset(&s, 0, sizeof(s));
::SxspFormatGUID(Entry->ProxyStubClsid32, buffProxyStubClsid32); ::SxspFormatGUID(Entry->BaseInterface, buffBaseInterface);
::FusionpFormatFlags(Entry->Flags, fFull, NUMBER_OF(s_rgComInterfaceFlags), s_rgComInterfaceFlags, buffFlags);
if (Entry->TypeLibraryId == GUID_NULL) buffTypeLibraryId.Win32Assign(L"<none>", 6); else ::SxspFormatGUID(Entry->TypeLibraryId, buffTypeLibraryId);
if (Entry->NameOffset != 0) { s.Length = static_cast<USHORT>(Entry->NameLength); s.MaximumLength = s.Length; s.Buffer = (PWSTR) (((ULONG_PTR) Entry) + Entry->NameOffset); }
if (fFull) { ::FusionpDbgPrintEx( Level, "%SACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION %p\n" "%S Size = %lu\n" "%S Flags = 0x%08lx (%S)\n", PLP, Entry, PLP, Entry->Size, PLP, Entry->Flags, static_cast<PCWSTR>(buffFlags));
::FusionpDbgPrintEx( Level, "%S ProxyStubClsid32 = %S\n" "%S NumMethods = %lu\n" "%S TypeLibraryId = %S\n", PLP, static_cast<PCWSTR>(buffProxyStubClsid32), PLP, Entry->NumMethods, PLP, static_cast<PCWSTR>(buffTypeLibraryId));
::FusionpDbgPrintEx( Level, "%S BaseInterface = %S\n" "%S NameLength = %lu (%u chars)\n" "%S NameOffset = %lu (-> %p)\n", PLP, static_cast<PCWSTR>(buffBaseInterface), PLP, Entry->NameLength, (Entry->NameLength / sizeof(WCHAR)), PLP, Entry->NameOffset, s.Buffer);
::FusionpDbgPrintEx( Level, "%S \"%wZ\"\n", PLP, &s); } else { rbuffBriefOutput.Win32Append(buffProxyStubClsid32); rbuffBriefOutput.Win32Append(L" ", 1); rbuffBriefOutput.Win32Append(s.Buffer, s.Length / sizeof(WCHAR)); } }
VOID SxspDbgPrintInstallSourceInfo( ULONG Level, bool fFull, PSXS_INSTALL_SOURCE_INFO Info, CBaseStringBuffer &rbuffPLP ) { PCWSTR PLP = rbuffPLP; if ( !PLP ) PLP = L"SXS.DLL:"; if ( !Info ) { ::FusionpDbgPrintEx( Level, "%S InstallationInfo is null!\n", PLP ); } else { DWORD dwFlags = Info->dwFlags;
::FusionpDbgPrintEx( Level, "%S InstallationInfo at 0x%08x - size = %d\n", "%S Flag set: %s catalog, %s codebase, %s prompt, %s in setup mode\n" "%S Codebase Name: %ls\n" "%S Prompt: %ls\n", PLP, Info, Info->cbSize, PLP, dwFlags & SXSINSTALLSOURCE_HAS_CATALOG ? "has" : "no", dwFlags & SXSINSTALLSOURCE_HAS_CODEBASE ? "has" : "no", dwFlags & SXSINSTALLSOURCE_HAS_PROMPT ? "has" : "no", dwFlags & SXSINSTALLSOURCE_INSTALLING_SETUP ? "is" : "not", PLP, Info->pcwszCodebaseName, PLP, Info->pcwszPromptOnRefresh); } }
|