mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
747 lines
21 KiB
747 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ntsdexts.c
|
|
|
|
Abstract:
|
|
|
|
This function contains the default ntsd debugger extensions
|
|
|
|
Author:
|
|
|
|
Mark Lucovsky (markl) 09-Apr-1991
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "ntsdextp.h"
|
|
|
|
WINDBG_EXTENSION_APIS ExtensionApis;
|
|
HANDLE ExtensionCurrentProcess;
|
|
|
|
DECLARE_API( version )
|
|
{
|
|
OSVERSIONINFOA VersionInformation;
|
|
HKEY hkey;
|
|
DWORD cb, dwType;
|
|
CHAR szCurrentType[128];
|
|
CHAR szCSDString[3+128];
|
|
|
|
INIT_API();
|
|
|
|
VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation);
|
|
if (!GetVersionEx( &VersionInformation )) {
|
|
dprintf("GetVersionEx failed - %u\n", GetLastError());
|
|
return;
|
|
}
|
|
|
|
szCurrentType[0] = '\0';
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
"Software\\Microsoft\\Windows NT\\CurrentVersion",
|
|
0,
|
|
KEY_READ,
|
|
&hkey
|
|
) == NO_ERROR
|
|
) {
|
|
cb = sizeof(szCurrentType);
|
|
if (RegQueryValueEx(hkey, "CurrentType", NULL, &dwType, szCurrentType, &cb ) != 0) {
|
|
szCurrentType[0] = '\0';
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
|
|
if (VersionInformation.szCSDVersion[0]) {
|
|
sprintf(szCSDString, ": %s", VersionInformation.szCSDVersion);
|
|
}
|
|
else {
|
|
szCSDString[0] = '\0';
|
|
}
|
|
|
|
dprintf("Version %d.%d (Build %d%s) %s\n",
|
|
VersionInformation.dwMajorVersion,
|
|
VersionInformation.dwMinorVersion,
|
|
VersionInformation.dwBuildNumber,
|
|
szCSDString,
|
|
szCurrentType
|
|
);
|
|
return;
|
|
}
|
|
|
|
DECLARE_API( help )
|
|
{
|
|
INIT_API();
|
|
|
|
while (*lpArgumentString == ' ')
|
|
lpArgumentString++;
|
|
|
|
if (*lpArgumentString == '\0') {
|
|
dprintf("setupexts help:\n\n");
|
|
dprintf("!version - Dump system version and build number\n");
|
|
dprintf("!help - This message\n");
|
|
dprintf("!ocm [address] [opt. flag] - Dump the OC_MANAGER structure at address, flag increased verbosity\n");
|
|
dprintf("!space [address] [opt. flag] - Dump the DISK_SPACE_LIST structure at specified address\n");
|
|
dprintf("!st [address] - Dump the contents of a STRING_TABLE structure at specified address\n");
|
|
dprintf("!stfind [address] [element] - Dump the specified string table element\n");
|
|
dprintf("!queue [address] [opt. flag] - Dump the specified file queue\n");
|
|
dprintf("!qcontext [address] - Dump the specified default queue context \n");
|
|
dprintf("!infdump [addr] [opt. flag] - Dump the specified hinf \n");
|
|
dprintf("!winntflags - Dump some winnt32 global flags \n");
|
|
dprintf("!winntstr - Dump some winnt32 global strings\n");
|
|
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CheckInterupted(
|
|
VOID
|
|
)
|
|
{
|
|
if ( CheckControlC() ) {
|
|
dprintf( "\nInterrupted\n\n" );
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Simple routine to convert from hex into a string of characters.
|
|
// Used by debugger extensions.
|
|
//
|
|
// by scottlu
|
|
//
|
|
|
|
char *
|
|
HexToString(
|
|
ULONG dw,
|
|
CHAR *pch
|
|
)
|
|
{
|
|
if (dw > 0xf) {
|
|
pch = HexToString(dw >> 4, pch);
|
|
dw &= 0xf;
|
|
}
|
|
|
|
*pch++ = ((dw >= 0xA) ? ('A' - 0xA) : '0') + (CHAR)dw;
|
|
*pch = 0;
|
|
|
|
return pch;
|
|
}
|
|
|
|
VOID
|
|
DumpStringTableHeader(
|
|
PSTRING_TABLE st
|
|
)
|
|
{
|
|
//
|
|
// dump the string table header
|
|
//
|
|
dprintf("\tBase Data ptr:\t0x%08x\n", st->Data);
|
|
dprintf("\tDataSize:\t0x%08x\n", st->DataSize);
|
|
dprintf("\tBufferSize:\t0x%08x\n", st->BufferSize);
|
|
dprintf("\tExtraDataSize:\t0x%08x\n", st->ExtraDataSize);
|
|
|
|
}
|
|
|
|
VOID
|
|
DumpOcComponent(
|
|
ULONG_PTR offset,
|
|
PSTRING_NODEW node,
|
|
deb_POPTIONAL_COMPONENTW pcomp
|
|
)
|
|
{
|
|
DWORD i;
|
|
PLONG count;
|
|
|
|
dprintf("OC_COMPONENT Data for node %ws : 0x%p\n", node->String, offset );
|
|
dprintf( "\t InfStringId:\t\t0x%08x\n", pcomp->InfStringId );
|
|
dprintf( "\t TopLevelStringId:\t0x%08x\n", pcomp->TopLevelStringId );
|
|
dprintf( "\t ParentStringId:\t0x%08x\n", pcomp->ParentStringId );
|
|
dprintf( "\t FirstChildStringId:\t0x%08x\n", pcomp->FirstChildStringId );
|
|
dprintf( "\t ChildrenCount:\t\t0x%08x\n", pcomp->ChildrenCount );
|
|
dprintf( "\t NextSiblingStringId:\t0x%08x\n", pcomp->NextSiblingStringId );
|
|
|
|
dprintf( "\t NeedsCount:\t\t%d\n", pcomp->NeedsCount );
|
|
count = malloc ( pcomp->NeedsCount * sizeof(LONG) );
|
|
if (count) {
|
|
// read and dump needs list
|
|
ReadMemory((DWORD_PTR) pcomp->NeedsStringIds, count, pcomp->NeedsCount*sizeof(LONG), NULL);
|
|
for (i = 0; i < pcomp->NeedsCount; i++) {
|
|
dprintf("\t NeedsStringIds #%d:\t0x%08x\n", i, count[i]);
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
|
|
dprintf( "\t NeededByCount:\t\t%d\n", pcomp->NeededByCount );
|
|
count = malloc ( pcomp->NeededByCount * sizeof(LONG) );
|
|
if (count) {
|
|
// read and dump needs list
|
|
ReadMemory((DWORD_PTR) pcomp->NeededByStringIds, count, pcomp->NeededByCount*sizeof(LONG), NULL);
|
|
for (i = 0; i < pcomp->NeededByCount; i++) {
|
|
dprintf("\t NeededByStringIds #%d: 0x%08x\n", i, count[i]);
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
dprintf( "\t ExcludeCount:\t\t%d\n", pcomp->ExcludeCount );
|
|
count = malloc ( pcomp->ExcludeCount * sizeof(LONG) );
|
|
if (count) {
|
|
// read and dump Excludes list
|
|
ReadMemory((DWORD_PTR) pcomp->ExcludeStringIds, count, pcomp->ExcludeCount*sizeof(LONG), NULL);
|
|
for (i = 0; i < pcomp->ExcludeCount; i++) {
|
|
dprintf("\t ExcludeStringIds #%d: 0x%08x\n", i, count[i]);
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
dprintf( "\t ExcludedByCount:\t%d\n", pcomp->ExcludedByCount );
|
|
count = malloc ( pcomp->ExcludedByCount * sizeof(LONG) );
|
|
if (count) {
|
|
// read and dump Excludes list
|
|
ReadMemory((DWORD_PTR) pcomp->ExcludedByStringIds, count, pcomp->ExcludedByCount*sizeof(LONG), NULL);
|
|
for (i = 0; i < pcomp->ExcludedByCount; i++) {
|
|
dprintf("\t ExcludesStringIds #%d:\t0x%08x\n", i, count[i]);
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
dprintf( "\t InternalFlags:\t\t0x%08x\n", pcomp->InternalFlags );
|
|
|
|
|
|
dprintf( "\t SizeApproximation:\t0x%08x\n", pcomp->SizeApproximation );
|
|
|
|
dprintf( "\t IconIndex:\t\t0x%08x\n", pcomp->IconIndex );
|
|
dprintf( "\t IconDll:\t\t%ws\n", pcomp->IconDll);
|
|
dprintf( "\t IconResource:\t\t%ws\n", pcomp->IconResource);
|
|
dprintf( "\t SelectionState:\t0x%08x\n", pcomp->SelectionState );
|
|
dprintf( "\t OriginalSelectionState:0x%08x\n", pcomp->OriginalSelectionState );
|
|
dprintf( "\t InstalledState:\t0x%08x\n", pcomp->InstalledState );
|
|
dprintf( "\t ModeBits:\t\t0x%08x\n", pcomp->ModeBits );
|
|
dprintf( "\t Description:\t\t%ws\n", pcomp->Description );
|
|
dprintf( "\t Tip:\t\t\t%ws\n", pcomp->Tip );
|
|
|
|
dprintf( "\t InstallationDllName:\t%ws\n", pcomp->InstallationDllName );
|
|
dprintf( "\t InterfaceFunctionName:\t%s\n", pcomp->InterfaceFunctionName );
|
|
dprintf( "\t InstallationDll:\t0x%08x\n", pcomp->InstallationDll );
|
|
//dprintf( "\t InstallationRoutine:\t%s\n", pcomp->InstallationRoutine );
|
|
dprintf( "\t ExpectedVersion:\t0x%08x\n", pcomp->ExpectedVersion );
|
|
dprintf( "\t Exists:\t\t0x%08x\n", pcomp->Exists );
|
|
dprintf( "\t Flags:\t\t\t0x%08x\n\n\n", pcomp->Flags );
|
|
|
|
}
|
|
|
|
PVOID
|
|
GetStringTableData(
|
|
PSTRING_TABLE st
|
|
)
|
|
{
|
|
LPVOID stdata;
|
|
|
|
stdata = (PVOID) malloc( st->DataSize );
|
|
if (!stdata) {
|
|
dprintf("error allocation memory (size 0x%08x\n", (ULONG_PTR) st->DataSize);
|
|
return NULL;
|
|
}
|
|
|
|
try {
|
|
ReadMemory((DWORD_PTR) st->Data, stdata, st->DataSize, NULL);
|
|
} except (EXCEPTION_EXECUTE_HANDLER) {
|
|
free( stdata );
|
|
return NULL;
|
|
}
|
|
|
|
return stdata;
|
|
}
|
|
|
|
PVOID
|
|
GetStringNodeExtraData(
|
|
PSTRING_NODEW node
|
|
)
|
|
{
|
|
PVOID extraData;
|
|
extraData = node->String + wcslen(node->String) + 1;
|
|
|
|
return extraData;
|
|
|
|
}
|
|
|
|
PSTRING_NODEW
|
|
GetNextNode(
|
|
PVOID stdata,
|
|
PSTRING_NODEW node,
|
|
PULONG_PTR offset
|
|
)
|
|
{
|
|
PVOID next;
|
|
|
|
if (node->NextOffset == -1) {
|
|
*offset = 0;
|
|
return NULL;
|
|
}
|
|
|
|
next = (PSTRING_NODEW)((LPBYTE)stdata + node->NextOffset);
|
|
*offset = node->NextOffset;
|
|
|
|
return next;
|
|
|
|
}
|
|
|
|
PSTRING_NODEW
|
|
GetFirstNode(
|
|
PVOID stdata,
|
|
ULONG_PTR offset,
|
|
PULONG_PTR poffset
|
|
)
|
|
{
|
|
PSTRING_NODEW node;
|
|
|
|
if (offset == -1) {
|
|
return NULL;
|
|
}
|
|
|
|
node = (PSTRING_NODEW) ((LPBYTE)stdata + offset);
|
|
*poffset = offset;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
LPCSTR
|
|
GetWizPage(
|
|
DWORD i
|
|
)
|
|
{
|
|
LPCSTR WizPage[] = {
|
|
"WizPagesWelcome", // welcome page
|
|
"WizPagesMode", // setup mode page
|
|
"WizPagesEarly", // pages that come after the mode page and before prenet pages
|
|
"WizPagesPrenet", // pages that come before network setup
|
|
"WizPagesPostnet", // pages that come after network setup
|
|
"WizPagesLate", // pages that come after postnet pages and before the final page
|
|
"WizPagesFinal", // final page
|
|
"WizPagesTypeMax"
|
|
};
|
|
|
|
return WizPage[i];
|
|
|
|
}
|
|
|
|
|
|
DECLARE_API( st )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This debugger extension dumps a string table at the address specified.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
DWORD ReturnLength;
|
|
PVOID pst;
|
|
STRING_TABLE st;
|
|
DWORD i;
|
|
DWORD_PTR offset;
|
|
PVOID stdata,pextradata;
|
|
PSTRING_NODEW node;//, prev;
|
|
|
|
|
|
INIT_API();
|
|
|
|
while (*lpArgumentString == ' ') {
|
|
lpArgumentString++;
|
|
}
|
|
|
|
pst = (PVOID)GetExpression( lpArgumentString );
|
|
|
|
move( st, pst );
|
|
|
|
dprintf("Base String Table Address:\t0x%p\n", pst);
|
|
|
|
DumpStringTableHeader( &st );
|
|
|
|
stdata = GetStringTableData( &st );
|
|
if (!stdata) {
|
|
dprintf("error retrieving string table data!\n");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// now, dump each node in the string table
|
|
//
|
|
for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
|
|
node = GetFirstNode(stdata, ((PULONG_PTR)stdata)[i], &offset );
|
|
if (!node) {
|
|
// dprintf("No data at hash bucket %d\n", i);
|
|
} else {
|
|
dprintf("Data at hash bucket %d\n", i);
|
|
while (node) {
|
|
dprintf("\tEntry Name:\t%ws (0x%08x)\n", node->String, offset);
|
|
pextradata = st.Data + offset + (wcslen(node->String) + 1)*sizeof(WCHAR) + sizeof(DWORD);
|
|
dprintf("\tExtra Data:\t0x%08x\n", pextradata );
|
|
//((LPBYTE)node->String + wcslen(node->String) + 1));
|
|
node = GetNextNode( stdata, node, &offset );
|
|
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
free( stdata );
|
|
|
|
}
|
|
|
|
DECLARE_API( stfind )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This debugger extension dumps the data for a given string table number
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
DWORD ReturnLength;
|
|
PVOID pst;
|
|
STRING_TABLE st;
|
|
DWORD i;
|
|
DWORD_PTR offset;
|
|
PVOID stdata,pextradata;
|
|
PSTRING_NODEW node;//, prev;
|
|
DWORD_PTR element;
|
|
|
|
|
|
INIT_API();
|
|
|
|
while (*lpArgumentString == ' ') {
|
|
lpArgumentString++;
|
|
}
|
|
|
|
pst = (PVOID)GetExpression( lpArgumentString );
|
|
|
|
while (*lpArgumentString && (*lpArgumentString != ' ') ) {
|
|
lpArgumentString++;
|
|
}
|
|
while (*lpArgumentString == ' ') {
|
|
lpArgumentString++;
|
|
}
|
|
|
|
if (*lpArgumentString) {
|
|
element = GetExpression( lpArgumentString );
|
|
} else {
|
|
dprintf("bogus usage\n");
|
|
}
|
|
|
|
|
|
move( st, pst );
|
|
|
|
stdata = GetStringTableData( &st );
|
|
if (!stdata) {
|
|
dprintf("error retrieving string table data!\n");
|
|
return;
|
|
}
|
|
//
|
|
// search each node in the string table
|
|
//
|
|
for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
|
|
node = GetFirstNode(stdata, ((PULONG_PTR)stdata)[i], &offset );
|
|
if (!node) {
|
|
|
|
} else {
|
|
|
|
while (node) {
|
|
if (element == offset) {
|
|
dprintf("\tEntry Name:\t%ws (0x%08x)\n", node->String, offset);
|
|
pextradata = st.Data + offset + (wcslen(node->String) + 1)*sizeof(WCHAR) + sizeof(DWORD);
|
|
dprintf("\tExtra Data:\t0x%08x\n", pextradata );
|
|
free( stdata );
|
|
return;
|
|
}
|
|
|
|
node = GetNextNode( stdata, node, &offset );
|
|
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
free( stdata );
|
|
|
|
dprintf("Couldn't find element\n");
|
|
|
|
}
|
|
|
|
|
|
DECLARE_API( ocm )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This debugger extension dumps an OC_MANAGER (UNICODE!) structure at the specified address
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
DWORD ReturnLength;
|
|
deb_OC_MANAGERW ocm;
|
|
PVOID pocm;
|
|
DWORD i;
|
|
DWORD_PTR offset;
|
|
STRING_TABLE inftable,comptable;
|
|
PVOID infdata,compdata;
|
|
PSTRING_NODEW node;
|
|
POC_INF pocinf;
|
|
deb_POPTIONAL_COMPONENTW pcomp;
|
|
DWORD Mask = 0;
|
|
PLONG count;
|
|
|
|
INIT_API();
|
|
|
|
|
|
while (*lpArgumentString == ' ') {
|
|
lpArgumentString++;
|
|
}
|
|
|
|
pocm = (PVOID)GetExpression( lpArgumentString );
|
|
|
|
while (*lpArgumentString && (*lpArgumentString != ' ') ) {
|
|
lpArgumentString++;
|
|
}
|
|
while (*lpArgumentString == ' ') {
|
|
lpArgumentString++;
|
|
}
|
|
|
|
if (*lpArgumentString) {
|
|
Mask = (DWORD)GetExpression( lpArgumentString );
|
|
}
|
|
|
|
move( ocm,(LPVOID)pocm);
|
|
|
|
//
|
|
// dump the OCM structure
|
|
//
|
|
dprintf("OC_MANAGER structure at Address:\t0x%08x\n", (ULONG_PTR) pocm);
|
|
dprintf("\tCallbacks :\n");
|
|
dprintf("\t\tFillInSetupDataA:\t0x%08x\n", (ULONG_PTR) ocm.Callbacks.FillInSetupDataA);
|
|
dprintf("\t\tLogError:\t\t0x%08x\n", (ULONG_PTR) ocm.Callbacks.LogError);
|
|
dprintf("\t\tSetReboot:\t\t0x%08x\n", (ULONG_PTR) ocm.Callbacks.SetReboot);
|
|
dprintf("\t\tFillInSetupDataW:\t0x%08x\n", (ULONG_PTR) ocm.Callbacks.FillInSetupDataW);
|
|
|
|
dprintf("\tMasterOcInf:\t\t0x%08x\n", ocm.MasterOcInf);
|
|
dprintf("\tUnattendedInf:\t\t0x%08x\n", ocm.UnattendedInf);
|
|
dprintf("\tMasterOcInfPath:\t%ws\n", ocm.MasterOcInfPath);
|
|
dprintf("\tUnattendInfPath:\t%ws\n", ocm.UnattendedInfPath);
|
|
dprintf("\tSourceDir:\t\t%ws\n", ocm.SourceDir);
|
|
dprintf("\tSuiteName:\t\t%ws\n", ocm.SuiteName);
|
|
dprintf("\tSetupPageTitle:\t\t%ws\n", ocm.SetupPageTitle);
|
|
dprintf("\tWindowTitle:\t%ws\n", ocm.WindowTitle);
|
|
dprintf("\tInfListStringTable:\t0x%08x\n", (ULONG_PTR)ocm.InfListStringTable);
|
|
dprintf("\tComponentStringTable:\t0x%08x\n", (ULONG_PTR)ocm.ComponentStringTable);
|
|
dprintf("\tComponentStringTable:\t0x%08x\n", (ULONG_PTR)ocm.OcSetupPage);
|
|
dprintf("\tSetupMode:\t\t%d\n", ocm.SetupMode);
|
|
dprintf("\tTopLevelOcCount:\t%d\n", ocm.TopLevelOcCount);
|
|
// Issue-vijeshs-09/18/2000: from 1 to count
|
|
count = malloc ( ocm.TopLevelOcCount * sizeof(LONG) );
|
|
|
|
if (count) {
|
|
// read and dump needs list
|
|
ReadMemory((LPVOID) ocm.TopLevelOcStringIds, count, ocm.TopLevelOcCount *sizeof(LONG), NULL);
|
|
for (i = 0; i < ocm.TopLevelOcCount; i++) {
|
|
dprintf("\t TopLevelOcStringIds #%d:\t0x%08x\n", i, count[i]);
|
|
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
dprintf("\tTopLevelParenOcCount:\t%d\n", ocm.TopLevelParentOcCount);
|
|
|
|
count = malloc ( ocm.TopLevelParentOcCount * sizeof(LONG) );
|
|
|
|
if (count) {
|
|
// read and dump needs list
|
|
ReadMemory((LPVOID) ocm.TopLevelParentOcStringIds, count, ocm.TopLevelParentOcCount *sizeof(LONG), NULL);
|
|
for (i = 0; i < ocm.TopLevelParentOcCount; i++) {
|
|
dprintf("\t TopLevelParentOcStringIds #%d:\t0x%08x\n", i, count[i]);
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
dprintf("\tSubComponentsPresent:\t%d\n", ocm.SubComponentsPresent);
|
|
|
|
//
|
|
// Issue-vijeshs-09/18/2000:WizardPagesOrder there's not really any way to tell the exact upper bound of
|
|
// each array, though we know that it's <= TopLevelParentOcCount...since this is the case
|
|
// we just dump the point to each array of pages...
|
|
//
|
|
for (i = 0; i < WizPagesTypeMax; i++) {
|
|
dprintf("\tWizardPagesOrder[%i] (%s)\t: 0x%08x\n",
|
|
i,
|
|
GetWizPage(i),
|
|
ocm.WizardPagesOrder[i] );
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
dprintf("\tPrivateDataSubkey:\t%ws\n", ocm.PrivateDataSubkey);
|
|
dprintf("\thKeyPrivateData:\t0x%08x\n", ocm.hKeyPrivateData);
|
|
dprintf("\thKeyPrivateDataRoot:\t0x%08x\n", ocm.hKeyPrivateDataRoot);
|
|
dprintf("\tProgressTextWindow:\t0x%08x\n", ocm.ProgressTextWindow);
|
|
|
|
dprintf("\tCurrentComponentStringId:\t0x%08x\n", ocm.CurrentComponentStringId);
|
|
dprintf("\tAbortedCount:\t\t%d\n", ocm.AbortedCount);
|
|
|
|
count = malloc ( ocm.AbortedCount * sizeof(LONG) );
|
|
|
|
if (count) {
|
|
// read and dump needs list
|
|
ReadMemory((LPVOID) ocm.AbortedComponentIds, count, ocm.AbortedCount *sizeof(LONG), NULL);
|
|
for (i = 0; i < (DWORD)ocm.AbortedCount; i++) {
|
|
dprintf("\t AbortedComponentIds #%d:\t0x%08x\n", i, count[i]);
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
free(count);
|
|
}
|
|
|
|
dprintf("\tInternalFlags:\t\t0x%08x\n\n\n", ocm.InternalFlags);
|
|
|
|
dprintf("\tSetupData.SetupMode :\t0x%08x\n", ocm.SetupData.SetupMode );
|
|
dprintf("\tSetupData.ProductType :\t0x%08x\n", ocm.SetupData.ProductType );
|
|
dprintf("\tSetupData.OperationFlags :\t0x%08x\n", ocm.SetupData.OperationFlags );
|
|
dprintf("\tSetupData.SourcePath :\t%ws\n", ocm.SetupData.SourcePath );
|
|
dprintf("\tSetupData.UnattendFile :\t%ws\n", ocm.SetupData.UnattendFile );
|
|
|
|
if ((Mask&1) && ocm.InfListStringTable) {
|
|
dprintf("\t\t***InfListStringTable***\n");
|
|
move (inftable, ocm.InfListStringTable);
|
|
infdata = GetStringTableData( &inftable );
|
|
if (!infdata) {
|
|
dprintf("error retrieving string table data!\n");
|
|
return;
|
|
}
|
|
|
|
// now, dump each node with data in the string table
|
|
for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
|
|
node = GetFirstNode(infdata, ((PULONG_PTR)infdata)[i], &offset );
|
|
if (!node) {
|
|
// dprintf("No data at hash bucket %d\n", i);
|
|
} else {
|
|
//dprintf("Data at hash bucket %d\n", i);
|
|
while (node) {
|
|
//dprintf("\tNode Name:%ws\n", node->String);
|
|
pocinf = (POC_INF) GetStringNodeExtraData( node );
|
|
if (pocinf) {
|
|
dprintf("\tNode Data for %ws (0x%08x): 0x%08x\n",
|
|
node->String,
|
|
offset,
|
|
pocinf->Handle
|
|
);
|
|
} else {
|
|
dprintf("\tNo Node Data for %ws\n",
|
|
node->String
|
|
);
|
|
}
|
|
node = GetNextNode( infdata, node, &offset );
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
free( infdata );
|
|
dprintf("\n\n");
|
|
}
|
|
|
|
if ((Mask&1) && ocm.ComponentStringTable) {
|
|
dprintf("\t\t***ComponentStringTable***\n");
|
|
move (comptable, ocm.ComponentStringTable);
|
|
compdata = GetStringTableData( &comptable );
|
|
if (!compdata) {
|
|
dprintf("error retrieving string table data!\n");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// dump each node with data in the string table
|
|
//
|
|
for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
|
|
node = GetFirstNode(infdata, ((PULONG_PTR)infdata)[i], &offset );
|
|
if (!node) {
|
|
// dprintf("No data at hash bucket %d\n", i);
|
|
} else {
|
|
//dprintf("Data at hash bucket %d\n", i);
|
|
while (node) {
|
|
//dprintf("\tNode Name:%ws\n", node->String);
|
|
pcomp = (deb_POPTIONAL_COMPONENTW) GetStringNodeExtraData( node );
|
|
if (pcomp) {
|
|
DumpOcComponent( offset , node, pcomp );
|
|
} else {
|
|
dprintf("\tNo Node Data for %ws\n",
|
|
node->String
|
|
);
|
|
}
|
|
|
|
if (CheckInterupted()) {
|
|
return;
|
|
}
|
|
|
|
node = GetNextNode( infdata, node, &offset );
|
|
}
|
|
}
|
|
}
|
|
|
|
free( compdata );
|
|
}
|
|
|
|
|
|
|
|
}
|