Leaked source code of windows server 2003
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.

1543 lines
40 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Wperf.c
  5. Abstract:
  6. Win32 application to display performance statictics.
  7. Author:
  8. Ken Reneris hacked into pperf.exe
  9. original code from Mark Enstrom
  10. Environment:
  11. Win32
  12. --*/
  13. //
  14. // set variable to define global variables
  15. //
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <windows.h>
  20. #include <errno.h>
  21. #include <malloc.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include "pperf.h"
  25. #include "..\pstat.h"
  26. //
  27. // global handles
  28. //
  29. HANDLE hInst;
  30. extern UCHAR Buffer[];
  31. extern HANDLE DriverHandle;
  32. //
  33. // Selected Display Mode (read from wp2.ini), default set here.
  34. //
  35. DISPLAY_ITEM *PerfGraphList;
  36. WINPERF_INFO WinperfInfo;
  37. VOID SnapNull (PDISPLAY_ITEM);
  38. VOID SnapPrivateInfo (PDISPLAY_ITEM);
  39. VOID SnapInterrupts (PDISPLAY_ITEM);
  40. VOID SnapCsTest (PDISPLAY_ITEM);
  41. ULONG DefaultDisplayMode = DISPLAY_MODE_TOTAL;
  42. ULONG UseGlobalMax, LogIt;
  43. ULONG GlobalMax;
  44. PDISPLAY_ITEM Calc1, Calc2;
  45. BOOLEAN LazyOp;
  46. #define MAX_EVENTS 2
  47. struct {
  48. ULONG EventId;
  49. PUCHAR ShortName;
  50. PUCHAR PerfName;
  51. } *Counters;
  52. struct {
  53. ULONG WhichCounter;
  54. ULONG ComboBoxIndex;
  55. PDISPLAY_ITEM pWhichGraph;
  56. BOOLEAN R0;
  57. BOOLEAN R3;
  58. UCHAR na[2];
  59. } ActiveCounters [MAX_EVENTS];
  60. SETEVENT CounterEvents[MAX_EVENTS];
  61. typedef struct {
  62. ULONG IdSel;
  63. PDISPLAY_ITEM WhichGraph;
  64. ULONG State;
  65. VOID (*Fnc)(PDISPLAY_ITEM);
  66. ULONG Param;
  67. PUCHAR Name;
  68. } GENCOUNTER, *PGENCOUNTER;
  69. GENCOUNTER GenCounts[] = {
  70. IDM_SCALE, NULL, 0, NULL, 0, NULL,
  71. IDM_LOGIT, NULL, 0, NULL, 0, NULL,
  72. IDM_SPIN_ACQUIRE, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, SpinLockAcquires), "KRes[0]",
  73. IDM_SPIN_COLL, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, SpinLockCollisions), "KRes[1]",
  74. IDM_SPIN_SPIN, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, SpinLockSpins), "KRes[2]",
  75. IDM_IRQL, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, Irqls), "KRes[3]",
  76. IDM_INT, NULL, 0, SnapInterrupts, 0, "Interrupts",
  77. // IDM_PERCENT, NULL, 0, SnapPercent, 0, "Percent 1-2",
  78. // to track checked state
  79. IDM_P5_R0_0, NULL, 0, NULL, 0, NULL,
  80. IDM_P5_R3_0, NULL, 0, NULL, 0, NULL,
  81. IDM_P5_K_0, NULL, 0, NULL, 0, NULL,
  82. IDM_P5_R0_1, NULL, 0, NULL, 0, NULL,
  83. IDM_P5_R3_1, NULL, 0, NULL, 0, NULL,
  84. IDM_P5_K_1, NULL, 0, NULL, 0, NULL,
  85. // eol
  86. 0, NULL, 0, NULL, 0, NULL
  87. };
  88. VOID
  89. InitComboBox (
  90. HWND hDlg,
  91. ULONG id,
  92. ULONG counter
  93. );
  94. VOID
  95. SetGenPerf (
  96. HWND hDlg,
  97. PGENCOUNTER GenCount
  98. );
  99. int
  100. __cdecl
  101. main(USHORT argc, CHAR **argv)
  102. /*++
  103. Routine Description:
  104. Windows entry point routine
  105. Arguments:
  106. Return Value:
  107. status of operation
  108. Revision History:
  109. 03-21-91 Initial code
  110. --*/
  111. {
  112. //
  113. //
  114. //
  115. HANDLE hInstance = GetModuleHandle(NULL);
  116. HANDLE hPrevInstance = (HANDLE)NULL;
  117. INT nCmdShow = SW_SHOWDEFAULT;
  118. USHORT _argc = argc;
  119. CHAR **_argv = argv;
  120. MSG msg;
  121. HBRUSH BackBrush;
  122. //
  123. // check for other instances of this program
  124. //
  125. BackBrush = CreateSolidBrush(RGB(192,192,192));
  126. if (!InitApplication(hInstance,BackBrush)) {
  127. //DbgPrint("Init Application fails\n");
  128. return (FALSE);
  129. }
  130. //
  131. // Perform initializations that apply to a specific instance
  132. //
  133. if (!InitInstance(hInstance, nCmdShow)){
  134. //DbgPrint("Init Instance fails\n");
  135. return (FALSE);
  136. }
  137. //
  138. // Acquire and dispatch messages until a WM_QUIT message is received.
  139. //
  140. while (GetMessage(&msg, // message structure
  141. (HWND)NULL, // handle of window receiving the message
  142. (UINT)NULL, // lowest message to examine
  143. (UINT)NULL)) // highest message to examine
  144. {
  145. TranslateMessage(&msg); // Translates virtual key codes
  146. DispatchMessage(&msg); // Dispatches message to window
  147. }
  148. DeleteObject(BackBrush);
  149. return (msg.wParam); // Returns the value from PostQuitMessage
  150. }
  151. BOOL
  152. InitApplication(
  153. HANDLE hInstance,
  154. HBRUSH hBackground)
  155. /*++
  156. Routine Description:
  157. Initializes window data and registers window class.
  158. Arguments:
  159. hInstance - current instance
  160. hBackground - background fill brush
  161. Return Value:
  162. status of operation
  163. Revision History:
  164. 02-17-91 Initial code
  165. --*/
  166. {
  167. WNDCLASS wc;
  168. BOOL ReturnStatus;
  169. //
  170. // Fill in window class structure with parameters that describe the
  171. // main window.
  172. //
  173. wc.style = CS_DBLCLKS; // Class style(s).
  174. wc.lpfnWndProc = MainWndProc; // Function to retrieve messages for
  175. // windows of this class.
  176. wc.cbClsExtra = 0; // No per-class extra data.
  177. wc.cbWndExtra = 0; // No per-window extra data.
  178. wc.hInstance = hInstance; // Application that owns the class.
  179. wc.hIcon = LoadIcon(hInstance, //
  180. MAKEINTRESOURCE(WINPERF_ICON)); // Load Winperf icon
  181. wc.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); // Load default cursor
  182. wc.hbrBackground = hBackground;; // Use background passed to routine
  183. wc.lpszMenuName = "pperfMenu"; // Name of menu resource in .RC file.
  184. wc.lpszClassName = "PPerfClass"; // Name used in call to CreateWindow.
  185. ReturnStatus = RegisterClass(&wc);
  186. return(ReturnStatus);
  187. }
  188. BOOL
  189. InitInstance(
  190. HANDLE hInstance,
  191. int nCmdShow
  192. )
  193. /*++
  194. Routine Description:
  195. Save instance handle and create main window. This function performs
  196. initialization tasks that cannot be shared by multiple instances.
  197. Arguments:
  198. hInstance - Current instance identifier.
  199. nCmdShow - Param for first ShowWindow() call.
  200. Return Value:
  201. status of operation
  202. Revision History:
  203. 02-17-91 Initial code
  204. --*/
  205. {
  206. DWORD WindowStyle;
  207. //
  208. // Save the instance handle in a static variable, which will be used in
  209. // many subsequent calls from this application to Windows.
  210. //
  211. hInst = hInstance;
  212. //
  213. // init the window position and size to be in the upper corner of
  214. // the screen, 200x100
  215. //
  216. //
  217. // What I want here is a way to get the WINDOW dimensions
  218. //
  219. WinperfInfo.WindowPositionX = 640 - 250;
  220. WinperfInfo.WindowPositionY = 0;
  221. WinperfInfo.WindowSizeX = 250;
  222. WinperfInfo.WindowSizeY = 100;
  223. //
  224. // read profile data from .ini file
  225. //
  226. // InitProfileData(&WinperfInfo);
  227. WinperfInfo.hMenu = LoadMenu(hInstance,"pperfMenu");
  228. //
  229. // Create a main window for this application instance.
  230. //
  231. WinperfInfo.hWndMain = CreateWindow(
  232. "PPerfClass", // See RegisterClass() call.
  233. "x86 Perf Meter", // Text for window title bar.
  234. WS_OVERLAPPEDWINDOW, // window style
  235. WinperfInfo.WindowPositionX, // Default horizontal position.
  236. WinperfInfo.WindowPositionY, // Default vertical position.
  237. WinperfInfo.WindowSizeX, // Default width.
  238. WinperfInfo.WindowSizeY, // Default height.
  239. (HWND)NULL, // Overlapped windows have no parent.
  240. (HMENU)NULL, // Use the window class menu.
  241. hInstance, // This instance owns this window.
  242. (LPVOID)NULL // Pointer not needed.
  243. );
  244. //
  245. // If window could not be created, return "failure"
  246. //
  247. if (!WinperfInfo.hWndMain) {
  248. return (FALSE);
  249. }
  250. //
  251. // Show menu initially
  252. //
  253. WindowStyle = GetWindowLong(WinperfInfo.hWndMain,GWL_STYLE);
  254. WindowStyle = (WindowStyle & (~STYLE_DISABLE_MENU)) | STYLE_ENABLE_MENU;
  255. SetMenu(WinperfInfo.hWndMain,WinperfInfo.hMenu);
  256. SetWindowLong(WinperfInfo.hWndMain,GWL_STYLE,WindowStyle);
  257. SetWindowPos(WinperfInfo.hWndMain, (HWND)NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
  258. ShowWindow(WinperfInfo.hWndMain,SW_SHOW);
  259. WinperfInfo.DisplayMode=STYLE_ENABLE_MENU;
  260. WinperfInfo.DisplayMenu = TRUE;
  261. //
  262. // Make the window visible; update its client area; and return "success"
  263. //
  264. SetFocus(WinperfInfo.hWndMain);
  265. ShowWindow(WinperfInfo.hWndMain, SW_SHOWNORMAL);
  266. UpdateWindow(WinperfInfo.hWndMain);
  267. return (TRUE);
  268. }
  269. VOID
  270. InitPossibleEventList()
  271. {
  272. UCHAR buffer[400];
  273. ULONG i, Count;
  274. NTSTATUS status;
  275. PEVENTID Event;
  276. IO_STATUS_BLOCK IOSB;
  277. if (! DriverHandle) {
  278. return;
  279. }
  280. //
  281. // Initialize possible counters
  282. //
  283. // determine how many events there are
  284. Event = (PEVENTID) buffer;
  285. Count = 0;
  286. do {
  287. *((PULONG) buffer) = Count;
  288. Count += 1;
  289. status = NtDeviceIoControlFile(
  290. DriverHandle,
  291. (HANDLE) NULL, // event
  292. (PIO_APC_ROUTINE) NULL,
  293. (PVOID) NULL,
  294. &IOSB,
  295. PSTAT_QUERY_EVENTS,
  296. buffer, // input buffer
  297. sizeof (buffer),
  298. NULL, // output buffer
  299. 0
  300. );
  301. } while (NT_SUCCESS(status));
  302. Counters = malloc(sizeof(*Counters) * Count);
  303. if (Counters == NULL) {
  304. printf("Memory allocation failed.\n");
  305. exit(1);
  306. }
  307. Count -= 1;
  308. for (i=0; i < Count; i++) {
  309. *((PULONG) buffer) = i;
  310. NtDeviceIoControlFile(
  311. DriverHandle,
  312. (HANDLE) NULL, // event
  313. (PIO_APC_ROUTINE) NULL,
  314. (PVOID) NULL,
  315. &IOSB,
  316. PSTAT_QUERY_EVENTS,
  317. buffer, // input buffer
  318. sizeof (buffer),
  319. NULL, // output buffer
  320. 0
  321. );
  322. Counters[i].EventId = Event->EventId;
  323. Counters[i].ShortName = _strdup (Event->Buffer);
  324. Counters[i].PerfName = _strdup (Event->Buffer + Event->DescriptionOffset);
  325. }
  326. Counters[i].EventId = 0;
  327. Counters[i].ShortName = NULL;
  328. Counters[i].PerfName = NULL;
  329. }
  330. INT_PTR
  331. CALLBACK
  332. MainWndProc(
  333. HWND hWnd,
  334. UINT message,
  335. WPARAM wParam,
  336. LPARAM lParam
  337. )
  338. /*++
  339. Routine Description:
  340. Process messages.
  341. Arguments:
  342. hWnd - window hande
  343. message - type of message
  344. wParam - additional information
  345. lParam - additional information
  346. Return Value:
  347. status of operation
  348. Revision History:
  349. 02-17-91 Initial code
  350. --*/
  351. {
  352. int DialogResult;
  353. PAINTSTRUCT ps;
  354. PDISPLAY_ITEM pPerf, p;
  355. ULONG l, i, x, y;
  356. HDC hDC;
  357. //
  358. // process each message
  359. //
  360. switch (message) {
  361. //
  362. // create window
  363. //
  364. case WM_CREATE:
  365. {
  366. BOOLEAN Fit;
  367. UINT Index;
  368. hDC = GetDC(hWnd);
  369. //
  370. // make brushes and pens
  371. //
  372. WinperfInfo.hBluePen = CreatePen(PS_SOLID,1,RGB(0,0,128));
  373. WinperfInfo.hDotPen = CreatePen(PS_DOT,1,RGB(0,0,0));
  374. WinperfInfo.hPPen[0] = CreatePen(PS_SOLID,1,RGB(255, 0, 0));
  375. WinperfInfo.hPPen[1] = CreatePen(PS_SOLID,1,RGB( 0, 255, 0));
  376. WinperfInfo.hPPen[2] = CreatePen(PS_SOLID,1,RGB(255, 255, 0));
  377. WinperfInfo.hPPen[3] = CreatePen(PS_SOLID,1,RGB(255, 0, 255));
  378. WinperfInfo.hPPen[4] = CreatePen(PS_SOLID,1,RGB(128, 0, 0));
  379. WinperfInfo.hPPen[5] = CreatePen(PS_SOLID,1,RGB( 0, 128, 0));
  380. WinperfInfo.hPPen[6] = CreatePen(PS_SOLID,1,RGB(128, 128, 0));
  381. WinperfInfo.hPPen[7] = CreatePen(PS_SOLID,1,RGB(128, 0, 128));
  382. WinperfInfo.hPPen[8] = CreatePen(PS_SOLID,1,RGB( 0, 0, 128));
  383. WinperfInfo.hPPen[9] = CreatePen(PS_SOLID,1,RGB( 0, 128, 128));
  384. WinperfInfo.hPPen[10]= CreatePen(PS_SOLID,1,RGB(128, 128, 128));
  385. // the other 20 pens will just reuse these handles
  386. WinperfInfo.hBackground = CreateSolidBrush(RGB(192,192,192));
  387. WinperfInfo.hLightBrush = CreateSolidBrush(RGB(255,255,255));
  388. WinperfInfo.hDarkBrush = CreateSolidBrush(RGB(128,128,128));
  389. WinperfInfo.hRedBrush = CreateSolidBrush(RGB(255,000,000));
  390. WinperfInfo.hGreenBrush = CreateSolidBrush(RGB(000,255,000));
  391. WinperfInfo.hBlueBrush = CreateSolidBrush(RGB(000,000,255));
  392. //
  393. // create thee fonts using NT default font families
  394. //
  395. WinperfInfo.SmallFont = CreateFont(8,
  396. 0,
  397. 0,
  398. 0,
  399. 400,
  400. FALSE,
  401. FALSE,
  402. FALSE,
  403. ANSI_CHARSET,
  404. OUT_DEFAULT_PRECIS,
  405. CLIP_DEFAULT_PRECIS,
  406. DRAFT_QUALITY,
  407. DEFAULT_PITCH,
  408. "Small Fonts");
  409. WinperfInfo.MediumFont = CreateFont(10,
  410. 0,
  411. 0,
  412. 0,
  413. 400,
  414. FALSE,
  415. FALSE,
  416. FALSE,
  417. ANSI_CHARSET,
  418. OUT_DEFAULT_PRECIS,
  419. CLIP_DEFAULT_PRECIS,
  420. DRAFT_QUALITY,
  421. DEFAULT_PITCH,
  422. "Times New Roman");
  423. WinperfInfo.LargeFont = CreateFont(14,
  424. 0,
  425. 0,
  426. 0,
  427. 400,
  428. FALSE,
  429. FALSE,
  430. FALSE,
  431. ANSI_CHARSET,
  432. OUT_DEFAULT_PRECIS,
  433. CLIP_DEFAULT_PRECIS,
  434. DRAFT_QUALITY,
  435. DEFAULT_PITCH,
  436. "Times New Roman");
  437. //
  438. // create a system timer event to call performance gathering routines by.
  439. //
  440. WinperfInfo.TimerId = SetTimer(hWnd,(UINT)TIMER_ID,(UINT)1000 * DELAY_SECONDS,(TIMERPROC)NULL);
  441. //
  442. // init performance routines
  443. //
  444. WinperfInfo.NumberOfProcessors = InitPerfInfo();
  445. // copy pen's for remaining processor breakout
  446. for (i=11; i < WinperfInfo.NumberOfProcessors; i++) {
  447. WinperfInfo.hPPen[i] = WinperfInfo.hPPen[i % 12];
  448. }
  449. if (!WinperfInfo.NumberOfProcessors) {
  450. MessageBox(hWnd,"P5Stat driver not installed","Winperf",MB_OK);
  451. DestroyWindow(hWnd);
  452. }
  453. //
  454. // init display variables
  455. //
  456. RefitWindows (hWnd, hDC);
  457. //
  458. // release the DC handle
  459. //
  460. ReleaseDC(hWnd,hDC);
  461. }
  462. break;
  463. //
  464. // re-size
  465. //
  466. case WM_SIZE:
  467. {
  468. //int i;
  469. RECT ClientRect;
  470. BOOLEAN Fit;
  471. hDC = GetDC(hWnd);
  472. //
  473. // get size of client area
  474. //
  475. GetWindowRect(hWnd,&ClientRect);
  476. WinperfInfo.WindowPositionX = ClientRect.left;
  477. WinperfInfo.WindowPositionY = ClientRect.top;
  478. WinperfInfo.WindowSizeX = ClientRect.right - ClientRect.left;
  479. WinperfInfo.WindowSizeY = ClientRect.bottom - ClientRect.top;
  480. RefitWindows(hWnd, NULL);
  481. }
  482. break;
  483. case WM_MOVE:
  484. {
  485. RECT ClientRect;
  486. hDC = GetDC(hWnd);
  487. //
  488. // get size of cleint area
  489. //
  490. GetWindowRect(hWnd,&ClientRect);
  491. WinperfInfo.WindowPositionX = ClientRect.left;
  492. WinperfInfo.WindowPositionY = ClientRect.top;
  493. WinperfInfo.WindowSizeX = ClientRect.right - ClientRect.left;
  494. WinperfInfo.WindowSizeY = ClientRect.bottom - ClientRect.top;
  495. ReleaseDC(hWnd,hDC);
  496. }
  497. break;
  498. //
  499. // command from application menu
  500. //
  501. case WM_COMMAND:
  502. switch (wParam){
  503. //
  504. // exit window
  505. //
  506. case IDM_EXIT:
  507. DestroyWindow(hWnd);
  508. break;
  509. //
  510. // about command
  511. //
  512. case IDM_SELECT:
  513. DialogResult = DialogBox(hInst, MAKEINTRESOURCE(IDM_SEL_DLG), hWnd, SelectDlgProc);
  514. if (DialogResult == DIALOG_SUCCESS) {
  515. RefitWindows(hWnd, NULL);
  516. }
  517. break;
  518. case IDM_DISPLAY_TOTAL:
  519. SetDefaultDisplayMode (hWnd, DISPLAY_MODE_TOTAL);
  520. break;
  521. case IDM_DISPLAY_BREAKDOWN:
  522. SetDefaultDisplayMode (hWnd, DISPLAY_MODE_BREAKDOWN);
  523. break;
  524. case IDM_DISPLAY_PER_PROCESSOR:
  525. SetDefaultDisplayMode (hWnd, DISPLAY_MODE_PER_PROCESSOR);
  526. break;
  527. case IDM_TOPMOST:
  528. //SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  529. // SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  530. SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0,
  531. SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  532. break;
  533. case IDM_THUNK:
  534. DialogBox(hInst, MAKEINTRESOURCE(IDM_THUNK_DLG), hWnd, ThunkDlgProc);
  535. break;
  536. case IDM_HACK:
  537. DoCSTest(hWnd);
  538. RefitWindows(hWnd, NULL);
  539. break;
  540. default:
  541. return (DefWindowProc(hWnd, message, wParam, lParam));
  542. }
  543. break;
  544. case WM_PAINT:
  545. //
  546. // repaint the window
  547. //
  548. {
  549. hDC = BeginPaint(hWnd,&ps);
  550. SelectObject(hDC,GetStockObject(NULL_BRUSH));
  551. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  552. DrawFrame(hDC,pPerf);
  553. DrawPerfText(hDC,pPerf);
  554. DrawPerfGraph(hDC,pPerf);
  555. }
  556. EndPaint(hWnd,&ps);
  557. }
  558. break;
  559. case WM_TIMER:
  560. {
  561. hDC = GetDC(hWnd);
  562. //
  563. // Calc new information
  564. //
  565. CalcPerf(PerfGraphList);
  566. //
  567. // If some lazy op, then perform it
  568. //
  569. if (LazyOp) {
  570. pPerf=PerfGraphList;
  571. while (pPerf) {
  572. if (pPerf->DeleteMe) {
  573. pPerf = SetDisplayToFalse (pPerf);
  574. } else {
  575. pPerf = pPerf->Next;
  576. }
  577. }
  578. RefitWindows(hWnd, hDC);
  579. LazyOp = FALSE;
  580. }
  581. //
  582. // update all performance information
  583. //
  584. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  585. if (pPerf->ChangeScale) {
  586. DrawPerfText(hDC,pPerf);
  587. DrawPerfGraph(hDC,pPerf);
  588. } else {
  589. DrawPerfText(hDC,pPerf);
  590. ShiftPerfGraph(hDC,pPerf);
  591. }
  592. }
  593. ReleaseDC(hWnd,hDC);
  594. }
  595. break;
  596. //
  597. // right double click
  598. //
  599. case WM_NCRBUTTONDBLCLK:
  600. case WM_RBUTTONDBLCLK:
  601. Calc1 = NULL;
  602. y = HIWORD(lParam);
  603. x = LOWORD(lParam);
  604. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  605. if (x > pPerf->PositionX && x < pPerf->PositionX+pPerf->Width &&
  606. y > pPerf->PositionY && y < pPerf->PositionY+pPerf->Height) {
  607. if (pPerf->IsCalc) {
  608. SetDisplayToFalse (pPerf);
  609. FreeDisplayItem (pPerf);
  610. RefitWindows (hWnd, NULL);
  611. break;
  612. }
  613. switch (pPerf->DisplayMode) {
  614. case DISPLAY_MODE_TOTAL: l = DISPLAY_MODE_BREAKDOWN; break;
  615. case DISPLAY_MODE_BREAKDOWN: l = DISPLAY_MODE_PER_PROCESSOR; break;
  616. case DISPLAY_MODE_PER_PROCESSOR: l = DISPLAY_MODE_TOTAL; break;
  617. }
  618. pPerf->DisplayMode = l;
  619. hDC = BeginPaint(hWnd,&ps);
  620. DrawPerfGraph(hDC,pPerf); // redraw graph in new mode
  621. EndPaint(hWnd,&ps);
  622. break;
  623. }
  624. }
  625. break;
  626. switch (DefaultDisplayMode) {
  627. case DISPLAY_MODE_TOTAL: l = DISPLAY_MODE_BREAKDOWN; break;
  628. case DISPLAY_MODE_BREAKDOWN: l = DISPLAY_MODE_PER_PROCESSOR; break;
  629. case DISPLAY_MODE_PER_PROCESSOR: l = DISPLAY_MODE_TOTAL; break;
  630. }
  631. DefaultDisplayMode = l;
  632. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  633. pPerf->DisplayMode = l;
  634. hDC = BeginPaint(hWnd,&ps);
  635. DrawPerfGraph(hDC,pPerf); // redraw graph in new mode
  636. EndPaint(hWnd,&ps);
  637. }
  638. break;
  639. //
  640. // handle a double click
  641. //
  642. case WM_NCLBUTTONDBLCLK:
  643. case WM_LBUTTONDBLCLK:
  644. {
  645. DWORD WindowStyle;
  646. //
  647. // get old window style, take out caption and menu
  648. //
  649. Calc1 = NULL;
  650. if (!IsIconic(hWnd)) {
  651. if (WinperfInfo.DisplayMenu) {
  652. WindowStyle = GetWindowLong(hWnd,GWL_STYLE);
  653. WindowStyle = (WindowStyle & (~STYLE_ENABLE_MENU)) | STYLE_DISABLE_MENU;
  654. SetMenu(hWnd,NULL);
  655. SetWindowLong(hWnd,GWL_STYLE,WindowStyle);
  656. SetWindowPos(hWnd, (HWND)NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
  657. ShowWindow(hWnd,SW_SHOW);
  658. WinperfInfo.DisplayMode=STYLE_DISABLE_MENU;
  659. WinperfInfo.DisplayMenu = FALSE;
  660. } else {
  661. WindowStyle = GetWindowLong(hWnd,GWL_STYLE);
  662. WindowStyle = (WindowStyle & (~STYLE_DISABLE_MENU)) | STYLE_ENABLE_MENU;
  663. SetMenu(hWnd,WinperfInfo.hMenu);
  664. SetWindowLong(hWnd,GWL_STYLE,WindowStyle);
  665. SetWindowPos(hWnd, (HWND)NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
  666. ShowWindow(hWnd,SW_SHOW);
  667. WinperfInfo.DisplayMode=STYLE_ENABLE_MENU;
  668. WinperfInfo.DisplayMenu = TRUE;
  669. }
  670. } else {
  671. DefWindowProc(hWnd, message, wParam, lParam);
  672. }
  673. }
  674. break;
  675. case WM_NCRBUTTONDOWN:
  676. case WM_RBUTTONDOWN:
  677. y = HIWORD(lParam);
  678. x = LOWORD(lParam);
  679. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  680. if (x > pPerf->PositionX && x < pPerf->PositionX+pPerf->Width &&
  681. y > pPerf->PositionY && y < pPerf->PositionY+pPerf->Height) {
  682. if (!Calc1) {
  683. Calc1 = pPerf;
  684. break;
  685. }
  686. if (Calc1 != pPerf) {
  687. Calc2 = pPerf;
  688. DialogBox(hInst, MAKEINTRESOURCE(IDM_CALC_DLG), hWnd, CalcDlgProc);
  689. Calc1 = Calc2 = NULL;
  690. break;
  691. }
  692. break;
  693. }
  694. }
  695. break;
  696. //
  697. // enable dragging with mouse in non-client
  698. //
  699. case WM_NCHITTEST:
  700. {
  701. lParam = DefWindowProc(hWnd, message, wParam, lParam);
  702. if ((WinperfInfo.DisplayMenu==FALSE) && (lParam == HTCLIENT)) {
  703. return(HTCAPTION);
  704. } else {
  705. return(lParam);
  706. }
  707. }
  708. break;
  709. case WM_DESTROY:
  710. {
  711. UINT Index;
  712. //
  713. // Save profile info
  714. //
  715. // SaveProfileData(&WinperfInfo);
  716. //
  717. // Delete Windows Objects
  718. //
  719. KillTimer(hWnd,TIMER_ID);
  720. DeleteObject(WinperfInfo.hBluePen);
  721. for (i=0; i < 12; i++) {
  722. DeleteObject(WinperfInfo.hPPen[i]);
  723. }
  724. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  725. DeleteMemoryContext(pPerf);
  726. }
  727. //
  728. // Destroy window
  729. //
  730. PostQuitMessage(0);
  731. }
  732. break;
  733. default:
  734. //
  735. // Passes message on if unproccessed
  736. //
  737. return (DefWindowProc(hWnd, message, wParam, lParam));
  738. }
  739. return ((LONG)NULL);
  740. }
  741. INT_PTR
  742. CALLBACK SelectDlgProc(
  743. HWND hDlg,
  744. unsigned int message,
  745. WPARAM wParam,
  746. LPARAM lParam
  747. )
  748. /*++
  749. Routine Description:
  750. Process message for select dialog box.
  751. Arguments:
  752. hDlg - window handle of the dialog box
  753. message - type of message
  754. wParam - message-specific information
  755. lParam - message-specific information
  756. Return Value:
  757. status of operation
  758. Revision History:
  759. 03-21-91 Initial code
  760. --*/
  761. {
  762. PDISPLAY_ITEM pPerf;
  763. UINT ButtonState;
  764. UINT Index, i;
  765. switch (message) {
  766. case WM_INITDIALOG:
  767. InitComboBox (hDlg, IDM_P5_GEN1, 0);
  768. InitComboBox (hDlg, IDM_P5_GEN2, 1);
  769. for (i=0; GenCounts[i].IdSel; i++) {
  770. SendDlgItemMessage(
  771. hDlg,
  772. GenCounts[i].IdSel,
  773. BM_SETCHECK,
  774. GenCounts[i].State,
  775. 0
  776. );
  777. }
  778. return (TRUE);
  779. case WM_COMMAND:
  780. switch(wParam) {
  781. //
  782. // end function
  783. //
  784. case IDOK:
  785. case IDM_ACCEPT:
  786. SetP5Perf (hDlg, IDM_P5_GEN1, 0);
  787. SetP5Perf (hDlg, IDM_P5_GEN2, 1);
  788. for (i=0; GenCounts[i].IdSel; i++) {
  789. SetGenPerf (hDlg, GenCounts+i);
  790. }
  791. UseGlobalMax = GenCounts[0].State;
  792. LogIt = GenCounts[1].State;
  793. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  794. pPerf->MaxToUse =
  795. UseGlobalMax ? &GlobalMax : &pPerf->Max;
  796. }
  797. if (wParam == IDOK) {
  798. EndDialog(hDlg, DIALOG_SUCCESS);
  799. } else {
  800. RefitWindows (NULL, NULL);
  801. }
  802. return (TRUE);
  803. case IDCANCEL:
  804. EndDialog(hDlg, DIALOG_CANCEL );
  805. return (TRUE);
  806. }
  807. }
  808. return (FALSE);
  809. }
  810. VOID
  811. RefitWindows (HWND hWnd, HDC CurhDC)
  812. {
  813. PDISPLAY_ITEM pPerf;
  814. BOOLEAN fit;
  815. ULONG Index;
  816. HDC hDC;
  817. hWnd = WinperfInfo.hWndMain;
  818. hDC = CurhDC;
  819. if (!CurhDC) {
  820. hDC = GetDC(hWnd);
  821. }
  822. fit = FitPerfWindows(hWnd,hDC,PerfGraphList);
  823. if (!fit) {
  824. //DbgPrint("Fit Fails\n");
  825. }
  826. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  827. DeleteMemoryContext(pPerf);
  828. CalcDrawFrame(pPerf);
  829. if (!CreateMemoryContext(hDC,pPerf)) {
  830. MessageBox(hWnd,"Error Allocating Memory","Winperf",MB_OK);
  831. DestroyWindow(hWnd);
  832. break;
  833. }
  834. }
  835. InvalidateRect(hWnd,(LPRECT)NULL,TRUE);
  836. if (!CurhDC) {
  837. ReleaseDC(hWnd,hDC);
  838. }
  839. }
  840. VOID
  841. InitComboBox (HWND hDlg, ULONG id, ULONG counter)
  842. {
  843. HWND ComboList;
  844. ULONG i, nIndex;
  845. ComboList = GetDlgItem(hDlg, id);
  846. SendMessage(ComboList, CB_RESETCONTENT, 0, 0);
  847. SendMessage(ComboList, CB_SETITEMDATA, 0L, 0L);
  848. if (Counters) {
  849. for (i=0; Counters[i].PerfName; i++) {
  850. nIndex = SendMessage(
  851. ComboList,
  852. CB_ADDSTRING,
  853. 0,
  854. (DWORD) Counters[i].PerfName
  855. );
  856. SendMessage(
  857. ComboList,
  858. CB_SETITEMDATA,
  859. nIndex,
  860. (DWORD) i
  861. );
  862. }
  863. }
  864. SendMessage(ComboList, CB_SETCURSEL, ActiveCounters[counter].ComboBoxIndex, 0L);
  865. }
  866. VOID
  867. SetP5Perf (HWND hDlg, ULONG IdCombo, ULONG counter)
  868. {
  869. static PUCHAR NameSuffix[] = { "", " (R0)", " (R3)", "" };
  870. HWND ComboList;
  871. ULONG nIndex, Mega, DU, BSEncoding, flag;
  872. PDISPLAY_ITEM pPerf;
  873. PUCHAR name;
  874. SETEVENT Event;
  875. ComboList = GetDlgItem(hDlg, IdCombo);
  876. nIndex = (int)SendMessage(ComboList, CB_GETCURSEL, 0, 0);
  877. ActiveCounters[counter].ComboBoxIndex = nIndex;
  878. memset (&Event, 0, sizeof (Event));
  879. Event.Active = TRUE;
  880. Event.KernelMode = SendDlgItemMessage(hDlg,IdCombo+1,BM_GETCHECK,0,0) ? TRUE : FALSE;
  881. Event.UserMode = SendDlgItemMessage(hDlg,IdCombo+2,BM_GETCHECK,0,0) ? TRUE : FALSE;
  882. BSEncoding = (Event.UserMode << 1) | Event.KernelMode;
  883. Mega = SendDlgItemMessage(hDlg,IdCombo+3,BM_GETCHECK,0,0) ? 1 : 0;
  884. //DU = SendDlgItemMessage(hDlg,IdCombo+3,BM_GETCHECK,0,0) ? 1 : 0;
  885. DU = 0;
  886. // get encoding for counter
  887. if ((!Event.KernelMode && !Event.UserMode) || nIndex == -1) {
  888. // no counter selected, done
  889. if (ActiveCounters[counter].pWhichGraph != NULL) {
  890. ClearGraph (ActiveCounters[counter].pWhichGraph);
  891. }
  892. return ;
  893. }
  894. // select counter
  895. nIndex = SendMessage(ComboList, CB_GETITEMDATA, nIndex, 0);
  896. Event.EventId = Counters[nIndex].EventId;
  897. ActiveCounters[counter].WhichCounter = nIndex;
  898. if (ActiveCounters[counter].pWhichGraph == NULL) {
  899. ActiveCounters[counter].pWhichGraph = AllocateDisplayItem();
  900. }
  901. pPerf = ActiveCounters[counter].pWhichGraph; // which window
  902. _snprintf (pPerf->PerfName,
  903. sizeof(pPerf->PerfName) - 1,
  904. "%s%s", Counters[nIndex].PerfName, NameSuffix[BSEncoding]);
  905. pPerf->PerfName[sizeof(pPerf->PerfName) - 1] = 0;
  906. flag = TRUE;
  907. if (Mega != pPerf->Mega || memcmp (&Event, CounterEvents+counter, sizeof (Event))) {
  908. flag = FALSE;
  909. CounterEvents[counter] = Event;
  910. SetCounterEvents (CounterEvents, sizeof CounterEvents);
  911. }
  912. pPerf->SnapData = SnapPrivateInfo; // generic snap
  913. pPerf->SnapParam1 = OFFSET(PSTATS, Counters[ counter ]);
  914. pPerf->Mega = Mega;
  915. SetDisplayToTrue (pPerf, IdCombo);
  916. if (flag) {
  917. // didn't change types
  918. return ;
  919. }
  920. // clear graph
  921. flag = pPerf->CalcId;
  922. ClearGraph (pPerf);
  923. pPerf->Mega = Mega;
  924. pPerf->CalcId = flag;
  925. SetDisplayToTrue (pPerf, IdCombo);
  926. UpdateInternalStats ();
  927. pPerf->SnapData (pPerf);
  928. UpdateInternalStats ();
  929. pPerf->SnapData (pPerf);
  930. }
  931. VOID
  932. ClearGraph (
  933. PDISPLAY_ITEM pPerf
  934. )
  935. {
  936. ULONG i, j;
  937. PULONG pDL;
  938. SetDisplayToFalse (pPerf);
  939. pPerf->Mega = FALSE;
  940. for (i=0 ; i < WinperfInfo.NumberOfProcessors+1; i++) {
  941. pDL = pPerf->DataList[i];
  942. for (j=0; j<DATA_LIST_LENGTH; j++) {
  943. *(pDL++) = 0;
  944. }
  945. }
  946. pPerf->Max = 1;
  947. pPerf->CurrentDrawingPos = 0;
  948. pPerf->ChangeScale = TRUE;
  949. }
  950. VOID
  951. SetGenPerf (HWND hDlg, PGENCOUNTER GenCount)
  952. {
  953. PDISPLAY_ITEM pPerf;
  954. ULONG ButtonState;
  955. GenCount->State = SendDlgItemMessage(hDlg,GenCount->IdSel,BM_GETCHECK,0,0);
  956. if (GenCount->Fnc == NULL) {
  957. return ;
  958. }
  959. if (GenCount->WhichGraph == NULL) {
  960. GenCount->WhichGraph = AllocateDisplayItem();
  961. }
  962. pPerf = GenCount->WhichGraph;
  963. if (!GenCount->State) {
  964. ClearGraph (pPerf);
  965. return ;
  966. }
  967. strncpy (pPerf->PerfName, GenCount->Name, sizeof(pPerf->PerfName) - 1);
  968. pPerf->PerfName[sizeof(pPerf->PerfName) - 1] = 0;
  969. pPerf->SnapData = GenCount->Fnc;
  970. pPerf->SnapParam1 = GenCount->Param;
  971. pPerf->SnapData (pPerf);
  972. SetDisplayToTrue (pPerf, GenCount->IdSel);
  973. }
  974. VOID
  975. SetDisplayToTrue (
  976. PDISPLAY_ITEM pPerf,
  977. ULONG sort
  978. )
  979. {
  980. PDISPLAY_ITEM p, *pp;
  981. Calc1 = NULL;
  982. if (pPerf->Display) { // already displayed
  983. return ; // just return
  984. }
  985. pPerf->DispName[sizeof(pPerf->DispName) - 1] = 0;
  986. if (pPerf->CalcId) {
  987. _snprintf (pPerf->DispName, sizeof(pPerf->DispName) - 1,
  988. "%d. %s", pPerf->CalcId, pPerf->PerfName);
  989. } else {
  990. strncpy (pPerf->DispName, pPerf->PerfName, sizeof(pPerf->DispName) - 1);
  991. }
  992. pPerf->DispNameLen = strlen (pPerf->DispName);
  993. pPerf->Display = TRUE; // set to display
  994. pPerf->sort = sort;
  995. // check to see if grap is already listed
  996. for (p = PerfGraphList; p; p = p->Next) {
  997. if (p == pPerf) {
  998. // already in the active list, ret
  999. return ;
  1000. }
  1001. }
  1002. // put graph in perfered sorting order
  1003. for (pp = &PerfGraphList; *pp; pp = &(*pp)->Next) {
  1004. if ((*pp)->sort > sort) {
  1005. break;
  1006. }
  1007. }
  1008. pPerf->Next = *pp;
  1009. *pp = pPerf;
  1010. }
  1011. PDISPLAY_ITEM
  1012. SetDisplayToFalse (
  1013. PDISPLAY_ITEM pPerf
  1014. )
  1015. {
  1016. PDISPLAY_ITEM *p, p1;
  1017. for (p = &PerfGraphList; *p; p = &(*p)->Next) { // remove graph from
  1018. if (*p == pPerf) { // active list
  1019. *p = pPerf->Next;
  1020. break;
  1021. }
  1022. }
  1023. if (pPerf->CalcId) {
  1024. Calc1 = Calc2 = NULL;
  1025. for (p1 = PerfGraphList; p1; p1 = p1->Next) {
  1026. p1->CalcPercent[0] = NULL;
  1027. p1->CalcPercent[1] = NULL;
  1028. }
  1029. }
  1030. pPerf->CalcId = 0;
  1031. pPerf->Display = FALSE; // clear flag
  1032. return *p;
  1033. }
  1034. VOID
  1035. SetDefaultDisplayMode (HWND hWnd, ULONG mode)
  1036. {
  1037. HDC hDC;
  1038. PDISPLAY_ITEM pPerf;
  1039. PAINTSTRUCT ps;
  1040. hDC = BeginPaint(hWnd,&ps);
  1041. DefaultDisplayMode = mode;
  1042. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  1043. if (pPerf->IsPercent) {
  1044. continue;
  1045. }
  1046. pPerf->DisplayMode = DefaultDisplayMode;
  1047. DrawPerfGraph(hDC,pPerf); // redraw graph in new mode
  1048. }
  1049. EndPaint(hWnd,&ps);
  1050. }
  1051. PDISPLAY_ITEM
  1052. AllocateDisplayItem()
  1053. {
  1054. PDISPLAY_ITEM pPerf;
  1055. UINT Index1, Index2;
  1056. PULONG pDL;
  1057. pPerf = malloc(sizeof (DISPLAY_ITEM));
  1058. if (pPerf == NULL) {
  1059. printf("Memory allocation failed.\n");
  1060. exit(1);
  1061. }
  1062. RtlZeroMemory (pPerf, sizeof (DISPLAY_ITEM));
  1063. pPerf->Display = FALSE;
  1064. pPerf->Max = 1;
  1065. pPerf->SnapData = SnapNull;
  1066. pPerf->DisplayMode = DefaultDisplayMode;
  1067. pPerf->AutoTotal = TRUE;
  1068. pPerf->MaxToUse = &pPerf->Max;
  1069. //
  1070. // I will not fix these as PerfName is not likely to be 1...
  1071. //
  1072. strcpy (pPerf->PerfName, "?");
  1073. strcpy (pPerf->DispName, "?");
  1074. pPerf->DispNameLen = 1;
  1075. for (Index1=0 ; Index1 < WinperfInfo.NumberOfProcessors+1; Index1++) {
  1076. pDL = malloc (DATA_LIST_LENGTH * sizeof (ULONG));
  1077. if (pDL == NULL) {
  1078. printf("Memory allocation failed.\n");
  1079. exit(1);
  1080. }
  1081. pPerf->DataList[Index1] = pDL;
  1082. RtlZeroMemory (pDL, sizeof(ULONG) * DATA_LIST_LENGTH);
  1083. }
  1084. return pPerf;
  1085. }
  1086. VOID
  1087. FreeDisplayItem(PDISPLAY_ITEM pPerf)
  1088. {
  1089. ULONG i;
  1090. for (i=0 ; i < WinperfInfo.NumberOfProcessors+1; i++) {
  1091. free (pPerf->DataList[i]);
  1092. }
  1093. free (pPerf);
  1094. }
  1095. //
  1096. // ************** HACKTEST
  1097. //
  1098. ULONG CsCount[32*32];
  1099. struct s_ThreadInfo {
  1100. PULONG Counter;
  1101. HDC MemoryDC;
  1102. HWND hWnd;
  1103. } ThreadInfo[32];
  1104. DWORD
  1105. WorkerCsTestThread (
  1106. struct s_ThreadInfo *TInfo
  1107. )
  1108. {
  1109. HDC hDC;
  1110. HDC hDCmem;
  1111. HBITMAP hbm;
  1112. ULONG i;
  1113. hDC = GetDC(TInfo->hWnd);
  1114. hDCmem= CreateCompatibleDC(hDC);
  1115. hbm = CreateCompatibleBitmap(hDC,100,100);
  1116. SelectObject(hDCmem,hbm);
  1117. for (i = 0; i < (ULONG)-1 ; i++) {
  1118. (*TInfo->Counter)++;
  1119. //GetPixel(hDC, 9999, 9999);
  1120. //BitBlt(hDC, 1, 1, 20, 20, TInfo->MemoryDC, 0, 0, SRCCOPY);
  1121. PatBlt(hDCmem,0,0,20,20,PATCOPY);
  1122. }
  1123. ReleaseDC(TInfo->hWnd,hDC);
  1124. return 0;
  1125. }
  1126. VOID
  1127. DoCSTest(HWND hWnd)
  1128. {
  1129. static ULONG ThreadCount = 0;
  1130. PDISPLAY_ITEM pPerf;
  1131. DWORD junk;
  1132. if (ThreadCount >= 32) {
  1133. return ;
  1134. }
  1135. pPerf = AllocateDisplayItem();
  1136. ThreadInfo[ThreadCount].Counter = &CsCount[ThreadCount];
  1137. ThreadInfo[ThreadCount].MemoryDC = pPerf->MemoryDC;
  1138. ThreadInfo[ThreadCount].hWnd = hWnd;
  1139. CreateThread (NULL, 0,
  1140. (LPTHREAD_START_ROUTINE) WorkerCsTestThread,
  1141. (LPVOID) &ThreadInfo[ThreadCount],
  1142. 0,
  1143. &junk);
  1144. pPerf->SnapData = SnapCsTest;
  1145. pPerf->SnapParam1 = ThreadCount;
  1146. ThreadCount++;
  1147. _snprintf (pPerf->PerfName,
  1148. sizeof(pPerf->PerfName) - 1,
  1149. "CS trans %ld", ThreadCount);
  1150. pPerf->PerfName[sizeof(pPerf->PerfName) - 1] = 0;
  1151. SetDisplayToTrue (pPerf, 1);
  1152. }
  1153. VOID
  1154. SnapCsTest (
  1155. IN OUT PDISPLAY_ITEM pPerf
  1156. )
  1157. {
  1158. ULONG i;
  1159. pPerf->CurrentDataPoint[1] = CsCount[pPerf->SnapParam1];
  1160. CsCount[pPerf->SnapParam1] = 0;
  1161. }