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

📄 vxdmon.c

📁 VxDMon_系统驱动监视器,对感兴趣的人会有帮助的。
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
*
*       VxdMon - VxD Device Monitor
*		
*		Copyright (c) 1996 Mark Russinovich and Bryce Cogswell
*
*		You have the right to take this code and use it in whatever way you
*		wish.
*
*    	PROGRAM: VxdMon.c
*
*    	PURPOSE: Communicates with the VxdMon VxD to display performance 
*				information	virtual device activity.
*
******************************************************************************/

#include <windows.h>    // includes basic windows functionality
#include <commctrl.h>   // includes the common control header
#include <stdio.h>
#include <string.h>
#include "resource.h"
#include "../vxd/vxdmon.h"

// Variables/definitions for the VxD that performs the actual monitoring.
#define			VXD_NAME		"\\\\.\\VXDMHLP.VXD"
static HANDLE	vxd_handle		= INVALID_HANDLE_VALUE;

// White space in services.dat and profile.dat
#define ISWHITE(c)	( (c)==' ' || (c)=='\t' || (c)=='\n' || (c)=='\r' )

// Indicate whether a service is hooked or not, or for higher levels of tree, whether
// sub-items are hooked or not.  These values correspond to the ImageList for the 
// selection tree.
enum {
	HOOK_NO		= 0,			// Not hooked
	HOOK_YES	= 1,			// Hooked
	HOOK_PART	= 2,			// Subset of subitems hooked
};

// Structure used to define each hookable service.  The set of services is defined
// by the services.dat file.
struct service {
	DWORD				Ordinal;		// VxD and service number
	char			*	Name;			// Name of service
	HTREEITEM			hTree;			// Pointer to item in service-selection tree
	BOOL				Hooked;			// Whether service is currently hooked
	struct service	*	Next;			// Next service pointer
};
// The global list of hookable services
struct service		*	ServiceList = NULL;


// Variables for reading statistics from our VxD
#define					MAX_SERVICE		2000
// Buffer into which VxD can copy statistics
struct vxdmon_stats		Stats[ MAX_SERVICE ];
// Current fraction of buffer filled
DWORD					numStats;

// Application instance handle
HINSTANCE				hInst;

// General buffer for storing temporary strings
static char				msgbuf[ 200 ];

// Root of selection tree
HTREEITEM				hSelectRoot;
// Image list for selection tree
HIMAGELIST  			hSelectImageList;
// Image list for ancestor/descendant trees
HIMAGELIST				hCallImageList;

// General cursor manipulation
HCURSOR 				hSaveCursor;
HCURSOR 				hHourGlass;

// name of stats file
char					szFileName[256];
BOOL					GotFile 		= FALSE;	// Do we have a valide file name

// name of help file
char					szHelpFileName[] = "VXDMON.HLP";

// name of call graph file
char					CallFileName[256];

// global status variables
BOOL					ProfileChanged	= FALSE; 	// new hook settings
BOOL					IgnoreUncalled	= TRUE;		// Ignore services never called
BOOL					Overhead		= TRUE;		// Compensate for hooking overhead
DWORD					OverheadCycles	= 0;		// Overhead incurred by VxD monitoring code

// Potential states of call-tree items.
// These correspond to the call-tree image list.
enum {
	CALL_NONE	= 0,
	CALL_UP		= 1,
	CALL_DOWN	= 2,
}; 

// Which service are we currently displaying a call tree for?
struct vxdmon_stats *	CallTreeStat;
BOOL					CallTreeDown	= FALSE;	// tree grows up or down?

BOOL					ResetStatsOnUpdate	= TRUE;

// procs
long APIENTRY MainWndProc( HWND, UINT, UINT, LONG );
long APIENTRY TreeWndProc( HWND, UINT, UINT, LONG );
long APIENTRY CallWndProc( HWND, UINT, UINT, LONG );
BOOL APIENTRY About( HWND, UINT, UINT, LONG );
//functions
BOOL InitApplication( HANDLE );
HWND InitInstance( HANDLE, int );
HWND CreateListView( HWND );
LRESULT NotifyHandler( HWND, UINT, WPARAM, LPARAM );
int CALLBACK ListViewCompareProc( LPARAM, LPARAM, LPARAM );
HWND CreateTreeView( HWND hWndParent );
BOOL AddTreeViewItems( HWND hwndTree );
HTREEITEM AddOneTreeViewItem( HWND hwndTree, HTREEITEM hParent, HTREEITEM hInsAfter,
							LPSTR szText, DWORD lParam );
