windows-nt/Source/XPSP1/NT/base/tools/ntsdexts/regexts.c
2020-09-26 16:20:57 +08:00

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