Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

886 lines
21 KiB

  1. #include "pwalker.h"
  2. #pragma hdrstop
  3. #include "resource.h"
  4. #define DLG_MSG(hwnd, message, fn) \
  5. case (message): return (BOOL) HANDLE_##message((hwnd), (wParam), (lParam), (fn))
  6. #define WPPS WritePrivateProfileString
  7. #define GPPI GetPrivateProfileInt
  8. #define Clear(x) memset(&x, 0, sizeof(x))
  9. #define DUMP_WINDOW_EXTRA 16
  10. #define GET_DUMP_PROCESS(hwnd) (HANDLE) GetWindowLong(hwnd, 0)
  11. #define GET_DUMP_START(hwnd) GetWindowLong(hwnd, 4)
  12. #define GET_DUMP_END(hwnd) GetWindowLong(hwnd, 8)
  13. #define GET_DUMP_OFFSET(hwnd) GetWindowLong(hwnd, 12)
  14. #define GET_DUMP_CY(hwnd) GetWindowLong(hwnd, 16)
  15. #define SET_DUMP_PROCESS(hwnd, x) SetWindowLong(hwnd, 0, (DWORD) x)
  16. #define SET_DUMP_START(hwnd, x) SetWindowLong(hwnd, 4, x)
  17. #define SET_DUMP_END(hwnd, x) SetWindowLong(hwnd, 8, x)
  18. #define SET_DUMP_OFFSET(hwnd, x) SetWindowLong(hwnd, 12, x)
  19. #define SET_DUMP_CY(hwnd, x) SetWindowLong(hwnd, 16, x)
  20. #define IDC_STATUS 8888
  21. // Type definitions for pointers to call tool help functions.
  22. typedef BOOL (WINAPI *MODULEWALK)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
  23. typedef BOOL (WINAPI *THREADWALK)(HANDLE hSnapshot, LPTHREADENTRY32 lpte);
  24. typedef BOOL (WINAPI *PROCESSWALK)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
  25. typedef HANDLE (WINAPI *CREATESNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID);
  26. //
  27. // global variables
  28. //
  29. static CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
  30. static MODULEWALK pModule32First = NULL;
  31. static MODULEWALK pModule32Next = NULL;
  32. static PROCESSWALK pProcess32First = NULL;
  33. static PROCESSWALK pProcess32Next = NULL;
  34. static THREADWALK pThread32First = NULL;
  35. static THREADWALK pThread32Next = NULL;
  36. static HINSTANCE ghInstance = NULL;
  37. static HWND ghwndProcesses = NULL;
  38. static HWND ghwndMemory = NULL;
  39. static HWND ghwndStatus = NULL;
  40. static HCURSOR ghWait = NULL;
  41. static BOOL gfToolhelp = FALSE;
  42. static HANDLE ghSnapshot = NULL;
  43. static HANDLE ghTargetProcess = NULL;
  44. static HWND ghwndDump = NULL;
  45. static UINT um_dump = 0;
  46. static DWORD gcyLine = 0;
  47. static char gszIniFile[] = "pwalker.ini";
  48. static char gszPreferences[] = "Preferences";
  49. static char gszDialogX[] = "X";
  50. static char gszDialogY[] = "Y";
  51. static char gszDumpWindowClass[] = "Dump Window";
  52. static char gszDumpX[] = "Dump X";
  53. static char gszDumpY[] = "Dump Y";
  54. static char gszDumpCX[] = "DumpCX";
  55. static char gszDumpCY[] = "DumpCY";
  56. //
  57. // forward functions declarations
  58. //
  59. BOOL CALLBACK main_dlgproc( HWND, UINT, WPARAM, LPARAM );
  60. void main_OnCommand( HWND, UINT, HWND, UINT );
  61. LONG main_OnNotify( HWND, int, LPNMHDR );
  62. BOOL main_OnInitDialog( HWND, HWND, LPARAM );
  63. void main_OnClose( HWND );
  64. void main_OnDestroy( HWND );
  65. BOOL InitToolhelp32 ( void );
  66. void WalkProcesses( void );
  67. void WalkProcess( void );
  68. void DumpProcessMemory( void );
  69. LRESULT CALLBACK dump_wndproc( HWND, UINT, WPARAM, LPARAM );
  70. int ListView_GetFocusItem( HWND );
  71. DWORD ListView_GetItemData( HWND, int );
  72. void __cdecl PrintStatus(LPCSTR, ...);
  73. void SaveSnapshot( HWND );
  74. //
  75. // main
  76. //
  77. int PASCAL
  78. WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
  79. {
  80. //
  81. // init common controls and toolhelp
  82. //
  83. InitCommonControls( );
  84. gfToolhelp = InitToolhelp32( );
  85. um_dump = RegisterWindowMessage( "Dump!" );
  86. ghWait = LoadCursor( NULL, IDC_WAIT );
  87. {
  88. TEXTMETRIC tm;
  89. HDC hDC;
  90. HFONT hFont;
  91. hDC = CreateCompatibleDC( NULL );
  92. hFont = SelectFont( hDC, GetStockFont( ANSI_FIXED_FONT ) );
  93. GetTextMetrics( hDC, &tm );
  94. SelectFont( hDC, hFont );
  95. DeleteDC( hDC );
  96. gcyLine = tm.tmHeight;
  97. }
  98. //
  99. // store instance handle (we'll need it later)
  100. //
  101. ghInstance = hInstance;
  102. //
  103. // create main window (all initializations are inside WM_INITDIALOG)
  104. //
  105. DialogBox( hInstance, MAKEINTATOM( IDD_MAIN ), NULL, main_dlgproc );
  106. return 0;
  107. }
  108. //
  109. // main dialog window proc
  110. //
  111. BOOL CALLBACK
  112. main_dlgproc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
  113. {
  114. switch( message ) {
  115. DLG_MSG( hwnd, WM_COMMAND, main_OnCommand );
  116. DLG_MSG( hwnd, WM_NOTIFY, main_OnNotify );
  117. DLG_MSG( hwnd, WM_INITDIALOG, main_OnInitDialog );
  118. DLG_MSG( hwnd, WM_CLOSE, main_OnClose );
  119. DLG_MSG( hwnd, WM_DESTROY, main_OnDestroy );
  120. }
  121. return FALSE;
  122. }
  123. void
  124. main_OnCommand( HWND hwnd, UINT id, HWND hCtl, UINT code)
  125. {
  126. switch( id ) {
  127. case IDOK:
  128. if( GetFocus( ) == ghwndProcesses ) {
  129. WalkProcess( );
  130. break;
  131. }
  132. if( GetFocus( ) == ghwndMemory ) {
  133. DumpProcessMemory( );
  134. }
  135. break;
  136. case IDM_UPDATE:
  137. WalkProcesses( );
  138. break;
  139. case IDM_SAVE:
  140. SaveSnapshot( hwnd );
  141. break;
  142. case IDM_EXIT:
  143. PostMessage( hwnd, WM_CLOSE, 0, 0 );
  144. break;
  145. }
  146. }
  147. //
  148. //
  149. //
  150. LONG
  151. main_OnNotify( HWND hwnd, int id, LPNMHDR lpHdr )
  152. {
  153. if( lpHdr->idFrom == IDC_PROCESSES && lpHdr->code == NM_CLICK ) {
  154. WalkProcess( );
  155. }
  156. if( lpHdr->idFrom == IDC_MEMORY && lpHdr->code == NM_CLICK ) {
  157. DumpProcessMemory( );
  158. }
  159. return 0;
  160. }
  161. //
  162. // initialize dialog box
  163. //
  164. BOOL
  165. main_OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam )
  166. {
  167. HICON hIcon;
  168. RECT R, r, rStatus;
  169. int x, y, cx, cy;
  170. LV_COLUMN co;
  171. //
  172. //
  173. //
  174. hIcon = LoadIcon( ghInstance, MAKEINTATOM( IDI_MAIN ) );
  175. SendMessage( hwnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon );
  176. // Create the status window.
  177. ghwndStatus = CreateStatusWindow(
  178. WS_VISIBLE | WS_CHILD | WS_BORDER,
  179. " ", hwnd, IDC_STATUS );
  180. SendMessage( ghwndStatus, SB_SIMPLE, TRUE, 0 );
  181. GetWindowRect(ghwndStatus, &rStatus );
  182. //
  183. // position dialog
  184. //
  185. GetWindowRect( hwnd, &r );
  186. GetWindowRect( GetDesktopWindow( ), &R );
  187. x = R.left + ((R.right - R.left) - (r.right - r.left)) / 2;
  188. y = R.top + ((R.bottom - R.top) - (r.bottom - r.top)) / 2;
  189. x = GetPrivateProfileInt( gszPreferences, gszDialogX, x, gszIniFile);
  190. y = GetPrivateProfileInt( gszPreferences, gszDialogY, y, gszIniFile);
  191. cx = r.right - r.left;
  192. cy = r.bottom - r.top + (rStatus.bottom - rStatus.top);
  193. SetWindowPos( hwnd, NULL, x, y, cx, cy, SWP_NOZORDER);
  194. x = rStatus.left;
  195. y = rStatus.top + (rStatus.bottom - rStatus.top);
  196. SetWindowPos( ghwndStatus, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
  197. //
  198. // create columns in "Processes" list control
  199. //
  200. ghwndProcesses = GetDlgItem( hwnd, IDC_PROCESSES );
  201. SetWindowFont( ghwndProcesses, GetStockFont( ANSI_FIXED_FONT ), FALSE );
  202. Clear( co );
  203. co.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  204. co.fmt = LVCFMT_LEFT;
  205. co.cx = 200;
  206. co.pszText = "Process";
  207. ListView_InsertColumn( ghwndProcesses, 0, &co );
  208. co.pszText = "Total Committed";
  209. co.cx = 200;
  210. ListView_InsertColumn( ghwndProcesses, 1, &co );
  211. ghwndMemory = GetDlgItem( hwnd, IDC_MEMORY );
  212. SetWindowFont( ghwndMemory, GetStockFont( ANSI_FIXED_FONT ), FALSE );
  213. co.cx = 100;
  214. co.fmt = LVCFMT_RIGHT;
  215. co.pszText = "Address";
  216. ListView_InsertColumn( ghwndMemory, 0, &co );
  217. co.pszText = "AllocBase";
  218. ListView_InsertColumn( ghwndMemory, 1, &co );
  219. co.pszText = "Size";
  220. ListView_InsertColumn( ghwndMemory, 2, &co );
  221. co.cx = 120;
  222. co.fmt = LVCFMT_LEFT;
  223. co.pszText = "Protection";
  224. ListView_InsertColumn( ghwndMemory, 3, &co );
  225. co.cx = 100;
  226. co.pszText = "Type";
  227. ListView_InsertColumn( ghwndMemory, 4, &co );
  228. FORWARD_WM_COMMAND( hwnd, IDM_UPDATE, 0, 0, PostMessage );
  229. SetFocus( ghwndProcesses );
  230. return TRUE;
  231. }
  232. //
  233. // just end dialog
  234. //
  235. void
  236. main_OnClose( HWND hwnd )
  237. {
  238. EndDialog( hwnd, IDOK );
  239. }
  240. //
  241. // perform any dialog cleanup
  242. //
  243. void
  244. main_OnDestroy( HWND hwnd )
  245. {
  246. char buf[12];
  247. RECT r;
  248. if( IsWindow( ghwndDump ) ) {
  249. DestroyWindow( ghwndDump );
  250. }
  251. if( gfToolhelp && ghTargetProcess ) {
  252. CloseHandle( ghTargetProcess );
  253. }
  254. if( gfToolhelp && ghSnapshot ) {
  255. CloseHandle( ghSnapshot );
  256. }
  257. //
  258. // save dialog position
  259. //
  260. GetWindowRect( hwnd, &r );
  261. wsprintf( buf, "%d", r.left );
  262. WPPS( gszPreferences, gszDialogX, buf, gszIniFile );
  263. wsprintf( buf, "%d", r.top );
  264. WPPS( gszPreferences, gszDialogY, buf, gszIniFile );
  265. }
  266. // Function that initializes tool help functions.
  267. BOOL InitToolhelp32 (void)
  268. {
  269. BOOL bRet = FALSE;
  270. HMODULE hKernel = NULL;
  271. // Obtain the module handle of the kernel to retrieve addresses of
  272. // the tool helper functions.
  273. hKernel = GetModuleHandle("KERNEL32.DLL");
  274. if (hKernel) {
  275. pCreateToolhelp32Snapshot =
  276. (CREATESNAPSHOT)GetProcAddress(hKernel,
  277. "CreateToolhelp32Snapshot");
  278. pModule32First = (MODULEWALK)GetProcAddress(hKernel,
  279. "Module32First");
  280. pModule32Next = (MODULEWALK)GetProcAddress(hKernel,
  281. "Module32Next");
  282. pProcess32First = (PROCESSWALK)GetProcAddress(hKernel,
  283. "Process32First");
  284. pProcess32Next = (PROCESSWALK)GetProcAddress(hKernel,
  285. "Process32Next");
  286. pThread32First = (THREADWALK)GetProcAddress(hKernel,
  287. "Thread32First");
  288. pThread32Next = (THREADWALK)GetProcAddress(hKernel,
  289. "Thread32Next");
  290. // All addresses must be non-NULL to be successful.
  291. // If one of these addresses is NULL, one of
  292. // the needed lists cannot be walked.
  293. bRet = pModule32First && pModule32Next && pProcess32First &&
  294. pProcess32Next && pThread32First && pThread32Next &&
  295. pCreateToolhelp32Snapshot;
  296. } else {
  297. bRet = FALSE; // could not get the module handle of kernel
  298. }
  299. return bRet;
  300. }
  301. void
  302. WalkProcesses( void )
  303. {
  304. LV_ITEM li;
  305. int item = 0;
  306. DWORD dwTasks;
  307. PROCESSENTRY32 pe;
  308. HLOCAL hTaskList;
  309. char *pszExename;
  310. HCURSOR hCursor = SetCursor( ghWait );
  311. Clear( pe );
  312. pe.dwSize = sizeof( pe );
  313. Clear( li );
  314. li.mask = LVIF_TEXT | LVIF_PARAM;
  315. ListView_DeleteAllItems( ghwndProcesses );
  316. ListView_DeleteAllItems( ghwndMemory );
  317. if( gfToolhelp ) {
  318. if( ghSnapshot ) {
  319. CloseHandle( ghSnapshot );
  320. }
  321. ghSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 );
  322. if( !ghSnapshot ) {
  323. goto done;
  324. }
  325. if( pProcess32First( ghSnapshot, &pe ) ) {
  326. do {
  327. pszExename = strrchr( pe.szExeFile, '\\' );
  328. if( pszExename ) {
  329. pszExename++;
  330. }else{
  331. pszExename = pe.szExeFile;
  332. }
  333. li.pszText = pszExename;
  334. li.lParam = pe.th32ProcessID;
  335. ListView_InsertItem( ghwndProcesses, &li );
  336. li.iItem = item++;
  337. } while( pProcess32Next( ghSnapshot, &pe ) );
  338. }
  339. }else{
  340. hTaskList = GetLocalTaskListNt( &dwTasks );
  341. for( li.iItem = 0; li.iItem < (int) dwTasks; li.iItem++ ) {
  342. GetLocalTaskNameNt( hTaskList, li.iItem,
  343. pe.szExeFile, sizeof( pe.szExeFile ) );
  344. pszExename = strrchr( pe.szExeFile, '\\' );
  345. if( pszExename ) {
  346. pszExename++;
  347. }else{
  348. pszExename = pe.szExeFile;
  349. }
  350. li.pszText = pszExename;
  351. li.lParam = GetLocalTaskProcessIdNt( hTaskList, li.iItem);
  352. ListView_InsertItem( ghwndProcesses, &li );
  353. }
  354. FreeLocalTaskListNt( hTaskList );
  355. }
  356. done:
  357. SetFocus( ghwndProcesses );
  358. SetCursor( hCursor );
  359. return ;
  360. }
  361. void
  362. WalkProcess( void )
  363. {
  364. MEMORY_BASIC_INFORMATION bi;
  365. VOID * lpAddress;
  366. LV_ITEM li;
  367. int item;
  368. char buf[32];
  369. DWORD dwProcess;
  370. HCURSOR hCursor = SetCursor( ghWait );
  371. item = ListView_GetFocusItem( ghwndProcesses );
  372. if( ghTargetProcess && gfToolhelp ) {
  373. CloseHandle( ghTargetProcess );
  374. }
  375. dwProcess = ListView_GetItemData( ghwndProcesses, item );
  376. __try {
  377. ghTargetProcess = OpenProcess(
  378. PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
  379. FALSE, dwProcess );
  380. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  381. PrintStatus( "Failure to open process %x (%d)",
  382. dwProcess, GetLastError() );
  383. }
  384. SetWindowRedraw( ghwndMemory, FALSE );
  385. Clear( bi );
  386. Clear( li );
  387. lpAddress = NULL;
  388. ListView_DeleteAllItems( ghwndMemory );
  389. __try {
  390. while( VirtualQueryEx( ghTargetProcess, lpAddress, &bi, sizeof( bi ) ) ) {
  391. lpAddress = (PVOID)((DWORD) lpAddress + bi.RegionSize );
  392. if( bi.State != MEM_COMMIT ) {
  393. continue;
  394. }
  395. li.iSubItem = 0;
  396. li.mask = LVIF_TEXT | LVIF_PARAM;
  397. wsprintf( buf, "%08x", bi.BaseAddress );
  398. li.pszText = buf;
  399. li.lParam = (DWORD) bi.BaseAddress;
  400. ListView_InsertItem( ghwndMemory, &li );
  401. li.iSubItem = 1;
  402. li.mask = LVIF_TEXT;
  403. wsprintf( buf, "%08x", bi.AllocationBase );
  404. li.pszText = buf;
  405. ListView_SetItem( ghwndMemory, &li );
  406. li.iSubItem = 2;
  407. wsprintf( buf, "%d", bi.RegionSize );
  408. li.pszText = buf;
  409. ListView_SetItem( ghwndMemory, &li );
  410. li.iSubItem = 3;
  411. buf[0] = '\0';
  412. if( (bi.Protect & PAGE_NOACCESS) == PAGE_NOACCESS ) {
  413. strcat( buf, "NOACCESS " );
  414. }
  415. if( (bi.Protect & PAGE_READONLY) == PAGE_READONLY ) {
  416. strcat( buf, "RO " );
  417. }
  418. if( (bi.Protect & PAGE_READWRITE) == PAGE_READWRITE ) {
  419. strcat( buf, "RW " );
  420. }
  421. if( (bi.Protect & PAGE_WRITECOPY) == PAGE_WRITECOPY ) {
  422. strcat( buf, "WC " );
  423. }
  424. if( (bi.Protect & PAGE_EXECUTE) == PAGE_EXECUTE ) {
  425. strcat( buf, "X " );
  426. }
  427. if( (bi.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ ) {
  428. strcat( buf, "XR " );
  429. }
  430. if( (bi.Protect & PAGE_EXECUTE_READWRITE) ==
  431. PAGE_EXECUTE_READWRITE ) {
  432. strcat( buf, "XRW " );
  433. }
  434. if( (bi.Protect & PAGE_EXECUTE_WRITECOPY) ==
  435. PAGE_EXECUTE_WRITECOPY ) {
  436. strcat( buf, "XWC " );
  437. }
  438. if( (bi.Protect & PAGE_GUARD) == PAGE_GUARD ) {
  439. strcat( buf, "Guard " );
  440. }
  441. if( (bi.Protect & PAGE_NOCACHE) == PAGE_NOCACHE ) {
  442. strcat( buf, "Nc " );
  443. }
  444. li.pszText = buf;
  445. ListView_SetItem( ghwndMemory, &li );
  446. li.iSubItem = 4;
  447. switch( bi.Type ) {
  448. case MEM_IMAGE:
  449. li.pszText = "Image";
  450. break;
  451. case MEM_MAPPED:
  452. li.pszText = "Mapped";
  453. break;
  454. case MEM_PRIVATE:
  455. li.pszText = "Private";
  456. break;
  457. default:
  458. li.pszText = "Bogus";
  459. break;
  460. }
  461. ListView_SetItem( ghwndMemory, &li );
  462. li.iItem++;
  463. }
  464. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  465. PrintStatus( "Failure in VirtualQueryEx (%d)", GetLastError() );
  466. }
  467. SetWindowRedraw( ghwndMemory, TRUE );
  468. InvalidateRect( ghwndMemory, NULL, TRUE );
  469. UpdateWindow( ghwndMemory );
  470. SetCursor( hCursor );
  471. }
  472. //
  473. //
  474. //
  475. void
  476. DumpProcessMemory( )
  477. {
  478. WNDCLASS wc;
  479. int x,y,cx,cy;
  480. int item;
  481. DWORD dwAddress;
  482. HCURSOR hCursor = SetCursor( ghWait );
  483. item = ListView_GetFocusItem( ghwndMemory );
  484. dwAddress = ListView_GetItemData( ghwndMemory, item );
  485. if( !GetClassInfo( ghInstance, gszDumpWindowClass, &wc ) ) {
  486. Clear( wc );
  487. wc.hInstance = ghInstance;
  488. wc.lpfnWndProc = dump_wndproc;
  489. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  490. wc.hIcon = LoadIcon( ghInstance, MAKEINTATOM( IDI_DUMP ) );
  491. wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  492. wc.cbWndExtra = DUMP_WINDOW_EXTRA;
  493. wc.lpszClassName = gszDumpWindowClass;
  494. if(!RegisterClass( &wc ) ) {
  495. PrintStatus( "Failure to register dump window class" );
  496. goto done;
  497. }
  498. }
  499. if( !IsWindow( ghwndDump ) ) {
  500. x = y = cx = cy = CW_USEDEFAULT;
  501. x = GPPI( gszPreferences, gszDumpX, x, gszIniFile );
  502. y = GPPI( gszPreferences, gszDumpY, y, gszIniFile );
  503. cx = GPPI( gszPreferences, gszDumpCX, cx, gszIniFile );
  504. cy = GPPI( gszPreferences, gszDumpCY, cy, gszIniFile );
  505. ghwndDump = CreateWindow( gszDumpWindowClass, "",
  506. WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  507. x, y, cx, cy, NULL, NULL, ghInstance, NULL );
  508. if( ghwndDump ) {
  509. SendMessage( ghwndDump, um_dump,
  510. (WPARAM) ghTargetProcess, (LPARAM) dwAddress );
  511. ShowWindow( ghwndDump, SW_SHOW );
  512. UpdateWindow( ghwndDump );
  513. }else{
  514. PrintStatus( "Error: %d", GetLastError() );
  515. }
  516. }else{
  517. SendMessage( ghwndDump, um_dump,
  518. (WPARAM) ghTargetProcess, (LPARAM) dwAddress );
  519. }
  520. done:
  521. SetCursor( hCursor );
  522. }
  523. BOOL
  524. dump_OnCreate( HWND hwnd, LPCREATESTRUCT lpCreate )
  525. {
  526. SetScrollRange( hwnd, SB_VERT, 0, 100, FALSE );
  527. SetScrollPos( hwnd, SB_VERT, 0, TRUE );
  528. return TRUE;
  529. }
  530. void
  531. dump_OnDestroy( HWND hwnd )
  532. {
  533. RECT r;
  534. char buf[32];
  535. GetWindowRect( hwnd, &r );
  536. wsprintf( buf, "%d", r.left );
  537. WPPS( gszPreferences, gszDumpX, buf, gszIniFile );
  538. wsprintf( buf, "%d", r.top );
  539. WPPS( gszPreferences, gszDumpY, buf, gszIniFile );
  540. wsprintf( buf, "%d", r.right - r.left );
  541. WPPS( gszPreferences, gszDumpCX, buf, gszIniFile );
  542. wsprintf( buf, "%d", r.bottom - r.top );
  543. WPPS( gszPreferences, gszDumpCY, buf, gszIniFile );
  544. }
  545. void
  546. dump_OnPaint( HWND hwnd )
  547. {
  548. PAINTSTRUCT ps;
  549. HFONT hFont;
  550. RECT r;
  551. int line, byte, nLines;
  552. char buf[1024];
  553. BYTE mem[18];
  554. char *p = buf;
  555. DWORD dwOffset = GET_DUMP_OFFSET( hwnd );
  556. DWORD dwEnd = GET_DUMP_END( hwnd );
  557. DWORD dwRead;
  558. HANDLE hProcess = GET_DUMP_PROCESS( hwnd );
  559. BeginPaint( hwnd, &ps );
  560. hFont = SelectFont( ps.hdc, GetStockObject( ANSI_FIXED_FONT ) );
  561. GetClientRect( hwnd, &r );
  562. nLines = (r.bottom - r.top) / gcyLine;
  563. for( line = 0; line < nLines; line++ ) {
  564. Clear( mem );
  565. __try {
  566. ReadProcessMemory( hProcess, (PVOID) dwOffset, mem, 16, &dwRead );
  567. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  568. strcpy( mem, "????????????????");
  569. }
  570. wsprintf(buf, "%08x ", dwOffset);
  571. p = buf + 9;
  572. for(byte = 0; byte < 16; byte++ ) {
  573. wsprintf( p, "%02x ", mem[byte] );
  574. p += (byte == 7) ? 4 : 3;
  575. }
  576. for( byte = 0; byte < 16; byte++ ) {
  577. if( mem[byte] >= ' ' ) {
  578. p[byte] = mem[byte];
  579. }else{
  580. p[byte] = ' ';
  581. }
  582. }
  583. p[16] = '\0';
  584. TextOut( ps.hdc, 0, line * gcyLine, buf, strlen( buf ) );
  585. dwOffset += 16;
  586. if( dwOffset > dwEnd) {
  587. break;
  588. }
  589. }
  590. SelectFont( ps.hdc, hFont );
  591. EndPaint( hwnd, &ps );
  592. }
  593. void
  594. dump_OnVScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos)
  595. {
  596. DWORD dwOffset = GET_DUMP_OFFSET( hwnd );
  597. DWORD dwStart = GET_DUMP_START( hwnd );
  598. DWORD dwEnd = GET_DUMP_END( hwnd );
  599. RECT r, ri;
  600. DWORD cyLines, Line, maxLine, newLine;
  601. GetClientRect( hwnd, &r );
  602. r.bottom -= (r.bottom - r.top) % gcyLine;
  603. cyLines = (r.bottom - r.top) / gcyLine;
  604. Line = (dwOffset - dwStart ) / 16;
  605. maxLine = ( dwEnd - dwStart ) / 16 - cyLines;
  606. switch( code ) {
  607. case SB_TOP:
  608. newLine = 0;
  609. break;
  610. case SB_BOTTOM:
  611. newLine = maxLine;
  612. break;
  613. case SB_PAGEUP:
  614. newLine = max( Line - cyLines + 1, 0 );
  615. break;
  616. case SB_PAGEDOWN:
  617. newLine = min( Line + cyLines - 1, maxLine );
  618. break;
  619. case SB_LINEUP:
  620. newLine = max( 0, Line - 1 );
  621. break;
  622. case SB_LINEDOWN:
  623. newLine = min( Line + 1, maxLine );
  624. break;
  625. case SB_THUMBPOSITION:
  626. case SB_THUMBTRACK:
  627. newLine = MulDiv( pos, maxLine, 100 );
  628. break;
  629. default:
  630. goto done;
  631. }
  632. SET_DUMP_OFFSET( hwnd, dwStart + newLine * 16 );
  633. pos = MulDiv(newLine, 100, maxLine );
  634. SetScrollPos( hwnd, SB_VERT, pos, TRUE );
  635. ScrollWindowEx( hwnd, 0, ( Line - newLine ) * gcyLine,
  636. NULL, &r, NULL, &ri, SW_INVALIDATE );
  637. InvalidateRect( hwnd, &ri, TRUE );
  638. done:
  639. UpdateWindow( hwnd );
  640. }
  641. void
  642. dump_OnSize( HWND hwnd, int state, int cx, int cy )
  643. {
  644. InvalidateRect( hwnd, NULL, TRUE );
  645. UpdateWindow( hwnd );
  646. }
  647. void
  648. dump_OnKey(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
  649. {
  650. switch( vk ) {
  651. case VK_DOWN:
  652. FORWARD_WM_VSCROLL( hwnd, NULL, SB_LINEDOWN, 0, PostMessage );
  653. break;
  654. case VK_UP:
  655. FORWARD_WM_VSCROLL( hwnd, NULL, SB_LINEUP, 0, PostMessage );
  656. break;
  657. case VK_PRIOR:
  658. FORWARD_WM_VSCROLL( hwnd, NULL, SB_PAGEUP, 0, PostMessage );
  659. break;
  660. case VK_NEXT:
  661. case ' ':
  662. FORWARD_WM_VSCROLL( hwnd, NULL, SB_PAGEDOWN, 0, PostMessage );
  663. break;
  664. case VK_HOME:
  665. FORWARD_WM_VSCROLL( hwnd, NULL, SB_TOP, 0, PostMessage );
  666. break;
  667. case VK_END:
  668. FORWARD_WM_VSCROLL( hwnd, NULL, SB_BOTTOM, 0, PostMessage );
  669. break;
  670. case VK_ESCAPE:
  671. PostMessage( hwnd, WM_CLOSE, 0, 0 );
  672. break;
  673. }
  674. }
  675. //
  676. // dump window proc
  677. //
  678. LRESULT CALLBACK
  679. dump_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
  680. {
  681. switch( message ) {
  682. HANDLE_MSG( hwnd, WM_CREATE, dump_OnCreate );
  683. HANDLE_MSG( hwnd, WM_DESTROY, dump_OnDestroy );
  684. HANDLE_MSG( hwnd, WM_PAINT, dump_OnPaint );
  685. HANDLE_MSG( hwnd, WM_VSCROLL, dump_OnVScroll );
  686. HANDLE_MSG( hwnd, WM_SIZE, dump_OnSize );
  687. HANDLE_MSG( hwnd, WM_KEYDOWN, dump_OnKey );
  688. default:
  689. if( message == um_dump ) {
  690. char buf[80];
  691. MEMORY_BASIC_INFORMATION bi;
  692. HANDLE hProcess = (HANDLE) wParam;
  693. DWORD dwOffset = (DWORD) lParam;
  694. wsprintf( buf, "Process %x at %x", wParam, lParam );
  695. SetWindowText( hwnd, buf );
  696. SetScrollPos( hwnd, SB_VERT, 0, TRUE );
  697. InvalidateRect( hwnd, NULL, TRUE );
  698. Clear( bi );
  699. if(! VirtualQueryEx( hProcess, (PVOID) dwOffset,
  700. &bi, sizeof( bi ) ) ) {
  701. PrintStatus( "Error: %d", GetLastError() );
  702. }
  703. SET_DUMP_PROCESS( hwnd, hProcess );
  704. SET_DUMP_START( hwnd, (DWORD) bi.BaseAddress );
  705. SET_DUMP_END( hwnd, (DWORD) bi.BaseAddress + bi.RegionSize );
  706. SET_DUMP_OFFSET( hwnd, (DWORD) bi.BaseAddress );
  707. }
  708. }
  709. return DefWindowProc( hwnd, message, wParam, lParam );
  710. }
  711. //
  712. // returns the number of the item which has focus or -1
  713. //
  714. int ListView_GetFocusItem( HWND hwnd )
  715. {
  716. int cItems = ListView_GetItemCount( hwnd );
  717. int item;
  718. for( item = 0; item < cItems; item++ ) {
  719. if( ListView_GetItemState( hwnd, item, LVIS_FOCUSED ) ) {
  720. return item;
  721. }
  722. }
  723. return -1;
  724. }
  725. //
  726. // returns .lParam of the specified item or -1
  727. //
  728. DWORD ListView_GetItemData( HWND hwnd, int item)
  729. {
  730. LV_ITEM li;
  731. if( item != -1 ) {
  732. Clear( li );
  733. li.mask = LVIF_PARAM;
  734. li.iItem = item;
  735. if( ListView_GetItem( hwnd, &li ) ) {
  736. return li.lParam;
  737. }
  738. }
  739. return (DWORD) -1;
  740. }
  741. //
  742. // formats message to status bar
  743. //
  744. void __cdecl
  745. PrintStatus(LPCSTR fmt, ...)
  746. {
  747. char buf[4096];
  748. va_list marker;
  749. va_start( marker, fmt );
  750. wvsprintf( buf, fmt, marker );
  751. va_end( marker );
  752. SendMessage( ghwndStatus, SB_SETTEXT, 0, (LPARAM) buf );
  753. }
  754. //
  755. //
  756. //
  757. void SaveSnapshot( HWND hwnd )
  758. {
  759. }