windows-nt/Source/XPSP1/NT/windows/appcompat/tools/dumpsdb/dumpsdb.cpp

285 lines
7.4 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*--
Copyright (c) 1999 Microsoft Corporation
Module Name:
dumpsdb.c
Abstract:
code for a dump tool for shim db files
Author:
dmunsil 02/02/2000
Revision History:
Notes:
This program dumps a text representation of all of the data in a shim db file.
--*/
#define _UNICODE
#define WIN
#define FLAT_32
#define TRUE_IF_WIN32 1
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#define _WINDOWS
#include <windows.h>
#include <stdio.h>
extern "C" {
#include "shimdb.h"
}
BOOL bDumpDB(PDB pdb, TAGID tiParent, WCHAR *szIndent, BOOL bWithTagIDs);
BOOL bGetTypeName(TAG tWhich, WCHAR *szName);
extern "C" int __cdecl wmain(int argc, wchar_t *argv[])
{
PDB pdb;
int nReturn = 0;
LPWSTR szDB = NULL;
BOOL bSuccess;
BOOL bWithTagIDs = TRUE;
WCHAR szIndent[500];
WCHAR szArg[500];
WCHAR szDbID[128];
PSDBDATABASEINFO psdbInfo = NULL;
if (argc < 2 || (argv[1][1] == '?')) {
wprintf(L" Usage: dumpsdb foo.sdb > foo.txt\n");
return 1;
}
if ((argv[1][0] == '/' || argv[1][0] == '-') &&
(argv[1][1] == 'd' || argv[1][1] == 'D')) {
bWithTagIDs = FALSE;
szDB = argv[2];
} else {
szDB = argv[1];
}
// Open the DB.
pdb = SdbOpenDatabase(szDB, DOS_PATH);
if (pdb == NULL) {
nReturn = 1;
wprintf(L"Error: can't open DB \"%s\"\n", szDB);
return 0;
}
SdbGetDatabaseInformationByName(szDB, &psdbInfo);
SdbGUIDToString(&psdbInfo->guidDB, szDbID);
wprintf(L"Dumping DB \"%s %s. Version %d.%d.\"\n",
szDB,
szDbID,
psdbInfo->dwVersionMajor,
psdbInfo->dwVersionMinor);
wcscpy(szIndent, L"");
SdbFreeDatabaseInformation(psdbInfo);
bSuccess = bDumpDB(pdb, TAGID_ROOT, szIndent, bWithTagIDs);
wprintf(L"Closing DB.\n");
SdbCloseDatabase(pdb);
return nReturn;
}
BOOL bGetTypeName(TAG tWhich, WCHAR *szName)
{
DWORD i;
LPCWSTR pName = SdbTagToString(tWhich);
if (NULL != pName) {
wcscpy(szName, pName);
return TRUE;
}
swprintf(szName, L"!unknown_tag!");
return TRUE;
}
BOOL bDumpDB(PDB pdb, TAGID tiParent, WCHAR *szIndent, BOOL bWithTagIDs)
{
TAGID tiTemp;
WCHAR szTemp[200];
WCHAR szNewIndent[200];
tiTemp = SdbGetFirstChild(pdb, tiParent);
while (tiTemp) {
TAG tWhich;
TAG_TYPE ttType;
DWORD dwData;
LARGE_INTEGER liData;
WCHAR szData[1000];
tWhich = SdbGetTagFromTagID(pdb, tiTemp);
ttType = GETTAGTYPE(tWhich);
if (!bGetTypeName(tWhich, szTemp)) {
wprintf(L"Error getting Tag name. Tag: 0x%4.4X\n", (DWORD)tWhich);
return FALSE;
}
if (bWithTagIDs) {
wprintf(L"%s0x%8.8X | 0x%4.4X | %-13s ", szIndent, tiTemp, tWhich, szTemp);
} else {
wprintf(L"%s%-13s ", szIndent, szTemp);
if (wcsstr(szTemp, L"_TAGID")) {
tiTemp = SdbGetNextChild(pdb, tiParent, tiTemp);
continue;
}
}
switch (ttType) {
case TAG_TYPE_NULL:
wprintf(L" | NULL |\n");
break;
case TAG_TYPE_BYTE:
dwData = SdbReadBYTETag(pdb, tiTemp, 0);
wprintf(L" | BYTE | 0x%2.2X\n", dwData);
break;
case TAG_TYPE_WORD:
dwData = SdbReadWORDTag(pdb, tiTemp, 0);
if (tWhich == TAG_INDEX_KEY || tWhich == TAG_INDEX_TAG) {
// for index tags and keys, we'd like to see what the names are
if (!bGetTypeName((TAG)dwData, szTemp)) {
wprintf(L"Error getting Tag name. Tag: 0x%4.4X\n", dwData);
return FALSE;
}
wprintf(L" | WORD | 0x%4.4X (%s)\n", dwData, szTemp);
} else {
wprintf(L" | WORD | 0x%4.4X\n", dwData);
}
break;
case TAG_TYPE_DWORD:
dwData = SdbReadDWORDTag(pdb, tiTemp, 0);
wprintf(L" | DWORD | 0x%8.8X\n", dwData);
break;
case TAG_TYPE_QWORD:
liData.QuadPart = SdbReadQWORDTag(pdb, tiTemp, 0);
wprintf(L" | QWORD | 0x%8.8X%8.8X\n", liData.HighPart, liData.LowPart);
break;
case TAG_TYPE_STRINGREF:
if (!SdbReadStringTag(pdb, tiTemp, szData, 1000 * sizeof(WCHAR))) {
wcscpy(szData, L"(error)");
}
wprintf(L" | STRINGREF | %s\n", szData);
break;
case TAG_TYPE_STRING:
dwData = SdbGetTagDataSize(pdb, tiTemp);
if (!SdbReadStringTag(pdb, tiTemp, szData, 1000)) {
wcscpy(szData, L"(error)");
}
wprintf(L" | STRING | Size 0x%8.8X | %s\n", dwData, szData);
break;
case TAG_TYPE_BINARY:
dwData = SdbGetTagDataSize(pdb, tiTemp);
wprintf(L" | BINARY | Size 0x%8.8X", dwData);
switch(tWhich) {
case TAG_INDEX_BITS:
{
char szKey[9];
DWORD dwRecords;
INDEX_RECORD *pRecords;
DWORD i;
wprintf(L"\n");
ZeroMemory(szKey, 9);
dwRecords = dwData / sizeof(INDEX_RECORD);
pRecords = (INDEX_RECORD *)SdbGetBinaryTagData(pdb, tiTemp);
for (i = 0; i < dwRecords; ++i) {
char *szRevKey;
int j;
szRevKey = (char *)&pRecords[i].ullKey;
for (j = 0; j < 8; ++j) {
szKey[j] = isprint(szRevKey[7-j]) ? szRevKey[7-j] : '.';
}
if (bWithTagIDs) {
wprintf(L"%s Key: 0x%I64X (\"%-8S\"), TAGID: 0x%08X\n",
szIndent, pRecords[i].ullKey, szKey, pRecords[i].tiRef);
} else {
wprintf(L"%s Key: 0x%I64X (\"%-8S\")\n",
szIndent, pRecords[i].ullKey, szKey);
}
}
}
break;
case TAG_EXE_ID:
case TAG_MSI_PACKAGE_ID:
case TAG_DATABASE_ID:
// this is exe id -- which happens to be GUID which we do understand
{
GUID *pGuid;
UNICODE_STRING sGuid;
pGuid = (GUID*)SdbGetBinaryTagData(pdb, tiTemp);
// convert this thing to string
if (pGuid && NT_SUCCESS(RtlStringFromGUID(*pGuid, &sGuid))) {
wprintf(L" | %s", sGuid.Buffer);
RtlFreeUnicodeString(&sGuid);
}
wprintf(L"\n");
}
break;
default:
wprintf(L"\n");
break;
}
break;
case TAG_TYPE_LIST:
dwData = SdbGetTagDataSize(pdb, tiTemp);
wprintf(L" | LIST | Size 0x%8.8X\n", dwData);
wcscpy(szNewIndent, szIndent);
wcscat(szNewIndent, L" ");
bDumpDB(pdb, tiTemp, szNewIndent, bWithTagIDs);
wprintf(L"%s-end- %s\n", szIndent, szTemp);
break;
default:
dwData = SdbGetTagDataSize(pdb, tiTemp);
wprintf(L" | UNKNOWN | Size 0x%8.8X\n", dwData);
break;
}
tiTemp = SdbGetNextChild(pdb, tiParent, tiTemp);
}
return TRUE;
}