FILEMON.C
上传用户:hmgghm
上传日期:2007-01-07
资源大小:335k
文件大小:88k
源码类别:

文件操作

开发平台:

Visual C++

  1. /******************************************************************************
  2. *
  3. *       FileMon - File System Monitor for Windows NT/9x
  4. *
  5. * Copyright (c) 1996-1998 Mark Russinovich and Bryce Cogswell
  6. *
  7. * See readme.txt for terms and conditions.
  8. *
  9. *     PROGRAM: FileMon.c
  10. *
  11. *     PURPOSE: Communicates with the FileMon driver to display 
  12. * file system activity information.
  13. *
  14. ******************************************************************************/
  15. #include <windows.h>    // includes basic windows functionality
  16. #include <windowsx.h>
  17. #include <tchar.h>
  18. #include <commctrl.h>   // includes the common control header
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <winioctl.h>
  22. #include "resource.h"
  23. #include "ioctlcmd.h"
  24. #include "filemon.h"
  25. #include "instdrv.h"
  26. HRESULT (CALLBACK *pDllGetVersionProc)( PDLLVERSIONINFO_ pdvi );
  27. // Handle to device driver
  28. static HANDLE SysHandle = INVALID_HANDLE_VALUE;
  29. // Drive name strings
  30. TCHAR DrvNames[][32] = {
  31. _T("UNKNOWN"),
  32. _T("FIXED"),
  33. _T("REMOTE"),
  34. _T("RAM"),
  35. _T("CD"),
  36. _T("REMOVEABLE"),
  37. };
  38. // drives that are hooked
  39. DWORD CurDriveSet;
  40. // The variable that holds the position settings
  41. POSITION_SETTINGS PositionInfo;
  42. // button definitions
  43. // for installations that support flat style
  44. TBBUTTON tbButtons[] = {
  45. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  46. { 0, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  47. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  48. { 2, IDM_CAPTURE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  49. { 4, IDM_AUTOSCROLL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  50. { 6, IDM_CLEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  51. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  52. { 9, IDM_TIME, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0 },
  53. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  54. { 5, IDM_FILTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  55. { 12, IDM_HISTORY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  56. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  57. { 7, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  58. { 11, IDM_JUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  59. { 8, 0, 0, TBSTYLE_BUTTON, 0L, 0},
  60. };
  61. #define NUMBUTTONS 15
  62. // for older installations
  63. TBBUTTON tbButtonsOld[] = {
  64. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  65. { 0, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  66. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  67. { 2, IDM_CAPTURE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  68. { 4, IDM_AUTOSCROLL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  69. { 6, IDM_CLEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  70. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  71. { 9, IDM_TIME, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0 },
  72. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  73. { 5, IDM_FILTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  74. { 12, IDM_HISTORY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  75. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
  76. { 7, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  77. { 11, IDM_JUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  78. };
  79. #define NUMBUTTONSOLD 14
  80. // Buffer into which driver can copy statistics
  81. char Stats[ MAX_STORE ];
  82. // Current fraction of buffer filled
  83. DWORD StatsLen;
  84. // Search string
  85. TCHAR FindString[256];
  86. FINDREPLACE FindTextInfo;
  87. DWORD FindFlags = FR_DOWN;
  88. BOOLEAN PrevMatch;
  89. TCHAR PrevMatchString[256];
  90. // Application instance handle
  91. HINSTANCE hInst;
  92. // Are we running on NT or 9x?
  93. BOOLEAN IsNT;
  94. // Misc globals
  95. HWND hWndMain;
  96. HWND hWndFind = NULL;
  97. UINT findMessageID;
  98. HWND hWndList;
  99. WNDPROC  ListViewWinMain;
  100. HWND hBalloon = NULL;
  101. BOOLEAN Capture = TRUE;
  102. BOOLEAN Autoscroll = TRUE;
  103. BOOLEAN Deleting = TRUE;
  104. BOOLEAN OnTop = FALSE;
  105. BOOLEAN ShowToolbar = TRUE;
  106. BOOLEAN HookPipes = FALSE;
  107. BOOLEAN HookSlots = FALSE;
  108. // Highlight colors
  109. DWORD HighlightFg;
  110. DWORD HighlightBg;
  111. // listview size limiting
  112. DWORD MaxLines = 0;
  113. DWORD LastRow = 0;
  114. // is time absolute or duration?
  115. BOOLEAN TimeIsDuration;
  116. // Filter strings
  117. TCHAR FilterString[MAXFILTERLEN];
  118. TCHAR ExcludeString[MAXFILTERLEN];
  119. TCHAR HighlightString[MAXFILTERLEN];
  120. // Recent filters
  121. char RecentInFilters[NUMRECENTFILTERS][MAXFILTERLEN];
  122. char RecentExFilters[NUMRECENTFILTERS][MAXFILTERLEN];
  123. char RecentHiFilters[NUMRECENTFILTERS][MAXFILTERLEN];
  124. // Filter-related
  125. FILTER FilterDefinition;
  126. // For info saving
  127. TCHAR szFileName[MAX_PATH];
  128. BOOLEAN FileChosen = FALSE;
  129. // font
  130. HFONT hFont;
  131. LOGFONT LogFont;
  132. // General buffer for storing temporary strings
  133. static TCHAR msgbuf[MAX_PATH];
  134. // General cursor manipulation
  135. HCURSOR  hSaveCursor;
  136. HCURSOR  hHourGlass;
  137. // performance counter frequency
  138. LARGE_INTEGER PerfFrequency;
  139. /******************************************************************************
  140. *
  141. * FUNCTION: Abort:
  142. *
  143. * PURPOSE: Handles emergency exit conditions.
  144. *
  145. *****************************************************************************/
  146. DWORD Abort( HWND hWnd, TCHAR * Msg )
  147. {
  148. LPVOID lpMsgBuf;
  149. TCHAR errmsg[MAX_PATH];
  150. DWORD error = GetLastError();
  151.  
  152. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  153. NULL, GetLastError(), 
  154. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  155. (LPTSTR) &lpMsgBuf, 0, NULL );
  156. if( IsNT ) UnloadDeviceDriver( SYS_NAME );
  157. _stprintf(errmsg, _T("%s: %s"), Msg, lpMsgBuf );
  158. if( error == ERROR_INVALID_HANDLE && IsNT ) 
  159. _stprintf(errmsg, _T("%snMake sure that you are an administrator and that ")
  160. _T("Filemon is located on a local drive."), errmsg  );
  161. MessageBox( hWnd, errmsg, _T("Filemon"), MB_OK|MB_ICONERROR );
  162. PostQuitMessage( 1 );
  163. LocalFree( lpMsgBuf );
  164. return -1;
  165. }
  166. /******************************************************************************
  167. *
  168. * FUNCTION: ExplorerJump
  169. *
  170. * PURPOSE: Opens Explorer and navigates the desired file/folder
  171. *
  172. *****************************************************************************/
  173. void ExplorerJump( HWND hWnd )
  174. {
  175. int currentItem;
  176. char path[MAX_PATH], msg[MAX_PATH*2];
  177. char *lastslash = NULL;
  178. char *ptr;
  179. // See if we can get a Registry path out of the listview
  180. // find the item with the focus
  181. currentItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED );
  182. if( currentItem == -1 ) {
  183. MessageBox( hWnd, "No item selected.", APPNAME, MB_OK|MB_ICONWARNING );
  184. return;
  185. }
  186. memset( path, 0, MAX_PATH );
  187. ListView_GetItemText( hWndList, currentItem, 4, path, MAX_PATH );
  188. // If the file is a handle reference, tell the user we're sorry
  189. if( path[0] == '0' ) {
  190. MessageBox( hWnd, "The full name of the selected directory or file is not available.",
  191. APPNAME, MB_OK|MB_ICONWARNING );
  192. return;
  193. }
  194. // Always explore the parent folder, if there is one
  195. ptr = path;
  196. while( *ptr ) {
  197. if( *ptr == '\' ) lastslash = ptr;
  198. ptr++;
  199. }
  200. if( lastslash ) *lastslash = 0;
  201. if( ShellExecute( hWnd, "explore", path, NULL, NULL, SW_SHOWNORMAL ) < (HINSTANCE) 32 ) {
  202. sprintf( msg, "Explorer could not open %s.", path );
  203. MessageBox( hWnd, msg, APPNAME, MB_OK|MB_ICONWARNING );
  204. return;
  205. }
  206. }
  207. /******************************************************************************
  208. *
  209. * FUNCTION: BalloonDialog
  210. *
  211. * PURPOSE: Dialog function for home-brewed balloon help.
  212. *
  213. ******************************************************************************/
  214. LONG APIENTRY BalloonDialog( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  215. {
  216. static ITEM_CLICK ctx;
  217. static RECT rect;
  218. static HFONT hfont;
  219. LPCREATESTRUCT lpcs;
  220. HDC hdc;
  221. POINTS pts;
  222. POINT pt;
  223. DWORD newclicktime;
  224. static POINT lastclickpt = {0,0};
  225. static DWORD lastclicktime = 0;
  226. switch (message) {
  227. case WM_CREATE:
  228. lpcs = (void *)lParam;
  229. ctx = *(PITEM_CLICK) lpcs->lpCreateParams;
  230. hdc = GetDC( hDlg );
  231. // is the app the focus?
  232. if( !GetFocus()) return -1;
  233. // Compute size of required rectangle
  234. rect.left = 0;
  235. rect.top = 1;
  236. rect.right = lpcs->cx;
  237. rect.bottom = lpcs->cy;
  238. SelectObject( hdc, hFont );
  239. DrawText( hdc, ctx.itemText, -1, &rect, 
  240. DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT );
  241. // if the bounding rectangle of the subitem is big enough to display
  242. // the text then don't pop the balloon
  243. if( ctx.itemPosition.right > rect.right + 3 ) {
  244. return -1;
  245. }
  246. // Move and resize window
  247. if( ctx.itemPosition.left - 5 + rect.right + 10 >
  248.  GetSystemMetrics(SM_CXFULLSCREEN) ) {
  249.  ctx.itemPosition.left = GetSystemMetrics(SM_CXFULLSCREEN) -
  250. (rect.right+10);
  251. }
  252. MoveWindow( hDlg, 
  253. ctx.itemPosition.left-1, ctx.itemPosition.top, 
  254. rect.right + 6, 
  255. rect.bottom + 1,
  256. TRUE );
  257. // Adjust rectangle so text is centered
  258. rect.left += 2;
  259. rect.right += 2;
  260. rect.top -= 1; 
  261. rect.bottom += 0;
  262. // make it so this window doesn't get the focus
  263. ShowWindow( hDlg, SW_SHOWNOACTIVATE );
  264. break;
  265. case WM_LBUTTONDBLCLK:
  266. case WM_RBUTTONDBLCLK:
  267. case WM_MBUTTONDBLCLK:
  268. case WM_LBUTTONDOWN:
  269. case WM_RBUTTONDOWN:
  270. case WM_MBUTTONDOWN:
  271. case WM_LBUTTONUP:
  272. case WM_RBUTTONUP:
  273. case WM_MBUTTONUP:
  274. pts = MAKEPOINTS( lParam );
  275. pt.x = (LONG) pts.x;
  276. pt.y = (LONG) pts.y;
  277. ClientToScreen( hDlg, &pt );
  278. // pass this through to the listview
  279. if( ScreenToClient( hWndList, &pt )) {
  280. if( message == WM_LBUTTONDOWN ) {
  281. // see if its a double click
  282. newclicktime = GetTickCount();
  283. if( pt.x == lastclickpt.x && pt.y == lastclickpt.y && 
  284. newclicktime - lastclicktime < 300 ) {
  285. message = WM_LBUTTONDBLCLK;
  286. }
  287. lastclicktime = newclicktime;
  288. lastclickpt = pt;
  289. }
  290. PostMessage( hWndList, message, wParam, (SHORT) pt.y<<16 | (SHORT) pt.x );
  291. }
  292. break;
  293. case WM_PAINT:
  294. hdc = GetDC( hDlg );
  295. // Set colors
  296. SetTextColor( hdc, 0x00000000 );
  297. SetBkMode( hdc, TRANSPARENT );
  298. SelectObject( hdc, hFont );
  299. DrawText( hdc, ctx.itemText, -1, &rect, 
  300. DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK );
  301. break;
  302. case WM_DESTROY:
  303. hBalloon = NULL;
  304. break;
  305. case WM_CLOSE:
  306. DestroyWindow( hDlg );
  307. break;
  308. }
  309.     return DefWindowProc( hDlg, message, wParam, lParam );
  310. }
  311. /******************************************************************************
  312. *
  313. * FUNCTION: CopySelection
  314. *
  315. * PURPOSE: Copies the currently selected line in the output to the clip
  316. * board.
  317. *
  318. *****************************************************************************/
  319. void CopySelection( HWND hWnd )
  320. {
  321.     LPTSTR  lptstrCopy; 
  322.     HGLOBAL hglbCopy; 
  323. DWORD size = 0, newSize;
  324. int currentItem, iColumn;
  325. TCHAR curText[MAXITEMLENGTH];
  326. TCHAR selectedText[NUMCOLUMNS * MAXITEMLENGTH];
  327. // Get the currently selected item and construct
  328. // the message to go to the clipboard
  329. currentItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED );
  330. if( currentItem == -1 ) {
  331. return;
  332. }
  333. selectedText[0] = 0;
  334. for( iColumn = 1; iColumn < NUMCOLUMNS; iColumn++ ) {
  335. curText[0] = 0;
  336. ListView_GetItemText( hWndList, currentItem, iColumn, 
  337. curText, MAXITEMLENGTH );
  338. strcat( selectedText, curText );
  339. strcat( selectedText, "t");
  340. }
  341. strcat( selectedText, "rn");
  342. // Empty the clipboard
  343.     if (!OpenClipboard( hWnd )) return; 
  344.     EmptyClipboard(); 
  345. size = strlen( selectedText )+1;
  346.     hglbCopy = GlobalAlloc( GMEM_DDESHARE|GMEM_MOVEABLE, size ); 
  347.     lptstrCopy = GlobalLock(hglbCopy); 
  348.     strcpy(lptstrCopy, selectedText );
  349.     GlobalUnlock(hglbCopy); 
  350. while( (currentItem = ListView_GetNextItem( hWndList, currentItem, 
  351. LVNI_SELECTED )) != -1) {
  352. selectedText[0] = 0;
  353. for( iColumn = 1; iColumn < NUMCOLUMNS; iColumn++ ) {
  354. curText[0] = 0;
  355. ListView_GetItemText( hWndList, currentItem, iColumn, 
  356. curText, MAXITEMLENGTH );
  357. strcat( selectedText, curText );
  358. strcat( selectedText, "t");
  359. }
  360. strcat( selectedText, "rn");
  361. newSize = size + strlen( selectedText );
  362. hglbCopy = GlobalReAlloc( hglbCopy, newSize, 0 );
  363. lptstrCopy = GlobalLock(hglbCopy); 
  364. strcpy( &lptstrCopy[size-1], selectedText );
  365. GlobalUnlock(hglbCopy); 
  366. size = newSize;
  367. }
  368. // Place it in the clipboard
  369. SetClipboardData(CF_TEXT, hglbCopy); 
  370.     CloseClipboard(); 
  371. }
  372. /******************************************************************************
  373. *
  374. * FUNCTION: CCHookProc
  375. *
  376. * PURPOSE: We use a hook procedure to force the stupid color
  377. * selection dialog to do what we want, including preview
  378. * the highlight text.
  379. *
  380. *****************************************************************************/
  381. UINT CALLBACK CCHookProc( HWND hDlg, 
  382.   UINT uiMsg, WPARAM wParam,  
  383.   LPARAM lParam )
  384. {
  385. static HWND  sample;
  386. static DWORD  newFg, newBg;
  387. static UINT colorOkString, setRgbString;
  388. switch( uiMsg ) {
  389. case WM_INITDIALOG:
  390. sample = GetDlgItem( hDlg, IDC_SAMPLE );
  391. newFg = HighlightFg;
  392. newBg = HighlightBg;
  393. colorOkString = RegisterWindowMessage( COLOROKSTRING );
  394. setRgbString  = RegisterWindowMessage( SETRGBSTRING ); 
  395. CheckRadioButton( hDlg, IDC_RADIOFG, IDC_RADIOBG, IDC_RADIOFG );
  396. SendMessage(hDlg, setRgbString, 0, newFg); 
  397. SetFocus( GetDlgItem( hDlg, IDC_DONE ));
  398. break;
  399. case WM_CTLCOLORSTATIC:
  400. if( (HWND) lParam == sample ) {
  401. SetBkColor(GET_WM_CTLCOLOR_HDC(wParam, lParam, msg), 
  402.                     newBg); 
  403. SetTextColor(GET_WM_CTLCOLOR_HDC(wParam, lParam, msg), 
  404.                     newFg); 
  405.             return (BOOL)GetStockObject(WHITE_BRUSH); 
  406. }
  407. break;
  408. case WM_COMMAND:
  409. if( wParam == IDC_DONE ) {
  410. HighlightFg = newFg;
  411. HighlightBg = newBg;
  412. PostMessage( hDlg, WM_COMMAND, IDABORT, 0 );
  413. return FALSE;
  414. }
  415. break;
  416. default:
  417. if( uiMsg == colorOkString ) {
  418. if( !IsDlgButtonChecked( hDlg, IDC_RADIOBG )) {
  419. newFg = ((LPCHOOSECOLOR) lParam)->rgbResult;
  420. InvalidateRect( sample, NULL, TRUE );
  421. SendMessage(hDlg, setRgbString, 0, newBg); 
  422. return TRUE;
  423. } else {
  424. newBg = ((LPCHOOSECOLOR) lParam)->rgbResult;
  425. InvalidateRect( sample, NULL, TRUE );
  426. SendMessage(hDlg, setRgbString, 0, newFg); 
  427. return TRUE;
  428. }
  429. }
  430. break;
  431. }
  432. return 0;
  433. }
  434. /******************************************************************************
  435. *
  436. * FUNCTION: SelectHighlightColors
  437. *
  438. * PURPOSE: Let's the user pick the highlight foreground and background
  439. * colors.
  440. *
  441. *****************************************************************************/
  442. VOID SelectHighlightColors( HWND hWnd )
  443. {
  444. DWORD dwColor;
  445. DWORD dwCustClrs [16];
  446. BOOL fSetColor = FALSE;
  447. int i;
  448. CHOOSECOLOR chsclr;
  449. for (i = 0; i < 15; i++)
  450. dwCustClrs [i] = RGB (255, 255, 255);
  451. dwColor = RGB (0, 0, 0);
  452. chsclr.lStructSize = sizeof (CHOOSECOLOR);
  453. chsclr.hwndOwner = hWnd;
  454. chsclr.hInstance = (HANDLE) hInst;
  455. chsclr.rgbResult = dwColor;
  456. chsclr.lpCustColors = (LPDWORD)dwCustClrs;
  457. chsclr.lCustData = 0L;
  458. chsclr.rgbResult = HighlightFg;
  459. chsclr.lpTemplateName = "CHOOSECOLORFG";
  460. chsclr.lpfnHook = (LPCCHOOKPROC)(FARPROC)CCHookProc;
  461. chsclr.Flags = CC_RGBINIT|CC_PREVENTFULLOPEN|
  462. CC_ENABLEHOOK|CC_ENABLETEMPLATE;
  463. ChooseColor (&chsclr);
  464. // Redraw to apply
  465. InvalidateRect( hWndList, NULL, TRUE );
  466. /******************************************************************************
  467. *
  468. * FUNCTION: FindInListview:
  469. *
  470. * PURPOSE: Searches for a string in the listview. Note: its okay if
  471. * items are being added to the list view or the list view
  472. * is cleared while this search is in progress - the effect
  473. * is harmless.
  474. *
  475. *****************************************************************************/
  476. BOOLEAN FindInListview(HWND hWnd, LPFINDREPLACE FindInfo )
  477. {
  478. int currentItem, clearItem;
  479. DWORD i;
  480. int subitem, numItems;
  481. TCHAR fieldtext[MAXITEMLENGTH];
  482. BOOLEAN match = FALSE;
  483. TCHAR errmsg[MAX_PATH];
  484. BOOLEAN goUp;
  485. // get the search direction
  486. goUp = ((FindInfo->Flags & FR_DOWN) == FR_DOWN);
  487. // initialize stuff
  488. if( !(numItems = ListView_GetItemCount( hWndList ))) {
  489. MessageBox( hWnd, TEXT("No items to search"), TEXT(APPNAME), 
  490. MB_OK|MB_ICONWARNING );
  491. if( hWndFind ) SetForegroundWindow( hWndFind );
  492. return FALSE;
  493. }
  494. // find the item with the focus
  495. currentItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED );
  496. // if no current item, start at the top or the bottom
  497. if( currentItem == -1 ) {
  498. if( goUp )
  499. currentItem = 0;
  500. else {
  501. if( PrevMatch ) {
  502. sprintf(errmsg, TEXT("Cannot find string "%s""), FindInfo->lpstrFindWhat );
  503. MessageBox( hWnd, errmsg, TEXT(APPNAME), MB_OK|MB_ICONWARNING );
  504. if( hWndFind ) SetForegroundWindow( hWndFind );
  505. else SetFocus( hWndList );
  506. return FALSE;
  507. }
  508. currentItem = numItems;
  509. }
  510. }
  511. // if we're continuing a search, start with the next item
  512. if( PrevMatch && !strcmp( FindString, PrevMatchString ) ) {
  513. if( goUp ) currentItem++;
  514. else currentItem--;
  515. if( (!goUp && currentItem < 0) ||
  516. (goUp && currentItem >= numItems )) {
  517. sprintf(errmsg, TEXT("Cannot find string "%s""), FindInfo->lpstrFindWhat );
  518. MessageBox( hWnd, errmsg, TEXT(APPNAME), MB_OK|MB_ICONWARNING );
  519. if( hWndFind ) SetForegroundWindow( hWndFind );
  520. else SetFocus( hWndList );
  521. return FALSE;
  522. }
  523. }
  524. // loop through each item looking for the string
  525. while( 1 ) {
  526. // get the item text
  527. for( subitem = 0; subitem < NUMCOLUMNS; subitem++ ) {
  528. fieldtext[0] = 0;
  529. ListView_GetItemText( hWndList, currentItem, subitem, fieldtext, 256 );
  530. // make sure enought string for a match
  531. if( strlen( fieldtext ) < strlen( FindInfo->lpstrFindWhat ))
  532. continue;
  533. // do a scan all the way through for the substring
  534. if( FindInfo->Flags & FR_WHOLEWORD ) {
  535. i = 0;
  536. while( fieldtext[i] ) {
  537. while( fieldtext[i] && fieldtext[i] != ' ' ) i++;
  538. if( FindInfo->Flags & FR_MATCHCASE ) 
  539. match = !strcmp( fieldtext, FindInfo->lpstrFindWhat );
  540. else
  541. match = !stricmp( fieldtext, FindInfo->lpstrFindWhat );
  542. if( match) break;
  543. i++;
  544. }
  545. } else {
  546. for( i = 0; i < strlen( fieldtext ) - strlen(FindInfo->lpstrFindWhat)+1; i++ ) {
  547. if( FindInfo->Flags & FR_MATCHCASE ) 
  548. match = !strncmp( &fieldtext[i], FindInfo->lpstrFindWhat, 
  549. strlen(FindInfo->lpstrFindWhat) );
  550. else
  551. match = !strnicmp( &fieldtext[i], FindInfo->lpstrFindWhat,
  552. strlen(FindInfo->lpstrFindWhat) );
  553. if( match ) break;
  554. }
  555. }
  556. if( match ) {
  557. strcpy( PrevMatchString, FindInfo->lpstrFindWhat );
  558. PrevMatch = TRUE;
  559. // Clear all previously-selected items
  560. while( (clearItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED )) != -1 ) {
  561. ListView_SetItemState( hWndList, clearItem, 0, LVIS_SELECTED|LVIS_FOCUSED );
  562. }
  563. ListView_SetItemState( hWndList, currentItem, 
  564. LVIS_SELECTED|LVIS_FOCUSED,
  565. LVIS_SELECTED|LVIS_FOCUSED );
  566. ListView_EnsureVisible( hWndList, currentItem, FALSE ); 
  567. SetFocus( hWndList );
  568. return TRUE;
  569. }
  570. }
  571. currentItem = currentItem + (goUp ? 1:-1);
  572. if( !currentItem || currentItem == numItems+1 ) {
  573. // end of the road
  574. break;
  575. }
  576. }
  577. sprintf(errmsg, TEXT("Cannot find string "%s""), FindInfo->lpstrFindWhat );
  578. MessageBox( hWnd, errmsg, TEXT(APPNAME), MB_OK|MB_ICONWARNING );
  579. if( hWndFind ) SetForegroundWindow( hWndFind );
  580. else SetFocus( hWndList );
  581. return FALSE;
  582. }
  583. /******************************************************************************
  584. *
  585. * FUNCTION: PopFindDialog:
  586. *
  587. * PURPOSE: Calls the find message dialog box.
  588. *
  589. *****************************************************************************/
  590. void PopFindDialog(HWND hWnd)
  591. {
  592. _tcscpy( FindString, PrevMatchString );
  593.     FindTextInfo.lStructSize = sizeof( FindTextInfo );
  594.     FindTextInfo.hwndOwner = hWnd;
  595.     FindTextInfo.hInstance = (HANDLE)hInst;
  596.     FindTextInfo.lpstrFindWhat = FindString;
  597.     FindTextInfo.lpstrReplaceWith = NULL;
  598.     FindTextInfo.wFindWhatLen = sizeof(FindString);
  599.     FindTextInfo.wReplaceWithLen = 0;
  600.     FindTextInfo.lCustData = 0;
  601.     FindTextInfo.Flags =  FindFlags;
  602.     FindTextInfo.lpfnHook = (LPFRHOOKPROC)(FARPROC)NULL;
  603.     FindTextInfo.lpTemplateName = NULL;
  604.     if ((hWndFind = FindText(&FindTextInfo)) == NULL)
  605. MessageBox( hWnd, _T("Unable to create Find dialog"), APPNAME, MB_OK|MB_ICONERROR );      
  606. }
  607. /****************************************************************************
  608. *
  609. * FUNCTION: MatchOkay
  610. *
  611. * PURPOSE: Only thing left after compare is more mask. This routine makes
  612. * sure that its a valid wild card ending so that its really a match.
  613. *
  614. ****************************************************************************/
  615. BOOLEAN MatchOkay( PCHAR Pattern )
  616. {
  617.     // If pattern isn't empty, it must be a wildcard
  618.     if( *Pattern && *Pattern != '*' ) {
  619.  
  620.        return FALSE;
  621.     }
  622.     // Matched
  623.     return TRUE;
  624. }
  625. /****************************************************************************
  626. *
  627. * FUNCTION: MatchWithPatternCore
  628. *
  629. * PURPOSE: Performs nifty wildcard comparison.
  630. *
  631. ****************************************************************************/
  632. BOOLEAN MatchWithPatternCore( PCHAR Pattern, PCHAR Name )
  633. {
  634. char matchchar;
  635.     // End of pattern?
  636.     if( !*Pattern ) {
  637.         return FALSE;
  638.     }
  639.     // If we hit a wild card, do recursion
  640.     if( *Pattern == '*' ) {
  641.         Pattern++;
  642.         while( *Name && *Pattern ) {
  643. matchchar = *Name;
  644. if( matchchar >= 'a' && 
  645. matchchar <= 'z' ) {
  646. matchchar -= 'a' - 'A';
  647. }
  648.             // See if this substring matches
  649.     if( *Pattern == matchchar ) {
  650.            if( MatchWithPatternCore( Pattern+1, Name+1 )) {
  651.                     return TRUE;
  652.                 }
  653.             }
  654.             // Try the next substring
  655.             Name++;
  656.         }
  657.         // See if match condition was met
  658.         return MatchOkay( Pattern );
  659.     } 
  660.     // Do straight compare until we hit a wild card
  661.     while( *Name && *Pattern != '*' ) {
  662. matchchar = *Name;
  663. if( matchchar >= 'a' && 
  664. matchchar <= 'z' ) {
  665. matchchar -= 'a' - 'A';
  666. }
  667.         if( *Pattern == matchchar ) {
  668.             Pattern++;
  669.             Name++;
  670.         } else {
  671.             return FALSE;
  672. }
  673.     }
  674.     // If not done, recurse
  675.     if( *Name ) {
  676.         return MatchWithPatternCore( Pattern, Name );
  677.     }
  678.     // Make sure its a match
  679.     return MatchOkay( Pattern );
  680. }
  681. /****************************************************************************
  682. *
  683. * FUNCTION: MatchWithHighlightPattern
  684. *
  685. * PURPOSE: Converts strings to upper-case before calling core 
  686. * comparison routine.
  687. *
  688. ****************************************************************************/
  689. BOOLEAN MatchWithHighlightPattern( PCHAR String )
  690. {
  691. char    *filterPtr;
  692. char    curFilterBuf[MAXFILTERLEN];
  693. char    *curFilter, *endFilter;
  694. // Is there a highlight filter?
  695. if( HighlightString[0] == ' ' &&
  696. !HighlightString[1] ) return FALSE;
  697. // see if its in an highlight
  698. filterPtr = HighlightString;
  699. curFilter = curFilterBuf;
  700. while( 1 ) {
  701. endFilter = strchr( filterPtr, ';' );
  702. if( !endFilter )
  703. curFilter = filterPtr;
  704. else {
  705. strncpy( curFilter, filterPtr, (int) (endFilter - filterPtr ) );
  706. curFilter[ (int) (endFilter - filterPtr ) ] = 0;
  707. }
  708. // Now do the comparison
  709. if( MatchWithPatternCore( curFilter, String ) ) {
  710. return TRUE;
  711. }
  712. if( endFilter ) filterPtr = endFilter+1;
  713. else break;
  714. }
  715. return FALSE;
  716. }
  717. /****************************************************************************
  718. *
  719. * FUNCTION: FilterProc
  720. *
  721. * PURPOSE: Processes messages for "Filter" dialog box
  722. *
  723. ****************************************************************************/
  724. BOOL APIENTRY FilterProc( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  725. {
  726. char newFilter[MAXFILTERLEN];
  727. char newExFilter[MAXFILTERLEN];
  728. char newHiFilter[MAXFILTERLEN], oldHighlight[MAXFILTERLEN];
  729. int i, j, nb;
  730. static HWND hInFilter;
  731. static HWND hExFilter;
  732. static HWND hHiFilter;
  733. switch ( message )  {
  734. case WM_INITDIALOG:
  735. // initialize the controls to reflect the current filter
  736. // We use a ' ' as a placeholder in the filter strings to represent no filter ("")
  737. hInFilter = GetDlgItem( hDlg, IDC_FILTERSTRING );
  738. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  739. if( RecentInFilters[i][0] ) {
  740. SendMessage( hInFilter, CB_ADDSTRING, 0, 
  741. (LPARAM ) (strcmp( RecentInFilters[i], " ") ? 
  742. RecentInFilters[i] : ""));
  743. }
  744. }
  745. hExFilter = GetDlgItem( hDlg, IDC_EXFILTERSTRING );
  746. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  747. if( RecentExFilters[i][0] ) {
  748. SendMessage( hExFilter, CB_ADDSTRING, 0, 
  749. (LPARAM ) (strcmp( RecentExFilters[i], " ") ? 
  750. RecentExFilters[i] : ""));
  751. }
  752. }
  753. hHiFilter = GetDlgItem( hDlg, IDC_HIFILTERSTRING );
  754. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  755. if( RecentHiFilters[i][0] ) {
  756. SendMessage( hHiFilter, CB_ADDSTRING, 0, 
  757. (LPARAM ) (strcmp( RecentHiFilters[i], " ") ? 
  758. RecentHiFilters[i] : ""));
  759. }
  760. }
  761. SendMessage( hInFilter, CB_SETCURSEL, 0, 0);
  762. SendMessage( hExFilter, CB_SETCURSEL, 0, 0);
  763. SendMessage( hHiFilter, CB_SETCURSEL, 0, 0);
  764. // Set the check box stats
  765. CheckDlgButton( hDlg, IDC_READ, 
  766. FilterDefinition.logreads ? BST_CHECKED : BST_UNCHECKED );
  767. CheckDlgButton( hDlg, IDC_WRITE, 
  768. FilterDefinition.logwrites ? BST_CHECKED : BST_UNCHECKED );
  769. return TRUE;
  770. case WM_COMMAND:              
  771. strcpy( oldHighlight, HighlightString );
  772. if ( LOWORD( wParam ) == IDOK )  {
  773. // make sure that max lines is legal
  774. GetDlgItemTextA( hDlg, IDC_FILTERSTRING, newFilter, MAXFILTERLEN );
  775. GetDlgItemTextA( hDlg, IDC_EXFILTERSTRING, newExFilter, MAXFILTERLEN );
  776. GetDlgItemTextA( hDlg, IDC_HIFILTERSTRING, newHiFilter, MAXFILTERLEN );
  777. if( !newFilter[0] ) strcpy( newFilter, " " );
  778. if( !newExFilter[0] ) strcpy( newExFilter, " " );
  779. if( !newHiFilter[0] ) strcpy( newHiFilter, " " );
  780. strcpy( FilterString, newFilter );
  781. strupr( FilterString );
  782. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  783. if( !stricmp( RecentInFilters[i], newFilter )) {
  784. i++;
  785. break;
  786. }
  787. }
  788. for( j = i-2; j != (DWORD) -1; j-- ) {
  789. strcpy( RecentInFilters[j+1], RecentInFilters[j] );
  790. }
  791. strcpy( RecentInFilters[0], newFilter );
  792. strcpy( ExcludeString, newExFilter );
  793. strupr( ExcludeString );
  794. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  795. if( !stricmp( RecentExFilters[i], newExFilter )) {
  796. i++;
  797. break;
  798. }
  799. }
  800. for( j = i-2; j != (DWORD) -1; j-- ) {
  801. strcpy( RecentExFilters[j+1], RecentExFilters[j] );
  802. }
  803. strcpy( RecentExFilters[0], newExFilter );
  804. strcpy( HighlightString, newHiFilter );
  805. strupr( HighlightString );
  806. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  807. if( !stricmp( RecentHiFilters[i], newHiFilter )) {
  808. i++;
  809. break;
  810. }
  811. }
  812. for( j = i-2; j != (DWORD) -1; j-- ) {
  813. strcpy( RecentHiFilters[j+1], RecentHiFilters[j] );
  814. }
  815. strcpy( RecentHiFilters[0], newHiFilter );
  816. if( stricmp( oldHighlight, HighlightString )) {
  817. InvalidateRgn( hWndList, NULL, TRUE );
  818. }
  819. // Get the button states
  820. FilterDefinition.logreads = 
  821. (IsDlgButtonChecked( hDlg, IDC_READ ) == BST_CHECKED);
  822. FilterDefinition.logwrites = 
  823. (IsDlgButtonChecked( hDlg, IDC_WRITE ) == BST_CHECKED);
  824. EndDialog( hDlg, TRUE );
  825. // Apply the new filter
  826. FilterDefinition.excludefilter[0] = 0;
  827. FilterDefinition.includefilter[0] = 0;
  828. if( strcmp( ExcludeString, " " ) )
  829. strcpy( FilterDefinition.excludefilter, ExcludeString );
  830. if( strcmp( FilterString, " " ) )
  831. strcpy( FilterDefinition.includefilter, FilterString );
  832. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_SETFILTER,
  833. (PVOID) &FilterDefinition, sizeof(FilterDefinition), 
  834. NULL, 0, &nb, NULL ) ) {
  835. MessageBox( hDlg, TEXT("Couldn't access device driver"), APPNAME, MB_ICONERROR );
  836. return FALSE;
  837. }
  838. return TRUE;
  839. } else if( LOWORD( wParam ) == IDCANCEL ) {
  840. EndDialog( hDlg, TRUE );
  841. } else if( LOWORD( wParam ) == IDRESET ) {
  842. // initialize the controls to reflect the current filter
  843. SetDlgItemText( hDlg, IDC_FILTERSTRING, "*" );
  844. SetDlgItemText( hDlg, IDC_EXFILTERSTRING, "" );
  845. SetDlgItemText( hDlg, IDC_HIFILTERSTRING, "" );
  846. CheckDlgButton( hDlg, IDC_READ, BST_CHECKED );
  847. CheckDlgButton( hDlg, IDC_WRITE, BST_CHECKED );
  848. if( stricmp( oldHighlight, HighlightString )) {
  849. InvalidateRgn( hWndList, NULL, TRUE );
  850. }
  851. }
  852. break;
  853. case WM_CLOSE:
  854. EndDialog( hDlg, TRUE );
  855. return TRUE;
  856. }
  857. return FALSE;   
  858. }
  859. /******************************************************************************
  860. *
  861. * FUNCTION: GetPositionSettings
  862. *
  863. * PURPOSE: Reads the Registry to get the last-set window position.
  864. *
  865. ******************************************************************************/
  866. VOID GetPositionSettings()
  867. {
  868. HKEY hKey;
  869. DWORD ParamSize, newPosSize, i;
  870. POSITION_SETTINGS newPositionInfo;
  871. LOGFONT lf;
  872. char *nextString;
  873. char recentExList[(MAXFILTERLEN+1) * NUMRECENTFILTERS + 1];
  874. char recentInList[(MAXFILTERLEN+1) * NUMRECENTFILTERS + 1];
  875. char recentHiList[(MAXFILTERLEN+1) * NUMRECENTFILTERS + 1];
  876. // Default font
  877. GetObject( GetStockObject(SYSTEM_FONT), sizeof lf, &lf ); 
  878. lf.lfWeight = FW_NORMAL;
  879. lf.lfHeight = 8;
  880. lf.lfWidth  = 0;
  881. strcpy( lf.lfFaceName, TEXT("MS Sans Serif") );
  882. PositionInfo.font = lf;
  883. // Fist, set the default settings
  884. PositionInfo.top = CW_USEDEFAULT;
  885. PositionInfo.left = CW_USEDEFAULT;
  886. PositionInfo.width = CW_USEDEFAULT;
  887. PositionInfo.height = CW_USEDEFAULT;
  888. PositionInfo.maximized = FALSE;
  889. PositionInfo.ontop = FALSE;
  890. PositionInfo.hookpipes = FALSE;
  891. PositionInfo.hookslots = FALSE;
  892. PositionInfo.highlightfg = 0x00FFFFFF;
  893. PositionInfo.highlightbg = 0x000000FF;
  894. // set the default listview widths
  895. PositionInfo.column[0] = 35;  // seq 
  896. PositionInfo.column[1] = 90;  // time
  897. PositionInfo.column[2] = 90;  // process
  898. PositionInfo.column[3] = 130; // irp
  899. PositionInfo.column[4] = 200; // path
  900. PositionInfo.column[5] = 70;  // result
  901. PositionInfo.column[6] = 150; // other
  902. // intialize the hooked drives
  903. PositionInfo.curdriveset = (DWORD) -1;
  904. // duration is default
  905. PositionInfo.timeduration = FALSE;
  906. // initialize history depth
  907. PositionInfo.historydepth = 0;
  908. // initialize filter
  909. recentInList[0] = '*';
  910. recentInList[1] = 0;
  911. recentInList[2] = 0;
  912. recentExList[0] = 0;
  913. recentHiList[0] = 0;
  914. memset( RecentExFilters,   0, sizeof( RecentExFilters ));
  915. memset( RecentInFilters,   0, sizeof( RecentInFilters ));
  916. memset( RecentHiFilters,   0, sizeof( RecentHiFilters ));
  917. PositionInfo.logreads = TRUE;
  918. PositionInfo.logwrites = TRUE;
  919. // first, get the last-entered params from the registry
  920. RegCreateKey(HKEY_CURRENT_USER, FILEMON_SETTINGS_KEY, &hKey );
  921. // get the params and ignore errors
  922. newPosSize = sizeof( PositionInfo );
  923. newPositionInfo.posversion = 0;
  924. RegQueryValueEx( hKey,FILEMON_SETTINGS_VALUE, NULL, NULL, (LPBYTE) &newPositionInfo,
  925. &newPosSize );
  926. ParamSize = sizeof( recentInList );
  927. RegQueryValueEx( hKey,FILEMON_RECENT_INFILTER_VALUE, NULL, NULL, (LPBYTE) &recentInList,
  928. &ParamSize );
  929. ParamSize = sizeof( recentExList );
  930. RegQueryValueEx( hKey,FILEMON_RECENT_EXFILTER_VALUE, NULL, NULL, (LPBYTE) &recentExList,
  931. &ParamSize );
  932. ParamSize = sizeof( recentHiList );
  933. RegQueryValueEx( hKey,FILEMON_RECENT_HIFILTER_VALUE, NULL, NULL, (LPBYTE) &recentHiList,
  934. &ParamSize );
  935. RegCloseKey( hKey );
  936. // only use the registry settings if the version matches
  937. if( newPositionInfo.posversion == POSITION_VERSION ) PositionInfo = newPositionInfo;
  938. // extract global settings from the value returned from the Registry (or the default)
  939. CurDriveSet = PositionInfo.curdriveset;
  940. MaxLines = PositionInfo.historydepth;
  941. TimeIsDuration = PositionInfo.timeduration;
  942. OnTop = PositionInfo.ontop;
  943. HookPipes = PositionInfo.hookpipes;
  944. HookSlots = PositionInfo.hookslots;
  945. // get misc device filter
  946. FilterDefinition.logreads = PositionInfo.logreads;
  947. FilterDefinition.logwrites = PositionInfo.logwrites;
  948. // Set up the recent filter arrays
  949. nextString = recentInList;
  950. i = 0;
  951. while( *nextString ) {
  952. strcpy( RecentInFilters[i++], nextString );
  953. nextString = &nextString[strlen(nextString)+1];
  954. }
  955. nextString = recentExList;
  956. i = 0;
  957. while( *nextString ) {
  958. strcpy( RecentExFilters[i++], nextString );
  959. nextString = &nextString[strlen(nextString)+1];
  960. }
  961. nextString = recentHiList;
  962. i = 0;
  963. while( *nextString ) {
  964. strcpy( RecentHiFilters[i++], nextString );
  965. nextString = &nextString[strlen(nextString)+1];
  966. }
  967. strcpy( FilterString, RecentInFilters[0] );
  968. strupr( FilterString );
  969. strcpy( ExcludeString, RecentExFilters[0] );
  970. strupr( ExcludeString );
  971. strcpy( HighlightString, RecentHiFilters[0] );
  972. strupr( HighlightString );
  973.     // Get font
  974. LogFont     = PositionInfo.font;
  975.   hFont       = CreateFontIndirect( &LogFont ); 
  976. // set highlight colors
  977. HighlightFg = PositionInfo.highlightfg;
  978. HighlightBg = PositionInfo.highlightbg;
  979. }
  980. /******************************************************************************
  981. *
  982. * FUNCTION: SavePositionSettings
  983. *
  984. * PURPOSE: Saves the current window settings to the Registry.
  985. *
  986. ******************************************************************************/
  987. VOID SavePositionSettings( HWND hWnd )
  988. {
  989. RECT rc;
  990. int i;
  991. char *nextInString, *nextExString, *nextHiString;
  992. char recentExList[(MAXFILTERLEN+1) * NUMRECENTFILTERS + 1];
  993. char recentInList[(MAXFILTERLEN+1) * NUMRECENTFILTERS + 1];
  994. char recentHiList[(MAXFILTERLEN+1) * NUMRECENTFILTERS + 1];
  995. HKEY hKey;
  996. // set version #
  997. PositionInfo.posversion = POSITION_VERSION;
  998. // get the position of the main window
  999. GetWindowRect( hWnd, &rc );
  1000. if( !IsIconic( hWnd )) {
  1001. PositionInfo.left = rc.left;
  1002. PositionInfo.top = rc.top;
  1003. PositionInfo.width = rc.right - rc.left;
  1004. PositionInfo.height = rc.bottom - rc.top;
  1005. PositionInfo.showtoolbar = ShowToolbar;
  1006. PositionInfo.maximized = IsZoomed( hWnd );
  1007. PositionInfo.ontop = OnTop;
  1008. PositionInfo.hookpipes = HookPipes;
  1009. PositionInfo.hookslots = HookSlots;
  1010. // get the history depth
  1011. PositionInfo.historydepth = MaxLines;
  1012. // get time format
  1013. PositionInfo.timeduration = TimeIsDuration;
  1014. // get the widths of the listview columns
  1015. for( i = 0; i < NUMCOLUMNS; i++ ) {
  1016. PositionInfo.column[i] = ListView_GetColumnWidth( hWndList, i );
  1017. }
  1018. // save font
  1019. PositionInfo.font = LogFont;
  1020. // get misc device filters
  1021. PositionInfo.logreads = FilterDefinition.logreads;
  1022. PositionInfo.logwrites = FilterDefinition.logwrites;
  1023. // save highlight colors
  1024. PositionInfo.highlightfg = HighlightFg;
  1025. PositionInfo.highlightbg = HighlightBg;
  1026. // get the current drive set
  1027. PositionInfo.curdriveset = CurDriveSet;
  1028. // Save recent filters
  1029. recentInList[0] = 0;
  1030. nextInString = recentInList;
  1031. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  1032. if( !RecentInFilters[i][0] ) {
  1033. break;
  1034. }
  1035. strcpy( nextInString, RecentInFilters[i] );
  1036. nextInString = &nextInString[ strlen( nextInString ) + 1];
  1037. }
  1038. *nextInString = 0;
  1039. recentExList[0] = 0;
  1040. nextExString = recentExList;
  1041. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  1042. if( !RecentExFilters[i][0] ) {
  1043. break;
  1044. }
  1045. strcpy( nextExString, RecentExFilters[i] );
  1046. nextExString = &nextExString[ strlen( nextExString ) + 1];
  1047. }
  1048. *nextExString = 0;
  1049. recentHiList[0] = 0;
  1050. nextHiString = recentHiList;
  1051. for( i = 0; i < NUMRECENTFILTERS; i++ ) {
  1052. if( !RecentHiFilters[i][0] ) {
  1053. break;
  1054. }
  1055. strcpy( nextHiString, RecentHiFilters[i] );
  1056. nextHiString = &nextHiString[ strlen( nextHiString ) + 1];
  1057. }
  1058. *nextHiString = 0;
  1059. // save connection info to registry
  1060. RegOpenKey(HKEY_CURRENT_USER, FILEMON_SETTINGS_KEY, &hKey );
  1061. RegSetValueEx( hKey, FILEMON_SETTINGS_VALUE, 0, REG_BINARY, (LPBYTE) &PositionInfo,
  1062. sizeof( PositionInfo ) );
  1063. RegSetValueEx( hKey, FILEMON_RECENT_INFILTER_VALUE, 0, REG_BINARY, (LPBYTE) &recentInList,
  1064. nextInString - recentInList + 1 );
  1065. RegSetValueEx( hKey, FILEMON_RECENT_EXFILTER_VALUE, 0, REG_BINARY, (LPBYTE) &recentExList,
  1066. nextExString - recentExList + 1 );
  1067. RegSetValueEx( hKey, FILEMON_RECENT_HIFILTER_VALUE, 0, REG_BINARY, (LPBYTE) &recentHiList,
  1068. nextHiString - recentHiList + 1 );
  1069. CloseHandle( hKey );
  1070. }
  1071. /******************************************************************************
  1072. *
  1073. * FUNCTION: HookDrives
  1074. *
  1075. * PURPOSE: Hook the currently selected drives, updating menu checks
  1076. *
  1077. ******************************************************************************/
  1078. DWORD HookDrives( HMENU DriveMenu, DWORD MaxDriveSet, DWORD CurDriveSet ) 
  1079. {
  1080. DWORD nb;
  1081. DWORD drive;
  1082. // Tell device driver which drives to monitor
  1083. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_SETDRIVES,
  1084. &CurDriveSet, sizeof CurDriveSet,
  1085. &CurDriveSet, sizeof CurDriveSet,
  1086. &nb, NULL ) )
  1087. return 0;
  1088. // Update menu items
  1089. for ( drive = 0; drive < 32; ++drive )
  1090. if ( MaxDriveSet & (1<<drive) )  {
  1091. if ( CurDriveSet & (1<<drive) )
  1092. CheckMenuItem( DriveMenu, IDC_DRIVE+drive, MF_BYCOMMAND|MF_CHECKED );
  1093. else
  1094. CheckMenuItem( DriveMenu, IDC_DRIVE+drive, MF_BYCOMMAND|MF_UNCHECKED );
  1095. }
  1096. return CurDriveSet;
  1097. }
  1098. /******************************************************************************
  1099. *
  1100. * FUNCTION: Split
  1101. *
  1102. * PURPOSE: Split a delimited line into components
  1103. *
  1104. ******************************************************************************/
  1105. int Split( char * line, char delimiter, char * items[] )
  1106. {
  1107. int cnt = 0;
  1108. for (;;)  {
  1109. // Add prefix to list of components
  1110. items[cnt++] = line;
  1111. // Check for more components
  1112. line = strchr( line, delimiter );
  1113. if ( line == NULL )
  1114. return cnt;
  1115. // Terminate previous component and move to next
  1116. *line++ = '';
  1117. }
  1118. }
  1119. /******************************************************************************
  1120. *
  1121. * FUNCTION: ListAppend
  1122. *
  1123. * PURPOSE: Add a new line to List window
  1124. *
  1125. ******************************************************************************/
  1126. BOOL List_Append( HWND hWndList, DWORD seq, LONGLONG time, char * line )
  1127. {
  1128. LV_ITEM lvI; // list view item structure
  1129. int row;
  1130. char * items[NUMCOLUMNS];
  1131. int itemcnt = 0;
  1132. FILETIME localTime;
  1133. SYSTEMTIME systemTime;
  1134. // Split line into columns
  1135. itemcnt = Split( line, 't', items );
  1136. if ( itemcnt == 0 )
  1137. return FALSE;
  1138. // Determine row number for request
  1139. if ( *items[0] )  {
  1140. // Its a new request.  Put at end.
  1141. row = 0x7FFFFFFF;
  1142. } else {
  1143. // Its a status.  Locate its associated request.
  1144. lvI.mask = LVIF_PARAM;
  1145. lvI.iSubItem = 0;
  1146. for ( row = ListView_GetItemCount(hWndList) - 1; row >= 0; --row )  {
  1147. lvI.iItem = row;
  1148. if ( ListView_GetItem( hWndList, &lvI )  &&  (DWORD)lvI.lParam == seq )
  1149. break;
  1150. }
  1151. if ( row == -1 )
  1152. // No request associated with status.
  1153. return FALSE;
  1154. }
  1155. // Sequence number if a new item
  1156. if ( *items[0] )  {
  1157. _stprintf( msgbuf, _T("%d"), seq );
  1158. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  1159. lvI.iItem = row;
  1160. lvI.iSubItem = 0;
  1161. lvI.pszText = msgbuf;
  1162. lvI.cchTextMax = lstrlen( lvI.pszText ) + 1;
  1163. lvI.lParam = seq;
  1164. row = ListView_InsertItem( hWndList, &lvI );
  1165. if ( row == -1 )  {
  1166. _stprintf( msgbuf, _T("Error adding item %d to list view"), seq );
  1167. MessageBox( hWndList, msgbuf, APPNAME, MB_OK|MB_ICONERROR );
  1168. return FALSE;
  1169. }
  1170.         LastRow = row;
  1171. }
  1172. if( IsNT ) {
  1173. // Time - note: in order to save space in the log records
  1174. // I convert all times read to date/times and, based on whether
  1175. // the year is reasonable, chose to interpret the time as 
  1176. // a timestamp or a duration.
  1177. FileTimeToLocalFileTime( (PFILETIME) &time, &localTime );
  1178. FileTimeToSystemTime( &localTime, &systemTime );
  1179. if( systemTime.wYear < 1998 || systemTime.wYear > 2100 ) {
  1180. _stprintf( msgbuf, _T("%10.8f"), (((float) time) /
  1181.   ((float) PerfFrequency.QuadPart)) );
  1182. } else {
  1183. GetTimeFormat( LOCALE_USER_DEFAULT, 0,
  1184. &systemTime, NULL, msgbuf, 64 );
  1185. }
  1186. } else {
  1187. if( TimeIsDuration ) {
  1188. _stprintf( msgbuf, _T("%10.8f"), (float) time * 0.8 / 1e6 );
  1189. } else {
  1190. DosDateTimeToFileTime( (WORD) (time >> 16), (WORD) time, &localTime );
  1191. FileTimeToSystemTime( &localTime, &systemTime );
  1192. GetTimeFormat( LOCALE_USER_DEFAULT, 0,
  1193. &systemTime, NULL, msgbuf, 64 );
  1194. }
  1195. }
  1196. ListView_SetItemText( hWndList, row, 1, msgbuf );
  1197. // Process name
  1198. if ( itemcnt>0 && *items[0] ) {
  1199. OemToChar( items[0], msgbuf );
  1200. ListView_SetItemText( hWndList, row, 2, msgbuf );
  1201. }
  1202. // Request type
  1203. if ( itemcnt>1 && *items[1] )  {
  1204. OemToChar( items[1], msgbuf );
  1205. ListView_SetItemText( hWndList, row, 3, msgbuf );
  1206. }
  1207. // Path
  1208. if ( itemcnt>2 && *items[2] )  {
  1209. OemToChar( items[2], msgbuf );
  1210. ListView_SetItemText( hWndList, row, 4, msgbuf );
  1211. }
  1212. // Result
  1213. if ( itemcnt>4 && *items[4] )  {
  1214. OemToChar( items[4], msgbuf );
  1215. ListView_SetItemText( hWndList, row, 5, msgbuf );
  1216. }
  1217. // Additional
  1218. if ( itemcnt>3 && *items[3] )  {
  1219. OemToChar( items[3], msgbuf );
  1220. ListView_SetItemText( hWndList, row, 6, msgbuf );
  1221. }
  1222. return TRUE;
  1223. }
  1224. /******************************************************************************
  1225. *
  1226. * FUNCTION: UpdateStatistics
  1227. *
  1228. * PURPOSE: Clear the statistics window and refill it with the current 
  1229. * contents of the statistics buffer.  Does not refresh the 
  1230. * buffer from the device driver.
  1231. *
  1232. ******************************************************************************/
  1233. void UpdateStatistics( HWND hWnd, HWND hWndList, BOOL Clear )
  1234. {
  1235. PENTRY ptr;
  1236. BOOLEAN itemsAdded = FALSE;
  1237. int totitems, i;
  1238. // Just return if nothing to do
  1239. if ( !Clear  &&  StatsLen < sizeof(int)+2 )
  1240. return;
  1241. // post hourglass icon
  1242. if( !IsNT ) {
  1243. hSaveCursor = SetCursor(hHourGlass);
  1244. SendMessage(hWndList, WM_SETREDRAW, FALSE, 0);
  1245. }
  1246. // Start with empty list
  1247. if ( Clear ) {
  1248. if( IsNT ) {
  1249. ListView_DeleteAllItems( hWndList );
  1250. } else {
  1251. totitems = ListView_GetItemCount( hWndList );
  1252. Deleting = TRUE;
  1253. for(i = 0; i < totitems; i++)
  1254. ListView_DeleteItem( hWndList, 0 );
  1255. Deleting = FALSE;
  1256. }
  1257. LastRow = 0;
  1258. }
  1259. // Add all List items from Stats[] data
  1260. for ( ptr = (void *)Stats; (char *)ptr < min(Stats+StatsLen,Stats + sizeof (Stats)); )  {
  1261.   // Add to list
  1262. ULONG len = strlen(ptr->text);
  1263.         
  1264. itemsAdded |= List_Append( hWndList, ptr->seq, ptr->time.QuadPart, ptr->text );
  1265. if( IsNT ) {
  1266. len += 4; len &= 0xFFFFFFFC; // +1 for null-terminator +3 for 32bit alignment
  1267. ptr = (void *)(ptr->text + len);
  1268. } else 
  1269. ptr = (void *)(ptr->text + len + 1);
  1270. }
  1271. // Empty the buffer
  1272. StatsLen = 0;
  1273. // only do stuff if we added stuff
  1274. if( itemsAdded ) {
  1275. // limit number of lines saved
  1276. if (MaxLines) {
  1277. SendMessage(hWndList, WM_SETREDRAW, FALSE, 0);
  1278. while ( LastRow > MaxLines ) {
  1279. ListView_DeleteItem ( hWndList, 0 );
  1280. LastRow--;
  1281. }
  1282. SendMessage(hWndList, WM_SETREDRAW, TRUE, 0);
  1283. }
  1284. // Scroll so newly added items are visible
  1285. if ( Autoscroll ) {
  1286. if( hBalloon ) DestroyWindow( hBalloon );
  1287. ListView_EnsureVisible( hWndList, ListView_GetItemCount(hWndList)-1, FALSE ); 
  1288. }
  1289. }
  1290. if( !IsNT) {
  1291. SendMessage(hWndList, WM_SETREDRAW, TRUE, 0);
  1292. InvalidateRect( hWndList, NULL, FALSE );
  1293. SetCursor( hSaveCursor );
  1294. }
  1295. }
  1296. /****************************************************************************
  1297. *
  1298. *    FUNCTION: CalcStringEllipsis
  1299. *
  1300. *    PURPOSE:  Determines if an item will fit in a listview row, and if
  1301. *    not, attaches the appropriate number of '.' to a truncated 
  1302. *    version.
  1303. *
  1304. ****************************************************************************/
  1305. BOOL WINAPI CalcStringEllipsis (HDC     hdc, 
  1306.                                 LPTSTR  szString, 
  1307.                                 int     cchMax, 
  1308.                                 UINT    uColWidth) 
  1309.     static TCHAR szEllipsis3[] = TEXT("..."); 
  1310.     static TCHAR szEllipsis2[] = TEXT(".."); 
  1311.     static TCHAR szEllipsis1[] = TEXT("."); 
  1312.     SIZE sizeString; 
  1313.     SIZE sizeEllipsis3, sizeEllipsis2, sizeEllipsis1; 
  1314.     int cbString; 
  1315.     LPTSTR lpszTemp; 
  1316.      
  1317.     // Adjust the column width to take into account the edges 
  1318.     uColWidth -= 4; 
  1319. // Allocate a string for us to work with.  This way we can mangle the 
  1320.     // string and still preserve the return value 
  1321.     lpszTemp = (LPTSTR)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, cchMax); 
  1322.     if (!lpszTemp) return FALSE;
  1323.     lstrcpy (lpszTemp, szString); 
  1324.  
  1325.     // Get the width of the string in pixels 
  1326.     cbString = lstrlen(lpszTemp); 
  1327.     if (!GetTextExtentPoint32 (hdc, lpszTemp, cbString, &sizeString)) {
  1328.         HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1329. return FALSE;
  1330.     } 
  1331.  
  1332.     // If the width of the string is greater than the column width shave 
  1333.     // the string and add the ellipsis 
  1334.     if ((ULONG)sizeString.cx > uColWidth) {
  1335.         if (!GetTextExtentPoint32 (hdc, 
  1336.                                    szEllipsis3, 
  1337.                                    lstrlen(szEllipsis3), 
  1338.                                    &sizeEllipsis3)) {
  1339. HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1340. return FALSE;
  1341.         } 
  1342.         if (!GetTextExtentPoint32 (hdc, 
  1343.                                    szEllipsis2, 
  1344.                                    lstrlen(szEllipsis2), 
  1345.                                    &sizeEllipsis2)) {
  1346. HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1347. return FALSE;
  1348.         } 
  1349.         if (!GetTextExtentPoint32 (hdc, 
  1350.                                    szEllipsis1, 
  1351.                                    lstrlen(szEllipsis1), 
  1352.                                    &sizeEllipsis1)) {
  1353. HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1354. return FALSE;
  1355.         } 
  1356.  
  1357.         while (cbString > 0) { 
  1358. lpszTemp[--cbString] = 0; 
  1359. if (!GetTextExtentPoint32 (hdc, lpszTemp, cbString, &sizeString)) {
  1360.   HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1361. return FALSE;
  1362. if ((ULONG)(sizeString.cx + DOTOFFSET + sizeEllipsis3.cx) <= uColWidth) { 
  1363. break;
  1364.         } 
  1365. lpszTemp[0] = szString[0];
  1366.   if((ULONG)(sizeString.cx + DOTOFFSET + sizeEllipsis3.cx) <= uColWidth) { 
  1367. lstrcat (lpszTemp, szEllipsis3); 
  1368. } else if((ULONG)(sizeString.cx + DOTOFFSET + sizeEllipsis2.cx) <= uColWidth) { 
  1369. lstrcat (lpszTemp, szEllipsis2); 
  1370. } else if((ULONG)(sizeString.cx + DOTOFFSET + sizeEllipsis1.cx) <= uColWidth) { 
  1371. lstrcat (lpszTemp, szEllipsis1); 
  1372. } else {
  1373. lpszTemp[0] = szString[0];
  1374. }
  1375.         lstrcpy (szString, lpszTemp); 
  1376.   HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1377. return TRUE;
  1378.     } else {
  1379. HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1380. return TRUE;
  1381. }
  1382. HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp); 
  1383. return FALSE;
  1384. /****************************************************************************
  1385. *
  1386. *    FUNCTION: DrawItemColumn
  1387. *
  1388. *    PURPOSE:  Draws text to the listview.
  1389. *
  1390. ****************************************************************************/
  1391. void WINAPI DrawItemColumn (HDC hdc, LPTSTR szText, LPRECT prcClip) 
  1392.     TCHAR szString[MAXITEMLENGTH]; 
  1393.     // Check to see if the string fits in the clip rect.  If not, truncate 
  1394.     // the string and add "...". 
  1395.     lstrcpy(szString, szText); 
  1396.     CalcStringEllipsis (hdc, szString, sizeof( szString ), prcClip->right - prcClip->left); 
  1397.     ExtTextOut (hdc, 
  1398.                 prcClip->left + 2, 
  1399.                 prcClip->top + 1, 
  1400.                 ETO_CLIPPED | ETO_OPAQUE, 
  1401.                 prcClip, 
  1402.                 szString, 
  1403.                 lstrlen(szString), 
  1404.                 NULL); 
  1405. /****************************************************************************
  1406. *
  1407. *    FUNCTION: DrawListViewItem
  1408. *
  1409. *    PURPOSE:  Handles a request from Windows to draw one of the lines
  1410. * in the listview window.
  1411. *
  1412. ****************************************************************************/
  1413. void DrawListViewItem(LPDRAWITEMSTRUCT lpDrawItem)
  1414. {
  1415. TCHAR  colString[NUMCOLUMNS][MAXITEMLENGTH];
  1416. BOOLEAN highlight = FALSE;
  1417.     LV_ITEM lvi;
  1418.     RECT rcClip;
  1419.     int iColumn;
  1420. DWORD width, leftOffset;
  1421. UINT uiFlags = ILD_TRANSPARENT;
  1422.     // Get the item image to be displayed
  1423.     lvi.mask = LVIF_IMAGE | LVIF_STATE;
  1424.     lvi.iItem = lpDrawItem->itemID;
  1425.     lvi.iSubItem = 0;
  1426.     ListView_GetItem(lpDrawItem->hwndItem, &lvi);
  1427. // Get the column text and see if there is a highlight
  1428. for( iColumn = 0; iColumn < NUMCOLUMNS; iColumn++ ) {
  1429. colString[iColumn][0] = 0;
  1430. ListView_GetItemText( hWndList, lpDrawItem->itemID,
  1431.   iColumn, colString[iColumn], 
  1432.   MAXITEMLENGTH);
  1433. if( !highlight && iColumn != 0) {
  1434. highlight = MatchWithHighlightPattern( colString[iColumn] );
  1435. }
  1436. }
  1437.     // Check to see if this item is selected
  1438. if (lpDrawItem->itemState & ODS_SELECTED) {
  1439.         // Set the text background and foreground colors
  1440. SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  1441.         SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
  1442. // Also add the ILD_BLEND50 so the images come out selected
  1443. uiFlags |= ILD_BLEND50;
  1444.     } else {
  1445.         // Set the text background and foreground colors to the standard window
  1446.         // colors
  1447. if( highlight ) {
  1448. SetTextColor(lpDrawItem->hDC, HighlightFg ); 
  1449.         SetBkColor(lpDrawItem->hDC, HighlightBg );
  1450. } else {
  1451. SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
  1452. SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
  1453. }
  1454.     }
  1455.     // Set up the new clipping rect for the first column text and draw it
  1456. leftOffset = 0;
  1457. for( iColumn = 0; iColumn< NUMCOLUMNS; iColumn++ ) {
  1458. width = ListView_GetColumnWidth( hWndList, iColumn );
  1459. rcClip.left = lpDrawItem->rcItem.left + leftOffset;
  1460. rcClip.right = lpDrawItem->rcItem.left + leftOffset + width;
  1461. rcClip.top = lpDrawItem->rcItem.top;
  1462. rcClip.bottom = lpDrawItem->rcItem.bottom;
  1463. DrawItemColumn(lpDrawItem->hDC, colString[iColumn], &rcClip);
  1464. leftOffset += width;
  1465. }
  1466.     // If we changed the colors for the selected item, undo it
  1467.     if (lpDrawItem->itemState & ODS_SELECTED) {
  1468.         // Set the text background and foreground colors
  1469.         SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
  1470.         SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
  1471.     }
  1472.     // If the item is focused, now draw a focus rect around the entire row
  1473.     if (lpDrawItem->itemState & ODS_FOCUS)
  1474.     {
  1475.         // Adjust the left edge to exclude the image
  1476.         rcClip = lpDrawItem->rcItem;
  1477.         // Draw the focus rect
  1478.         DrawFocusRect(lpDrawItem->hDC, &rcClip);
  1479.     }
  1480. }
  1481. /****************************************************************************
  1482. *    FUNCTION: ListViewSubclass(HWND,UINT,WPARAM)
  1483. *
  1484. *    PURPOSE:  Subclasses the listview so that we can do tooltips
  1485. *
  1486. ****************************************************************************/
  1487. LRESULT CALLBACK ListViewSubclass(HWND hWnd, UINT uMsg, WPARAM wParam,
  1488.         LPARAM lParam)
  1489. {
  1490. ITEM_CLICK itemClick;
  1491. LVHITTESTINFO hitItem;
  1492. static initTrack = FALSE;
  1493. POINT           hitPoint, topleftPoint, bottomrightPoint;
  1494. RECT listRect;
  1495. static POINTS  mousePosition;
  1496. if( !initTrack ) {
  1497. SetTimer( hWnd, 2, BALLOONDELAY, NULL );
  1498. initTrack = TRUE;
  1499. }
  1500.     switch (uMsg) {
  1501. case WM_LBUTTONDBLCLK:
  1502. case WM_RBUTTONDBLCLK:
  1503. case WM_MBUTTONDBLCLK:
  1504. case WM_LBUTTONUP:
  1505. case WM_RBUTTONUP:
  1506. case WM_MBUTTONUP:
  1507. case WM_LBUTTONDOWN:
  1508. case WM_MBUTTONDOWN:
  1509. case WM_MOUSEMOVE:
  1510. // delete any existing balloon
  1511. if( hBalloon ) DestroyWindow( hBalloon );
  1512. // save mouse position and reset the timer
  1513. mousePosition = MAKEPOINTS( lParam );
  1514. SetTimer( hWnd, 2, BALLOONDELAY, NULL );
  1515. break;
  1516. case WM_VSCROLL:
  1517. case WM_HSCROLL:
  1518. case WM_KEYDOWN:
  1519. if( hBalloon ) DestroyWindow( hBalloon );
  1520. if( uMsg == WM_KEYDOWN && 
  1521. wParam == VK_ESCAPE &&
  1522. hWndFind ) {
  1523. DestroyWindow( hWndFind );
  1524. hWndFind = NULL;
  1525. }
  1526. break;
  1527. case WM_RBUTTONDOWN:
  1528. mousePosition = MAKEPOINTS( lParam );
  1529. SetTimer( hWnd, 2, BALLOONDELAY, NULL );
  1530. // fall-through
  1531. case WM_TIMER:
  1532. // are we currently in the listview?
  1533. GetCursorPos( &hitPoint );
  1534. GetClientRect( hWnd, &listRect );
  1535. topleftPoint.x = listRect.left;
  1536. topleftPoint.y = listRect.top;
  1537. ClientToScreen( hWnd, &topleftPoint );
  1538. bottomrightPoint.x = listRect.right;
  1539. bottomrightPoint.y = listRect.bottom;
  1540. ClientToScreen( hWnd, &bottomrightPoint );
  1541. if( hitPoint.x < topleftPoint.x ||
  1542. hitPoint.x > bottomrightPoint.x ||
  1543. hitPoint.y < topleftPoint.y ||
  1544. hitPoint.y > bottomrightPoint.y ||
  1545. (hWndFind && GetFocus() != hWndList) ) {
  1546. // delete any existing balloon
  1547. if( hBalloon ) DestroyWindow( hBalloon );
  1548. break;
  1549. }
  1550. hitItem.pt.x = mousePosition.x;
  1551. hitItem.pt.y =  mousePosition.y;
  1552. if( ListView_SubItemHitTest( hWndList, &hitItem ) != -1 ) {
  1553. itemClick.itemText[0] = 0;
  1554. ListView_GetItemText( hWndList, hitItem.iItem,
  1555. hitItem.iSubItem, itemClick.itemText, 1024 );
  1556. // delete any existing balloon
  1557. if( hBalloon ) DestroyWindow( hBalloon );
  1558. if( strlen( itemClick.itemText ) ) {
  1559. if( hitItem.iSubItem ) {
  1560. ListView_GetSubItemRect( hWndList, hitItem.iItem, hitItem.iSubItem,
  1561. LVIR_BOUNDS, &itemClick.itemPosition);
  1562. itemClick.itemPosition.bottom -= itemClick.itemPosition.top;
  1563. itemClick.itemPosition.right  -= itemClick.itemPosition.left;
  1564. } else {
  1565. ListView_GetSubItemRect( hWndList, hitItem.iItem, 0,
  1566. LVIR_BOUNDS, &itemClick.itemPosition);
  1567. itemClick.itemPosition.bottom -= itemClick.itemPosition.top;
  1568. itemClick.itemPosition.right  = ListView_GetColumnWidth( hWndList, 0 );
  1569. itemClick.itemPosition.left   = 0;
  1570. }
  1571. hitPoint.y = itemClick.itemPosition.top;
  1572. hitPoint.x = itemClick.itemPosition.left;
  1573. ClientToScreen( hWnd, &hitPoint );
  1574. itemClick.itemPosition.left = hitPoint.x;
  1575. itemClick.itemPosition.top  = hitPoint.y;
  1576. // pop-up a balloon (tool-tip like window)
  1577. hBalloon = CreateWindowEx( 0, "BALLOON", 
  1578. "balloon", 
  1579. WS_POPUP|WS_BORDER,
  1580. 100, 100,
  1581. 200, 200,
  1582. hWndMain, NULL, hInst, 
  1583. &itemClick );
  1584. if( hBalloon) SetFocus( hWnd );
  1585. }
  1586. }
  1587. break;
  1588.     }
  1589. // pass-through to real listview handler
  1590.     return CallWindowProc(ListViewWinMain, hWnd, uMsg, wParam, 
  1591.             lParam);
  1592. }
  1593. /****************************************************************************
  1594. *    FUNCTION: CreateListView(HWND)
  1595. *
  1596. *    PURPOSE:  Creates the statistics list view window and initializes it
  1597. *
  1598. ****************************************************************************/
  1599. HWND CreateList( HWND hWndParent )                                     
  1600. {
  1601. HWND hWndList;        // handle to list view window
  1602. RECT rc;             // rectangle for setting size of window
  1603. LV_COLUMN lvC; // list view column structure
  1604. DWORD j;
  1605. static char process9xLabel[] = {"Process"};
  1606. static struct {
  1607. TCHAR * Label; // title of column
  1608. DWORD Fmt;
  1609. DWORD Width;
  1610. } column[] = {
  1611. { "#" , 35 },
  1612. { "Time" , 40 },
  1613. { "Process" , 90 },
  1614. { "Request" , 90 },
  1615. { "Path" , 225 },
  1616. { "Result" , 90 },
  1617. { "Other" , 150 },
  1618. };
  1619. // Ensure that the common control DLL is loaded.
  1620. InitCommonControls();
  1621. // Set the column widths according to the user-settings
  1622. for( j = 0; j < NUMCOLUMNS; j++ ) {
  1623. column[j].Width = PositionInfo.column[j];
  1624. }
  1625. // Get the size and position of the parent window.
  1626. GetClientRect( hWndParent, &rc );
  1627. // Create the list view window
  1628. hWndList = CreateWindowEx(  0L, WC_LISTVIEW, TEXT(""), 
  1629. WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT |
  1630. LVS_OWNERDRAWFIXED,
  1631. 0, ShowToolbar ? TOOLBARHEIGHT : 0, 
  1632. rc.right - rc.left, 
  1633. rc.bottom - rc.top - (ShowToolbar ? TOOLBARHEIGHT : 0),
  1634. hWndParent, (HMENU)ID_LIST, hInst, NULL );
  1635. if ( hWndList == NULL )
  1636. return NULL;
  1637. // Make it a nice fix-width font for easy reading
  1638. SendMessage( hWndList, WM_SETFONT, (WPARAM) hFont, (LPARAM) 0 );
  1639. // Initialize columns
  1640. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1641. lvC.fmt = LVCFMT_LEFT; // left-align column
  1642. // Add the columns.
  1643. for ( j = 0; j < sizeof column/sizeof column[0]; ++j )  {
  1644. lvC.iSubItem = j;
  1645. lvC.cx = column[j].Width;
  1646. if( j == 2 && !IsNT ) 
  1647. lvC.pszText = process9xLabel;
  1648. else 
  1649. lvC.pszText = column[j].Label;
  1650. if ( ListView_InsertColumn( hWndList, j, &lvC ) == -1 )
  1651. return NULL;
  1652. }
  1653. // Set full-row selection
  1654. SendMessage( hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE,
  1655. LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT );
  1656. // Sub-class
  1657. ListViewWinMain = (WNDPROC) SetWindowLong(hWndList, 
  1658.                                               GWL_WNDPROC, 
  1659.                                               (DWORD)ListViewSubclass); 
  1660. return hWndList;
  1661. }
  1662. /****************************************************************************
  1663. *    FUNCTION: SaveFile()
  1664. *
  1665. *    PURPOSE:  Lets the user go select a file.
  1666. *
  1667. ****************************************************************************/
  1668. void SaveFile( HWND hWnd, HWND ListBox, BOOLEAN SaveAs )
  1669. {
  1670. OPENFILENAME SaveFileName;
  1671. TCHAR szFile[MAX_PATH] = _T(""), fieldtext[MAXITEMLENGTH];
  1672. TCHAR output[MAXITEMLENGTH*NUMCOLUMNS];
  1673. FILE *hFile;
  1674. int numitems;
  1675. int row, subitem;
  1676. if( SaveAs || !FileChosen ) {
  1677. SaveFileName.lStructSize       = sizeof (SaveFileName);
  1678. SaveFileName.hwndOwner         = hWnd;
  1679. SaveFileName.hInstance         = (HANDLE) hInst;
  1680. SaveFileName.lpstrFilter       = _T("File Info (*.LOG)*.LOGAll (*.*)*.*");
  1681. SaveFileName.lpstrCustomFilter = (LPTSTR)NULL;
  1682. SaveFileName.nMaxCustFilter    = 0L;
  1683. SaveFileName.nFilterIndex      = 1L;
  1684. SaveFileName.lpstrFile         = szFile;
  1685. SaveFileName.nMaxFile          = 256;
  1686. SaveFileName.lpstrFileTitle    = NULL;
  1687. SaveFileName.nMaxFileTitle     = 0;
  1688. SaveFileName.lpstrInitialDir   = NULL;
  1689. SaveFileName.lpstrTitle        = _T("Save File Info...");
  1690. SaveFileName.nFileOffset       = 0;
  1691. SaveFileName.nFileExtension    = 0;
  1692. SaveFileName.lpstrDefExt       = _T("*.log");
  1693. SaveFileName.lpfnHook    = NULL;
  1694.   SaveFileName.Flags = OFN_LONGNAMES|OFN_HIDEREADONLY;
  1695. if( !GetSaveFileName( &SaveFileName )) 
  1696. return;
  1697. } else 
  1698. // open previous szFile
  1699. _tcscpy( szFile, szFileName );
  1700. // open the file
  1701. hFile = _tfopen( szFile, _T("w") );
  1702. if( !hFile ) {
  1703. MessageBox( NULL, _T("Create File Failed."),
  1704. _T("Save Error"), MB_OK|MB_ICONSTOP );
  1705. return;
  1706. }
  1707. // post hourglass icon
  1708. SetCapture(hWnd);
  1709. hSaveCursor = SetCursor(hHourGlass);
  1710. numitems = ListView_GetItemCount(ListBox);
  1711. for ( row = 0; row < numitems; row++ )  {
  1712. output[0] = 0;
  1713. for( subitem = 0; subitem < NUMCOLUMNS; subitem++ ) {
  1714. fieldtext[0] = 0;
  1715. ListView_GetItemText( ListBox, row, subitem, fieldtext, 256 );
  1716. _tcscat( output, fieldtext );
  1717. _tcscat( output, _T("t") );
  1718. }
  1719. _ftprintf( hFile, _T("%sn"), output );
  1720. }
  1721. fclose( hFile );
  1722. _tcscpy( szFileName, szFile );
  1723. FileChosen = TRUE;
  1724. SetCursor( hSaveCursor );
  1725. ReleaseCapture(); 
  1726. }
  1727. /****************************************************************************
  1728. *
  1729. * FUNCTION: HistoryProc
  1730. *
  1731. * PURPOSE: Processes messages for "Filter" dialog box
  1732. *
  1733. ****************************************************************************/
  1734. BOOL APIENTRY HistoryProc( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  1735. {
  1736. DWORD newMaxLines, numRows;
  1737. char history[64];
  1738. switch ( message )  {
  1739. case WM_INITDIALOG:
  1740. // initialize the controls to reflect the current filter
  1741. sprintf( history, "%d", MaxLines );
  1742. SetDlgItemTextA( hDlg, IDC_HISTORY, history );
  1743. SendMessage (GetDlgItem( hDlg, IDC_SPIN), UDM_SETRANGE, 0L, 
  1744. MAKELONG (9999, 0));
  1745. return TRUE;
  1746. case WM_COMMAND:              
  1747. if ( LOWORD( wParam ) == IDOK )  {
  1748. // make sure that max lines is legal
  1749. GetDlgItemTextA( hDlg, IDC_HISTORY, history, 64 );
  1750. if( !sscanf( history, "%d", &newMaxLines )) {
  1751. MessageBox( NULL, TEXT("Invalid History Depth."),
  1752. TEXT("Filter Error"), MB_OK|MB_ICONWARNING );
  1753. return TRUE;
  1754. MaxLines = newMaxLines;
  1755. EndDialog( hDlg, TRUE );
  1756. if (MaxLines ) {
  1757. numRows = ListView_GetItemCount( hWndList );
  1758. SendMessage(hWndList, WM_SETREDRAW, FALSE, 0);
  1759. while ( numRows >= MaxLines ) {
  1760. ListView_DeleteItem ( hWndList, 0 );
  1761. numRows--;
  1762. }
  1763. SendMessage(hWndList, WM_SETREDRAW, TRUE, 0);
  1764. }
  1765. return TRUE;
  1766. } else if( LOWORD( wParam ) == IDCANCEL ) {
  1767. EndDialog( hDlg, TRUE );
  1768. } else if( LOWORD( wParam ) == IDRESET ) {
  1769. // reset filter to default of none
  1770. SetDlgItemTextA( hDlg, IDC_HISTORY, "0" );
  1771. }
  1772. break;
  1773. case WM_CLOSE:
  1774. EndDialog( hDlg, TRUE );
  1775. return TRUE;
  1776. }
  1777. return FALSE;   
  1778. }
  1779. /****************************************************************************
  1780. *
  1781. * FUNCTION: About
  1782. *
  1783. * PURPOSE: Processes messages for "About" dialog box
  1784. *
  1785. ****************************************************************************/
  1786. BOOL APIENTRY About( HWND hDlg, UINT message, UINT wParam, LONG lParam )
  1787. {
  1788. switch ( message )  {
  1789. case WM_INITDIALOG:
  1790. return TRUE;
  1791. case WM_COMMAND:              
  1792. if ( LOWORD( wParam ) == IDOK )  {
  1793.   EndDialog( hDlg, TRUE );
  1794.   return TRUE;
  1795. }
  1796. break;
  1797. case WM_CLOSE:
  1798. EndDialog( hDlg, TRUE );
  1799. return TRUE;
  1800. }
  1801. return FALSE;   
  1802. }
  1803. /******************************************************************************
  1804. *
  1805. * FUNCTION: GetDLLVersion
  1806. *
  1807. * PURPOSE: Gets the version number of the specified DLL.
  1808. *
  1809. ******************************************************************************/
  1810. HRESULT GetDLLVersion( PTCHAR DllName, LPDWORD pdwMajor, LPDWORD pdwMinor)
  1811. {
  1812. HINSTANCE hDll;
  1813. HRESULT hr = S_OK;
  1814. DLLVERSIONINFO_ dvi;
  1815. *pdwMajor = 0;
  1816. *pdwMinor = 0;
  1817. //Load the DLL.
  1818. hDll = LoadLibrary(DllName);
  1819. if( hDll ) {
  1820.    pDllGetVersionProc = (PVOID)GetProcAddress(hDll, "DllGetVersion");
  1821.    if(pDllGetVersionProc) {
  1822.   
  1823.   ZeroMemory(&dvi, sizeof(dvi));
  1824.   dvi.cbSize = sizeof(dvi);
  1825.   hr = (*pDllGetVersionProc)(&dvi);
  1826.   
  1827.   if(SUCCEEDED(hr)) {
  1828.  *pdwMajor = dvi.dwMajorVersion;
  1829.  *pdwMinor = dvi.dwMinorVersion;
  1830.   }
  1831.     } else {
  1832.   // If GetProcAddress failed, the DLL is a version previous to the one 
  1833.   // shipped with IE 3.x.
  1834.   *pdwMajor = 4;
  1835.   *pdwMinor = 0;
  1836.       }
  1837.    
  1838.   FreeLibrary(hDll);
  1839.   return hr;
  1840. }
  1841. return E_FAIL;
  1842. }
  1843. /****************************************************************************
  1844. *
  1845. *    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
  1846. *
  1847. *    PURPOSE:  Processes messages for the statistics window.
  1848. *
  1849. ****************************************************************************/
  1850. LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam) 
  1851. {
  1852. static DWORD MaxDriveSet = 0;
  1853. static HMENU DriveMenu;
  1854.     static HWND hWndTT;
  1855. static HWND hWndToolbar;
  1856. static POINTS   hoverPoints;
  1857. DWORD newDriveSet;
  1858. LPTOOLTIPTEXT lpToolTipText;
  1859. LPFINDREPLACE findMessageInfo;
  1860. #if _DEBUG
  1861. ULONG irpcount;
  1862. #endif
  1863. POINT hitPoint;
  1864. LOGFONT lf;
  1865. CHOOSEFONT chf;
  1866. RECT listRect;
  1867. DWORD nb, versionNumber;
  1868. TEXTMETRIC textMetrics;
  1869. DWORD drive, drivetype;
  1870. TCHAR Path[ MAX_PATH ];
  1871. static TCHAR szBuf[MAX_PATH];
  1872. TCHAR  name[ MAX_PATH ];
  1873. TCHAR *File;
  1874. RECT rc;  
  1875. DWORD majorver, minorver;
  1876. WIN32_FIND_DATA findData;
  1877. HANDLE findHandle;
  1878. DWORD startTime;
  1879. HDC hDC;
  1880. FILE_SYSTEM_TYPE fsType;
  1881. PAINTSTRUCT Paint;
  1882. switch ( message ) {
  1883. case WM_CREATE:
  1884. // get hourglass icon ready
  1885. hHourGlass = LoadCursor( NULL, IDC_WAIT );
  1886. // post hourglass icon
  1887. SetCapture(hWnd);
  1888. hSaveCursor = SetCursor(hHourGlass);
  1889. // determine performance counter frequency
  1890. QueryPerformanceFrequency( &PerfFrequency );
  1891. // Create the toolbar control - use modern style if available.
  1892. GetDLLVersion( _T("comctl32.dll"), &majorver, &minorver );
  1893. if( majorver > 4 || (majorver == 4 && minorver >= 70) ) {
  1894. hWndToolbar = CreateToolbarEx( 
  1895. hWnd, TOOLBAR_FLAT | WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,  
  1896. ID_TOOLBAR, NUMTOOLBARBUTTONS, hInst, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtons,
  1897. NUMBUTTONS, 16,16,16,15, sizeof(TBBUTTON)); 
  1898. } else {
  1899. hWndToolbar = CreateToolbarEx( 
  1900. hWnd, WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,  
  1901. ID_TOOLBAR, NUMTOOLBARBUTTONS, hInst, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtonsOld,
  1902. NUMBUTTONSOLD, 16,16,16,15, sizeof(TBBUTTON)); 
  1903. }
  1904. if (hWndToolbar == NULL ) MessageBox (NULL, _T("Toolbar not created!"), NULL, MB_OK );
  1905. // Create the ListBox within the main window
  1906. hWndList = CreateList( hWnd );
  1907. if ( hWndList == NULL )   MessageBox( NULL, _T("List not created!"), NULL, MB_OK );
  1908.     // open the handle to the device
  1909. if( IsNT ) {
  1910. GetCurrentDirectory( sizeof Path, Path );
  1911. _stprintf( Path+lstrlen(Path), _T("\%s"), SYS_FILE );
  1912. findHandle = FindFirstFile( Path, &findData );
  1913. if( findHandle == INVALID_HANDLE_VALUE ) {
  1914. if( !SearchPath( NULL, SYS_FILE, NULL, sizeof(Path), Path, &File ) ) {
  1915. _stprintf( msgbuf, _T("%s was not found."), SYS_NAME );
  1916. return Abort( hWnd, msgbuf );
  1917. }
  1918. } else FindClose( findHandle );
  1919. UnloadDeviceDriver( SYS_NAME );
  1920. if ( ! LoadDeviceDriver( SYS_NAME, Path, &SysHandle ) )  {
  1921. _stprintf( msgbuf, _T("Opening %s (%s): error %d"), SYS_NAME, Path,
  1922. GetLastError( ) );
  1923. return Abort( hWnd, msgbuf );
  1924. }
  1925. // Correct driver version?
  1926. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_VERSION,
  1927. NULL, 0, &versionNumber, sizeof(DWORD), &nb, NULL ) ||
  1928. versionNumber != FILEMONVERSION ) {
  1929. MessageBox( hWnd, _T("Filemon located a driver with the wrong version.n")
  1930. _T("If you just installed a new version you must reboot before you aren")
  1931. _T("able to use it."), _T("Filemon"), MB_ICONERROR);
  1932. PostQuitMessage( 1 );
  1933. return 0;
  1934. }
  1935. } else {
  1936. // connect with VxD
  1937. SysHandle = CreateFile( VXD_FILE, 0, 0, NULL,
  1938. 0, FILE_FLAG_OVERLAPPED|
  1939. FILE_FLAG_DELETE_ON_CLOSE,
  1940. NULL );
  1941. if ( SysHandle == INVALID_HANDLE_VALUE )  {
  1942. _stprintf( msgbuf, "%s is not loaded properly.", VXD_NAME );
  1943. return Abort( hWnd, msgbuf );
  1944. }
  1945. }
  1946. // Have driver zero information
  1947. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_ZEROSTATS,
  1948. NULL, 0, NULL, 0, &nb, NULL ) ) {
  1949. Abort( hWnd, _T("Couldn't access device driver") );
  1950. return 0;
  1951. }
  1952. // Set up the filter
  1953. FilterDefinition.excludefilter[0] = 0;
  1954. FilterDefinition.includefilter[0] = 0;
  1955. if( strcmp( ExcludeString, " " ) )
  1956. strcpy( FilterDefinition.excludefilter, ExcludeString );
  1957. if( strcmp( FilterString, " " ) )
  1958. strcpy( FilterDefinition.includefilter, FilterString );
  1959. // Give the user to change initial filter
  1960. if( strcmp( FilterString, "*" ) ||
  1961. (*ExcludeString && strcmp( ExcludeString, " "))) {
  1962. DialogBox( hInst, TEXT("InitFilter"), hWnd, (DLGPROC) FilterProc );
  1963. } else {
  1964. // tell the driver the initial filter
  1965. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_SETFILTER,
  1966. &FilterDefinition, sizeof(FILTER), NULL, 
  1967. 0, &nb, NULL ) ) {
  1968. return Abort( hWnd, _T("Couldn't access device driver") );
  1969. }
  1970. }
  1971. // tell the driver the timing type
  1972. if ( !DeviceIoControl( SysHandle, IOCTL_FILEMON_TIMETYPE,
  1973. (PVOID) &TimeIsDuration, sizeof(BOOLEAN), 
  1974. NULL, 0, &nb, NULL ) )
  1975. {
  1976. return Abort( hWnd, _T("Couldn't access device driver") );
  1977. }
  1978. CheckMenuItem( GetMenu(hWnd), IDM_TIME,
  1979. MF_BYCOMMAND|(TimeIsDuration?MF_CHECKED:MF_UNCHECKED) ); 
  1980. // Tell driver to start filtering
  1981. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_STARTFILTER,
  1982. NULL, 0, NULL, 0, &nb, NULL ) )
  1983. {
  1984. return Abort( hWnd, _T("Couldn't access device driver") );
  1985. }
  1986. // Create a pop-up menu item with the drives
  1987. if( IsNT ) {
  1988. DriveMenu = CreateMenu();
  1989. // Add the special file systems menu items
  1990. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_STRING,
  1991. IDC_DRIVE+PIPE_DRIVE, _T("Named Pipes") );
  1992. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_STRING,
  1993. IDC_DRIVE+SLOT_DRIVE, _T("Mail Slots") );
  1994. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_SEPARATOR,
  1995. 0, NULL );
  1996. // Get available drives we can monitor
  1997. MaxDriveSet = GetLogicalDrives();
  1998. if( PositionInfo.curdriveset != (DWORD) -1 )
  1999. CurDriveSet = PositionInfo.curdriveset;
  2000. else
  2001. CurDriveSet = MaxDriveSet;
  2002. for ( drive = 0; drive < 32; ++drive )  {
  2003. if ( MaxDriveSet & (1 << drive) )  {
  2004. _stprintf( name, _T("%c:\"), 'A'+drive );
  2005. switch ( GetDriveType( name ) )  {
  2006. // We don't like these: remove them
  2007. case 0: // The drive type cannot be determined.
  2008. case 1: // The root directory does not exist.
  2009. drivetype = DRVUNKNOWN;
  2010. CurDriveSet &= ~(1 << drive);
  2011. break;
  2012. case DRIVE_REMOVABLE: // The drive can be removed from the drive.
  2013. drivetype = DRVREMOVE;
  2014. CurDriveSet &= ~(1 << drive);
  2015. break;
  2016. case DRIVE_CDROM: // The drive is a CD-ROM drive.
  2017. drivetype = DRVCD;
  2018. CurDriveSet &= ~(1 << drive);
  2019. break;
  2020. // We like these types
  2021. case DRIVE_FIXED: // The disk cannot be removed from the drive.
  2022. drivetype = DRVFIXED;
  2023. break;
  2024. case DRIVE_REMOTE: // The drive is a remote (network) drive.
  2025. drivetype = DRVREMOTE;
  2026. break;
  2027. case DRIVE_RAMDISK: // The drive is a RAM disk.
  2028. drivetype = DRVRAM;
  2029. break;
  2030. }
  2031. _stprintf( name, _T("Drive &%c: (%s)"), 'A'+drive, DrvNames[drivetype] );
  2032. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_STRING,
  2033. IDC_DRIVE+drive, name );
  2034. }
  2035. }
  2036. // Add "all drives"/"no drives"
  2037. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_SEPARATOR,
  2038. 0, NULL );
  2039. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_STRING,
  2040. IDC_DRIVE+ALLDRIVES, "All Drives" );
  2041. InsertMenu( DriveMenu, 0xFFFFFFFF, MF_BYPOSITION|MF_STRING,
  2042. IDC_DRIVE+NODRIVES, "No Drives" );
  2043. // Insert into top-level menu
  2044. InsertMenu( GetMenu( hWnd ), 3, MF_BYPOSITION|MF_POPUP|MF_STRING,
  2045. (UINT)DriveMenu, _T("&Drives") );
  2046. // Have driver hook the selected drives
  2047. CurDriveSet = HookDrives( DriveMenu, MaxDriveSet, CurDriveSet );
  2048. if( HookPipes ) {
  2049. fsType = NPFS;
  2050. if( !DeviceIoControl( SysHandle, HookPipes ? IOCTL_FILEMON_HOOKSPECIAL :
  2051. IOCTL_FILEMON_UNHOOKSPECIAL,
  2052. &fsType, sizeof(fsType), NULL, 0, &nb, NULL )) {
  2053. MessageBox( hWnd, _T("Filemon could not attach to Named Pipe File System"), 
  2054. APPNAME, MB_ICONWARNING|MB_OK );
  2055. HookPipes = FALSE;
  2056. }
  2057. }
  2058. if( HookSlots ) {
  2059. fsType = MSFS;
  2060. if( !DeviceIoControl( SysHandle, HookSlots ? IOCTL_FILEMON_HOOKSPECIAL :
  2061. IOCTL_FILEMON_UNHOOKSPECIAL,
  2062. &fsType, sizeof(fsType), NULL, 0, &nb, NULL )) {
  2063. MessageBox( hWnd, _T("Filemon could not attach to Mail Slot File System"), 
  2064. APPNAME, MB_ICONWARNING|MB_OK );
  2065. HookSlots = FALSE;
  2066. }
  2067. }
  2068. CheckMenuItem( DriveMenu, IDC_DRIVE+PIPE_DRIVE, MF_BYCOMMAND|
  2069. (HookPipes ? MF_CHECKED:MF_UNCHECKED ));
  2070. CheckMenuItem( DriveMenu, IDC_DRIVE+SLOT_DRIVE, MF_BYCOMMAND|
  2071. (HookSlots ? MF_CHECKED:MF_UNCHECKED ));
  2072. }
  2073. // set the time type bitmap
  2074. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_TIME, (TimeIsDuration?10:9) );
  2075. // Start up timer to periodically update screen
  2076. SetTimer( hWnd, 1, 500/*ms*/, NULL );
  2077. // Initialization done
  2078. SetCursor( hSaveCursor );
  2079. ReleaseCapture();
  2080. return 0;
  2081. case WM_NOTIFY:
  2082. // Make sure its intended for us
  2083. if ( wParam == ID_LIST )  {
  2084. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  2085. switch ( pNm->hdr.code )  {
  2086.         case LVN_BEGINLABELEDIT:
  2087. // Don't allow editing of information
  2088. return TRUE;
  2089. case NM_DBLCLK:
  2090. case NM_RETURN:
  2091. // open the specified file/folder in Explorer, if we can
  2092. ExplorerJump( hWnd );
  2093. return TRUE;
  2094. case HDN_ENDTRACK:
  2095. // Listview header sizes changed
  2096. InvalidateRect( hWndList, NULL, TRUE );
  2097. return FALSE;
  2098. }
  2099. } else {
  2100. switch (((LPNMHDR) lParam)->code) 
  2101. {
  2102. case TTN_NEEDTEXT:    
  2103. // Display the ToolTip text.
  2104. lpToolTipText = (LPTOOLTIPTEXT)lParam;
  2105.      LoadString (hInst, lpToolTipText->hdr.idFrom, szBuf, sizeof(szBuf));
  2106.      lpToolTipText->lpszText = szBuf;
  2107. break;
  2108. default:
  2109. return FALSE;
  2110. }
  2111. }
  2112. return FALSE;
  2113. case WM_COMMAND:
  2114. switch ( LOWORD( wParam ) )  {
  2115. // stats related commands to send to driver
  2116. case IDM_CLEAR:
  2117. // Have driver zero information
  2118. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_ZEROSTATS,
  2119. NULL, 0, NULL, 0, &nb, NULL ) )
  2120. {
  2121. Abort( hWnd, _T("Couldn't access device driver") );
  2122. return 0;
  2123. }
  2124. // Update statistics windows
  2125. UpdateStatistics( hWnd, hWndList, TRUE );
  2126. return 0;
  2127. case IDM_HELP:
  2128. WinHelp(hWnd, _T("filemon.hlp"), HELP_CONTENTS, 0L);
  2129. return 0;
  2130. case IDM_CAPTURE:
  2131. // Disable filtering
  2132. Capture = !Capture;
  2133. if ( ! DeviceIoControl( SysHandle, 
  2134. Capture ? IOCTL_FILEMON_STARTFILTER: IOCTL_FILEMON_STOPFILTER,
  2135. NULL, 0, NULL, 0, &nb, NULL ) )
  2136. {
  2137. Abort( hWnd, _T("Couldn't access device driver") );
  2138. return 0;
  2139. }
  2140. CheckMenuItem( GetMenu(hWnd), IDM_CAPTURE,
  2141. MF_BYCOMMAND|(Capture?MF_CHECKED:MF_UNCHECKED) );
  2142. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_CAPTURE, (Capture?2:1) );
  2143. InvalidateRect( hWndToolbar, NULL, TRUE );
  2144. return 0;
  2145. case IDM_AUTOSCROLL:
  2146. Autoscroll = !Autoscroll;
  2147. CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
  2148. MF_BYCOMMAND|(Autoscroll?MF_CHECKED:MF_UNCHECKED) ); 
  2149. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, (Autoscroll?4:3) );
  2150. InvalidateRect( hWndToolbar, NULL, TRUE );
  2151. return 0;
  2152. case IDM_TIME:
  2153. TimeIsDuration = !TimeIsDuration;
  2154. CheckMenuItem( GetMenu(hWnd), IDM_TIME,
  2155. MF_BYCOMMAND|(TimeIsDuration?MF_CHECKED:MF_UNCHECKED) ); 
  2156. // tell the driver
  2157. if ( !DeviceIoControl( SysHandle, IOCTL_FILEMON_TIMETYPE,
  2158. (PVOID) &TimeIsDuration, sizeof(BOOLEAN), 
  2159. NULL, 0, &nb, NULL ) )
  2160. {
  2161. Abort( hWnd, _T("Couldn't access device driver") );
  2162. return 0;
  2163. }
  2164. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_TIME, (TimeIsDuration?10:9) );
  2165. InvalidateRect( hWndToolbar, NULL, TRUE );
  2166. return 0;
  2167. case IDM_COPY:
  2168. CopySelection( hWnd );
  2169. return FALSE;
  2170. case IDM_JUMP:
  2171. // open the folder in regedit if we can
  2172. ExplorerJump( hWnd );
  2173. return FALSE;
  2174. case IDM_HISTORY:
  2175. DialogBox( hInst, TEXT("History"), hWnd, (DLGPROC) HistoryProc );
  2176. return 0;
  2177. case IDM_FILTER:
  2178. DialogBox( hInst, _T("Filter"), hWnd, (DLGPROC) FilterProc );
  2179. return 0;
  2180. case IDM_EXIT:
  2181. // Close ourself
  2182. SendMessage( hWnd, WM_CLOSE, 0, 0 );
  2183. return 0;
  2184. case IDM_FIND:
  2185. // search the listview
  2186. if( !hWndFind ) {
  2187. PrevMatch = FALSE;
  2188. PopFindDialog( hWnd );
  2189. } else if( PrevMatch ) {
  2190. // treat this like a find-next
  2191. SetCapture(hWndFind);
  2192. hSaveCursor = SetCursor(hHourGlass);
  2193. EnableWindow( hWndFind, FALSE );
  2194. if (FindInListview( hWnd, &FindTextInfo ) ) {
  2195. Autoscroll = FALSE;
  2196. CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
  2197. MF_BYCOMMAND|MF_UNCHECKED ); 
  2198. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, 3 );
  2199. }
  2200. EnableWindow( hWndFind, TRUE );
  2201. SetCursor( hSaveCursor );
  2202. ReleaseCapture(); 
  2203. }
  2204. return 0;
  2205. case IDM_HIGHLIGHT:
  2206. SelectHighlightColors( hWnd );
  2207. break;
  2208. case IDM_FONT:
  2209. hDC = GetDC (hWndList );
  2210. lf = LogFont;
  2211. chf.hDC = CreateCompatibleDC (hDC);
  2212. ReleaseDC (hWnd, hDC);
  2213. chf.lStructSize = sizeof (CHOOSEFONT);
  2214. chf.hwndOwner = hWndList;
  2215. chf.lpLogFont = &lf;
  2216. chf.Flags     = CF_SCREENFONTS|CF_ENABLETEMPLATE|
  2217. CF_INITTOLOGFONTSTRUCT| CF_LIMITSIZE; 
  2218. chf.rgbColors = RGB (0, 0, 0);
  2219. chf.lCustData = 0;
  2220. chf.hInstance = (HANDLE)hInst;
  2221. chf.lpszStyle = (LPTSTR)NULL;
  2222. chf.nFontType = SCREEN_FONTTYPE;
  2223. chf.nSizeMin  = 0;
  2224. chf.nSizeMax  = 20;
  2225. chf.lpfnHook  = (LPCFHOOKPROC)(FARPROC)NULL;
  2226. chf.lpTemplateName = (LPTSTR)MAKEINTRESOURCE (FORMATDLGORD31);
  2227. if( ChooseFont( &chf ) ) {
  2228. LogFont = lf;
  2229. // Update listview font
  2230. DeleteObject( hFont );
  2231.   hFont = CreateFontIndirect( &LogFont ); 
  2232. SendMessage( hWndList, WM_SETFONT, 
  2233. (WPARAM) hFont, 0);
  2234. InvalidateRgn( hWndList, NULL, TRUE );
  2235. // Trick the listview into updating
  2236. GetWindowRect( hWndMain, &rc );
  2237. SetWindowPos( hWndMain, NULL,
  2238. rc.left, rc.top, 
  2239. rc.right - rc.left -1 , 
  2240. rc.bottom - rc.top,
  2241. SWP_NOZORDER );
  2242. SetWindowPos( hWndMain, NULL,
  2243. rc.left, rc.top, 
  2244. rc.right - rc.left, 
  2245. rc.bottom - rc.top,
  2246. SWP_NOZORDER );
  2247. }
  2248. return FALSE;
  2249. case IDM_ABOUT:
  2250. // Show the names of the authors
  2251. DialogBox( hInst, _T("AboutBox"), hWnd, (DLGPROC)About );
  2252. return 0;
  2253. case IDM_SAVE:
  2254. SaveFile( hWnd, hWndList, FALSE );
  2255. return 0;
  2256. case IDM_SAVEAS:
  2257. SaveFile( hWnd, hWndList, TRUE );
  2258. return 0;
  2259. default:
  2260. // selection in drive menu?
  2261. if( IsNT ) {
  2262. drive = LOWORD( wParam ) - IDC_DRIVE;
  2263. if ( drive < 32 )  {
  2264. if( drive == ALLDRIVES ) {
  2265. newDriveSet = MaxDriveSet;
  2266. } else if( drive == NODRIVES ) {
  2267. newDriveSet = 0;
  2268. } else {
  2269. // Toggle status
  2270. newDriveSet = CurDriveSet ^ (1 << drive);
  2271. }
  2272. // Have driver hook the selected drives
  2273. CurDriveSet = HookDrives( DriveMenu, MaxDriveSet, newDriveSet );
  2274. if( newDriveSet != CurDriveSet ) {
  2275. for( drive = 0; drive < 26; drive++ ) {
  2276. if( newDriveSet & (1 << drive ) && 
  2277. !(CurDriveSet & (1 << drive))) {
  2278. sprintf( szBuf, "Filemon could not attach to drive %C:",
  2279. drive + L'A' );
  2280. MessageBox( hWnd, szBuf, 
  2281. APPNAME, MB_ICONWARNING|MB_OK );
  2282. }
  2283. }
  2284. }
  2285. return FALSE;
  2286. } else if( drive == PIPE_DRIVE ) {
  2287. HookPipes = !HookPipes;
  2288. fsType = NPFS;
  2289. if( !DeviceIoControl( SysHandle, HookPipes ? IOCTL_FILEMON_HOOKSPECIAL :
  2290. IOCTL_FILEMON_UNHOOKSPECIAL,
  2291. &fsType, sizeof(fsType), NULL, 0, &nb, NULL )) {
  2292. _stprintf( msgbuf, _T("Filemon could not attach to Named Pipe File System"));
  2293. MessageBox( hWnd, msgbuf, 
  2294. APPNAME, MB_ICONWARNING|MB_OK );
  2295. HookPipes = FALSE;
  2296. }
  2297. CheckMenuItem( DriveMenu, IDC_DRIVE+PIPE_DRIVE, MF_BYCOMMAND|
  2298. (HookPipes ? MF_CHECKED:MF_UNCHECKED ));
  2299. } else if( drive == SLOT_DRIVE ) {
  2300. HookSlots = !HookSlots;
  2301. fsType = MSFS;
  2302. if( !DeviceIoControl( SysHandle, HookSlots ? IOCTL_FILEMON_HOOKSPECIAL :
  2303. IOCTL_FILEMON_UNHOOKSPECIAL,
  2304. &fsType, sizeof(fsType), NULL, 0, &nb, NULL )) {
  2305. _stprintf( msgbuf, _T("Filemon could not attach to Mail Slot File System"));
  2306. MessageBox( hWnd, msgbuf, 
  2307. APPNAME, MB_ICONWARNING|MB_OK );
  2308. HookSlots = FALSE;
  2309. }
  2310. CheckMenuItem( DriveMenu, IDC_DRIVE+SLOT_DRIVE, MF_BYCOMMAND|
  2311. (HookSlots ? MF_CHECKED:MF_UNCHECKED ));
  2312. } else {
  2313. // Default behavior
  2314. return DefWindowProc( hWnd, message, wParam, lParam );
  2315. }
  2316. }
  2317. }
  2318. break;
  2319. case WM_TIMER:
  2320. // Time to query the device driver for more data
  2321. if ( Capture )  {
  2322. // don't process for more than a second without pausing
  2323. startTime = GetTickCount();
  2324. for (;;)  {
  2325. // Have driver fill Stats buffer with information
  2326. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_GETSTATS,
  2327. NULL, 0, &Stats, sizeof Stats,
  2328. &StatsLen, NULL ) )
  2329. {
  2330. Abort( hWnd, _T("Couldn't access device driver") );
  2331. return TRUE;
  2332. }
  2333. if ( StatsLen == 0 )
  2334. break;
  2335. // Update statistics windows
  2336. UpdateStatistics( hWnd, hWndList, FALSE );
  2337. if( GetTickCount() - startTime > 1000 ) break;
  2338. }
  2339. }
  2340. // delete balloon if necessary
  2341. if( hBalloon ) {
  2342. GetCursorPos( &hitPoint );
  2343. GetWindowRect( hWndList, &listRect );
  2344. if( hitPoint.x < listRect.left ||
  2345. hitPoint.x > listRect.right ||
  2346. hitPoint.y < listRect.top ||
  2347. hitPoint.y > listRect.bottom ) {
  2348. DestroyWindow( hBalloon );
  2349. }
  2350. }
  2351. return 0;
  2352. case WM_SIZE:
  2353. // Move or resize the List
  2354.             MoveWindow( hWndList, 0, TOOLBARHEIGHT, LOWORD(lParam), HIWORD(lParam)-TOOLBARHEIGHT, TRUE );
  2355. MoveWindow( hWndToolbar, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE );
  2356. if( hBalloon ) DestroyWindow( hBalloon );
  2357.             return 0;
  2358. case WM_MEASUREITEM:
  2359. // If its the listview that's being queried, return the height of the
  2360. // font
  2361. if( ((MEASUREITEMSTRUCT *) lParam)->CtlType == ODT_LISTVIEW ) {
  2362. hDC = GetDC( hWndList );
  2363. SelectObject( hDC, hFont );
  2364. if( !GetTextMetrics( hDC, &textMetrics)) return FALSE;
  2365. ((MEASUREITEMSTRUCT *) lParam)->itemHeight = textMetrics.tmHeight + 1;
  2366. ReleaseDC( hWndList, hDC );
  2367. }
  2368. return DefWindowProc( hWnd, message, wParam, lParam );
  2369. case WM_DRAWITEM:
  2370. DrawListViewItem( (LPDRAWITEMSTRUCT) lParam );
  2371. break;
  2372. case WM_ACTIVATE:
  2373. case WM_SETFOCUS:
  2374. SetFocus( hWndList );
  2375. break;
  2376. case WM_MOUSEMOVE:
  2377. case WM_MOVE:
  2378. if( hBalloon ) DestroyWindow( hBalloon );
  2379. return 0;
  2380. case WM_CLOSE:
  2381. #if _DEBUG
  2382. if( IsNT ) {
  2383. // see if the driver can unload
  2384. if ( ! DeviceIoControl( SysHandle, IOCTL_FILEMON_UNLOADQUERY,
  2385. NULL, 0, NULL, 0,
  2386. &irpcount, NULL ) ) {
  2387. Abort( hWnd, _T("Couldn't access device driver") );
  2388. return 0;
  2389. }
  2390. if( irpcount ) {
  2391. _stprintf( msgbuf,  _T("The Filemon device driver cannot unloadn")
  2392. _T("at this time due to oustanding requests.nn")
  2393. _T("Do you wish to exit the GUI now?"));
  2394. if( MessageBox( hWnd, msgbuf, APPNAME, MB_ICONSTOP|MB_YESNO ) == IDNO )
  2395. return 0;
  2396. } else {
  2397. if ( ! UnloadDeviceDriver( SYS_NAME ) )  {
  2398. _stprintf( msgbuf, _T("Error unloading "%s""), SYS_NAME );
  2399. MessageBox( hWnd, msgbuf, APPNAME, MB_OK );
  2400. }
  2401. }
  2402. #endif
  2403. CloseHandle( SysHandle );
  2404. SavePositionSettings( hWnd );
  2405. return DefWindowProc( hWnd, message, wParam, lParam );
  2406. case WM_PAINT:
  2407. if( !IsNT && Deleting ) {
  2408. hDC = BeginPaint( hWnd, &Paint );
  2409. EndPaint( hWnd, &Paint );
  2410. return TRUE;
  2411. }
  2412. return DefWindowProc( hWnd, message, wParam, lParam );
  2413. case WM_DESTROY:
  2414. PostQuitMessage(0);
  2415. return 0;
  2416. default:
  2417. // is it a find-string message?
  2418. if (message == findMessageID ){ 
  2419. // get a pointer to the find structure
  2420. findMessageInfo = (LPFINDREPLACE)lParam;
  2421. // If the FR_DIALOGTERM flag is set, invalidate the find window handle
  2422. if( findMessageInfo->Flags & FR_DIALOGTERM) {
  2423. hWndFind = NULL;
  2424. PrevMatch = FALSE;
  2425.     FindFlags = FindTextInfo.Flags & (FR_DOWN|FR_MATCHCASE|FR_WHOLEWORD);
  2426. return 0;
  2427. }
  2428. // if the FR_FINDNEXT flag is set, go do the search
  2429. if( findMessageInfo->Flags & FR_FINDNEXT ) {
  2430. SetCapture(hWndFind);
  2431. hSaveCursor = SetCursor(hHourGlass);
  2432. EnableWindow( hWndFind, FALSE );
  2433. if( FindInListview( hWnd, findMessageInfo ) ) {
  2434. Autoscroll = FALSE;
  2435. CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
  2436. MF_BYCOMMAND|MF_UNCHECKED ); 
  2437. SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, 3 );
  2438. }
  2439. EnableWindow( hWndFind, TRUE );
  2440. ReleaseCapture(); 
  2441. return 0;
  2442. }
  2443. return 0;
  2444. }
  2445. // Default behavior
  2446. return DefWindowProc( hWnd, message, wParam, lParam );
  2447. }
  2448. return 0;
  2449. }
  2450. /****************************************************************************
  2451. *
  2452. *    FUNCTION: InitApplication(HANDLE)
  2453. *
  2454. *    PURPOSE: Initializes window data and registers window class
  2455. *
  2456. ****************************************************************************/
  2457. BOOL InitApplication( HANDLE hInstance )
  2458. {
  2459. WNDCLASS  wc;
  2460. // Fill in window class structure with parameters that describe the
  2461. // main (statistics) window. 
  2462. wc.style = 0;                     
  2463. wc.lpfnWndProc = (WNDPROC)MainWndProc; 
  2464. wc.cbClsExtra = 0;              
  2465. wc.cbWndExtra = 0;              
  2466. wc.hInstance = hInstance;       
  2467. wc.hIcon = LoadIcon( hInstance, _T("APPICON") );
  2468. wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  2469. wc.hbrBackground = (HBRUSH)(COLOR_INACTIVEBORDER + 1); // Default color
  2470. wc.lpszMenuName = _T("LISTMENU");  
  2471. wc.lpszClassName = _T("FileMonClass");
  2472. if ( ! RegisterClass( &wc ) )
  2473. return FALSE;
  2474. wc.lpszMenuName   = NULL;
  2475.   wc.lpfnWndProc    = (WNDPROC) BalloonDialog;
  2476. wc.hbrBackground  = CreateSolidBrush( 0x00E0FFFF );
  2477. wc.lpszClassName  = _T("BALLOON");
  2478. RegisterClass( &wc );
  2479. return TRUE;
  2480. }
  2481. /****************************************************************************
  2482. *
  2483. *    FUNCTION:  InitInstance(HANDLE, int)
  2484. *
  2485. *    PURPOSE:  Saves instance handle and creates main window
  2486. *
  2487. ****************************************************************************/
  2488. HWND InitInstance( HANDLE hInstance, int nCmdShow )
  2489. {
  2490. // get the window position settings from the registry
  2491. GetPositionSettings();
  2492. // create the main window
  2493. hInst = hInstance;
  2494. hWndMain = CreateWindow( _T("FileMonClass"), 
  2495. _T("File Monitor - Systems Internals: http://www.sysinternals.com"), 
  2496. WS_OVERLAPPEDWINDOW,
  2497. PositionInfo.left, PositionInfo.top, 
  2498. PositionInfo.width, PositionInfo.height,
  2499. NULL, NULL, hInstance, NULL );
  2500. // if window could not be created, return "failure" 
  2501. if ( ! hWndMain )
  2502. return NULL;
  2503. // make the window visible; update its client area; and return "success"
  2504. ShowWindow( hWndMain, nCmdShow );
  2505. // maximize it if necessary
  2506. if( PositionInfo.maximized ) {
  2507. ShowWindow( hWndMain, SW_SHOWMAXIMIZED );
  2508. }
  2509. UpdateWindow( hWndMain ); 
  2510. if( OnTop ) {
  2511. SetWindowPos( hWndMain, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE );
  2512. CheckMenuItem( GetMenu(hWndMain), IDM_ONTOP,
  2513. MF_BYCOMMAND|(OnTop?MF_CHECKED:MF_UNCHECKED) );
  2514. }
  2515. return hWndMain;      
  2516. }
  2517. /****************************************************************************
  2518. *
  2519. * FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
  2520. *
  2521. * PURPOSE: calls initialization function, processes message loop
  2522. *
  2523. ****************************************************************************/
  2524. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  2525. LPSTR lpCmdLine, int nCmdShow )
  2526. {
  2527. MSG  msg;      
  2528. HWND hWnd;
  2529. HACCEL hAccel;
  2530.   DWORD NTVersion;
  2531.         
  2532. if ( ! InitApplication( hInstance ) )
  2533. return FALSE;   
  2534. // get NT version
  2535. NTVersion = GetVersion();
  2536. if( NTVersion >= 0x80000000 ) {
  2537. IsNT = FALSE;
  2538. } else {
  2539. IsNT = TRUE;
  2540. }
  2541. // initializations that apply to a specific instance 
  2542. if ( (hWnd = InitInstance( hInstance, nCmdShow )) == NULL )
  2543. return FALSE;
  2544. // load accelerators
  2545. hAccel = LoadAccelerators( hInstance, _T("ACCELERATORS"));
  2546. // register for the find window message
  2547.     findMessageID = RegisterWindowMessage( FINDMSGSTRING );
  2548. // acquire and dispatch messages until a WM_QUIT message is received.
  2549. while ( GetMessage( &msg, NULL, 0, 0 ) )  {
  2550. if( !TranslateAccelerator( hWnd, hAccel, &msg ) &&
  2551. (!hWndFind || !IsWindow(hWndFind) || !IsDialogMessage( hWndFind, &msg ))) {
  2552. TranslateMessage( &msg );
  2553. DispatchMessage( &msg ); 
  2554. }
  2555. }
  2556. return msg.wParam;  
  2557. }