📄 regmon.c
字号:
/******************************************************************************
*
* Regmon - Registry Monitor for Windows NT and Windows 9x
*
* Copyright (c) 1996 - 1998 Mark Russinovich and Bryce Cogswell
*
* See readme.txt for terms and conditions.
*
* PROGRAM: Regmon.c
*
* PURPOSE: Communicates with the RegMon driver to display
* registry activity information.
*
******************************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <commctrl.h>
#include <stdio.h>
#include <string.h>
#include <winioctl.h>
#include "resource.h"
#include "ioctlcmd.h"
#include "regmon.h"
// this typedef, present in newer include files,
// supports the building regmon on older systems
typedef struct
{
DWORD cbSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformID;
} DLLVERSIONINFO_, *PDLLVERSIONINFO_;
HRESULT (CALLBACK *pDllGetVersionProc)( PDLLVERSIONINFO_ pdvi );
// delay for listview subitem tooltip
#define BALLOONDELAY 10
// toolbar height plus the borders
#define TOOLBARHEIGHT 28
// Number of columns in the listview
#define NUMCOLUMNS 6
// Variables/definitions for the driver that performs the actual monitoring.
#define SYS_FILE _T("REGSYS.SYS")
#define SYS_NAME _T("REGMON")
#define VXD_FILE "\\\\.\\REGVXD.VXD"
#define VXD_NAME "REGVXD"
static HANDLE SysHandle = INVALID_HANDLE_VALUE;
// length in ms we wait for Regedit to update its display
#define REGEDITSLOWWAIT 750
// version number for position settings
#define POSVERSION 400
// Position settings data structure
typedef struct {
int posversion;
int left;
int top;
int width;
int height;
DWORD column[NUMCOLUMNS];
DWORD historydepth;
BOOLEAN maximized;
FILTER filter;
BOOLEAN ontop;
} POSITION_SETTINGS;
// The variable that holds the position settings
POSITION_SETTINGS PositionInfo;
// typedef for balloon popup
typedef struct {
CHAR itemText[1024];
RECT itemPosition;
} ITEM_CLICK, *PITEM_CLICK;
// toolbar constants
#define ID_TOOLBAR 1
// defined for comtl32.dll version 4.7
#define TOOLBAR_FLAT 0x800
// button definitions
// for installations that support flat style
TBBUTTON tbButtons[] = {
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{ 0, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
{ 2, IDM_CAPTURE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 4, IDM_AUTOSCROLL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 6, IDM_CLEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
{ 5, IDM_FILTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
{ 7, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 9, IDM_JUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
};
#define NUMBUTTONS 12
// for older installations
TBBUTTON tbButtonsOld[] = {
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{ 0, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{ 2, IDM_CAPTURE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 4, IDM_AUTOSCROLL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 6, IDM_CLEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{ 5, IDM_FILTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{ 7, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{ 9, IDM_JUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
};
#define NUMBUTTONSOLD 11
// Buffer into which driver can copy statistics
char Stats[ MAX_STORE ];
// Current fraction of buffer filled
DWORD StatsLen;
// Search string
TCHAR FindString[256];
FINDREPLACE FindTextInfo;
DWORD FindFlags = FR_DOWN;
BOOLEAN PrevMatch;
TCHAR PrevMatchString[256];
// Application instance handle
HINSTANCE hInst;
// For info saving
TCHAR szFileName[256];
BOOLEAN FileChosen = FALSE;
// Windows NT or Windows 9x?
BOOLEAN IsNT;
// Misc globals
HWND hWndMain;
HWND hWndFind = NULL;
UINT findMessageID;
HWND hWndList;
WNDPROC ListViewWinMain;
HWND hBalloon = NULL;
BOOLEAN Capture = TRUE;
BOOLEAN Autoscroll = TRUE;
BOOLEAN BootLog = FALSE;
BOOLEAN BootLogMenuUsed = FALSE;
BOOLEAN Deleting = FALSE;
BOOLEAN OnTop = FALSE;
// Driver's registry key
TCHAR DriverRegistryKey[] = _T("System\\CurrentControlSet\\Services\\Regmon");
// General buffer for storing temporary strings
static TCHAR msgbuf[ 257 ];
// Filter-related
FILTER FilterDefinition;
// listview size limiting
DWORD MaxLines = 0;
DWORD LastRow = 0;
// General cursor manipulation
HCURSOR hSaveCursor;
HCURSOR hHourGlass;
/******************************************************************************
*
* FUNCTION: RegeditJump
*
* PURPOSE: Opens Regedit and navigates the desired key
*
*****************************************************************************/
void RegeditJump( HWND hWnd )
{
int currentItem;
int pos;
char * ch;
HWND regeditHwnd, regeditMainHwnd;
char compressPath[MAX_PATH];
HKEY hKey;
char *value = NULL;
DWORD status;
char RegPath[MAX_PATH];
DEVMODE devMode;
// Get the color depth, which can effect the speed that Regedit
// responds to keyboard commands
devMode.dmSize = sizeof(DEVMODE);
EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &devMode );
// See if we can get a Registry path out of the listview
// find the item with the focus
currentItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED );
if( currentItem == -1 ) {
MessageBox( hWnd, _T("No item selected."),
_T("Regmon"), MB_OK|MB_ICONWARNING );
return;
}
memset( compressPath, 0, MAX_PATH );
ListView_GetItemText( hWndList, currentItem, 3, compressPath, MAX_PATH );
// If the key is a handle reference, tell the user we're sorry
if( compressPath[0] == '0' ) {
MessageBox( hWnd, _T("The full name of the selected key or value is not available."),
_T("Regmon"), MB_OK|MB_ICONWARNING );
return;
}
// We need to uncompress abbreviations
if( !strncmp( compressPath, "HKLM", strlen("HKLM"))) {
sprintf( RegPath, "\\HKEY_LOCAL_MACHINE%s", &compressPath[strlen("HKLM")] );
status = RegOpenKey( HKEY_LOCAL_MACHINE, &compressPath[strlen("HKLM")+1], &hKey );
} else if( !strncmp( compressPath, "HKCU", strlen("HKCU"))) {
sprintf( RegPath, "\\HKEY_CURRENT_USER%s", &compressPath[strlen("HKCU")] );
status = RegOpenKey( HKEY_CURRENT_USER, &compressPath[strlen("HKCU")+1], &hKey );
} else if( !strncmp( compressPath, "HKCC", strlen("HKCC"))) {
sprintf( RegPath, "\\HKEY_CURRENT_CONFIG%s", &compressPath[strlen("HKCC")] );
status = RegOpenKey( HKEY_CURRENT_CONFIG, &compressPath[strlen("HKCC")+1], &hKey );
} else if( !strncmp( compressPath, "HKCR", strlen("HKCR"))) {
sprintf( RegPath, "\\HKEY_CLASSES_ROOT%s", &compressPath[strlen("HKCR")] );
status = RegOpenKey( HKEY_CLASSES_ROOT, &compressPath[strlen("HKCR")+1], &hKey );
} else if( !strncmp( compressPath, "HKU", strlen("HKU"))) {
sprintf( RegPath, "\\HKEY_USERS%s", &compressPath[strlen("HKU")] );
status = RegOpenKey( HKEY_USERS, &compressPath[strlen("HKU")+1], &hKey );
} else {
strcpy( RegPath, compressPath );
status = FALSE;
}
// Is it a value or a key?
if( status == ERROR_SUCCESS ) {
RegCloseKey( hKey );
strcat( RegPath, "\\" );
} else {
value = strrchr( RegPath, '\\')+1;
*strrchr( RegPath, '\\' ) = 0;
}
// Open RegEdit
regeditMainHwnd = FindWindow( "RegEdit_RegEdit", NULL );
if ( regeditMainHwnd == NULL ) {
SHELLEXECUTEINFO info;
memset( &info, 0, sizeof info );
info.cbSize = sizeof info;
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.lpVerb = "open";
info.lpFile = "regedit.exe";
info.nShow = SW_SHOWNORMAL;
ShellExecuteEx( &info );
WaitForInputIdle( info.hProcess, INFINITE );
regeditMainHwnd = FindWindow( "RegEdit_RegEdit", NULL );
}
if( regeditMainHwnd == NULL ) {
MessageBox( hWnd, _T("Regmon was unable to launch Regedit."),
_T("Regmon"), MB_OK|MB_ICONERROR );
return;
}
ShowWindow( regeditMainHwnd, SW_SHOW );
SetForegroundWindow( regeditMainHwnd );
// Get treeview
regeditHwnd = FindWindowEx( regeditMainHwnd, NULL, "SysTreeView32", NULL );
SetForegroundWindow( regeditHwnd );
SetFocus( regeditHwnd );
// Close it up
for ( pos = 0; pos < 30; ++pos ) {
UINT vk = VK_LEFT;
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
}
// wait for slow displays -
// Regedit takes a while to open keys with lots of subkeys
// when running at high color depths
if( devMode.dmBitsPerPel > 8 ) Sleep(REGEDITSLOWWAIT);
// Open path
for ( ch = RegPath; *ch; ++ch ) {
if ( *ch == '\\' ) {
UINT vk = VK_RIGHT;
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
// wait for slow displays -
// Regedit takes a while to open keys with lots of subkeys
// when running at high color depths
if( devMode.dmBitsPerPel > 8 ) Sleep(REGEDITSLOWWAIT);
} else {
UINT vk = toupper(*ch);
SendMessage( regeditHwnd, WM_CHAR, vk, 0 );
}
}
// If its a value select the value
if( value ) {
UINT vk = VK_HOME;
regeditHwnd = FindWindowEx( regeditMainHwnd, NULL, "SysListView32", NULL );
SetForegroundWindow( regeditHwnd );
SetFocus( regeditHwnd );
Sleep(1000); // have to wait for Regedit to update listview
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
for ( ch = value; *ch; ++ch ) {
UINT vk = toupper(*ch);
SendMessage( regeditHwnd, WM_CHAR, vk, 0 );
}
}
SetForegroundWindow( regeditMainHwnd );
SetFocus( regeditMainHwnd );
}
/******************************************************************************
*
* FUNCTION: Abort:
*
* PURPOSE: Handles emergency exit conditions.
*
*****************************************************************************/
LONG Abort( HWND hWnd, TCHAR * Msg )
{
LPVOID lpMsgBuf;
TCHAR errmsg[256];
DWORD error = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
if( IsNT ) UnloadDeviceDriver( SYS_NAME );
sprintf(errmsg, _T("%s: %s"), Msg, lpMsgBuf );
if( error == ERROR_INVALID_HANDLE && IsNT )
wsprintf(errmsg, _T("%s\nMake sure that you are an administrator and that ")
_T("Regmon is located on a local drive."), errmsg );
MessageBox( hWnd, errmsg, _T("Regmon"), MB_OK|MB_ICONERROR );
PostQuitMessage( 1 );
LocalFree( lpMsgBuf );
return -1;
}
/******************************************************************************
*
* FUNCTION: BalloonDialog
*
* PURPOSE: Dialog function for home-brewed balloon help.
*
******************************************************************************/
LONG APIENTRY BalloonDialog( HWND hDlg, UINT message, UINT wParam, LONG lParam )
{
static ITEM_CLICK ctx;
static RECT rect;
static HFONT hfont;
LPCREATESTRUCT lpcs;
HDC hdc;
POINTS pts;
POINT pt;
DWORD newclicktime;
NONCLIENTMETRICS ncm;
static POINT lastclickpt = {0,0};
static DWORD lastclicktime = 0;
switch (message) {
case WM_CREATE:
lpcs = (void *)lParam;
ctx = *(PITEM_CLICK) lpcs->lpCreateParams;
hdc = GetDC( hDlg );
// Get font
if ( hfont == NULL ) {
memset(&ncm, 0, sizeof(ncm));
ncm.cbSize = sizeof(ncm);
SystemParametersInfo( SPI_GETNONCLIENTMETRICS,
0, &ncm, 0);
hfont = CreateFontIndirect( &ncm.lfMessageFont );
}
// is the app the focus?
if( !GetFocus()) return -1;
// Compute size of required rectangle
rect.left = 0;
rect.top = 0;
rect.right = lpcs->cx;
rect.bottom = lpcs->cy;
SelectObject( hdc, hfont );
DrawText( hdc, ctx.itemText, -1, &rect,
DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT );
// if the bounding rectangle of the subitem is big enough to display
// the text then don't pop the balloon
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -