|
|
/*--
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; }
|