Example: Listing Registry Keys and Contents
Program 3-2 (lsW, the file and directory listing program); it processes registry keys and name/value pairs rather than directories and files.
Program 3-4. lsReg: Listing Registry Keys and Contents
/* Chapter 3. lsReg: Registry list command. Adapted from Prog. 3-2. */
/* lsReg [options] SubKey */
#include "EvryThng.h"
BOOL TraverseRegistry (HKEY, LPTSTR, LPTSTR, LPBOOL);
BOOL DisplayPair (LPTSTR, DWORD, LPBYTE, DWORD, LPBOOL);
BOOL DisplaySubKey (LPTSTR, LPTSTR, PFILETIME, LPBOOL);
int _tmain (int argc, LPTSTR argv [])
{
BOOL Flags [2], ok = TRUE;
TCHAR KeyName [MAX_PATH + 1];
LPTSTR pScan;
DWORD i, KeyIndex;
HKEY hKey, hNextKey;
/* Tables of predefined key names and keys. */
LPTSTR PreDefKeyNames [] = {
_T ("HKEY_LOCAL_MACHINE"), _T ("HKEY_CLASSES_ROOT"),
_T ("HKEY_CURRENT_USER"), _T ("HKEY_CURRENT_CONFIG"), NULL };
HKEY PreDefKeys [] = {
HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT,
HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG };
KeyIndex = Options (
argc, argv, _T ("Rl"), &Flags [0], &Flags [1], NULL);
/* "Parse" the search pattern into "key" and "subkey". */
/* Build the key. */
pScan = argv [KeyIndex];
for (i = 0; *pScan != _T ('\\') && *pScan != _T ('\0');
pScan++, i++) KeyName [i] = *pScan;
KeyName [i] = _T ('\0');
if (*pScan == _T ('\\')) pScan++;
/* Translate predefined key name to an HKEY. */
for (i = 0; PreDefKeyNames [i] != NULL &&
_tcscmp (PreDefKeyNames [i], KeyName) != 0; i++);
hKey = PreDefKeys [i];
RegOpenKeyEx (hKey, pScan, 0, KEY_READ, &hNextKey);
hKey = hNextKey;
ok = TraverseRegistry (hKey, argv [KeyIndex], NULL, Flags);
return ok ? 0 : 1;
}
BOOL TraverseRegistry (HKEY hKey, LPTSTR FullKeyName, LPTSTR SubKey,
LPBOOL Flags)
/* Traverse registry key and subkeys if the -R option is set. */
{
HKEY hSubK;
BOOL Recursive = Flags [0];
LONG Result;
DWORD ValType, Index, NumSubKs, SubKNameLen, ValNameLen, ValLen;
DWORD MaxSubKLen, NumVals, MaxValNameLen, MaxValLen;
FILETIME LastWriteTime;
LPTSTR SubKName, ValName;
LPBYTE Val;
TCHAR FullSubKName [MAX_PATH + 1];
/* Open up the key handle. */
RegOpenKeyEx (hKey, SubKey, 0, KEY_READ, &hSubK);
/* Find max size info regarding the key and allocate storage. */
RegQueryInfoKey (hSubK, NULL, NULL, NULL, &NumSubKs,
&MaxSubKLen, NULL, &NumVals, &MaxValNameLen,
&MaxValLen, NULL, &LastWriteTime);
SubKName = malloc (MaxSubKLen+1); /* Size w/o null. */
ValName = malloc (MaxValNameLen+1); /* Allow for null. */
Val = malloc (MaxValLen); /* Size in bytes. */
/* First pass for name/value pairs. */
for (Index = 0; Index < NumVals; Index++) {
ValNameLen = MaxValNameLen + 1; /* Set each time! */
ValLen = MaxValLen + 1;
RegEnumValue (hSubK, Index, ValName,
&ValNameLen, NULL, &ValType, Val, &ValLen);
DisplayPair (ValName, ValType, Val, ValLen, Flags);
}
/* Second pass for subkeys. */
for (Index = 0; Index < NumSubKs; Index++) {
SubKNameLen = MaxSubKLen + 1;
RegEnumKeyEx (hSubK, Index, SubKName, &SubKNameLen,
NULL, NULL, NULL, &LastWriteTime);
DisplaySubKey (FullKName, SubKName, &LastWriteTime, Flags);
if (Recursive) {
_stprintf (FullSubKName, _T ("%s\\%s"), FullKName,
SubKName);
TraverseRegistry (hSubK, FullSubKName, SubKName, Flags);
}
}
_tprintf (_T ("\n"));
free (SubKName); free (ValName); free (Val);
RegCloseKey (hSubK);
return TRUE;
}
BOOL DisplayPair (LPTSTR ValueName, DWORD ValueType,
LPBYTE Value, DWORD ValueLen, LPBOOL Flags)
/* Function to display name/value pairs. */
{
LPBYTE pV = Value;
DWORD i;
_tprintf (_T ("\nValue: %s = "), ValueName);
switch (ValueType) {
case REG_FULL_RESOURCE_DESCRIPTOR: /* 9: hardware description. */
case REG_BINARY: /* 3: Binary data in any form. */
for (i = 0; i < ValueLen; i++, pV++)
_tprintf (_T (" %x"), *pV);
break;
case REG_DWORD: /* 4: A 32-bit number. */
_tprintf (_T ("%x"), (DWORD)*Value);
break;
case REG_MULTI_SZ: /* 7: Array of null-terminated strings. */
case REG_SZ: /* 1: A null-terminated string. */
_tprintf (_T ("%s"), (LPTSTR) Value);
break;
/* ... Several other types ... */
}
return TRUE;
}
BOOL DisplaySubKey (LPTSTR KeyName, LPTSTR SubKeyName,
PFILETIME pLastWrite, LPBOOL Flags)
{
BOOL Long = Flags [1];
SYSTEMTIME SysLastWrite;
_tprintf (_T ("\nSubkey: %s"), KeyName);
if (_tcslen (SubKeyName) > 0)
_tprintf (_T ("\\%s "), SubKeyName);
if (Long) {
FileTimeToSystemTime (pLastWrite, &SysLastWrite);
_tprintf (_T ("%02d/%02d/%04d %02d:%02d:%02d"),
SysLastWrite.wMonth, SysLastWrite.wDay,
SysLastWrite.wYear, SysLastWrite.wHour,
SysLastWrite.wMinute, SysLastWrite.wSecond);
}
return TRUE;
}