📄 vxdmon.c
字号:
*
* FUNCTION: SetTreeItemState
*
* PURPOSE: Set the selected/unselected state of a service-selection tree
* item, simultaneously recursing on all children to ensure their
* state matches the state of the parent.
*
******************************************************************************/
UINT SetTreeItemState( HWND hTree, HTREEITEM hItem, UINT State, BOOL recurse )
{
TV_ITEM tvi;
HTREEITEM Parent, Child;
// Set item we're modifying
tvi.hItem = hItem;
// Check if this is a toggle operation
if ( State == HOOK_PART ) {
// Toggle current image info
tvi.mask = TVIF_IMAGE;
TreeView_GetItem( hTree, &tvi );
switch ( tvi.iImage ) {
case HOOK_YES: State = HOOK_NO; break;
case HOOK_NO: State = HOOK_YES; break;
case HOOK_PART: State = HOOK_NO; break;
}
}
// Set new info
tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvi.iImage = State;
tvi.iSelectedImage = State;
TreeView_SetItem( hTree, &tvi );
// Set any children via recursive descent
for ( Child = TreeView_GetChild( hTree, hItem );
Child != NULL;
Child = TreeView_GetNextSibling( hTree, Child ) )
{
SetTreeItemState( hTree, Child, State, TRUE );
}
// Actually, check to see if this is a child toggle- if so, then set the parent
// to partial, unless all its children are selected - in that case set to partial
if ( !recurse && (Parent = TreeView_GetParent( hTree, hItem)) ) {
SetTreeParentState( hTree, Parent );
// do the parent
if( Parent = TreeView_GetParent( hTree, Parent) )
SetTreeParentState( hTree, Parent );
}
return State;
}
/****************************************************************************
*
* FUNCTION: TreeWndProc(HWND, unsigned, WORD, LONG)
*
* PURPOSE: Processes messages for service-selection treeview
*
****************************************************************************/
LONG APIENTRY TreeWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam )
{
static HWND hWndTreeView; // Handle of the tree window
NM_TREEVIEW * tv;
switch ( message ) {
case WM_CREATE:
// Create the tree view window and initialize its
// image list
hWndTreeView = CreateTreeView( hWnd );
if ( hWndTreeView == NULL )
MessageBox( NULL, "Tree View not created!", NULL, MB_OK );
// Add items to the tree window
if ( ! AddTreeViewItems( hWndTreeView ) )
MessageBox( NULL, "Items not added", NULL, MB_OK );
// Use user profile to select initial set of services
DefaultTreeSelections( hWndTreeView );
break;
case WM_SIZE:
// Move or resize the service-selection treeview.
MoveWindow( hWndTreeView, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
break;
case WM_NOTIFY:
// Process clicks on items, for selecting/deselecting items
if ( wParam != ID_TREEVIEW )
return 0;
tv = (NM_TREEVIEW *) lParam;
if ( tv->hdr.code == NM_CLICK ) {
// Its a click
TV_HITTESTINFO tvhti;
HTREEITEM htiItemClicked;
HTREEITEM hItemRange;
// Ensure the click was on something interesting
tvhti.pt = ClickPoint( hWndTreeView );
htiItemClicked = TreeView_HitTest( hWndTreeView, &tvhti );
if ( htiItemClicked == NULL || !(tvhti.flags & TVHT_ONITEM) )
break;
// If the item previously selected is not this item and the shift
// key is pressed, select all items in between.
hItemRange = TreeView_GetSelection( hWndTreeView );
if ( hItemRange && hItemRange != htiItemClicked && (GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
RECT rcSelected;
RECT rcClicked;
// check the selected item
/*ToggleTreeItemState( hWndTreeView, hItemRange );*/
// Get the rectangle of the selected and clicked items - we
// need these to determine if the clicked item is above or
// below the selected item
TreeView_GetItemRect( hWndTreeView, hItemRange, &rcSelected, FALSE );
TreeView_GetItemRect( hWndTreeView, htiItemClicked, &rcClicked, FALSE );
//check the rest of the items in between
if ( rcClicked.top > rcSelected.top ) {
while ( (hItemRange = TreeView_GetNextVisible(hWndTreeView, hItemRange)) != htiItemClicked )
SetTreeItemState( hWndTreeView, hItemRange, HOOK_PART, FALSE );
} else {
while ( (hItemRange = TreeView_GetPrevVisible(hWndTreeView, hItemRange)) != htiItemClicked )
SetTreeItemState( hWndTreeView, hItemRange, HOOK_PART, FALSE );
}
}
// Switch state of clicked item
SetTreeItemState( hWndTreeView, htiItemClicked, HOOK_PART, FALSE );
// mark as changed
ProfileChanged = TRUE;
}
break;
case WM_COMMAND:
switch ( LOWORD( wParam )) {
case IDOK:
// Hook all currently selected services
HookServices( hWndTreeView, hSelectRoot );
break;
case IDM_SAVE:
// Save a list of the currently selected services to a file
WriteDefaultTreeSelections( hWndTreeView, hSelectRoot );
ProfileChanged = FALSE;
break;
case IDM_EXIT:
// All done, we can exit
SendMessage( hWnd, WM_CLOSE, 0, 0 );
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
break;
case WM_CLOSE:
// Never really close down. Just hide so we don't lose our state.
ShowWindow( hWnd, SW_HIDE );
return 0;
case WM_DESTROY:
// Now we really have to shut down
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam );
}
return 0;
}
/****************************************************************************
*
* FUNCTION: CreateTreeView(HWND)
*
* PURPOSE: Creates the service-selection tree view window and initializes it
*
****************************************************************************/
HWND CreateTreeView( HWND hWndParent )
{
HWND hwndTree; // handle to tree view window
RECT rc; // rectangle for setting size of window
// Ensure that the common control DLL is loaded.
InitCommonControls();
// Get the size and position of the parent window.
GetClientRect( hWndParent, &rc );
// Create and fill image list for selection tree view
hSelectImageList = ImageList_Create( 16, 16, ILC_MASK, 5, 1 );
ImageList_AddIcon( hSelectImageList, LoadIcon( hInst, "UNSELECTED" ));
ImageList_AddIcon( hSelectImageList, LoadIcon( hInst, "SELECTED" ));
ImageList_AddIcon( hSelectImageList, LoadIcon( hInst, "SOMESELECTED" ));
// Create the tree view window.
hwndTree = CreateWindowEx( 0L, WC_TREEVIEW, "",
WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,
0, 0, rc.right - rc.left, rc.bottom - rc.top - 15,
hWndParent, (HMENU)ID_TREEVIEW, hInst, NULL );
if ( hwndTree ) {
// Add image list
TreeView_SetImageList( hwndTree, hSelectImageList, 0 );
// Set backdrop for images
ImageList_SetBkColor( hSelectImageList, GetSysColor( COLOR_WINDOW ));
}
return hwndTree;
}
/****************************************************************************
*
* FUNCTION: AddTreeViewItems(HWND)
*
* PURPOSE: Fills in the services tree view list.
*
****************************************************************************/
BOOL AddTreeViewItems( HWND hwndTree )
{
SECURITY_ATTRIBUTES security;
HANDLE fp; // file handle
char Line[ 100 ]; // line read from file
int len = 0; // current length of line read from file
DWORD n;
HTREEITEM hPrevDevice; // Last device added
HTREEITEM hPrevService; // Last service added
// Open the services.dat file
memset( &security, 0, sizeof security );
security.nLength = sizeof security;
fp = CreateFile( "services.dat", GENERIC_READ, FILE_SHARE_READ,
&security, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( fp == INVALID_HANDLE_VALUE ) {
char msgbuf[ 200 ];
wsprintf( msgbuf, "Can't open \"services.dat\": Error %d", GetLastError() );
MessageBox( NULL, msgbuf, NULL, MB_OK );
return FALSE;
}
// First add the root item
hSelectRoot = AddOneTreeViewItem( hwndTree, TVI_ROOT, TVI_LAST, "All Virtual Devices", 0 );
// Initialize previous values
hPrevDevice = hSelectRoot;
hPrevService = TVI_FIRST;
// Iterate over lines of file reading and adding items
while ( ReadFile( fp, Line+len, sizeof Line - len, &n, NULL ) ) {
DWORD Ordinal = 0; // Ordinal of service being read
char * Name; // Name of service being read
char * p = Line; // Pointer for parsing line
// Adjust new line length
len += n;
// Scan for ordinal
while ( len > 0 && ISWHITE(*p) )
++p, --len;
if ( len == 0 )
break;
for (;;) {
DWORD ch = (DWORD)CharUpper( (LPTSTR)*p++ );
if ( --len == 0 )
break;
if ( ch >= '0' && ch <= '9' ) Ordinal = Ordinal * 16 + ch - '0';
else if ( ch >= 'A' && ch <= 'F' ) Ordinal = Ordinal * 16 + ch - 'A' + 10;
else break;
}
if ( len == 0 || Ordinal == 0 || !ISWHITE(p[-1]) ) {
MessageBox( NULL, "Badly formatted ordinal", NULL, MB_OK );
return FALSE;
}
// Scan for service name
while ( len > 0 && ISWHITE(*p) )
++p, --len;
Name = p;
while ( len > 0 && !ISWHITE(*p) )
++p, --len;
*p++ = '\0'; --len;
// Add service to tree view
if ( Ordinal == (DWORD)-1 ) {
// Add a device.
hPrevDevice = AddOneTreeViewItem( hwndTree, hSelectRoot, TVI_SORT, Name, 0 );
hPrevService = TVI_FIRST;
} else {
// Add a service
struct service * s = NewService( Ordinal, Name );
wsprintf( msgbuf, "0x%08X %s", Ordinal, Name );
hPrevService = AddOneTreeViewItem( hwndTree, hPrevDevice, hPrevService, msgbuf, (DWORD)s );
s->hTree = hPrevService;
}
// Adjust contents of line for next pass
MoveMemory( Line, p, len );
}
CloseHandle( fp );
return TRUE;
}
/***************************************************************************
*
* FUNCTION: AddOneItem( HTREEITEM, LPSTR, HTREEITEM, int )
*
* PURPOSE: Inserts a tree view item in service tree in the specified place.
*
****************************************************************************/
// This function fills out the TV_ITEM and TV_INSERTSTRUCT structures
// and adds the item to the tree view control.
HTREEITEM AddOneTreeViewItem( HWND hwndTree, HTREEITEM hParent, HTREEITEM hInsAfter,
LPSTR szText, DWORD lParam )
{
HTREEITEM hItem;
TV_ITEM tvI;
TV_INSERTSTRUCT tvIns;
// The pszText, iImage, and iSelectedImage are filled out.
tvI.mask = TVIF_TEXT | TVIF_PARAM;
tvI.pszText = szText;
tvI.cchTextMax = lstrlen( szText );
tvI.lParam = lParam;
tvIns.item = tvI;
tvIns.hInsertAfter = hInsAfter;
tvIns.hParent = hParent;
// Insert the item into the tree.
hItem = (HTREEITEM)SendMessage( hwndTree, TVM_INSERTITEM, 0, (LPARAM)&tvIns);
return hItem;
}
/***************************************************************************
*
* FUNCTION: DefaultTreeSelections( HTREEITEM )
*
* PURPOSE: Read the list of services that we're previously hooked from
* the profile.dat file, and mark those services as selected in
* the current service-selection tree.
*
****************************************************************************/
BOOL DefaultTreeSelections( HWND hwndTree )
{
SECURITY_ATTRIBUTES security;
HANDLE fp;
char Line[ 100 ];
int len = 0;
DWORD n;
DWORD cnt = 0;
// open the file
memset( &security, 0, sizeof security );
security.nLength = sizeof security;
fp = CreateFile( "profile.dat", GENERIC_READ, FILE_SHARE_READ,
&security, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( fp == INVALID_HANDLE_VALUE )
return FALSE;
// Read file to add additional items
while ( ReadFile( fp, Line+len, sizeof Line - len, &n, NULL ) ) {
struct service * Service;
DWORD Ordinal = 0;
char * p = Line;
// Adjust new line length
len += n;
// Scan for ordinal
while ( len > 0 && ISWHITE(*p) )
++p, --len;
if ( len == 0 )
break;
for (;;) {
DWORD ch = (DWORD)CharUpper( (LPTSTR)*p++ );
if ( --len == 0 )
break;
if ( ch >= '0' && ch <= '9' ) Ordinal = Ordinal * 16 + ch - '0';
else if ( ch >= 'A' && ch <= 'F' ) Ordinal = Ordinal * 16 + ch - 'A' + 10;
else break;
}
if ( len == 0 || Ordinal == 0 || !ISWHITE(p[-1]) ) {
MessageBox( NULL, "Badly formatted ordinal", NULL, MB_OK );
return FALSE;
}
// register ordinal as being hooked
if ( Service = LookupService( Ordinal ) ) {
SetTreeItemState( hwndTree, Service->hTree, HOOK_YES, FALSE );
++cnt;
}
// Adjust contents of line for next pass
MoveMemory( Line, p, len );
}
CloseHandle( fp );
// Determine if we should hook the selections just read in.
wsprintf( msgbuf, "Hook previously saved selections now?\n(%d services)", cnt );
if ( MessageBox( NULL, msgbuf, "VxDMon", MB_YESNO ) == IDYES ) {
// Yes, hook them now.
HookServices( hwndTree, hSelectRoot );
}
return TRUE;
}
/******************************************************************************
*
* FUNCTION: WriteHookServices
*
* PURPOSE: Write to a file all services in service-selection tree that are
* currently selected.
*
******************************************************************************/
BOOL WriteHookServices( HANDLE fp, HWND hTree, HTREEITEM hItem )
{
HTREEITEM Child = TreeView_GetChild( hTree, hItem );
if ( Child ) {
// This is not a leaf item. Recurse on all children.
while ( Child != NULL ) {
WriteHookServices( fp, hTree, Child );
Child = TreeView_GetNextSibling( hTree, Child );
}
} else {
// Leaf item. Write out status
TV_ITEM tvi;
struct service * pService;
// Determine current hook state
tvi.hItem = hItem;
tvi.mask = TVIF_IMAGE | TVIF_PARAM;
TreeView_GetItem( hTree, &tvi );
pService = (struct service *) tvi.lParam;
if ( tvi.iImage == HOOK_YES ) {
char Line[ 100 ];
DWORD cnt = 0;
wsprintf( Line, "%08X\r\n", pService->Ordinal );
WriteFile( fp, Line, strlen(Line), &cnt, NULL );
}
}
return TRUE;
}
/******************************************************************************
*
* FUNCTION: WriteDefaultTreeSelections
*
* PURPOSE: Traverse the service-selection tree and write to the
* profile.dat file all services that are currently selected.
*
******************************************************************************/
void WriteDefaultTreeSelections( HWND hwndTree, HTREEITEM hItem )
{
SECURITY_ATTRIBUTES security;
HANDLE fp;
// Open file
memset( &security, 0, sizeof security );
security.nLength = sizeof security;
fp = CreateFile( "profile.dat", GENERIC_WRITE, FILE_SHARE_WRITE,
&security, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if ( fp == INVALID_HANDLE_VALUE ) {
wsprintf( msgbuf, "Can't open \"profile.dat\": Error %d", GetLastError() );
MessageBox( NULL, msgbuf, NULL, MB_OK );
return;
}
// Recurse writing items
WriteHookServices( fp, hwndTree, hItem );
// close file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -