/******************************************************************* * * 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] [![ | *]] - Dumps registry information\n"); dprintf("!dreg -d ... - Prints binary values as DWORDs\n"); dprintf("!dreg -w ... - Prints binary values as WORDs\n"); dprintf("!dreg !* - Prints all values under \n"); dprintf("!dreg - Prints all subkeys of \n"); dprintf("\n"); dprintf(" 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 : ""); 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 : ""); 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