BOOL DefaultTreeSelections( HWND hwndTree );
BOOL HookServices( HWND hTree, HTREEITEM hItem );
POINT ClickPoint( HWND hWnd );
BOOL AddCallTreeItems( HWND hTree, HTREEITEM Parent, struct vxdmon_stats * stats, int depth );
void WriteDefaultTreeSelections( HWND hTree, HTREEITEM hItem );
void CreateCallTree( HWND hWnd, struct vxdmon_stats * item, BOOL calldown );
BOOL GetFileName( HWND hWnd, char *FileName, char *Filter, char *Ext );
void SaveStatisticsData( HWND hWnd, HWND hWndListView );
void RefreshStatistics( HWND hWnd, HWND hWndListView, int SortItem );

/******************************************************************************
*
*	FUNCTION:	Abort:
*
*	PURPOSE:	Handles emergency exit conditions.
*
*****************************************************************************/
void Abort( HWND hWnd, char * Msg )
{
	MessageBox( hWnd, Msg, "VxdMon", MB_OK );
	PostQuitMessage( 1 );
}

/******************************************************************************
*
*	FUNCTION:	StringDup:
*
*	PURPOSE:	Convenience function for duplicating a string into heap-allocated memory.
*
******************************************************************************/
char * StringDup( const char * str )
{
	char * new = LocalAlloc( LPTR, strlen(str)+1 );
	strcpy( new, str );
	return new;
}

/******************************************************************************
*
*	FUNCTION:	LookupService
*
*	PURPOSE:	Searches the list of services defined by services.dat for a particular ordinal.
*
******************************************************************************/
struct service * LookupService( DWORD Ordinal )
{
	struct service * p = ServiceList;
	while ( p  &&  p->Ordinal != Ordinal )
		p = p->Next;
	return p;
}

/******************************************************************************
*
*	FUNCTION:	NewService
*
*	PURPOSE:	Allocates space for and initializes a new service.
*				Used while reading the services.dat file.
*
******************************************************************************/
struct service * NewService( DWORD Ordinal, const char * Name )
{
	struct service *	New	 = LocalAlloc( LPTR, sizeof *New );
	// Initialize info for new service
	New->Ordinal	= Ordinal;
	New->Name		= StringDup( Name );
	// Add to list of services
	New->Next		= ServiceList;
	ServiceList		= New;
	// Return newly created service
	return New;
}

/******************************************************************************
*
*	FUNCTION:	ServiceName
*
*	PURPOSE:	Convenience function for both searching for a service by ordinal, and then
*				returning the name of the service.
*
******************************************************************************/
char * ServiceName( DWORD ord )
{
	struct service * s = LookupService( ord );
	if ( s )
		return s->Name;
	else
		return "???";
}



/****************************************************************************
*
*	FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
*
*	PURPOSE:	calls initialization function, processes message loop
*
****************************************************************************/
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{
	MSG 	msg;      
	HWND	hWnd;
	HANDLE 	hAccel ;                 

	if ( ! InitApplication( hInstance ) )
		return FALSE;     

	/* Perform initializations that apply to a specific instance */
	if ( (hWnd = InitInstance( hInstance, nCmdShow )) == NULL )
		return FALSE;

  	// load menu accelerators
	hAccel = LoadAccelerators ( hInstance, "Accelerators") ;

	/* Acquire and dispatch messages until a WM_QUIT message is received. */
	while ( GetMessage( &msg, NULL, 0, 0 ) )  {
		if (!TranslateAccelerator (hWnd, hAccel, &msg)) {
			TranslateMessage( &msg );
			DispatchMessage( &msg ); 
		}
	}
	return msg.wParam;										 
}


