REGMON.C
上传用户:kevenhsn
上传日期:2007-01-03
资源大小:251k
文件大小:61k
源码类别:

系统编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *
  3. *       Regmon - Registry Monitor for Windows NT and Windows 9x
  4. *
  5. * Copyright (c) 1996 - 1998 Mark Russinovich and Bryce Cogswell
  6. *
  7. * See readme.txt for terms and conditions.
  8. *
  9. *     PROGRAM: Regmon.c
  10. *
  11. *     PURPOSE: Communicates with the RegMon driver to display 
  12. * registry activity information.
  13. *
  14. ******************************************************************************/
  15. #include <windows.h>   
  16. #include <windowsx.h>
  17. #include <tchar.h>
  18. #include <commctrl.h>  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <winioctl.h>
  22. #include "resource.h"
  23. #include "ioctlcmd.h"
  24. #include "regmon.h"
  25. // this typedef, present in newer include files,
  26. // supports the building regmon on older systems
  27. typedef struct 
  28. {
  29.     DWORD cbSize;
  30.     DWORD dwMajorVersion;
  31.     DWORD dwMinorVersion;
  32.     DWORD dwBuildNumber;
  33.     DWORD dwPlatformID;
  34. } DLLVERSIONINFO_, *PDLLVERSIONINFO_;
  35. HRESULT (CALLBACK *pDllGetVersionProc)( PDLLVERSIONINFO_ pdvi );
  36. // delay for listview subitem tooltip
  37. #define BALLOONDELAY    10
  38. // toolbar height plus the borders
  39. #define TOOLBARHEIGHT 28
  40. // Number of columns in the listview
  41. #define NUMCOLUMNS 6
  42. // Variables/definitions for the driver that performs the actual monitoring.
  43. #define SYS_FILE _T("REGSYS.SYS")
  44. #define SYS_NAME _T("REGMON")
  45. #define VXD_FILE "\\.\REGVXD.VXD"
  46. #define VXD_NAME "REGVXD"
  47. static HANDLE SysHandle = INVALID_HANDLE_VALUE;
  48. // length in ms we wait for Regedit to update its display 
  49. #define REGEDITSLOWWAIT 750
  50. // version number for position settings
  51. #define POSVERSION 400
  52. // Position settings data structure 
  53. typedef struct {
  54. int posversion;
  55. int left;
  56. int top;
  57. int width;
  58. int height;
  59. DWORD column[NUMCOLUMNS];
  60. DWORD historydepth;
  61. BOOLEAN maximized;
  62. FILTER  filter;
  63. BOOLEAN ontop;
  64. } POSITION_SETTINGS;
  65. // The variable that holds the position settings
  66. POSITION_SETTINGS PositionInfo;
  67. // typedef for balloon popup
  68. typedef struct {
  69. CHAR itemText[1024];
  70. RECT itemPosition;
  71. } ITEM_CLICK, *PITEM_CLICK;
  72. // toolbar constants
  73. #define ID_TOOLBAR         1
  74. // defined for comtl32.dll version 4.7
  75. #define TOOLBAR_FLAT 0x800
  76. // button definitions
  77. // for installations that support flat style
  78. TBBUTTON tbButtons[] = {
  79. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  80. { 0, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  81. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  82. { 2, IDM_CAPTURE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  83. { 4, IDM_AUTOSCROLL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  84. { 6, IDM_CLEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  85. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  86. { 5, IDM_FILTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  87. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  88. { 7, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  89. { 9, IDM_JUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  90. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  91. };
  92. #define NUMBUTTONS 12
  93. // for older installations
  94. TBBUTTON tbButtonsOld[] = {
  95. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  96. { 0, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  97. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  98. { 2, IDM_CAPTURE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  99. { 4, IDM_AUTOSCROLL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  100. { 6, IDM_CLEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  101. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  102. { 5, IDM_FILTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  103. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  104. { 7, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  105. { 9, IDM_JUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  106. };  
  107. #define NUMBUTTONSOLD 11
  108. // Buffer into which driver can copy statistics
  109. char Stats[ MAX_STORE ];
  110. // Current fraction of buffer filled
  111. DWORD StatsLen;
  112. // Search string
  113. TCHAR FindString[256];
  114. FINDREPLACE FindTextInfo;
  115. DWORD FindFlags = FR_DOWN;
  116. BOOLEAN PrevMatch;
  117. TCHAR PrevMatchString[256];
  118. // Application instance handle
  119. HINSTANCE hInst;
  120. // For info saving
  121. TCHAR szFileName[256];
  122. BOOLEAN FileChosen = FALSE;
  123. // Windows NT or Windows 9x?
  124. BOOLEAN IsNT;
  125. // Misc globals
  126. HWND hWndMain;
  127. HWND hWndFind = NULL;
  128. UINT findMessageID;
  129. HWND hWndList;
  130. WNDPROC  ListViewWinMain;
  131. HWND hBalloon = NULL;
  132. BOOLEAN Capture = TRUE;
  133. BOOLEAN Autoscroll = TRUE;
  134. BOOLEAN BootLog = FALSE;
  135. BOOLEAN BootLogMenuUsed = FALSE;
  136. BOOLEAN Deleting = FALSE;
  137. BOOLEAN OnTop = FALSE;
  138. // Driver's registry key
  139. TCHAR DriverRegistryKey[] = _T("System\CurrentControlSet\Services\Regmon");
  140. // General buffer for storing temporary strings
  141. static TCHAR msgbuf[ 257 ];
  142. // Filter-related
  143. FILTER FilterDefinition;
  144. // listview size limiting
  145. DWORD MaxLines = 0;
  146. DWORD LastRow = 0;
  147. // General cursor manipulation
  148. HCURSOR  hSaveCursor;
  149. HCURSOR  hHourGlass;
  150. /******************************************************************************
  151. *
  152. * FUNCTION: RegeditJump
  153. *
  154. * PURPOSE: Opens Regedit and navigates the desired key
  155. *
  156. *****************************************************************************/
  157. void RegeditJump( HWND hWnd )
  158. {
  159. int currentItem;
  160. int pos;
  161. char * ch;
  162. HWND regeditHwnd, regeditMainHwnd;
  163. char compressPath[MAX_PATH];
  164. HKEY hKey;
  165. char *value = NULL;
  166. DWORD status;
  167. char RegPath[MAX_PATH];
  168. DEVMODE devMode;
  169. // Get the color depth, which can effect the speed that Regedit
  170. // responds to keyboard commands
  171. devMode.dmSize = sizeof(DEVMODE);
  172. EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &devMode );
  173. // See if we can get a Registry path out of the listview
  174. // find the item with the focus
  175. currentItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED );
  176. if( currentItem == -1 ) {
  177. MessageBox( hWnd, _T("No item selected."),
  178. _T("Regmon"), MB_OK|MB_ICONWARNING );
  179. return;
  180. }
  181. memset( compressPath, 0, MAX_PATH );
  182. ListView_GetItemText( hWndList, currentItem, 3, compressPath, MAX_PATH );
  183. // If the key is a handle reference, tell the user we're sorry
  184. if( compressPath[0] == '0' ) {
  185. MessageBox( hWnd, _T("The full name of the selected key or value is not available."),
  186. _T("Regmon"), MB_OK|MB_ICONWARNING );
  187. return;
  188. }
  189. // We need to uncompress abbreviations
  190. if( !strncmp( compressPath, "HKLM", strlen("HKLM"))) {
  191. sprintf( RegPath, "\HKEY_LOCAL_MACHINE%s", &compressPath[strlen("HKLM")] );
  192. status = RegOpenKey( HKEY_LOCAL_MACHINE, &compressPath[strlen("HKLM")+1], &hKey );
  193. } else if( !strncmp( compressPath, "HKCU", strlen("HKCU"))) {
  194. sprintf( RegPath, "\HKEY_CURRENT_USER%s", &compressPath[strlen("HKCU")] );
  195. status = RegOpenKey( HKEY_CURRENT_USER, &compressPath[strlen("HKCU")+1], &hKey );
  196. } else if( !strncmp( compressPath, "HKCC", strlen("HKCC"))) {
  197. sprintf( RegPath, "\HKEY_CURRENT_CONFIG%s", &compressPath[strlen("HKCC")] );
  198. status = RegOpenKey( HKEY_CURRENT_CONFIG, &compressPath[strlen("HKCC")+1], &hKey );
  199. } else if( !strncmp( compressPath, "HKCR", strlen("HKCR"))) {
  200. sprintf( RegPath, "\HKEY_CLASSES_ROOT%s", &compressPath[strlen("HKCR")] );
  201. status = RegOpenKey( HKEY_CLASSES_ROOT, &compressPath[strlen("HKCR")+1], &hKey );
  202. } else if( !strncmp( compressPath, "HKU", strlen("HKU"))) {
  203. sprintf( RegPath, "\HKEY_USERS%s", &compressPath[strlen("HKU")] );
  204. status = RegOpenKey( HKEY_USERS, &compressPath[strlen("HKU")+1], &hKey );
  205. } else {
  206. strcpy( RegPath, compressPath );
  207. status = FALSE;
  208. }
  209. // Is it a value or a key?
  210. if( status == ERROR_SUCCESS ) {
  211. RegCloseKey( hKey );
  212. strcat( RegPath, "\" );
  213. } else {
  214. value = strrchr( RegPath, '\')+1;
  215. *strrchr( RegPath, '\' ) = 0;
  216. }
  217. // Open RegEdit
  218. regeditMainHwnd = FindWindow( "RegEdit_RegEdit", NULL );
  219. if ( regeditMainHwnd == NULL )  {
  220. SHELLEXECUTEINFO info;
  221. memset( &info, 0, sizeof info );
  222. info.cbSize = sizeof info;
  223. info.fMask = SEE_MASK_NOCLOSEPROCESS; 
  224. info.lpVerb = "open"; 
  225. info.lpFile = "regedit.exe"; 
  226. info.nShow = SW_SHOWNORMAL; 
  227. ShellExecuteEx( &info );
  228. WaitForInputIdle( info.hProcess, INFINITE );
  229. regeditMainHwnd = FindWindow( "RegEdit_RegEdit", NULL );
  230. if( regeditMainHwnd == NULL ) {
  231. MessageBox( hWnd, _T("Regmon was unable to launch Regedit."),
  232. _T("Regmon"), MB_OK|MB_ICONERROR );
  233. return;
  234. }
  235.     ShowWindow( regeditMainHwnd, SW_SHOW );
  236. SetForegroundWindow( regeditMainHwnd );
  237. // Get treeview
  238. regeditHwnd = FindWindowEx( regeditMainHwnd, NULL, "SysTreeView32", NULL );
  239. SetForegroundWindow( regeditHwnd );
  240. SetFocus( regeditHwnd );
  241. // Close it up
  242. for ( pos = 0; pos < 30; ++pos )  {
  243. UINT vk = VK_LEFT;
  244. SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
  245. }
  246. // wait for slow displays - 
  247. // Regedit takes a while to open keys with lots of subkeys
  248. // when running at high color depths 
  249. if( devMode.dmBitsPerPel > 8 ) Sleep(REGEDITSLOWWAIT); 
  250. // Open path
  251. for ( ch = RegPath; *ch; ++ch )  {
  252. if ( *ch == '\' )  {
  253. UINT vk = VK_RIGHT;
  254. SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
  255. // wait for slow displays - 
  256. // Regedit takes a while to open keys with lots of subkeys
  257. // when running at high color depths 
  258. if( devMode.dmBitsPerPel > 8 ) Sleep(REGEDITSLOWWAIT); 
  259. } else {
  260. UINT vk = toupper(*ch);
  261. SendMessage( regeditHwnd, WM_CHAR, vk, 0 );
  262. }
  263. }
  264. // If its a value select the value
  265. if( value ) {
  266. UINT vk = VK_HOME;
  267. regeditHwnd = FindWindowEx( regeditMainHwnd, NULL, "SysListView32", NULL );
  268. SetForegroundWindow( regeditHwnd );
  269. SetFocus( regeditHwnd );
  270. Sleep(1000); // have to wait for Regedit to update listview
  271. SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
  272. for ( ch = value; *ch; ++ch )  {
  273. UINT vk = toupper(*ch);
  274. SendMessage( regeditHwnd, WM_CHAR, vk, 0 );
  275. }
  276. }
  277. SetForegroundWindow( regeditMainHwnd );
  278. SetFocus( regeditMainHwnd );
  279. }
  280. /******************************************************************************
  281. *
  282. * FUNCTION: Abort:
  283. *
  284. * PURPOSE: Handles emergency exit conditions.
  285. *
  286. *****************************************************************************/
  287. LONG Abort( HWND hWnd, TCHAR * Msg )
  288. {
  289. LPVOID lpMsgBuf;
  290. TCHAR errmsg[256];
  291. DWORD error = GetLastError();
  292.  
  293. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  294. NULL, GetLastError(), 
  295. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  296. (LPTSTR) &lpMsgBuf, 0, NULL );
  297. if( IsNT ) UnloadDeviceDriver( SYS_NAME );
  298. sprintf(errmsg, _T("%s: %s"), Msg, lpMsgBuf );
  299. if( error == ERROR_INVALID_HANDLE && IsNT ) 
  300. wsprintf(errmsg, _T("%snMake sure that you are an administrator and that ")
  301. _T("Regmon is located on a local drive."), errmsg  );
  302. MessageBox( hWnd, errmsg, _T("Regmon"), MB_OK|MB_ICONERROR );
  303. PostQuitMessage( 1 );
  304. LocalFree( lpMsgBuf );
  305. return -1;
  306. }
  307. /******************************************************************************
  308. *
  309. * FUNCTION: BalloonDialog
  310. *
  311. * PURPOSE: Dialog function for home-brewed balloon help.
  312. *
  313. ******************************************************************************/
  314. LONG APIENTRY BalloonDialog( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  315. {
  316. static ITEM_CLICK ctx;
  317. static RECT rect;
  318. static HFONT hfont;
  319. LPCREATESTRUCT lpcs;
  320. HDC hdc;
  321. POINTS pts;
  322. POINT pt;
  323. DWORD newclicktime;
  324.     NONCLIENTMETRICS ncm;
  325. static POINT lastclickpt = {0,0};
  326. static DWORD lastclicktime = 0;
  327. switch (message) {
  328. case WM_CREATE:
  329. lpcs = (void *)lParam;
  330. ctx = *(PITEM_CLICK) lpcs->lpCreateParams;
  331. hdc = GetDC( hDlg );
  332. // Get font
  333. if ( hfont == NULL )  {
  334. memset(&ncm, 0, sizeof(ncm));
  335. ncm.cbSize = sizeof(ncm);
  336. SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 
  337. 0, &ncm, 0);
  338.   hfont = CreateFontIndirect( &ncm.lfMessageFont ); 
  339. // is the app the focus?
  340. if( !GetFocus()) return -1;
  341. // Compute size of required rectangle
  342. rect.left = 0;
  343. rect.top = 0;
  344. rect.right = lpcs->cx;
  345. rect.bottom = lpcs->cy;
  346. SelectObject( hdc, hfont );
  347. DrawText( hdc, ctx.itemText, -1, &rect, 
  348. DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT );
  349. // if the bounding rectangle of the subitem is big enough to display
  350. // the text then don't pop the balloon
  351. if( ctx.itemPosition.right > rect.right + 11 ) {
  352. return -1;
  353. }
  354. // Move and resize window
  355. if( ctx.itemPosition.left - 5 + rect.right + 10 >
  356.  GetSystemMetrics(SM_CXFULLSCREEN) ) {
  357.  ctx.itemPosition.left = GetSystemMetrics(SM_CXFULLSCREEN) -
  358. (rect.right+10);
  359. }
  360. MoveWindow( hDlg, 
  361. ctx.itemPosition.left+3, ctx.itemPosition.top, 
  362. rect.right + 6, 
  363. rect.bottom + 1,
  364. TRUE );
  365. // Adjust rectangle so text is centered
  366. rect.left += 2;
  367. rect.right += 2;
  368. rect.top -= 1; 
  369. rect.bottom += 0;
  370. // make it so this window doesn't get the focus
  371. ShowWindow( hDlg, SW_SHOWNOACTIVATE );
  372. break;
  373. case WM_LBUTTONDBLCLK:
  374. case WM_RBUTTONDBLCLK:
  375. case WM_MBUTTONDBLCLK:
  376. case WM_LBUTTONDOWN:
  377. case WM_RBUTTONDOWN:
  378. case WM_MBUTTONDOWN:
  379. case WM_LBUTTONUP:
  380. case WM_RBUTTONUP:
  381. case WM_MBUTTONUP:
  382. pts = MAKEPOINTS( lParam );
  383. pt.x = (LONG) pts.x;
  384. pt.y = (LONG) pts.y;
  385. ClientToScreen( hDlg, &pt );
  386. // pass this through to the listview
  387. if( ScreenToClient( hWndList, &pt )) {
  388. if( message == WM_LBUTTONDOWN ) {
  389. // see if its a double click
  390. newclicktime = GetTickCount();
  391. if( pt.x == lastclickpt.x && pt.y == lastclickpt.y && 
  392. newclicktime - lastclicktime < 300 ) {
  393. message = WM_LBUTTONDBLCLK;
  394. }
  395. lastclicktime = newclicktime;
  396. lastclickpt = pt;
  397. }
  398. PostMessage( hWndList, message, wParam, (SHORT) pt.y<<16 | (SHORT) pt.x );
  399. }
  400. break;
  401. case WM_PAINT:
  402. hdc = GetDC( hDlg );
  403. // Set colors
  404. SetTextColor( hdc, 0x00000000 );
  405. SetBkMode( hdc, TRANSPARENT );
  406. SelectObject( hdc, hfont );
  407. DrawText( hdc, ctx.itemText, -1, &rect, 
  408. DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK );
  409. break;
  410. case WM_DESTROY:
  411. hBalloon = NULL;
  412. break;
  413. case WM_CLOSE:
  414. DestroyWindow( hDlg );
  415. break;
  416. }
  417.     return DefWindowProc( hDlg, message, wParam, lParam );
  418. }
  419. /******************************************************************************
  420. *
  421. * FUNCTION: FindInListview:
  422. *
  423. * PURPOSE: Searches for a string in the listview. Note: its okay if
  424. * items are being added to the list view or the list view
  425. * is cleared while this search is in progress - the effect
  426. * is harmless.
  427. *
  428. *****************************************************************************/
  429. BOOLEAN FindInListview(HWND hWnd, LPFINDREPLACE FindInfo )
  430. {
  431. int currentItem;
  432. DWORD i;
  433. int subitem, numItems;
  434. TCHAR fieldtext[256];
  435. BOOLEAN match = FALSE;
  436. TCHAR errmsg[256];
  437. BOOLEAN goUp;
  438. // get the search direction
  439. goUp = ((FindInfo->Flags & FR_DOWN) == FR_DOWN);
  440. // initialize stuff
  441. if( !(numItems = ListView_GetItemCount( hWndList ))) {
  442. MessageBox( hWnd, _T("No items to search"), _T("Regmon"), 
  443. MB_OK|MB_ICONWARNING );
  444. SetForegroundWindow( hWndFind );
  445. return FALSE;
  446. }
  447. // find the item with the focus
  448. currentItem = ListView_GetNextItem( hWndList, 0, LVNI_SELECTED );
  449. // if no current item, start at the top or the bottom
  450. if( currentItem == -1 ) {
  451. if( goUp )
  452. currentItem = 0;
  453. else {
  454. if( PrevMatch ) {
  455. sprintf(errmsg, _T("Cannot find string "%s""), FindInfo->lpstrFindWhat );
  456. MessageBox( hWnd, errmsg, _T("Regmon"), MB_OK|MB_ICONWARNING );
  457. SetForegroundWindow( hWndFind );
  458. return FALSE;
  459. }
  460. currentItem = numItems;
  461. }
  462. }
  463. // if we're continuing a search, start with the next item
  464. if( PrevMatch && !strcmp( FindString, PrevMatchString ) ) {
  465. if( goUp ) currentItem++;
  466. else currentItem--;
  467. if( (!goUp && currentItem < 0) ||
  468. (goUp && currentItem >= numItems )) {
  469. sprintf(errmsg, _T("Cannot find string "%s""), FindInfo->lpstrFindWhat );
  470. MessageBox( hWnd, errmsg, _T("Regmon"), MB_OK|MB_ICONWARNING );
  471. SetForegroundWindow( hWndFind );
  472. return FALSE;
  473. }
  474. }
  475. // loop through each item looking for the string
  476. while( 1 ) {
  477. // get the item text
  478. for( subitem = 0; subitem < NUMCOLUMNS; subitem++ ) {
  479. fieldtext[0] = 0;
  480. ListView_GetItemText( hWndList, currentItem, subitem, fieldtext, MAX_PATH );
  481. // make sure enought string for a match
  482. if( strlen( fieldtext ) < strlen( FindInfo->lpstrFindWhat ))
  483. continue;
  484. // do a scan all the way through for the substring
  485. if( FindInfo->Flags & FR_WHOLEWORD ) {
  486. i = 0;
  487. while( fieldtext[i] ) {
  488. while( fieldtext[i] && fieldtext[i] != ' ' ) i++;
  489. if( FindInfo->Flags & FR_MATCHCASE ) 
  490. match = !strcmp( fieldtext, FindInfo->lpstrFindWhat );
  491. else
  492. match = !stricmp( fieldtext, FindInfo->lpstrFindWhat );
  493. if( match) break;
  494. i++;
  495. }
  496. } else {
  497. for( i = 0; i < strlen( fieldtext ) - strlen(FindInfo->lpstrFindWhat)+1; i++ ) {
  498. if( FindInfo->Flags & FR_MATCHCASE ) 
  499. match = !strncmp( &fieldtext[i], FindInfo->lpstrFindWhat, 
  500. strlen(FindInfo->lpstrFindWhat) );
  501. else
  502. match = !strnicmp( &fieldtext[i], FindInfo->lpstrFindWhat,
  503. strlen(FindInfo->lpstrFindWhat) );
  504. if( match ) break;
  505. }
  506. }
  507. if( match ) {
  508. strcpy( PrevMatchString, FindInfo->lpstrFindWhat );
  509. PrevMatch = TRUE;
  510. ListView_SetItemState( hWndList, currentItem, 
  511. LVIS_SELECTED|LVIS_FOCUSED,
  512. LVIS_SELECTED|LVIS_FOCUSED );
  513. ListView_EnsureVisible( hWndList, currentItem, FALSE ); 
  514. SetFocus( hWndList );
  515. return TRUE;
  516. }
  517. }
  518. currentItem = currentItem + (goUp ? 1:-1);
  519. if( !currentItem || currentItem == numItems+1 ) {
  520. // end of the road
  521. break;
  522. }
  523. }
  524. sprintf(errmsg, _T("Cannot find string "%s""), FindInfo->lpstrFindWhat );
  525. MessageBox( hWnd, errmsg, _T("Regmon"), MB_OK|MB_ICONWARNING );
  526. SetForegroundWindow( hWndFind );
  527. return FALSE;
  528. }
  529. /******************************************************************************
  530. *
  531. * FUNCTION: PopFindDialog:
  532. *
  533. * PURPOSE: Calls the find message dialog box.
  534. *
  535. *****************************************************************************/
  536. void PopFindDialog(HWND hWnd)
  537. {
  538. strcpy( FindString, PrevMatchString );
  539.     FindTextInfo.lStructSize = sizeof( FindTextInfo );
  540.     FindTextInfo.hwndOwner = hWnd;
  541.     FindTextInfo.hInstance = (HANDLE)hInst;
  542.     FindTextInfo.lpstrFindWhat = FindString;
  543.     FindTextInfo.lpstrReplaceWith = NULL;
  544.     FindTextInfo.wFindWhatLen = sizeof(FindString);
  545.     FindTextInfo.wReplaceWithLen = 0;
  546.     FindTextInfo.lCustData = 0;
  547.     FindTextInfo.Flags =  FindFlags;
  548.     FindTextInfo.lpfnHook = (LPFRHOOKPROC)(FARPROC)NULL;
  549.     FindTextInfo.lpTemplateName = NULL;
  550.     if ((hWndFind = FindText(&FindTextInfo)) == NULL)
  551. MessageBox( hWnd, _T("Unable to create Find dialog"), _T("Regmon"), MB_OK|MB_ICONERROR );      
  552. }
  553. /******************************************************************************
  554. *
  555. * FUNCTION: Get_Position_Settings
  556. *
  557. * PURPOSE: Reads the Registry to get the last-set window position.
  558. *
  559. ******************************************************************************/
  560. VOID Get_Position_Settings()
  561. {
  562. HKEY hKey;
  563. DWORD ParamSize;
  564. POSITION_SETTINGS regPositionInfo;
  565. // Fist, set the default settings
  566. PositionInfo.top = CW_USEDEFAULT;
  567. PositionInfo.left = CW_USEDEFAULT;
  568. PositionInfo.width = CW_USEDEFAULT;
  569. PositionInfo.height = CW_USEDEFAULT;
  570. PositionInfo.maximized = FALSE;
  571. PositionInfo.ontop = FALSE;
  572. // set the default listview widths
  573. PositionInfo.column[0] = 35;
  574. PositionInfo.column[1] = 90;
  575. PositionInfo.column[2] = 130;
  576. PositionInfo.column[3] = 200;
  577. PositionInfo.column[4] = 70;
  578. PositionInfo.column[5] = 150;
  579. // Initialize the filter
  580. sprintf( PositionInfo.filter.processfilter, "*" );
  581. strcpy( PositionInfo.filter.processexclude, "" );
  582. sprintf( PositionInfo.filter.pathfilter,    "*" );
  583. sprintf( PositionInfo.filter.excludefilter, "" );
  584. PositionInfo.filter.logsuccess = TRUE;
  585. PositionInfo.filter.logerror   = TRUE;
  586. PositionInfo.filter.logreads   = TRUE;
  587. PositionInfo.filter.logwrites  = TRUE;
  588. // set the default history depth (infinite)
  589. PositionInfo.historydepth = 0;
  590. // first, get the last-entered params from the registry
  591. RegCreateKey(HKEY_CURRENT_USER, 
  592. _T("Software\Systems Internals\Regmon"),
  593. &hKey );
  594. // get the params and ignore errors
  595. ParamSize = sizeof( PositionInfo );
  596. RegQueryValueEx( hKey,_T("Settings"), NULL, NULL, (LPBYTE) &regPositionInfo,
  597. &ParamSize );
  598. RegCloseKey( hKey );
  599. // only use the registry settings if the version matches
  600. if( regPositionInfo.posversion == POSVERSION ) PositionInfo = regPositionInfo;
  601. // extract the history depth
  602. MaxLines = PositionInfo.historydepth;
  603. OnTop = PositionInfo.ontop;
  604. // initialize filter
  605. FilterDefinition    = PositionInfo.filter;
  606. }
  607. /******************************************************************************
  608. *
  609. * FUNCTION: Save_Position_Settings
  610. *
  611. * PURPOSE: Saves the current window settings to the Registry.
  612. *
  613. ******************************************************************************/
  614. VOID Save_Position_Settings( HWND hWnd )
  615. {
  616. RECT rc;
  617. int i;
  618. HKEY hKey;
  619. // set version #
  620. PositionInfo.posversion = POSVERSION;
  621. // get the position of the main window
  622. GetWindowRect( hWnd, &rc );
  623. if( !IsIconic( hWnd )) {
  624. PositionInfo.left = rc.left;
  625. PositionInfo.top = rc.top;
  626. PositionInfo.width = rc.right - rc.left;
  627. PositionInfo.height = rc.bottom - rc.top;
  628. PositionInfo.maximized = IsZoomed( hWnd );
  629. PositionInfo.ontop = OnTop;
  630. // get the widths of the listview columns
  631. for( i = 0; i < NUMCOLUMNS; i++ ) {
  632. PositionInfo.column[i] = ListView_GetColumnWidth( hWndList, i );
  633. }
  634. // get the history depth
  635. PositionInfo.historydepth = MaxLines;
  636. // save filters
  637. PositionInfo.filter = FilterDefinition;
  638. // save connection info to registry
  639. RegOpenKey(HKEY_CURRENT_USER, 
  640. _T("Software\Systems Internals\Regmon"),
  641. &hKey );
  642. RegSetValueEx( hKey, _T("Settings"), 0, REG_BINARY, (LPBYTE) &PositionInfo,
  643. sizeof( PositionInfo ) );
  644. RegCloseKey( hKey );
  645. }
  646. /******************************************************************************
  647. *
  648. * FUNCTION: Split
  649. *
  650. * PURPOSE: Split a delimited line into components
  651. *
  652. ******************************************************************************/
  653. int Split( char * line, char delimiter, char * items[] )
  654. {
  655. int cnt = 0;
  656. for (;;)  {
  657. // Add prefix to list of components
  658. items[cnt++] = line;
  659. // Check for more components
  660. line = strchr( line, delimiter );
  661. if ( line == NULL )
  662. return cnt;
  663. // Terminate previous component and move to next
  664. *line++ = '';
  665. }
  666. }
  667. /******************************************************************************
  668. *
  669. * FUNCTION: ListAppend
  670. *
  671. * PURPOSE: Add a new line to List window
  672. *
  673. ******************************************************************************/
  674. BOOL List_Append( HWND hWndList, DWORD seq, char * line )
  675. {
  676. LV_ITEM lvI; // list view item structure
  677. int row;
  678. char * items[20];
  679. int itemcnt = 0;
  680. // Split line into columns
  681. itemcnt = Split( line, 't', items );
  682. if ( itemcnt == 0 )
  683. return FALSE;
  684. // Determine row number for request
  685. if ( *items[0] )  {
  686. // Its a new request.  Put at end.
  687. row = 0x7FFFFFFF;
  688. } else {
  689. // Its a status.  Locate its associated request.
  690. lvI.mask = LVIF_PARAM;
  691. lvI.iSubItem = 0;
  692. for ( row = ListView_GetItemCount(hWndList) - 1; row >= 0; --row )  {
  693. lvI.iItem = row;
  694. if ( ListView_GetItem( hWndList, &lvI )  &&  (DWORD)lvI.lParam == seq )
  695. break;
  696. }
  697. if ( row == -1 )
  698. // No request associated with status.
  699. return FALSE;
  700. }
  701. // Sequence number if a new item
  702. if ( *items[0] )  {
  703. wsprintf( msgbuf, _T("%d"), seq );
  704. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  705. lvI.iItem = row;
  706. lvI.iSubItem = 0;
  707. lvI.pszText = msgbuf;
  708. lvI.cchTextMax = lstrlen( lvI.pszText ) + 1;
  709. lvI.lParam = seq;
  710. row = ListView_InsertItem( hWndList, &lvI );
  711. if ( row == -1 )  {
  712. wsprintf( msgbuf, _T("Error adding item %d to list view"), seq );
  713. MessageBox( hWndList, msgbuf, _T("Regmon Error"), MB_OK );
  714. return FALSE;
  715. }
  716.         LastRow = row;
  717. }
  718. // Process name
  719. if ( itemcnt>0 && *items[0] ) {
  720. OemToChar( items[0], msgbuf );
  721. ListView_SetItemText( hWndList, row, 1, msgbuf );
  722. }
  723. // Request type
  724. if ( itemcnt>1 && *items[1] )  {
  725. OemToChar( items[1], msgbuf );
  726. ListView_SetItemText( hWndList, row, 2, msgbuf );
  727. }
  728. // Path
  729. if ( itemcnt>2 && *items[2] )  {
  730. OemToChar( items[2], msgbuf );
  731. ListView_SetItemText( hWndList, row, 3, msgbuf );
  732. }
  733. // Result
  734. if ( itemcnt>3 && *items[3] )  {
  735. OemToChar( items[3], msgbuf );
  736. ListView_SetItemText( hWndList, row, 4, msgbuf );
  737. }
  738. // Additional
  739. if ( itemcnt>4 && *items[4] )  {
  740. OemToChar( items[4], msgbuf );
  741. ListView_SetItemText( hWndList, row, 5, msgbuf );
  742. }
  743. return TRUE;
  744. }
  745. /******************************************************************************
  746. *
  747. * FUNCTION: UpdateStatistics
  748. *
  749. * PURPOSE: Clear the statistics window and refill it with the current 
  750. * contents of the statistics buffer.  Does not refresh the 
  751. * buffer from the device driver.
  752. *
  753. ******************************************************************************/
  754. void UpdateStatistics( HWND hWnd, HWND hWndList, BOOL Clear )
  755. {
  756. PENTRY ptr;
  757. BOOLEAN itemsAdded = FALSE;
  758. int totitems, i;
  759. // Just return if nothing to do
  760. if ( !Clear  &&  StatsLen < sizeof(int)+2 )
  761. return;
  762. if( !IsNT ) {
  763. hSaveCursor = SetCursor(hHourGlass);
  764. SendMessage(hWndList, WM_SETREDRAW, FALSE, 0);
  765. }
  766. // Start with empty list
  767. if ( Clear ) {
  768. if( IsNT ) {
  769. ListView_DeleteAllItems( hWndList );
  770. } else {
  771. totitems = ListView_GetItemCount( hWndList );
  772. Deleting = TRUE;
  773. for(i = 0; i < totitems; i++)
  774. ListView_DeleteItem( hWndList, 0 );
  775. Deleting = FALSE;
  776. }
  777. LastRow = 0;
  778. }
  779. // Add all List items from Stats[] data
  780. for ( ptr = (void *)Stats; (char *)ptr < min(Stats+StatsLen,Stats + sizeof (Stats)); )  {
  781.   // Add to list
  782. ULONG len = strlen(ptr->text);
  783.         if( IsNT ) {
  784. len += 4; len &= 0xFFFFFFFC; // +1 for null-terminator +3 for 32bit alignment
  785. }
  786. itemsAdded |= List_Append( hWndList, ptr->seq, ptr->text );
  787. if( IsNT ) ptr = (void *)(ptr->text + len);
  788. else       ptr = (void *)(ptr->text + len + 1);
  789. }
  790. // Empty the buffer
  791. StatsLen = 0;
  792. // only do this if we added items
  793. if( itemsAdded ) {
  794. // limit number of lines saved
  795. if (MaxLines) {
  796. SendMessage(hWndList, WM_SETREDRAW, FALSE, 0);
  797. while ( LastRow > MaxLines ) {
  798. ListView_DeleteItem ( hWndList, 0 );
  799. LastRow--;
  800. }
  801. SendMessage(hWndList, WM_SETREDRAW, TRUE, 0);
  802. }
  803. // Scroll so newly added items are visible
  804. if ( Autoscroll ) {
  805. if( hBalloon ) DestroyWindow( hBalloon );
  806. ListView_EnsureVisible( hWndList, ListView_GetItemCount(hWndList)-1, FALSE ); 
  807. }
  808. }
  809. if( !IsNT ) {
  810. SetCursor( hSaveCursor );
  811. SendMessage(hWndList, WM_SETREDRAW, TRUE, 0);
  812. InvalidateRect( hWndList, NULL, FALSE );
  813. }
  814. }
  815. /****************************************************************************
  816. *    FUNCTION: ListViewSubclass(HWND,UINT,WPARAM)
  817. *
  818. *    PURPOSE:  Subclasses the listview so that we can do tooltips
  819. *
  820. ****************************************************************************/
  821. LRESULT CALLBACK ListViewSubclass(HWND hWnd, UINT uMsg, WPARAM wParam,
  822.         LPARAM lParam)
  823. {
  824. ITEM_CLICK itemClick;
  825. LVHITTESTINFO hitItem;
  826. static initTrack = FALSE;
  827. POINT           hitPoint, topleftPoint, bottomrightPoint;
  828. RECT listRect;
  829. static POINTS  mousePosition;
  830. if( !initTrack ) {
  831. SetTimer( hWnd, 2, BALLOONDELAY, NULL );
  832. initTrack = TRUE;
  833. }
  834.     switch (uMsg) {
  835. case WM_LBUTTONDBLCLK:
  836. case WM_RBUTTONDBLCLK:
  837. case WM_MBUTTONDBLCLK:
  838. case WM_LBUTTONUP:
  839. case WM_RBUTTONUP:
  840. case WM_MBUTTONUP:
  841. case WM_LBUTTONDOWN:
  842. case WM_MBUTTONDOWN:
  843. case WM_MOUSEMOVE:
  844. // delete any existing balloon
  845. if( hBalloon ) DestroyWindow( hBalloon );
  846. // save mouse position and reset the timer
  847. mousePosition = MAKEPOINTS( lParam );
  848. SetTimer( hWnd, 2, BALLOONDELAY, NULL );
  849. break;
  850. case WM_KEYDOWN:
  851. case WM_VSCROLL:
  852. case WM_HSCROLL:
  853. if( hBalloon ) DestroyWindow( hBalloon );
  854. break;
  855. case WM_RBUTTONDOWN:
  856. mousePosition = MAKEPOINTS( lParam );
  857. SetTimer( hWnd, 2, BALLOONDELAY, NULL );
  858. // fall-through
  859. case WM_TIMER:
  860. // are we currently in the listview?
  861. GetCursorPos( &hitPoint );
  862. GetClientRect( hWnd, &listRect );
  863. topleftPoint.x = listRect.left;
  864. topleftPoint.y = listRect.top;
  865. ClientToScreen( hWnd, &topleftPoint );
  866. bottomrightPoint.x = listRect.right;
  867. bottomrightPoint.y = listRect.bottom;
  868. ClientToScreen( hWnd, &bottomrightPoint );
  869. if( hitPoint.x < topleftPoint.x ||
  870. hitPoint.x > bottomrightPoint.x ||
  871. hitPoint.y < topleftPoint.y ||
  872. hitPoint.y > bottomrightPoint.y ||
  873. (hWndFind && GetFocus() != hWndList) ) {
  874. // delete any existing balloon
  875. if( hBalloon ) DestroyWindow( hBalloon );
  876. break;
  877. }
  878. hitItem.pt.x = mousePosition.x;
  879. hitItem.pt.y =  mousePosition.y;
  880. if( ListView_SubItemHitTest( hWndList, &hitItem ) != -1 ) {
  881. itemClick.itemText[0] = 0;
  882. ListView_GetItemText( hWndList, hitItem.iItem,
  883. hitItem.iSubItem, itemClick.itemText, 1024 );
  884. // delete any existing balloon
  885. if( hBalloon ) DestroyWindow( hBalloon );
  886. if( strlen( itemClick.itemText ) ) {
  887. if( hitItem.iSubItem ) {
  888. ListView_GetSubItemRect( hWndList, hitItem.iItem, hitItem.iSubItem,
  889. LVIR_BOUNDS, &itemClick.itemPosition);
  890. itemClick.itemPosition.bottom -= itemClick.itemPosition.top;
  891. itemClick.itemPosition.right  -= itemClick.itemPosition.left;
  892. } else {
  893. ListView_GetSubItemRect( hWndList, hitItem.iItem, 1,
  894. LVIR_BOUNDS, &itemClick.itemPosition);
  895. itemClick.itemPosition.bottom -= itemClick.itemPosition.top;
  896. itemClick.itemPosition.right  = itemClick.itemPosition.left;
  897. itemClick.itemPosition.left   = 0;
  898. }
  899. hitPoint.y = itemClick.itemPosition.top;
  900. hitPoint.x = itemClick.itemPosition.left;
  901. ClientToScreen( hWnd, &hitPoint );
  902. itemClick.itemPosition.left = hitPoint.x;
  903. itemClick.itemPosition.top  = hitPoint.y;
  904. // pop-up a balloon (tool-tip like window)
  905. hBalloon = CreateWindowEx( 0, _T("BALLOON"), 
  906. _T("balloon"), 
  907. WS_POPUP|WS_BORDER,
  908. 100, 100,
  909. 200, 200,
  910. hWndMain, NULL, hInst, 
  911. &itemClick );
  912. if( hBalloon) SetFocus( hWnd );
  913. }
  914. }
  915. break;
  916.     }
  917. // pass-through to real listview handler
  918.     return CallWindowProc(ListViewWinMain, hWnd, uMsg, wParam, 
  919.             lParam);
  920. }
  921. /****************************************************************************
  922. *    FUNCTION: CreateListView(HWND)
  923. *
  924. *    PURPOSE:  Creates the statistics list view window and initializes it
  925. *
  926. ****************************************************************************/
  927. HWND CreateList( HWND hWndParent )                                     
  928. {
  929. HWND hWndList;        // handle to list view window
  930. RECT rc;             // rectangle for setting size of window
  931. LV_COLUMN lvC; // list view column structure
  932. DWORD j;
  933. static struct {
  934. TCHAR * Label; // title of column
  935. DWORD Width; // width of column in pixels
  936. DWORD Fmt;
  937. } column[] = {
  938. { "#" , 35 },
  939. { "Process" , 90 },
  940. { "Request" , 90 },
  941. { "Path" , 225 },
  942. { "Result" , 90 },
  943. { "Other" , 150 },
  944. };
  945. // Ensure that the common control DLL is loaded.
  946. InitCommonControls();
  947. // Set the column widths according to the user-settings
  948. for( j = 0; j < NUMCOLUMNS; j++ ) {
  949. column[j].Width = PositionInfo.column[j];
  950. }
  951. // Get the size and position of the parent window.
  952. GetClientRect( hWndParent, &rc );
  953. // Create the list view window
  954. hWndList = CreateWindowEx( /* WS_EX_CLIENTEDGE */ 0L, WC_LISTVIEW, _T(""), 
  955. WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT |
  956. LVS_SINGLESEL,
  957. 0, TOOLBARHEIGHT, rc.right - rc.left, rc.bottom - rc.top - TOOLBARHEIGHT,
  958. hWndParent, (HMENU)ID_LIST, hInst, NULL );
  959. if ( hWndList == NULL )
  960. return NULL;
  961. // Initialize columns
  962. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  963. lvC.fmt = LVCFMT_LEFT; // left-align column
  964. // Add the columns.
  965. for ( j = 0; j < sizeof column/sizeof column[0]; ++j )  {
  966. lvC.iSubItem = j;
  967. lvC.cx = column[j].Width;
  968.   lvC.pszText = column[j].Label;
  969. if ( ListView_InsertColumn( hWndList, j, &lvC ) == -1 )
  970. return NULL;
  971. }
  972. // set full-row selection
  973. SendMessage( hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE,
  974. LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT );
  975. // sub-class
  976. ListViewWinMain = (WNDPROC) SetWindowLong(hWndList, 
  977.                                               GWL_WNDPROC, 
  978.                                               (DWORD)ListViewSubclass); 
  979. return hWndList;
  980. }
  981. /****************************************************************************
  982. *    FUNCTION: SaveFile()
  983. *
  984. *    PURPOSE:  Lets the user go select a file.
  985. *
  986. ****************************************************************************/
  987. void SaveFile( HWND hWnd, HWND ListBox, BOOLEAN SaveAs )
  988. {
  989. OPENFILENAME SaveFileName;
  990. char szFile[256] = "", fieldtext[256], output[1024];
  991. FILE *hFile;
  992. int numitems;
  993. int row, subitem;
  994. if( SaveAs || !FileChosen ) {
  995. SaveFileName.lStructSize       = sizeof (SaveFileName);
  996. SaveFileName.hwndOwner         = hWnd;
  997. SaveFileName.hInstance         = (HANDLE) hInst;
  998. SaveFileName.lpstrFilter       = "Reg Data (*.RGD)*.RGDAll (*.*)*.*";
  999. SaveFileName.lpstrCustomFilter = (LPTSTR)NULL;
  1000. SaveFileName.nMaxCustFilter    = 0L;
  1001. SaveFileName.nFilterIndex      = 1L;
  1002. SaveFileName.lpstrFile         = szFile;
  1003. SaveFileName.nMaxFile          = 256;
  1004. SaveFileName.lpstrFileTitle    = NULL;
  1005. SaveFileName.nMaxFileTitle     = 0;
  1006. SaveFileName.lpstrInitialDir   = NULL;
  1007. SaveFileName.lpstrTitle        = "Save File Info...";
  1008. SaveFileName.nFileOffset       = 0;
  1009. SaveFileName.nFileExtension    = 0;
  1010. SaveFileName.lpstrDefExt       = "*.rgd";
  1011. SaveFileName.lpfnHook    = NULL;
  1012.   SaveFileName.Flags = OFN_LONGNAMES|OFN_HIDEREADONLY;
  1013. if( !GetSaveFileName( &SaveFileName )) 
  1014. return;
  1015. } else 
  1016. // open previous szFile
  1017. strcpy( szFile, szFileName );
  1018. // open the file
  1019. hFile = fopen( szFile, "w" );
  1020. if( !hFile ) {
  1021. MessageBox( NULL, "Create File Failed.",
  1022. "Save Error", MB_OK|MB_ICONSTOP );
  1023. return;
  1024. }
  1025. // post hourglass icon
  1026. SetCapture(hWnd);
  1027. hSaveCursor = SetCursor(hHourGlass);
  1028. numitems = ListView_GetItemCount(ListBox);
  1029. for ( row = 0; row < numitems; row++ )  {
  1030. output[0] = 0;
  1031. for( subitem = 0; subitem < 6; subitem++ ) {
  1032. fieldtext[0] = 0;
  1033. ListView_GetItemText( ListBox, row, subitem, fieldtext, 256 );
  1034. strcat( output, fieldtext );
  1035. strcat( output, "t" );
  1036. }
  1037. fprintf( hFile, "%sn", output );
  1038. }
  1039. fclose( hFile );
  1040. strcpy( szFileName, szFile );
  1041. FileChosen = TRUE;
  1042. SetCursor( hSaveCursor );
  1043. ReleaseCapture(); 
  1044. }
  1045. /****************************************************************************
  1046. *
  1047. * FUNCTION: FilterProc
  1048. *
  1049. * PURPOSE: Processes messages for "Filter" dialog box
  1050. *
  1051. ****************************************************************************/
  1052. BOOL APIENTRY FilterProc( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  1053. {
  1054. int nb;
  1055. FILTER upcaseFilter;
  1056. DWORD newMaxLines;
  1057. char history[64];
  1058. switch ( message )  {
  1059. case WM_INITDIALOG:
  1060. // initialize the controls to reflect the current filter
  1061. SetDlgItemText( hDlg, IDC_PROCFILTER, FilterDefinition.processfilter );
  1062. SetDlgItemText( hDlg, IDC_PROCEXCLUDE, FilterDefinition.processexclude );
  1063. SetDlgItemText( hDlg, IDC_PATHFILTER, FilterDefinition.pathfilter );
  1064. SetDlgItemText( hDlg, IDC_EXCLUDEFILTER, FilterDefinition.excludefilter );
  1065. CheckDlgButton( hDlg, IDC_SUCCESS, FilterDefinition.logsuccess );
  1066. CheckDlgButton( hDlg, IDC_ERROR,   FilterDefinition.logerror );
  1067. CheckDlgButton( hDlg, IDC_LOGREADS, FilterDefinition.logreads );
  1068. CheckDlgButton( hDlg, IDC_LOGWRITES,   FilterDefinition.logwrites );
  1069. sprintf( history, "%d", MaxLines );
  1070. SetDlgItemText( hDlg, IDC_HISTORY, history );
  1071. return TRUE;
  1072. case WM_COMMAND:              
  1073. if ( LOWORD( wParam ) == IDOK )  {
  1074. // make sure that max lines is legal
  1075. GetDlgItemTextA( hDlg, IDC_HISTORY, history, 64 );
  1076. if( !sscanf( history, "%d", &newMaxLines )) {
  1077. MessageBox( NULL, _T("Invalid History Depth."),
  1078. _T("Filter Error"), MB_OK|MB_ICONWARNING );
  1079. return TRUE;
  1080. MaxLines = newMaxLines;
  1081. // read the values that were set
  1082. GetDlgItemText( hDlg, IDC_PROCFILTER, FilterDefinition.processfilter, MAXFILTERLEN );
  1083. GetDlgItemText( hDlg, IDC_PROCEXCLUDE, FilterDefinition.processexclude, MAXFILTERLEN );
  1084. GetDlgItemText( hDlg, IDC_PATHFILTER, FilterDefinition.pathfilter, MAXFILTERLEN );
  1085. GetDlgItemText( hDlg, IDC_EXCLUDEFILTER, FilterDefinition.excludefilter, MAXFILTERLEN );
  1086. FilterDefinition.logsuccess = IsDlgButtonChecked( hDlg, IDC_SUCCESS );
  1087. FilterDefinition.logerror   = IsDlgButtonChecked( hDlg, IDC_ERROR );
  1088. FilterDefinition.logreads = IsDlgButtonChecked( hDlg, IDC_LOGREADS );
  1089. FilterDefinition.logwrites   = IsDlgButtonChecked( hDlg, IDC_LOGWRITES );
  1090. // make an upcase version for the driver
  1091. upcaseFilter = FilterDefinition;
  1092. _strupr(upcaseFilter.processfilter);
  1093. _strupr(upcaseFilter.processexclude);
  1094. _strupr(upcaseFilter.pathfilter);
  1095. _strupr(upcaseFilter.excludefilter);
  1096.  
  1097. // tell the driver the new filter
  1098. if ( ! DeviceIoControl( SysHandle, REGMON_setfilter,
  1099. &upcaseFilter, sizeof(FILTER), NULL, 
  1100. 0, &nb, NULL ) )
  1101. {
  1102. Abort( hDlg, _T("Couldn't access device driver") );
  1103. return TRUE;
  1104. }
  1105. EndDialog( hDlg, TRUE );
  1106. return TRUE;
  1107. } else if( LOWORD( wParam ) == IDCANCEL ) {
  1108. EndDialog( hDlg, TRUE );
  1109. } else if( LOWORD( wParam ) == IDRESET ) {
  1110. // reset filter to default of none
  1111. sprintf( FilterDefinition.processfilter, "*" );
  1112. sprintf( FilterDefinition.processexclude, "" );
  1113. sprintf( FilterDefinition.pathfilter, "*" );
  1114. sprintf( FilterDefinition.excludefilter, "");
  1115. FilterDefinition.logsuccess = TRUE;
  1116. FilterDefinition.logerror = TRUE;
  1117. FilterDefinition.logreads = TRUE;
  1118. FilterDefinition.logwrites = TRUE;
  1119. MaxLines = 0;
  1120.  
  1121. // initialize the controls to reflect the current filter
  1122. SetDlgItemText( hDlg, IDC_PROCFILTER, FilterDefinition.processfilter );
  1123. SetDlgItemText( hDlg, IDC_PROCEXCLUDE, FilterDefinition.processexclude );
  1124. SetDlgItemText( hDlg, IDC_PATHFILTER, FilterDefinition.pathfilter );
  1125. SetDlgItemText( hDlg, IDC_EXCLUDEFILTER, FilterDefinition.excludefilter );
  1126. CheckDlgButton( hDlg, IDC_SUCCESS, FilterDefinition.logsuccess );
  1127. CheckDlgButton( hDlg, IDC_ERROR,   FilterDefinition.logerror );
  1128. CheckDlgButton( hDlg, IDC_LOGREADS, FilterDefinition.logreads );
  1129. CheckDlgButton( hDlg, IDC_LOGWRITES,   FilterDefinition.logwrites );
  1130. SetDlgItemText( hDlg, IDC_HISTORY, "0" );
  1131. }
  1132. break;
  1133. case WM_CLOSE:
  1134. EndDialog( hDlg, TRUE );
  1135. return TRUE;
  1136. }
  1137. return FALSE;   
  1138. }
  1139. /****************************************************************************
  1140. *
  1141. * FUNCTION: About
  1142. *
  1143. * PURPOSE: Processes messages for "About" dialog box
  1144. *
  1145. ****************************************************************************/
  1146. BOOL APIENTRY About( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  1147. {
  1148. switch ( message )  {
  1149.    case WM_INITDIALOG:
  1150.   return TRUE;
  1151.    case WM_COMMAND:              
  1152.   if ( LOWORD( wParam ) == IDOK )  {
  1153.   EndDialog( hDlg, TRUE );
  1154.   return TRUE;
  1155.   }
  1156.   break;
  1157.    case WM_CLOSE:
  1158.   EndDialog( hDlg, TRUE );
  1159.   return TRUE;
  1160. }
  1161. return FALSE;   
  1162. }
  1163. /******************************************************************************
  1164. *
  1165. * FUNCTION: GetDLLVersion
  1166. *
  1167. * PURPOSE: Gets the version number of the specified DLL.
  1168. *
  1169. ******************************************************************************/
  1170. HRESULT GetDLLVersion( PCHAR DllName, LPDWORD pdwMajor, LPDWORD pdwMinor)
  1171. {
  1172. HINSTANCE hDll;
  1173. HRESULT hr = S_OK;
  1174. DLLVERSIONINFO_ dvi;
  1175. *pdwMajor = 0;
  1176. *pdwMinor = 0;
  1177. //Load the DLL.
  1178. hDll = LoadLibrary(DllName);
  1179. if( hDll ) {
  1180.    pDllGetVersionProc = (PVOID)GetProcAddress(hDll, _T("DllGetVersion"));
  1181.    if(pDllGetVersionProc) {
  1182.   
  1183.   ZeroMemory(&dvi, sizeof(dvi));
  1184.   dvi.cbSize = sizeof(dvi);
  1185.   hr = (*pDllGetVersionProc)(&dvi);
  1186.   
  1187.   if(SUCCEEDED(hr)) {
  1188.  *pdwMajor = dvi.dwMajorVersion;
  1189.  *pdwMinor = dvi.dwMinorVersion;
  1190.   }
  1191.     } else {
  1192.   // If GetProcAddress failed, the DLL is a version previous to the one 
  1193.   // shipped with IE 3.x.
  1194.   *pdwMajor = 4;
  1195.   *pdwMinor = 0;
  1196.       }
  1197.    
  1198.   FreeLibrary(hDll);
  1199.   return hr;
  1200. }
  1201. return E_FAIL;
  1202. }
  1203. /****************************************************************************
  1204. *
  1205. *    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
  1206. *
  1207. *    PURPOSE:  Processes messages for the statistics window.
  1208. *
  1209. ****************************************************************************/
  1210. LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam) 
  1211. {
  1212. DWORD nb, versionNumber;
  1213. DWORD length, type, tag, driverStart;
  1214. TCHAR Path[ MAX_PATH ];
  1215. HKEY hDriverKey;
  1216. static TCHAR group[] = "System Bus Extender";
  1217. static TCHAR driverPath[ MAX_PATH ];
  1218. TCHAR systemRoot[ MAX_PATH ];
  1219. static TCHAR logFile[ MAX_PATH ];
  1220. static HWND hWndToolbar;
  1221. LPTOOLTIPTEXT lpToolTipText;
  1222. static TCHAR szBuf[128];
  1223. LPFINDREPLACE findMessageInfo;
  1224. DWORD majorver, minorver;
  1225. TCHAR *File;
  1226. WIN32_FIND_DATA findData;
  1227. HANDLE findHandle;
  1228. DWORD startTime;
  1229. POINT hitPoint;
  1230. RECT listRect;
  1231. HDC hDC;
  1232. PAINTSTRUCT Paint;
  1233. MENUITEMINFO bootMenuItem;
  1234. switch ( message ) {
  1235. case WM_CREATE:
  1236. // get hourglass icon ready
  1237. hHourGlass = LoadCursor( NULL, IDC_WAIT );
  1238. // post hourglass icon
  1239. SetCapture(hWnd);
  1240. hSaveCursor = SetCursor(hHourGlass);
  1241. // Create the toolbar control - use modern style if available.
  1242. GetDLLVersion( "comctl32.dll", &majorver, &minorver );
  1243. if( majorver > 4 || (majorver == 4 && minorver >= 70) ) {
  1244. hWndToolbar = CreateToolbarEx( 
  1245. hWnd, TOOLBAR_FLAT | WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,  
  1246. ID_TOOLBAR, 9, hInst, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtons,
  1247. NUMBUTTONS, 16,16,16,15, sizeof(TBBUTTON)); 
  1248. } else {
  1249. hWndToolbar = CreateToolbarEx( 
  1250. hWnd, WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,  
  1251. ID_TOOLBAR, 9, hInst, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtonsOld,
  1252. NUMBUTTONSOLD, 16,16,16,15, sizeof(TBBUTTON)); 
  1253. }
  1254. if (hWndToolbar == NULL )
  1255. MessageBox (NULL, _T("Toolbar not created!"), NULL, MB_OK );
  1256. // Create the ListBox within the main window
  1257. hWndList = CreateList( hWnd );
  1258. if ( hWndList == NULL )
  1259. MessageBox( NULL, _T("List not created!"), NULL, MB_OK );
  1260.     // open the handle to the device
  1261. if( IsNT ) {
  1262. // Add the log boot menu item
  1263. bootMenuItem.cbSize = sizeof( bootMenuItem );
  1264. bootMenuItem.fMask = MIIM_TYPE;
  1265. bootMenuItem.fType = MFT_SEPARATOR;
  1266. InsertMenuItem( GetSubMenu( GetMenu(hWnd), 1 ), 
  1267. GetMenuItemCount( GetSubMenu( GetMenu(hWnd), 1 )),
  1268. TRUE, &bootMenuItem );
  1269. bootMenuItem.fMask = MIIM_TYPE|MIIM_ID;
  1270. bootMenuItem.fType = MFT_STRING;
  1271. bootMenuItem.wID = IDM_BOOTLOG;
  1272. bootMenuItem.dwTypeData = (PCHAR) "Log &Boot";
  1273. InsertMenuItem( GetSubMenu( GetMenu(hWnd), 1 ), 
  1274. GetMenuItemCount( GetSubMenu( GetMenu(hWnd), 1 )),
  1275. TRUE, &bootMenuItem );
  1276. GetCurrentDirectory( sizeof Path, Path );
  1277. sprintf( Path+lstrlen(Path), _T("\%s"), SYS_FILE );
  1278. findHandle = FindFirstFile( Path, &findData );
  1279. if( findHandle == INVALID_HANDLE_VALUE ) {
  1280. if( !SearchPath( NULL, SYS_FILE, NULL, sizeof(Path), Path, &File ) ) {
  1281. sprintf( msgbuf, _T("%s was not found."), SYS_FILE );
  1282. return Abort( hWnd, msgbuf );
  1283. }
  1284. } else FindClose( findHandle );
  1285. // read driver start type to see if boot-logging is enabled
  1286. driverStart = SERVICE_DEMAND_START;
  1287. if( RegOpenKey( HKEY_LOCAL_MACHINE, DriverRegistryKey, &hDriverKey ) == 
  1288. ERROR_SUCCESS ) {
  1289. length = sizeof( driverStart );
  1290. RegQueryValueEx( hDriverKey, "Start", NULL, &type,
  1291. (PBYTE) &driverStart, &length);
  1292. RegCloseKey( hDriverKey );
  1293. BootLog = (driverStart != SERVICE_DEMAND_START);
  1294. // check boot logging menu item if boot start
  1295. CheckMenuItem( GetMenu(hWnd), IDM_BOOTLOG,
  1296. MF_BYCOMMAND|(BootLog?MF_CHECKED:MF_UNCHECKED) ); 
  1297. // copy the driver to <winnt>system32drivers so that we can do
  1298. // boot-time monitoring with the flip of a bit
  1299. // get the system root
  1300. if( !GetEnvironmentVariable( "SYSTEMROOT", systemRoot, sizeof(systemRoot))) {
  1301. strcpy( msgbuf, _T("Could not resolve SYSTEMROOT environment variable") );
  1302. return Abort( hWnd, msgbuf );
  1303. }
  1304. sprintf( logFile, _T("%s\REGMON.LOG"), systemRoot );
  1305. sprintf( driverPath, _T("%s\system32\drivers\%s"), 
  1306. systemRoot, SYS_FILE );
  1307. if( !CopyFile( Path, driverPath, FALSE )) {
  1308. sprintf( msgbuf, _T("Unable to copy %s to %snn")
  1309. _T("Make sure that regsys.sys is in the current directory."), 
  1310. SYS_NAME, driverPath );
  1311. return Abort( hWnd, msgbuf );
  1312. }
  1313. if ( ! LoadDeviceDriver( SYS_NAME, driverPath, &SysHandle ) )  {
  1314. sprintf( msgbuf, _T("Opening %s (%s): error %d"), SYS_NAME, Path,
  1315. GetLastError( ) );
  1316. return Abort( hWnd, msgbuf );
  1317. }
  1318. // Correct driver version?
  1319. if ( ! DeviceIoControl( SysHandle, REGMON_version,
  1320. NULL, 0, &versionNumber, sizeof(DWORD), &nb, NULL ) ||
  1321. versionNumber != REGMONVERSION )
  1322. {
  1323. MessageBox( hWnd, _T("Regmon located a driver with the wrong version.n")
  1324. _T("nIf you just installed a new version you must reboot before you are")
  1325. _T("able to use it."), _T("Regmon"), MB_ICONERROR);
  1326. return -1;
  1327. }
  1328. } else {
  1329. // Win9x
  1330. SysHandle = CreateFile( VXD_FILE, 0, 0, NULL,
  1331. 0, FILE_FLAG_OVERLAPPED|
  1332. FILE_FLAG_DELETE_ON_CLOSE,
  1333. NULL );
  1334. if ( SysHandle == INVALID_HANDLE_VALUE )  {
  1335. wsprintf( msgbuf, "%s is not loaded properly.", VXD_NAME );
  1336. Abort( hWnd, msgbuf );
  1337. return FALSE;
  1338. }
  1339. }
  1340. // Have driver zero information
  1341. if ( ! DeviceIoControl( SysHandle, REGMON_zerostats,
  1342. NULL, 0, NULL, 0, &nb, NULL ) )
  1343. {
  1344. return Abort( hWnd, _T("Couldn't access device driver") );
  1345. }
  1346. // Give the user to change initial filter
  1347. if( strcmp(FilterDefinition.processfilter, "*") ||
  1348. strcmp(FilterDefinition.processexclude, "") ||
  1349. strcmp(FilterDefinition.pathfilter, "*")    ||
  1350. strcmp(FilterDefinition.excludefilter, "")  ||
  1351. !FilterDefinition.logsuccess ||
  1352. !FilterDefinition.logerror   ||
  1353. !FilterDefinition.logreads   ||
  1354. !FilterDefinition.logwrites ) {
  1355. DialogBox( hInst, _T("InitFilter"), hWnd, (DLGPROC) FilterProc );
  1356. } else {
  1357. // tell the driver the initial filter
  1358. if ( ! DeviceIoControl( SysHandle, REGMON_setfilter,
  1359. &FilterDefinition, sizeof(FILTER), NULL, 
  1360. 0, &nb, NULL ) )
  1361. {
  1362. return Abort( hWnd, _T("Couldn't access device driver") );
  1363. }
  1364. }
  1365. // Start up timer to periodically update screen
  1366. SetTimer( hWnd, 1, 500/*ms*/, NULL );
  1367. // Have driver turn on hooks
  1368. if ( ! DeviceIoControl( SysHandle, REGMON_hook,
  1369. NULL, 0, NULL, 0, &nb, NULL ) )
  1370. {
  1371. return Abort( hWnd, _T("Couldn't access device driver") );
  1372. }
  1373. // Initialization done
  1374. SetCursor( hSaveCursor );
  1375. ReleaseCapture();
  1376. return FALSE;
  1377. case WM_NOTIFY:
  1378. // Make sure its intended for us
  1379. if ( wParam == ID_LIST )  {
  1380. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  1381. switch ( pNm->hdr.code )  {
  1382.         case LVN_BEGINLABELEDIT:
  1383. // Don't allow editing of information
  1384. return TRUE;
  1385. case NM_DBLCLK:
  1386. case NM_RETURN:
  1387. // open the specified key in Regedit, if we can
  1388. RegeditJump( hWnd );
  1389. return TRUE;
  1390. }
  1391. } else {
  1392. switch (((LPNMHDR) lParam)->code) 
  1393. {
  1394. case TTN_NEEDTEXT:    
  1395. // Display the ToolTip text.
  1396. lpToolTipText = (LPTOOLTIPTEXT)lParam;
  1397.      LoadString (hInst, lpToolTipText->hdr.idFrom, szBuf, sizeof(szBuf));
  1398.      lpToolTipText->lpszText = szBuf;
  1399. break;
  1400. default:
  1401. return FALSE;
  1402. }
  1403. }
  1404. return FALSE;
  1405. case WM_COMMAND:
  1406. switch ( LOWORD( wParam ) )  {
  1407. // stats related commands to send to driver
  1408. case IDM_CLEAR:
  1409. // Have driver zero information
  1410. if ( ! DeviceIoControl( SysHandle, REGMON_zerostats,
  1411. NULL, 0, NULL, 0, &nb, NULL ) )
  1412. {
  1413. Abort( hWnd, _T("Couldn't access device driver") );
  1414. return TRUE;
  1415. }
  1416. // Update statistics windows
  1417. UpdateStatistics( hWnd, hWndList, TRUE );
  1418. return FALSE;
  1419. case IDM_HELP:
  1420. WinHelp(hWnd, _T("regmon.hlp"), HELP_CONTENTS, 0L);
  1421. return 0;
  1422. case IDM_FIND:
  1423. // search the listview
  1424. if( !hWndFind ) {
  1425. PrevMatch = FALSE;
  1426. PopFindDialog( hWnd );
  1427. } else if( PrevMatch ) {
  1428. // treat this like a find-next
  1429. SetCapture(hWndFind);
  1430. hSaveCursor = SetCursor(hHourGlass);
  1431. EnableWindow( hWndFind, FALSE );
  1432. if (FindInListview( hWnd, &FindTextInfo ) ) {
  1433. Autoscroll = FALSE;
  1434. CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
  1435. MF_BYCOMMAND|MF_UNCHECKED ); 
  1436. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, 3 );
  1437. }
  1438. EnableWindow( hWndFind, TRUE );
  1439. SetCursor( hSaveCursor );
  1440. ReleaseCapture(); 
  1441. }
  1442. return 0;
  1443. case IDM_CAPTURE:
  1444. // Read statistics from driver
  1445. Capture = !Capture;
  1446. CheckMenuItem( GetMenu(hWnd), IDM_CAPTURE,
  1447. MF_BYCOMMAND|(Capture?MF_CHECKED:MF_UNCHECKED) );
  1448. // Have driver turn on hooks
  1449. if ( ! DeviceIoControl( SysHandle, Capture ? REGMON_hook : 
  1450. REGMON_unhook,
  1451. NULL, 0, NULL, 0, &nb, NULL ) )
  1452. {
  1453. Abort( hWnd, _T("Couldn't access device driver") );
  1454. return TRUE;
  1455. }
  1456. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_CAPTURE, (Capture?2:1) );
  1457. InvalidateRect( hWndToolbar, NULL, TRUE );
  1458. return FALSE;
  1459. case IDM_AUTOSCROLL:
  1460. Autoscroll = !Autoscroll;
  1461. CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
  1462. MF_BYCOMMAND|(Autoscroll?MF_CHECKED:MF_UNCHECKED) ); 
  1463. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, (Autoscroll?4:3) );
  1464. InvalidateRect( hWndToolbar, NULL, TRUE );
  1465. return FALSE;
  1466. case IDM_BOOTLOG:
  1467. BootLog = !BootLog;
  1468. CheckMenuItem( GetMenu(hWnd), IDM_BOOTLOG,
  1469. MF_BYCOMMAND|(BootLog?MF_CHECKED:MF_UNCHECKED) ); 
  1470. if( BootLog ) {
  1471. sprintf( msgbuf, 
  1472. _T("Regmon has been configured to log Registry activity to %s during the next boot"),
  1473. logFile );
  1474. MessageBox( hWnd, msgbuf, _T("Regmon"), MB_OK|MB_ICONINFORMATION);
  1475. }
  1476. BootLogMenuUsed = TRUE;
  1477. return FALSE;
  1478. case IDM_EXIT:
  1479. // Close ourself
  1480. SendMessage( hWnd, WM_CLOSE, 0, 0 );
  1481. return FALSE;
  1482. case IDM_FILTER:
  1483. DialogBox( hInst, _T("Filter"), hWnd, (DLGPROC) FilterProc );
  1484. return FALSE;
  1485. case IDM_ONTOP:
  1486. OnTop = !OnTop;
  1487. if( OnTop ) SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, 
  1488. SWP_NOMOVE|SWP_NOSIZE );
  1489. else  SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, 
  1490. SWP_NOMOVE|SWP_NOSIZE );
  1491. CheckMenuItem( GetMenu(hWnd), IDM_ONTOP,
  1492. MF_BYCOMMAND|(OnTop?MF_CHECKED:MF_UNCHECKED) );
  1493. return 0;
  1494. case IDM_JUMP:
  1495. // open the specified key in Regedit, if we can
  1496. RegeditJump( hWnd );
  1497. return FALSE;
  1498. case IDM_ABOUT:
  1499. // Show the names of the authors
  1500. DialogBox( hInst, _T("AboutBox"), hWnd, (DLGPROC)About );
  1501. return FALSE;
  1502. case IDM_SAVE:
  1503. SaveFile( hWnd, hWndList, FALSE );
  1504. return FALSE;
  1505. case IDM_SAVEAS:
  1506. SaveFile( hWnd, hWndList, TRUE );
  1507. return FALSE;
  1508. default:
  1509. // Default behavior
  1510. return DefWindowProc( hWnd, message, wParam, lParam );
  1511. }
  1512. break;
  1513. case WM_TIMER:
  1514. // Time to query the device driver for more data
  1515. if ( Capture )  {
  1516. // don't process for more than a second without pausing
  1517. startTime = GetTickCount();
  1518. for (;;)  {
  1519. // Have driver fill Stats buffer with information
  1520. if ( ! DeviceIoControl( SysHandle, REGMON_getstats,
  1521. NULL, 0, &Stats, sizeof Stats,
  1522. &StatsLen, NULL ) )
  1523. {
  1524. Abort( hWnd, _T("Couldn't access device driver") );
  1525. return TRUE;
  1526. }
  1527. if ( StatsLen == 0 )
  1528. break;
  1529. // Update statistics windows
  1530. UpdateStatistics( hWnd, hWndList, FALSE );
  1531. if( GetTickCount() - startTime > 1000 ) break;
  1532. }
  1533. }
  1534. // delete balloon if necessary
  1535. if( hBalloon ) {
  1536. GetCursorPos( &hitPoint );
  1537. GetWindowRect( hWndList, &listRect );
  1538. if( hitPoint.x < listRect.left ||
  1539. hitPoint.x > listRect.right ||
  1540. hitPoint.y < listRect.top ||
  1541. hitPoint.y > listRect.bottom ) {
  1542. DestroyWindow( hBalloon );
  1543. }
  1544. }
  1545. return FALSE;
  1546. case WM_SIZE:
  1547. // Move or resize the List
  1548. MoveWindow( hWndToolbar, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE );
  1549.             MoveWindow( hWndList, 0, TOOLBARHEIGHT, LOWORD(lParam), HIWORD(lParam)-TOOLBARHEIGHT, TRUE );
  1550. if( hBalloon ) DestroyWindow( hBalloon );
  1551. return FALSE;
  1552. case WM_MOVE:
  1553. case WM_MOUSEMOVE:
  1554. if( hBalloon ) DestroyWindow( hBalloon );
  1555. return FALSE;
  1556. case WM_CLOSE:
  1557. // Have driver unhook if necessary
  1558. if( Capture ) {
  1559. if ( ! DeviceIoControl( SysHandle, REGMON_unhook,
  1560. NULL, 0, NULL, 0, &nb, NULL ) )
  1561. {
  1562. Abort( hWnd, _T("Couldn't access device driver") );
  1563. return TRUE;
  1564. }
  1565. }
  1566. KillTimer( hWnd, 1 );
  1567. CloseHandle( SysHandle );
  1568. #if _DEBUG
  1569. if ( IsNT &&  !UnloadDeviceDriver( SYS_NAME ) )  {
  1570. wsprintf( msgbuf, _T("Error unloading "%s""), SYS_NAME );
  1571. MessageBox( hWnd, msgbuf, _T("Regmon"), MB_OK );
  1572. }
  1573. #endif
  1574. // Make sure the user knows boot logging will take place
  1575. if( IsNT ) {
  1576. if( !BootLogMenuUsed && BootLog ) {
  1577. sprintf( msgbuf, 
  1578. _T("Regmon is configured to log Registry activity to %s during the next boot"),
  1579. logFile );
  1580. MessageBox( hWnd, msgbuf, _T("Regmon"), MB_ICONINFORMATION);
  1581. }
  1582. // if boot logging isn't enabled, delete the driver from 
  1583. // the drivers directory
  1584. if( !BootLog ) {
  1585. if( RegCreateKey( HKEY_LOCAL_MACHINE, DriverRegistryKey, &hDriverKey ) == 
  1586. ERROR_SUCCESS ) {
  1587. driverStart = SERVICE_DEMAND_START;
  1588. RegSetValueEx( hDriverKey, _T("Start"), 0, REG_DWORD, 
  1589. (PBYTE) &driverStart, sizeof(driverStart));
  1590. RegDeleteValue( hDriverKey, _T("Group"));
  1591. RegDeleteValue( hDriverKey, _T("Tag"));
  1592. DeleteFile( driverPath );
  1593. }
  1594. } else {
  1595. // boot logging on - configure the regmon service key.
  1596. if( RegCreateKey( HKEY_LOCAL_MACHINE, DriverRegistryKey, &hDriverKey ) == 
  1597. ERROR_SUCCESS ) {
  1598. // the driver is already in the winntsystem32drivers directory
  1599. driverStart = SERVICE_BOOT_START;
  1600. RegDeleteValue( hDriverKey, _T("DeleteFlag" ));
  1601. RegSetValueEx( hDriverKey, _T("Start"), 0, REG_DWORD, 
  1602. (PBYTE) &driverStart, sizeof(driverStart));
  1603. RegSetValueEx( hDriverKey, "Group", 0, REG_SZ, group, sizeof( group ));
  1604. tag = 1;
  1605. RegSetValueEx( hDriverKey, "Tag", 0, REG_DWORD, 
  1606. (PBYTE) &tag, sizeof(tag));
  1607. RegSetValueEx( hDriverKey, "Type", 0, REG_DWORD,
  1608. (PBYTE) &tag, sizeof(tag));
  1609. sprintf( Path, _T("System32\Drivers\%s"),
  1610. SYS_FILE );
  1611. RegSetValueEx( hDriverKey, _T("ImagePath"), 0, REG_EXPAND_SZ,
  1612. Path, strlen(Path));
  1613. RegCloseKey( hDriverKey );
  1614. } else {
  1615. Abort( hWnd, _T("Regmon could not configure boot logging"));
  1616. }
  1617. }
  1618. if( hDriverKey != INVALID_HANDLE_VALUE ) RegCloseKey( hDriverKey );
  1619. }
  1620. Save_Position_Settings( hWnd );
  1621. return DefWindowProc( hWnd, message, wParam, lParam );
  1622. case WM_SETFOCUS:
  1623. SetFocus( hWndList );
  1624. break;
  1625. case WM_DESTROY:
  1626. PostQuitMessage(0);
  1627. return FALSE;
  1628. case WM_PAINT:
  1629. if( !IsNT && Deleting ) {
  1630. hDC = BeginPaint( hWnd, &Paint );
  1631. EndPaint( hWnd, &Paint );
  1632. return TRUE;
  1633. }
  1634. return DefWindowProc( hWnd, message, wParam, lParam );
  1635. default:
  1636. // is it a find-string message?
  1637. if (message == findMessageID ){ 
  1638. // get a pointer to the find structure
  1639. findMessageInfo = (LPFINDREPLACE)lParam;
  1640. // If the FR_DIALOGTERM flag is set, invalidate the find window handle
  1641. if( findMessageInfo->Flags & FR_DIALOGTERM) {
  1642. hWndFind = NULL;
  1643. PrevMatch = FALSE;
  1644.     FindFlags = FindTextInfo.Flags & (FR_DOWN|FR_MATCHCASE|FR_WHOLEWORD);
  1645. return 0;
  1646. }
  1647. // if the FR_FINDNEXT flag is set, go do the search
  1648. if( findMessageInfo->Flags & FR_FINDNEXT ) {
  1649. SetCapture(hWndFind);
  1650. hSaveCursor = SetCursor(hHourGlass);
  1651. EnableWindow( hWndFind, FALSE );
  1652. if( FindInListview( hWnd, findMessageInfo ) ) {
  1653. Autoscroll = FALSE;
  1654. CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
  1655. MF_BYCOMMAND|MF_UNCHECKED ); 
  1656. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, 3 );
  1657. }
  1658. EnableWindow( hWndFind, TRUE );
  1659. ReleaseCapture(); 
  1660. return 0;
  1661. }
  1662. return 0;
  1663. }
  1664. // Default behavior
  1665. return DefWindowProc( hWnd, message, wParam, lParam );
  1666. }
  1667. return FALSE;
  1668. }
  1669. /****************************************************************************
  1670. *
  1671. *    FUNCTION: InitApplication(HANDLE)
  1672. *
  1673. *    PURPOSE: Initializes window data and registers window class
  1674. *
  1675. ****************************************************************************/
  1676. BOOL InitApplication( HANDLE hInstance )
  1677. {
  1678. WNDCLASS  wc;
  1679. // Fill in window class structure with parameters that describe the
  1680. // main (statistics) window. 
  1681. wc.style = 0;                     
  1682. wc.lpfnWndProc = (WNDPROC)MainWndProc; 
  1683. wc.cbClsExtra = 0;              
  1684. wc.cbWndExtra = 0;              
  1685. wc.hInstance = hInstance;       
  1686. wc.hIcon = LoadIcon( hInstance, _T("ICON") );
  1687. wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  1688. wc.hbrBackground = (HBRUSH)(COLOR_INACTIVEBORDER + 1); // Default color
  1689. wc.lpszMenuName = _T("LISTMENU");  
  1690. wc.lpszClassName = _T("RegmonClass");
  1691. if ( ! RegisterClass( &wc ) )
  1692. return FALSE;
  1693. wc.lpszMenuName   = NULL;
  1694.   wc.lpfnWndProc    = (WNDPROC) BalloonDialog;
  1695. wc.hbrBackground  = CreateSolidBrush( 0x00E0FFFF );
  1696. wc.lpszClassName  = "BALLOON";
  1697. RegisterClass( &wc );
  1698. return TRUE;
  1699. }
  1700. /****************************************************************************
  1701. *
  1702. *    FUNCTION:  InitInstance(HANDLE, int)
  1703. *
  1704. *    PURPOSE:  Saves instance handle and creates main window
  1705. *
  1706. ****************************************************************************/
  1707. HWND InitInstance( HANDLE hInstance, int nCmdShow )
  1708. {
  1709. // get the window position settings from the registry
  1710. Get_Position_Settings();
  1711. hInst = hInstance;
  1712. hWndMain = CreateWindow( _T("RegmonClass"), _T("Registry Monitor"), 
  1713. WS_OVERLAPPEDWINDOW,
  1714. PositionInfo.left, PositionInfo.top, 
  1715. PositionInfo.width, PositionInfo.height,
  1716. NULL, NULL, hInstance, NULL );
  1717. // if window could not be created, return "failure" 
  1718. if ( ! hWndMain )
  1719. return NULL;
  1720. // make the window visible; update its client area; and return "success"
  1721. ShowWindow( hWndMain, nCmdShow );
  1722. UpdateWindow( hWndMain ); 
  1723. // maximize it if necessary
  1724. if( PositionInfo.maximized ) {
  1725. ShowWindow( hWndMain, SW_SHOWMAXIMIZED );
  1726. }
  1727. if( OnTop ) {
  1728. SetWindowPos( hWndMain, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE );
  1729. CheckMenuItem( GetMenu(hWndMain), IDM_ONTOP,
  1730. MF_BYCOMMAND|(OnTop?MF_CHECKED:MF_UNCHECKED) );
  1731. }
  1732. return hWndMain;      
  1733. }
  1734. /****************************************************************************
  1735. *
  1736. * FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
  1737. *
  1738. * PURPOSE: calls initialization function, processes message loop
  1739. *
  1740. ****************************************************************************/
  1741. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  1742. LPSTR lpCmdLine, int nCmdShow )
  1743. {
  1744. MSG  msg;      
  1745. HWND hWnd;
  1746. HACCEL hAccel;
  1747.   DWORD NTVersion;
  1748.         
  1749. if ( ! InitApplication( hInstance ) )
  1750. return FALSE;   
  1751. // get NT version
  1752. NTVersion = GetVersion();
  1753. if( NTVersion >= 0x80000000 ) {
  1754. IsNT = FALSE;
  1755. } else {
  1756. IsNT = TRUE;
  1757. }
  1758. // initializations that apply to a specific instance 
  1759. if ( (hWnd = InitInstance( hInstance, nCmdShow )) == NULL )
  1760. return FALSE;
  1761. // load accelerators
  1762. hAccel = LoadAccelerators( hInstance, _T("ACCELERATORS"));
  1763. // register for the find window message
  1764.     findMessageID = RegisterWindowMessage( FINDMSGSTRING );
  1765. // acquire and dispatch messages until a WM_QUIT message is received.
  1766. while ( GetMessage( &msg, NULL, 0, 0 ) )  {
  1767. if( !TranslateAccelerator( hWnd, hAccel, &msg ) &&
  1768. (!hWndFind || !IsWindow(hWndFind) || !IsDialogMessage( hWndFind, &msg ))) {
  1769. TranslateMessage( &msg );
  1770. DispatchMessage( &msg ); 
  1771. }
  1772. }
  1773. return msg.wParam;  
  1774. }