414 lines
10 KiB
C
414 lines
10 KiB
C
/*******************************************************************
|
|
*
|
|
* Copyright (c) 1999 Microsoft Corporation
|
|
*
|
|
* DESCRIPTION: an extension to dump the contents of registry keys and values
|
|
*
|
|
* AUTHOR:
|
|
* Based on Code by : danielwe (Dan Weisman)
|
|
* ntsd addition by : kksharma (Kshitiz K. Sharma)
|
|
*
|
|
* DATE:4/20/1999
|
|
*
|
|
*******************************************************************/
|
|
|
|
|
|
#ifndef KERNEL
|
|
|
|
#ifndef Print
|
|
#define Print dprintf
|
|
#endif
|
|
|
|
|
|
#define OFLAG(l) (1L << ((DWORD)#@l - (DWORD)'a'))
|
|
#define LINE_NUMBER 0
|
|
#define NUM_ASCII_CHARS 16
|
|
#define NUM_HEX_CHARS (NUM_ASCII_CHARS * 3)
|
|
#define SPACE 7
|
|
#define PB_BUFFER_SIZE (NUM_ASCII_CHARS * 50)
|
|
|
|
VOID dregHelp() {
|
|
dprintf("!dreg -[d|w] <keyPath>[![<valueName> | *]] - Dumps registry information\n");
|
|
dprintf("!dreg -d ... - Prints binary values as DWORDs\n");
|
|
dprintf("!dreg -w ... - Prints binary values as WORDs\n");
|
|
dprintf("!dreg <keyPath>!* - Prints all values under <keyPath>\n");
|
|
dprintf("!dreg <keyPath> - Prints all subkeys of <keyPath>\n");
|
|
dprintf("\n");
|
|
dprintf("<keypath> can begin with any of the following:\n");
|
|
dprintf("\thklm - HKEY_LOCAL_MACHINE\n");
|
|
dprintf("\thkcu - HKEY_CURRENT_USER\n");
|
|
dprintf("\thkcr - HKEY_CLASSES_ROOT\n");
|
|
dprintf("\thku - HKEY_USERS\n");
|
|
dprintf("\tif absent, hklm is assumed\n");
|
|
dprintf("\n");
|
|
dprintf("Ex:\n");
|
|
dprintf("!dreg hkcu\\Software\\Microsoft\n");
|
|
dprintf("!dreg System\\CurrentControlSet\\Services\\Tcpip!*\n");
|
|
dprintf("!dreg System\\CurrentControlSet\\Services\\Tcpip!Start\n");
|
|
}
|
|
|
|
VOID PrintBinary(PBYTE pbData, DWORD cbData, USHORT uWidth)
|
|
{
|
|
CHAR line[80];
|
|
INT i;
|
|
INT ascii = 0;
|
|
PBYTE temp = pbData;
|
|
BOOL fDone = FALSE;
|
|
DWORD cbCount = 0;
|
|
|
|
CHAR hex_digits[] = "0123456789ABCDEF";
|
|
|
|
while (!fDone)
|
|
{
|
|
DWORD cb;
|
|
|
|
memset(line, 0x20, sizeof(line));
|
|
Print("%04X: ", cbCount);
|
|
for (ascii = 0,i = LINE_NUMBER, cb = 0;
|
|
ascii < NUM_ASCII_CHARS;
|
|
ascii++, temp++)
|
|
{
|
|
if ((DWORD)(temp - pbData) >= cbData)
|
|
{
|
|
if (cbData < PB_BUFFER_SIZE)
|
|
{
|
|
fDone = TRUE;
|
|
break;
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
line[i] = hex_digits[(*temp & 0xF0) >> 4];
|
|
line[i + 1] = hex_digits[(*temp & 0x0F)];
|
|
cb++;
|
|
if ((ascii + 1) % uWidth == 0)
|
|
{
|
|
line[i + 2] = 0x20;
|
|
i++;
|
|
if (uWidth > 1)
|
|
{
|
|
line[i + 3] = 0x20;
|
|
i++;
|
|
}
|
|
else if (uWidth == 1 && (!(cb % 4)))
|
|
{
|
|
line[i + 3] = 0x20;
|
|
line[i + 4] = 0x20;
|
|
i += 2;
|
|
}
|
|
}
|
|
i += 2;
|
|
line[ascii + NUM_HEX_CHARS + SPACE + LINE_NUMBER] =
|
|
(isprint(*temp) ? *temp : '.');
|
|
cbCount++;
|
|
}
|
|
|
|
line[79] = 0;
|
|
Print("%s\n", line);
|
|
}
|
|
}
|
|
|
|
VOID PrintMultiSz(PBYTE pbData)
|
|
{
|
|
LPSTR sz = (LPSTR)pbData;
|
|
DWORD csz = 0;
|
|
|
|
while (*sz)
|
|
{
|
|
Print("%d: \"%s\"\n", csz, *sz ? sz : "<empty>");
|
|
csz++;
|
|
sz += lstrlenA(sz) + 1;
|
|
}
|
|
}
|
|
|
|
VOID PrintRegistryValue(DWORD dwType, PBYTE pbData, DWORD cbData, USHORT uWidth)
|
|
{
|
|
switch (dwType)
|
|
{
|
|
case REG_SZ:
|
|
Print("REG_SZ: \"%s\"\n", *pbData ? pbData : "<empty>");
|
|
break;
|
|
|
|
case REG_EXPAND_SZ:
|
|
{
|
|
CHAR szExpanded[MAX_PATH + 1];
|
|
|
|
Print("REG_EXPAND_SZ: \"%s\"\n", pbData);
|
|
ExpandEnvironmentStringsA((LPCSTR)pbData, (LPSTR)&szExpanded,
|
|
MAX_PATH);
|
|
Print("expanded = \"%s\"\n", szExpanded);
|
|
break;
|
|
}
|
|
|
|
case REG_DWORD:
|
|
{
|
|
DWORD dwData = * ((DWORD *)pbData);
|
|
|
|
Print("REG_DWORD: %lu = 0x%08X\n", dwData, dwData);
|
|
break;
|
|
}
|
|
|
|
case REG_BINARY:
|
|
{
|
|
Print("REG_BINARY:\n");
|
|
PrintBinary(pbData, cbData, uWidth);
|
|
break;
|
|
}
|
|
|
|
case REG_MULTI_SZ:
|
|
{
|
|
Print("REG_MULTI_SZ:\n");
|
|
PrintMultiSz(pbData);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID EnumSubKeys(HKEY hkeyRoot, LPSTR szKey)
|
|
{
|
|
HKEY hkey;
|
|
LONG l;
|
|
BOOL fFound = FALSE;
|
|
|
|
l = RegOpenKeyExA(hkeyRoot, szKey, 0, KEY_READ, &hkey);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
FILETIME ft;
|
|
DWORD cbName;
|
|
CHAR szName[MAX_PATH + 1];
|
|
DWORD dwIndex;
|
|
|
|
for (dwIndex = 0; l == ERROR_SUCCESS; dwIndex++)
|
|
{
|
|
cbName = MAX_PATH;
|
|
l = RegEnumKeyExA(hkey, dwIndex, szName, &cbName, NULL,
|
|
NULL, NULL,&ft);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
Print("Subkey: %s\n", szName);
|
|
fFound = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
else
|
|
{
|
|
Print("Could not open subkey %s. Error (%d).\n", szKey, l);
|
|
}
|
|
|
|
if (!fFound)
|
|
{
|
|
Print("No subkeys\n");
|
|
}
|
|
}
|
|
|
|
VOID EnumValues(HKEY hkeyRoot, LPSTR szKey, USHORT uWidth)
|
|
{
|
|
HKEY hkey;
|
|
LONG l;
|
|
BOOL fFound = FALSE;
|
|
|
|
l = RegOpenKeyExA(hkeyRoot, szKey, 0, KEY_READ, &hkey);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
DWORD cbMax;
|
|
|
|
l = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, &cbMax, NULL, NULL);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
DWORD cbName;
|
|
CHAR szName[MAX_PATH + 1];
|
|
DWORD dwIndex;
|
|
PBYTE pbData;
|
|
DWORD dwType;
|
|
DWORD cbData;
|
|
|
|
pbData = (PBYTE)LocalAlloc(LPTR, cbMax);
|
|
|
|
if (pbData)
|
|
{
|
|
for (dwIndex = 0; l == ERROR_SUCCESS; dwIndex++)
|
|
{
|
|
cbName = MAX_PATH;
|
|
cbData = cbMax;
|
|
l = RegEnumValueA(hkey, dwIndex, szName, &cbName, NULL,
|
|
&dwType, pbData, &cbData);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
Print("Value: \"%s\" - ", szName);
|
|
PrintRegistryValue(dwType, pbData, cbData, uWidth);
|
|
Print("------------------------------------------------------------------------\n");
|
|
fFound = TRUE;
|
|
}
|
|
}
|
|
|
|
LocalFree(pbData);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
else
|
|
{
|
|
Print("Could not open subkey %s. Error (%d).\n", szKey, l);
|
|
}
|
|
|
|
if (!fFound)
|
|
{
|
|
Print("No values\n");
|
|
}
|
|
}
|
|
|
|
/************************************************************************\
|
|
* Procedure: Idreg
|
|
*
|
|
* Description: Dumps registry value
|
|
*
|
|
* Returns: fSuccess
|
|
*
|
|
* 4/14/1999 Created DanielWe
|
|
*
|
|
\************************************************************************/
|
|
BOOL Idreg(
|
|
DWORD opts,
|
|
LPCSTR InString)
|
|
{
|
|
LONG l;
|
|
HKEY hkey;
|
|
DWORD cbData = 0;
|
|
DWORD dwType;
|
|
LPBYTE pbData = NULL;
|
|
LPSTR szKey = NULL;
|
|
LPSTR szValue = NULL;
|
|
CHAR String[512];
|
|
LPTSTR lpas = String;
|
|
LPTSTR lpasOrig = String;
|
|
HKEY hkeyRoot;
|
|
|
|
strcpy(String, InString);
|
|
|
|
// Eat leading spaces first
|
|
while (*lpas && *lpas == ' ')
|
|
{
|
|
lpas++;
|
|
}
|
|
|
|
while (*lpas && *lpas != '\\')
|
|
{
|
|
lpas++;
|
|
}
|
|
|
|
if (!*lpas)
|
|
{
|
|
// Corner case.. no backslash at all. Assume HKLM and start over
|
|
hkeyRoot = HKEY_LOCAL_MACHINE;
|
|
lpas = lpasOrig;
|
|
}
|
|
else
|
|
{
|
|
// Figure out which hive they want to open
|
|
*lpas = 0;
|
|
if (!lstrcmpiA(lpasOrig, "hkcu"))
|
|
{
|
|
hkeyRoot = HKEY_CURRENT_USER;
|
|
lpas++;
|
|
}
|
|
else if (!lstrcmpiA(lpasOrig, "hklm"))
|
|
{
|
|
hkeyRoot = HKEY_LOCAL_MACHINE;
|
|
lpas++;
|
|
}
|
|
else if (!lstrcmpiA(lpasOrig, "hku"))
|
|
{
|
|
hkeyRoot = HKEY_USERS;
|
|
lpas++;
|
|
}
|
|
else if (!lstrcmpiA(lpasOrig, "hkcr"))
|
|
{
|
|
hkeyRoot = HKEY_CLASSES_ROOT;
|
|
lpas++;
|
|
}
|
|
else if (!lstrcmpiA(lpasOrig, "help"))
|
|
{
|
|
dregHelp();
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
hkeyRoot = HKEY_LOCAL_MACHINE;
|
|
|
|
// Restore the backslash because we assume if they don't use these
|
|
// keywords, then they want HKLM
|
|
*lpas = '\\';
|
|
lpas = lpasOrig;
|
|
}
|
|
}
|
|
|
|
szKey = (LPSTR)lpas;
|
|
|
|
while (*lpas && *lpas != '!')
|
|
{
|
|
lpas++;
|
|
}
|
|
|
|
if (*lpas)
|
|
{
|
|
// Null terminate the !
|
|
*lpas++ = 0;
|
|
|
|
// mark beginning of new string
|
|
szValue = (LPSTR)lpas;
|
|
}
|
|
|
|
if (szKey == NULL || *szKey == 0)
|
|
{
|
|
Print("Expected subkey name\n");
|
|
dregHelp();
|
|
return FALSE;
|
|
}
|
|
if (szValue == NULL || *szValue == 0)
|
|
{
|
|
EnumSubKeys(hkeyRoot, szKey);
|
|
}
|
|
else if (!lstrcmpA(szValue, "*"))
|
|
{
|
|
EnumValues(hkeyRoot, szKey, (USHORT)opts);
|
|
}
|
|
else
|
|
{
|
|
l = RegOpenKeyExA(hkeyRoot, (LPCSTR)szKey, 0, KEY_READ, &hkey);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
l = RegQueryValueExA(hkey, (LPCSTR)szValue, NULL, &dwType, NULL,
|
|
&cbData);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
pbData = (LPBYTE)LocalAlloc(LPTR, cbData);
|
|
l = RegQueryValueExA(hkey, (LPCSTR)szValue, NULL, &dwType, pbData,
|
|
&cbData);
|
|
if (ERROR_SUCCESS == l)
|
|
{
|
|
PrintRegistryValue(dwType, pbData, cbData, (USHORT)opts);
|
|
}
|
|
|
|
LocalFree(pbData);
|
|
}
|
|
else
|
|
{
|
|
Print("Could not query value %s!%s. Error (%d).\n", szKey, szValue, l);
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
else
|
|
{
|
|
Print("Could not open subkey %s. Error (%d).\n", szKey, l);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#endif // !KERNEL
|