2303 lines
74 KiB
C++
2303 lines
74 KiB
C++
#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;
|
|
|
|
/*
|
|
Declaration of dumpers are moved from the relatively public sxsp.h
|
|
to here to contain their use.
|
|
|
|
These functions should be preceded by FusionpDbgWouldPrintAtFilterLevel calls
|
|
and surrounded by __try/__except(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
These function can consume a lot of stack, and time, when their output
|
|
ultimately doesn't go anywhere, and they overflow the small commited stack
|
|
in csrss under stress.
|
|
*/
|
|
|
|
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;
|
|
|
|
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);
|
|
}
|
|
|
|
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
|
|
)
|
|
{
|
|
__try
|
|
{
|
|
if (::FusionpDbgWouldPrintAtFilterLevel(Level))
|
|
{
|
|
::SxsppDbgPrintActivationContextData(Level, ::FusionpDbgWouldPrintAtFilterLevel(FUSION_DBG_LEVEL_FULLACTCTX), Data, rbuffPLP);
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
/* Just eat it, we are seeing failures now in DbgPrint even
|
|
with relatively shallow callstacks
|
|
*/
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
// Abuse the buffFlags buffer for the new per-line prefix.
|
|
rbuffPLP.Win32Append(L" ", 3);
|
|
|
|
for (i=0; i<Data->EntryCount; i++)
|
|
::SxspDbgPrintActivationContextDataTocEntry(Level, fFull, Base, &FirstEntry[i], rbuffPLP);
|
|
|
|
rbuffPLP.Left(cchSave);
|
|
PLP = rbuffPLP;
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
{
|
|
PVOID Section = (PVOID) (((ULONG_PTR) Base) + Entries[i].Offset);
|
|
CSmallStringBuffer buffSectionId;
|
|
PCSTR pszSectionName = "<untranslatable>";
|
|
|
|
if (ExtensionGuid != NULL)
|
|
{
|
|
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")
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
#if 0 // redundant at least in non-full prints
|
|
if (fFull)
|
|
::FusionpDbgPrintEx(
|
|
Level,
|
|
"%SSection Id %S at %p\n",
|
|
PLP, static_cast<PCWSTR>(buffSectionId), Section);
|
|
else
|
|
::FusionpDbgPrintEx(
|
|
Level,
|
|
"%S%s Data\n",
|
|
PLP, pszSectionName);
|
|
#endif //
|
|
|
|
::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, "NDP 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"";
|
|
|
|
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)
|
|
{
|
|
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
|
|
{
|
|
buffBriefOutput.Win32ResizeBuffer(cchPLP + 3 + 38 + 4, eDoNotPreserveBufferContents);
|
|
buffBriefOutput.Win32Format(L"%s %38s | ", PLP, static_cast<PCWSTR>(buffFormattedGuid));
|
|
}
|
|
|
|
if (EntryData != NULL)
|
|
{
|
|
if (ExtensionGuid == NULL)
|
|
{
|
|
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 0 // replace when the list of flags is non-empty
|
|
static const FUSION_FLAG_FORMAT_MAP_ENTRY s_rgWCRedirectionFlags[] =
|
|
{
|
|
};
|
|
#endif // 0
|
|
|
|
if (PLP == NULL)
|
|
PLP = L"";
|
|
|
|
memset(&s1, 0, sizeof(s1));
|
|
memset(&s2, 0, sizeof(s2));
|
|
|
|
::FusionpFormatFlags(
|
|
Entry->Flags,
|
|
fFull,
|
|
#if 0 // replace when the list of flags is nonempty
|
|
NUMBER_OF(s_rgWCRedirectionFlags), s_rgWCRedirectionFlags,
|
|
#else
|
|
0, NULL,
|
|
#endif
|
|
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
|
|
{
|
|
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_NDP_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 AssemblyName [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);
|
|
}
|
|
}
|