📄 regviewer.cpp
字号:
{
// Set the *hKeyRoot handle based
// on the text taken from the ListBox.
if (lstrcmp (NameLBSelect, TEXT("HKEY_CLASSES_ROOT")) == 0)
*hKeyRoot = HKEY_CLASSES_ROOT;
if (lstrcmp (NameLBSelect, TEXT("HKEY_USERS")) == 0)
*hKeyRoot = HKEY_USERS;
if (lstrcmp (NameLBSelect, TEXT("HKEY_LOCAL_MACHINE")) == 0)
*hKeyRoot = HKEY_LOCAL_MACHINE;
if (lstrcmp (NameLBSelect, TEXT("HKEY_CURRENT_USER")) == 0)
*hKeyRoot = HKEY_CURRENT_USER;
hKey = *hKeyRoot; // hKey is used in RegEnumKey().
}//end if/else *hKeyRoot
QueryKey (hDlg, hKey);
RegCloseKey (hKey); // Close the key handle.
// rect.top = 0; rect.left = 5; rect.right = 1200; rect.bottom = 25;
// hDC = GetDC (hDlg);
// FillRect (hDC, &rect, GetStockObject(WHITE_BRUSH));
// TextOut (hDC, 5, 5, RegPath, strlen(RegPath));
// ReleaseDC (hDlg, hDC);
// SetDlgItemText (hDlg, IDE_TEXTOUT, RegPath);
{
TCHAR rgFullPath[MAX_PATH];
TCHAR *pszRoot = TEXT("HKEY_CLASSES_ROOT");
if ( hKey == HKEY_USERS ) pszRoot = TEXT("HKEY_USERS");
else if ( hKey == HKEY_LOCAL_MACHINE ) pszRoot = TEXT("HKEY_LOCAL_MACHINE");
else if ( hKey == HKEY_CURRENT_USER ) pszRoot = TEXT("HKEY_CURRENT_USER");
if ( *RegPath )
wsprintf(rgFullPath, TEXT("%s\\%s"), pszRoot, RegPath);
else
lstrcpy(rgFullPath, pszRoot);
SetDlgItemText (hDlg, IDE_TEXTOUT, rgFullPath);
}
}
/************************************************************************\
*
* FUNCTION: QueryKey();
*
* PURPOSE: To display the key's children (subkeys) and the names of
* the Values associated with it. This function uses RegEnumKey,
* RegEnumValue, and RegQueryInfoKey.
*
\************************************************************************/
VOID QueryKey (HWND hDlg, HKEY hKey)
{
TCHAR KeyName[MAX_PATH];
TCHAR ClassName[MAX_PATH] = TEXT(""); // Buffer for class name.
DWORD dwcClassLen = MAX_PATH; // Length of class string.
DWORD dwcSubKeys; // Number of sub keys.
DWORD dwcMaxSubKey; // Longest sub key size.
DWORD dwcMaxClass; // Longest class string.
DWORD dwcValues; // Number of values for this key.
DWORD dwcMaxValueName; // Longest Value name.
DWORD dwcMaxValueData; // Longest Value data.
DWORD dwcSecDesc; // Security descriptor.
FILETIME ftLastWriteTime; // Last write time.
DWORD cbName;
DWORD i;
DWORD retCode;
DWORD j;
DWORD retValue;
TCHAR ValueName[MAX_VALUE_NAME];
DWORD dwcValueName = MAX_VALUE_NAME;
TCHAR Buf[80];
// Get Class name, Value count.
RegQueryInfoKey (hKey, // Key handle.
ClassName, // Buffer for class name.
&dwcClassLen, // Length of class string.
NULL, // Reserved.
&dwcSubKeys, // Number of sub keys.
&dwcMaxSubKey, // Longest sub key size.
&dwcMaxClass, // Longest class string.
&dwcValues, // Number of values for this key.
&dwcMaxValueName, // Longest Value name.
&dwcMaxValueData, // Longest Value data.
&dwcSecDesc, // Security descriptor.
&ftLastWriteTime); // Last write time.
SetDlgItemText (hDlg, IDE_CLASS, ClassName);
SetDlgItemInt (hDlg, IDE_CVALUES, dwcValues, FALSE);
SendMessage (GetDlgItem (hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG)TEXT(".."));
// Loop until RegEnumKey fails, get
// the name of each child and enter
// it into the box.
// Enumerate the Child Keys.
// SetCursor (LoadCursor (NULL, IDC_WAIT));
for (i=0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
{
cbName = MAX_PATH;
retCode = RegEnumKeyEx(
hKey, // handle of key to enumerate
i, // index of subkey to enumerate
KeyName, // address of buffer for subkey name
&cbName, // address for size of subkey buffer
NULL, // reserved
NULL, // address of buffer for class string
NULL, // address for size of class buffer
NULL
);
if (retCode == (DWORD)ERROR_SUCCESS)
SendMessage (GetDlgItem(hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG)KeyName);
}
// Enumerate the Key Values
if (dwcValues)
for (j = 0, retValue = ERROR_SUCCESS; j < dwcValues; j++)
{
dwcValueName = MAX_VALUE_NAME;
ValueName[0] = TEXT('\0');
retValue = RegEnumValue (hKey, j, ValueName,
&dwcValueName,
NULL,
NULL,
NULL,
NULL);
if (retValue != (DWORD)ERROR_SUCCESS &&
retValue != ERROR_INSUFFICIENT_BUFFER)
{
wsprintf (Buf, TEXT("Line:%d 0 based index = %d, retValue = %d, ValueLen = %d"),
__LINE__, j, retValue, dwcValueName);
}
Buf[0] = TEXT('\0');
if (!lstrlen(ValueName))
lstrcpy (ValueName, TEXT("<NO NAME>"));
wsprintf (Buf, TEXT("%d) %s "), j, ValueName);
SendMessage (GetDlgItem (hDlg, IDL_LISTBOX2),
LB_ADDSTRING, 0, (LONG)Buf);
}// end for(;;)
// SetCursor (LoadCursor (NULL, IDC_ARROW));
}
/************************************************************************\
*
* FUNCTION: DisplayKeyData();
*
* PURPOSE: To display the keys values and value types to the Value edit
* field. This function is called when the right hand listbox
* is double clicked. The functionality is much like that found
* in the function PrintTree, please see it for more details.
*
\************************************************************************/
VOID DisplayKeyData (HWND hDlg, TCHAR *RegPath, HKEY hKeyRoot)
{
HKEY hKey;
DWORD dwLBIndex;
TCHAR Buf[LINE_LEN];
TCHAR ValueName[MAX_VALUE_NAME];
DWORD cbValueName = MAX_VALUE_NAME;
DWORD dwType;
DWORD retCode;
TCHAR ClassName[MAX_PATH];
DWORD dwcClassLen = MAX_PATH;
DWORD dwcSubKeys;
DWORD dwcMaxSubKey;
DWORD dwcMaxClass;
DWORD dwcValues;
DWORD dwcMaxValueName;
DWORD dwcMaxValueData;
DWORD dwcSecDesc;
FILETIME ftLastWriteTime;
BYTE *bData;
DWORD cbData;
TCHAR *outBuf;
DWORD i;
DWORD cStrLen;
TCHAR *BinaryStrBuf;
TCHAR *ptr;
// OPEN THE KEY.
// LBIndex should == value index.
dwLBIndex = SendMessage (GetDlgItem (hDlg, IDL_LISTBOX2),
LB_GETCURSEL, 0, 0);
retCode = RegOpenKeyEx (hKeyRoot, // Key handle at root level.
RegPath, // Path name of child key.
0, // Reserved.
KEY_EXECUTE, // Requesting read access.
&hKey); // Address of key to be returned.
if (retCode)
{
wsprintf (Buf, TEXT("Error: RegOpenKeyEx = %d"), retCode);
MessageBox (hDlg, Buf, TEXT("DisplayKeyData()"), MB_OK);
return;
}
// ADD A QUERY AND ALLOCATE A BUFFER FOR BDATA.
// SetCursor (LoadCursor (NULL, IDC_WAIT));
retCode =
RegQueryInfoKey (hKey, // Key handle.
ClassName, // Buffer for class name.
&dwcClassLen, // Length of class string.
NULL, // Reserved.
&dwcSubKeys, // Number of sub keys.
&dwcMaxSubKey, // Longest sub key size.
&dwcMaxClass, // Longest class string.
&dwcValues, // Number of values for this key.
&dwcMaxValueName, // Longest Value name.
&dwcMaxValueData, // Longest Value data.
&dwcSecDesc, // Security descriptor.
&ftLastWriteTime); // Last write time.
if (retCode)
{
wsprintf (Buf, TEXT("Error: RegQIK = %d, %d"), retCode, __LINE__);
MessageBox (hDlg, Buf, TEXT(""), MB_OK);
}
bData = (BYTE *) LocalAlloc(LMEM_FIXED, dwcMaxValueData);
cbData = dwcMaxValueData;
// ENUMERATE THE KEY.
retCode = RegEnumValue (hKey, // Key handle returned from RegOpenKeyEx.
dwLBIndex, // Value index, taken from listbox.
ValueName, // Name of value.
&cbValueName,// Size of value name.
NULL, // Reserved, dword = NULL.
&dwType, // Type of data.
bData, // Data buffer.
&cbData); // Size of data buffer.
if (retCode != ERROR_SUCCESS)
{
if (dwType < REG_FULL_RESOURCE_DESCRIPTOR)
{
wsprintf (Buf, TEXT("Error: RegEnumValue = %d, cbData = %d, line %d"),
retCode, cbData, __LINE__);
MessageBox (hDlg, Buf, TEXT(""), MB_OK);
}
}
switch (dwType)
{
// REG_NONE ( 0 ) // No value type
// REG_SZ ( 1 ) // Unicode nul terminated string
// REG_EXPAND_SZ ( 2 ) // Unicode nul terminated string
// (with environment variable references)
// REG_BINARY ( 3 ) // Free form binary
// REG_DWORD ( 4 ) // 32-bit number
// REG_DWORD_LITTLE_ENDIAN ( 4 ) // 32-bit number (same as REG_DWORD)
// REG_DWORD_BIG_ENDIAN ( 5 ) // 32-bit number
// REG_LINK ( 6 ) // Symbolic Link (unicode)
// REG_MULTI_SZ ( 7 ) // Multiple Unicode strings
// REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map
// REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description
case REG_NONE:
SetDlgItemText (hDlg, IDE_VALUE1, (LPCTSTR) TEXT("REG_NONE: No defined value type."));
break;
case REG_SZ:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_SZ: A null-terminated Unicode string."));
outBuf = (TCHAR *) LocalAlloc(LMEM_FIXED, cbData + (2*sizeof(TCHAR)));
*outBuf = TEXT('\0');
lstrcat (outBuf, TEXT("\""));
lstrcat (outBuf, (LPTSTR) bData);
lstrcat (outBuf, TEXT("\""));
SetDlgItemText (hDlg, IDE_VALUE2, outBuf);
LocalFree ((HLOCAL)outBuf);
break;
case REG_EXPAND_SZ:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_EXPAND_SZ: A String referencing environment variables i.e. PATH."));
outBuf = (TCHAR *)LocalAlloc (LMEM_FIXED, cbData + (2*sizeof(TCHAR)));
*outBuf = TEXT('\0');
lstrcat (outBuf, TEXT("\""));
lstrcat (outBuf, (LPTSTR) bData);
lstrcat (outBuf, TEXT("\""));
SetDlgItemText (hDlg, IDE_VALUE2, outBuf);
LocalFree ((HLOCAL)outBuf);
break;
case REG_BINARY:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_BINARY: Freeform binary data."));
BinaryStrBuf = (TCHAR * )LocalAlloc (LMEM_FIXED, 3*(cbData+1) * sizeof(TCHAR));
if (BinaryStrBuf)
{
for (i = 0; i < cbData; i++)
{
wsprintf (BinaryStrBuf+(3*i), TEXT("%02x "), (BYTE)bData[i]);
}
BinaryStrBuf[i*3] = TEXT('\0');
SetDlgItemText (hDlg, IDE_VALUE2, BinaryStrBuf);
}
else
{
MessageBox (hDlg, TEXT("Error: BinaryStrBuf = malloc failed"),
TEXT("Debug: DisplayKeyData"), MB_OK);
}
SetDlgItemText (hDlg, IDL_LISTBOX2, BinaryStrBuf);
LocalFree ((HLOCAL)BinaryStrBuf);
break;
case REG_DWORD:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_DWORD: A 32 bit number."));
SetDlgItemInt (hDlg, IDE_VALUE2, *(UINT *)bData, FALSE);
break;
case REG_DWORD_BIG_ENDIAN:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_DWORD_BIG_ENDIAN: A 32 bit number in big endian format."));
SetDlgItemInt (hDlg, IDE_VALUE2, *(UINT *)bData, TRUE);
break;
case REG_LINK:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_LINK: A Unicode symbolic link."));
SetDlgItemText (hDlg, IDE_VALUE2, (LPTSTR) bData);
break;
case REG_MULTI_SZ:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_MULTI_SZ: An array of null-terminated strings."));
// Count the NULLs in the buffer to
// find out how many strings there are.
for (i=0, cStrLen=4; i < cbData; i++)
if (!bData[i])
cStrLen+=4; // Add room for two quotes and two
// spaced per string.
outBuf = (TCHAR *)LocalAlloc (LMEM_FIXED, cbData + cStrLen);
ptr = (LPTSTR) bData; // Set ptr to beginning of buffer.
*outBuf = TEXT('\0'); // Initialize output string.
lstrcat (outBuf, TEXT("{ ")); // Do first bracket.
while (*ptr) // Loop til you hit 2 NULLs in a row.
{
lstrcat (outBuf, TEXT("\"")); // Put quotes around each string.
lstrcat (outBuf, ptr);
lstrcat (outBuf, TEXT("\" "));
ptr += lstrlen(ptr)+1;
}
lstrcat (outBuf, TEXT("}")); // Add final bracket.
SetDlgItemText (hDlg, IDE_VALUE2, outBuf);
LocalFree ((HLOCAL) outBuf); // free output string.
break;
case REG_RESOURCE_LIST: // CM_RESOURCE_LIST is complex. Print it
// as a free formed binary data for now.
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_RESOURCE_LIST: A device-driver resource list."));
// How to handle sprintf
BinaryStrBuf = (TCHAR *) LocalAlloc (LMEM_FIXED, 3*(cbData+1) * sizeof(TCHAR));
if (BinaryStrBuf)
{
for (i = 0; i < cbData; i++)
{
wsprintf (BinaryStrBuf+(3*i), TEXT("%02x "), (BYTE)bData[i]);
}
BinaryStrBuf[3*i] = TEXT('\0');
SetDlgItemText (hDlg, IDE_VALUE2, BinaryStrBuf);
}
else
{
MessageBox (hDlg, TEXT("Error: BinaryStrBuf = malloc failed"),
TEXT("Debug: DisplayKeyData"), MB_OK);
}
SetDlgItemText (hDlg, IDL_LISTBOX2, BinaryStrBuf);
LocalFree ((HLOCAL)BinaryStrBuf);
break;
case REG_FULL_RESOURCE_DESCRIPTOR:
SetDlgItemText (hDlg, IDE_VALUE1, TEXT("REG_FULL_RESOURCE_DESCRIPTOR: A resource list in the hardware description."));
break;
default:
wsprintf (Buf, TEXT("Undefined in this verion of the Registry Viewer. %d"),
dwType);
SetDlgItemText (hDlg, IDE_VALUE1, Buf);
break;
} // end switch
LocalFree ((HLOCAL)bData);
// SetCursor (LoadCursor (NULL, IDC_ARROW));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -