⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regmon.c

📁 一个完整的注册表监视器
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************
*
*       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 + -