/****************************************************************************
*
*    FUNCTION: InitApplication(HANDLE)
*
*    PURPOSE: Initializes window data and registers window class
*
****************************************************************************/
BOOL InitApplication( HANDLE hInstance )	/* current instance             */
{
	WNDCLASS  wc;
	
	/* Fill in window class structure with parameters that describe the       */
	/* main (statistics) window.                                                           */
	wc.style			= 0;                     
	wc.lpfnWndProc		= (WNDPROC)MainWndProc; 
	wc.cbClsExtra		= 0;              
	wc.cbWndExtra		= 0;              
	wc.hInstance		= hInstance;       
	wc.hIcon			= LoadIcon( hInstance, "APPICON" );
	wc.hCursor			= LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground	= GetStockObject( /*WHITE_BRUSH*/ LTGRAY_BRUSH ); 
	wc.lpszMenuName		= "LISTMENU";  
	wc.lpszClassName	= "VxDMonClass";
	if ( ! RegisterClass( &wc ) )
		return FALSE;


	/* Fill in window class structure with parameters that describe the       */
	/* service-selection tree view window.                                                           */
	wc.style			= 0;                     
	wc.lpfnWndProc		= (WNDPROC)TreeWndProc; 
	wc.cbClsExtra		= 0;              
	wc.cbWndExtra		= 0;              
	wc.hInstance		= hInstance;       
	wc.hIcon			= LoadIcon( hInstance, "TREEICON" );
	wc.hCursor			= LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground	= GetStockObject( /*WHITE_BRUSH*/ LTGRAY_BRUSH ); 
	wc.lpszMenuName		= "TREEMENU";  
	wc.lpszClassName	= "VxDMonTreeClass";
	if ( ! RegisterClass( &wc ) )
		return FALSE;

	/* Fill in window class structure with parameters that describe the       */
	/* call tree window.                                                           */
	wc.style			= 0;                     
	wc.lpfnWndProc		= (WNDPROC)CallWndProc; 
	wc.cbClsExtra		= 0;              
	wc.cbWndExtra		= sizeof(DWORD);	// reserve memory for tree handle
	wc.hInstance		= hInstance;       
	wc.hCursor			= LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground	= GetStockObject( /*WHITE_BRUSH*/ LTGRAY_BRUSH ); 
	wc.lpszMenuName		= "CALLMENU";  
	// register call-down class
	wc.lpszClassName	= "VxDMonCallDownClass";
	wc.hIcon			= LoadIcon( hInstance, "CALLEE" );
	if ( ! RegisterClass( &wc ) )
		return FALSE;
	// register call-up class
	wc.lpszClassName	= "VxDMonCallUpClass";
	wc.hIcon			= LoadIcon( hInstance, "CALLER" );
 	if ( ! RegisterClass( &wc ) )
		return FALSE;

	return TRUE;
}


/****************************************************************************
*
*    FUNCTION:  InitInstance(HANDLE, int)
*
*    PURPOSE:  Saves instance handle and creates main window
*
****************************************************************************/
HWND InitInstance( HANDLE hInstance, int nCmdShow )
{
	HWND hWndMain;

	hInst = hInstance;

	hWndMain = CreateWindow( "VxDMonClass", "VxD Monitor", 
							WS_OVERLAPPEDWINDOW,
							CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
							NULL, NULL, hInstance, NULL );

	/* If window could not be created, return "failure" */
	if ( ! hWndMain )
		return NULL;
	
	/* Make the window visible; update its client area; and return "success" */
	ShowWindow( hWndMain, nCmdShow );
	UpdateWindow( hWndMain ); 
	return hWndMain;      
}

/****************************************************************************
*
*    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
*
*    PURPOSE:  Processes messages for the statistics window.
*
****************************************************************************/
LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam) 
{
	static HWND		hTree;
	static HWND		hWndListView;
	static int		SortItem = -1;
	DWORD			row, statcmd;
	LV_HITTESTINFO	htInfo;
	DWORD			nb;
	LV_ITEM			Item;

	switch ( message ) {

		case WM_CREATE:

			// get hourglass icon ready
			hHourGlass = LoadCursor( NULL, IDC_WAIT );

			// Create the listview within the main window
			hWndListView = CreateListView( hWnd );
			if ( hWndListView == NULL )
				MessageBox( NULL, "Listview not created!", NULL, MB_OK );

		    // open the handle to the VXD
			vxd_handle = CreateFile( VXD_NAME, 0, 0, NULL,
									0, FILE_FLAG_DELETE_ON_CLOSE, NULL );
			if ( vxd_handle == INVALID_HANDLE_VALUE )  {
				wsprintf( msgbuf, "Opening %s: error %d", VXD_NAME, 
								GetLastError( ) );
				Abort( hWnd, msgbuf );
			}
			// Have VxD compute overhead of service hooking
			// Do this before hooking any services
			if ( ! DeviceIoControl(	vxd_handle, VXDMON_getoverhead,
									NULL, 0, &OverheadCycles, sizeof(DWORD),
									&nb, NULL ) )
			{
				MessageBox( hWnd, "Couldn't get monitoring overhead", NULL, MB_OK );
				OverheadCycles = 0;
			}

			// Create the service selection tree view, but don't show it yet.
			hTree = CreateWindow(
						"VxDMonTreeClass", "Hook Selection", WS_OVERLAPPEDWINDOW,
						CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
						NULL, NULL, hInst, NULL );
			if ( !hTree )  {
				wsprintf( msgbuf, "Treeview not created: Error %d", GetLastError() );
				MessageBox( NULL, msgbuf, NULL, MB_OK );
			}

			// Create and fill image list for call tree view
			hCallImageList = ImageList_Create( 16, 16, ILC_MASK, 2, 1 );
			ImageList_AddIcon( hCallImageList, LoadIcon( hInst, "SELECTED"  ));
			ImageList_AddIcon( hCallImageList, LoadIcon( hInst, "CALLER" ));
			ImageList_AddIcon( hCallImageList, LoadIcon( hInst, "CALLEE" ));

			// Initialize check marks on menu items
			CheckMenuItem( GetMenu( hWnd ), IDM_RESETONUPDATE, 
							MF_BYCOMMAND | (ResetStatsOnUpdate?MF_CHECKED:MF_UNCHECKED) );

			break;

		case WM_NOTIFY:
			// Make sure its intended for us
			if ( wParam == ID_LISTVIEW )  {
				NM_LISTVIEW	* pNm = (NM_LISTVIEW *)lParam;
				switch ( pNm->hdr.code )  {

			        case LVN_BEGINLABELEDIT:
						// Don't allow editing of service information
						return TRUE;

					case LVN_COLUMNCLICK:
						// post hourglass icon
						SetCapture( hWnd );
						hSaveCursor = SetCursor(hHourGlass);

						// The user clicked a column header - sort by this criterion.
						ListView_SortItems( pNm->hdr.hwndFrom, ListViewCompareProc,
											(LPARAM)pNm->iSubItem );
						SortItem = pNm->iSubItem;

						// notify user that operation is done
						SetCursor( hSaveCursor );
						ReleaseCapture();
						break;

					case NM_DBLCLK:
					case NM_RDBLCLK:
						// On double click pull up call-tree view for item
						htInfo.pt = ClickPoint( hWndListView );
						// Determine service clicked upon
						row = ListView_HitTest( hWndListView, &htInfo );
						if ( row != (DWORD)-1  &&  htInfo.flags & LVHT_ONITEMLABEL )  {
							// Create call graph for item
							LV_ITEM		Item;
							// Get additional information about service clicked on
							Item.mask		= LVIF_PARAM;
							Item.iItem		= row;
							Item.iSubItem	= 0;
							if ( ! ListView_GetItem( hWndListView, &Item ) )
								return 0;
							// Create the call tree window
							CreateCallTree( hWnd,
											(struct vxdmon_stats *) Item.lParam,
											pNm->hdr.code == NM_DBLCLK );
						}
						break;
				}
			}
			return 0;

		case WM_COMMAND:

			switch ( LOWORD( wParam ) )	 {

				case IDM_TREEVIEW:
					/* Make the service selection window visible and update its client area */
					ShowWindow( hTree, SW_SHOWNORMAL );
					BringWindowToTop( hTree );
					UpdateWindow( hTree ); 
					return TRUE;      

				// stats related commands to send to VxD
				case IDM_ZEROSTATS:
					// Zero information on screen
					for ( row = 0; row < numStats; ++row )  {
						Stats[row].Enter	= 0;
						Stats[row].Exit		= 0;
						Stats[row].Time		= 0;
					}
					// Have VxD likewise zero information
					if ( ! DeviceIoControl(	vxd_handle, VXDMON_zerostats,
											NULL, 0, NULL, 0, NULL, NULL ) )
					{
						Abort( hWnd, "Couldn't access VxD" );
						return TRUE;
					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -