ReactOS  0.4.15-dev-489-g75a0787
rosperf.c
Go to the documentation of this file.
1 /*
2  * ReactOS RosPerf - ReactOS GUI performance test program
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 /*
19  * Ideas copied from x11perf:
20  *
21  * Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
22  *
23  * All Rights Reserved
24  *
25  * Permission to use, copy, modify, and distribute this software and its
26  * documentation for any purpose and without fee is hereby granted,
27  * provided that the above copyright notice appear in all copies and that
28  * both that copyright notice and this permission notice appear in
29  * supporting documentation, and that the name of Digital not be
30  * used in advertising or publicity pertaining to distribution of the
31  * software without specific, written prior permission.
32  *
33  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
34  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
35  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
36  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
37  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
38  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
39  * SOFTWARE.
40  */
41 
42 #include <limits.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <windows.h>
46 #include <reactos/buildno.h>
47 
48 #include "rosperf.h"
49 
50 #define MAINWND_WIDTH 400
51 #define MAINWND_HEIGHT 400
52 
53 static HWND LabelWnd;
54 
55 unsigned
56 NullInit(void **Context, PPERF_INFO PerfInfo, unsigned Reps)
57 {
58  *Context = NULL;
59 
60  return Reps;
61 }
62 
63 void
64 NullCleanup(void *Context, PPERF_INFO PerfInfo)
65 {
66 }
67 
68 static void
70 {
71  MSG Msg;
72 
73  while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
74  {
75  if (WM_QUIT == Msg.message)
76  {
77  exit(Msg.wParam);
78  }
81  }
82 }
83 
84 static void
86 {
87  InvalidateRect(PerfInfo->Wnd, NULL, TRUE);
88  UpdateWindow(PerfInfo->Wnd);
89 }
90 
91 static unsigned
93 {
94 #define GOAL 2500 /* Try to get up to 2.5 seconds */
95 #define ENOUGH 2000 /* But settle for 2.0 seconds */
96 #define TICK 10 /* Assume clock not faster than .01 seconds */
97 
98  unsigned Reps, DidReps; /* Reps desired, reps performed */
99  unsigned Exponent;
100  void *Context;
101  DWORD StartTick;
102  DWORD Duration;
103 
104  /* Attempt to get an idea how long each rep lasts by getting enough
105  reps to last more than ENOUGH. Then scale that up to the number of
106  seconds desired.
107 
108  If init call to test ever fails, return False and test will be skipped.
109  */
110 
111  Reps = 1;
112  for (;;)
113  {
114  ClearWindow(PerfInfo);
115  DidReps = (*Test->Init)(&Context, PerfInfo, Reps);
116  ProcessMessages();
117  if (0 == DidReps)
118  {
119  return 0;
120  }
121  StartTick = GetTickCount();
122  (*Test->Proc)(Context, PerfInfo, Reps);
123  Duration = GetTickCount() - StartTick;
124  (*Test->PassCleanup) (Context, PerfInfo);
125  (*Test->Cleanup)(Context, PerfInfo);
126  ProcessMessages();
127 
128  if (DidReps != Reps)
129  {
130  /* The test can't do the number of reps as we asked for.
131  Give up */
132  return DidReps;
133  }
134  /* Did we go long enough? */
135  if (ENOUGH <= Duration)
136  {
137  break;
138  }
139 
140  /* Don't let too short a clock make new reps wildly high */
141  if (Duration <= TICK)
142  {
143  Reps *= 10;
144  }
145  else
146  {
147  /* Try to get up to GOAL seconds. */
148  Reps = (int)(GOAL * (double) Reps / (double) Duration) + 1;
149  }
150  }
151 
152  Reps = (int) ((double) PerfInfo->Seconds * 1000.0 * (double) Reps / (double) Duration) + 1;
153 
154  /* Now round reps up to 1 digit accuracy, so we don't get stupid-looking
155  numbers of repetitions. */
156  Reps--;
157  Exponent = 1;
158  while (9 < Reps)
159  {
160  Reps /= 10;
161  Exponent *= 10;
162  }
163  Reps = (Reps + 1) * Exponent;
164 
165  return Reps;
166 }
167 
168 static void
170 {
171  WCHAR Status[128];
172 
173  _snwprintf(Status, sizeof(Status) / sizeof(Status[0]), L"%d %s %s", Try, Message, Test);
177 }
178 
179 static double
181 {
182  /* It's kind of silly to print out things like ``193658.4/sec'' so just
183  junk all but 3 most significant digits. */
184 
185  double exponent, sign;
186 
187  exponent = 1.0;
188  /* the code below won't work if d should happen to be non-positive. */
189  if (d < 0.0)
190  {
191  d = -d;
192  sign = -1.0;
193  }
194  else
195  {
196  sign = 1.0;
197  }
198 
199  if (1000.0 <= d)
200  {
201  do
202  {
203  exponent *= 10.0;
204  }
205  while (1000.0 <= d / exponent);
206  d = (double)((int)(d / exponent + 0.5));
207  d *= exponent;
208  }
209  else
210  {
211  if (0.0 != d)
212  {
213  while (d * exponent < 100.0)
214  {
215  exponent *= 10.0;
216  }
217  }
218  d = (double)((int)(d * exponent + 0.5));
219  d /= exponent;
220  }
221 
222  return d * sign;
223 }
224 
225 static void
226 ReportTimes(DWORD Time, int Reps, LPCWSTR Label, BOOL Average)
227 {
228  double MSecsPerObj, ObjsPerSec;
229 
230  if (0 != Time)
231  {
232  MSecsPerObj = (double) Time / (double) Reps;
233  ObjsPerSec = (double) Reps * 1000.0 / (double) Time;
234 
235  /* Round obj/sec to 3 significant digits. Leave msec untouched, to
236  allow averaging results from several repetitions. */
237  ObjsPerSec = RoundTo3Digits(ObjsPerSec);
238 
239  wprintf(L"%7d %s @ %8.4f msec (%8.1f/sec): %s\n",
240  Reps, Average ? L"trep" : L"reps", MSecsPerObj, ObjsPerSec, Label);
241  }
242  else
243  {
244  wprintf(L"%6d %sreps @ 0.0 msec (unmeasurably fast): %s\n",
245  Reps, Average ? L"t" : L"", Label);
246  }
247 
248 }
249 
250 static void
252 {
253  unsigned Reps;
254  unsigned Repeat;
255  void *Context;
256  DWORD StartTick;
257  DWORD Time, TotalTime;
258 
259  DisplayStatus(LabelWnd, L"Calibrating", Test->Label, 0);
260  Reps = CalibrateTest(Test, PerfInfo);
261  if (0 == Reps)
262  {
263  return;
264  }
265 
266  Reps = Test->Init(&Context, PerfInfo, Reps);
267  if (0 == Reps)
268  {
269  return;
270  }
271  TotalTime = 0;
272  for (Repeat = 0; Repeat < PerfInfo->Repeats; Repeat++)
273  {
274  DisplayStatus(LabelWnd, L"Testing", Test->Label, Repeat + 1);
275  ClearWindow(PerfInfo);
276  StartTick = GetTickCount();
277  (*Test->Proc)(Context, PerfInfo, Reps);
278  Time = GetTickCount() - StartTick;
279  ProcessMessages();
280  TotalTime += Time;
281  ReportTimes(Time, Reps, Test->Label, FALSE);
282  (*Test->PassCleanup)(Context, PerfInfo);
283  ProcessMessages();
284  }
285  (*Test->Cleanup)(Context, PerfInfo);
286  ReportTimes(TotalTime, Repeat * Reps, Test->Label, TRUE);
287  ProcessMessages();
288 }
289 
290 static void
292 {
293  OSVERSIONINFOEXW VersionInfo;
294  BOOL OsVersionInfoEx;
295  HKEY hKey;
296  WCHAR ProductType[9] = { L'\0' };
297  DWORD BufLen, dwType;
298  LONG Ret;
299  unsigned RosVersionLen;
300  LPWSTR RosVersion;
301 
302  /* Try calling GetVersionEx using the OSVERSIONINFOEX structure.
303  * If that fails, try using the OSVERSIONINFO structure. */
304 
305  ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFOEXW));
306  VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
307 
308  OsVersionInfoEx = GetVersionExW((OSVERSIONINFOW *) &VersionInfo);
309  if (! OsVersionInfoEx)
310  {
311  VersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
312  if (! GetVersionExW((OSVERSIONINFOW *) &VersionInfo))
313  {
314  return;
315  }
316  }
317 
318  RosVersion = VersionInfo.szCSDVersion + wcslen(VersionInfo.szCSDVersion) + 1;
319  RosVersionLen = sizeof(VersionInfo.szCSDVersion) / sizeof(VersionInfo.szCSDVersion[0]) -
320  (RosVersion - VersionInfo.szCSDVersion);
321  if (7 <= RosVersionLen && 0 == _wcsnicmp(RosVersion, L"ReactOS", 7))
322  {
323  wprintf(L"Running on %s\n", RosVersion);
324  return;
325  }
326 
327  switch (VersionInfo.dwPlatformId)
328  {
329  /* Test for the Windows NT product family. */
331 
332  /* Test for the specific product. */
333  if (5 == VersionInfo.dwMajorVersion && 2 == VersionInfo.dwMinorVersion)
334  {
335  wprintf(L"Running on Microsoft Windows Server 2003, ");
336  }
337  else if (5 == VersionInfo.dwMajorVersion && 1 == VersionInfo.dwMinorVersion)
338  {
339  wprintf(L"Running on Microsoft Windows XP ");
340  }
341  else if (5 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
342  {
343  wprintf(L"Running on Microsoft Windows 2000 ");
344  }
345  else if (VersionInfo.dwMajorVersion <= 4 )
346  {
347  wprintf(L"Running on Microsoft Windows NT ");
348  }
349 
350  /* Test for specific product on Windows NT 4.0 SP6 and later. */
351  if (OsVersionInfoEx)
352  {
353  /* Test for the workstation type. */
354  if (VER_NT_WORKSTATION == VersionInfo.wProductType)
355  {
356  if (4 == VersionInfo.dwMajorVersion)
357  {
358  wprintf(L"Workstation 4.0 ");
359  }
360  else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_PERSONAL))
361  {
362  wprintf(L"Home Edition ");
363  }
364  else
365  {
366  wprintf(L"Professional ");
367  }
368  }
369 
370  /* Test for the server type. */
371  else if (VER_NT_SERVER == VersionInfo.wProductType ||
372  VER_NT_DOMAIN_CONTROLLER == VersionInfo.wProductType)
373  {
374  if (5 == VersionInfo.dwMajorVersion && 2 == VersionInfo.dwMinorVersion)
375  {
376  if (0 != (VersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
377  {
378  wprintf(L"Datacenter Edition ");
379  }
380  else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
381  {
382  wprintf(L"Enterprise Edition ");
383  }
384  else if (VER_SUITE_BLADE == VersionInfo.wSuiteMask)
385  {
386  wprintf(L"Web Edition ");
387  }
388  else
389  {
390  wprintf(L"Standard Edition ");
391  }
392  }
393 
394  else if (5 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
395  {
396  if (0 != (VersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
397  {
398  wprintf(L"Datacenter Server ");
399  }
400  else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
401  {
402  wprintf(L"Advanced Server " );
403  }
404  else
405  {
406  wprintf(L"Server " );
407  }
408  }
409 
410  else /* Windows NT 4.0 */
411  {
412  if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
413  {
414  wprintf(L"Server 4.0, Enterprise Edition ");
415  }
416  else
417  {
418  wprintf(L"Server 4.0 ");
419  }
420  }
421  }
422  }
423  else /* Test for specific product on Windows NT 4.0 SP5 and earlier */
424  {
426  L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
427  0, KEY_QUERY_VALUE, &hKey);
428  if (ERROR_SUCCESS != Ret)
429  {
430  return;
431  }
432 
433  BufLen = sizeof(ProductType);
434  Ret = RegQueryValueExW(hKey, L"ProductType", NULL, &dwType,
435  (LPBYTE) ProductType, &BufLen);
436 
437  RegCloseKey(hKey);
438 
439  if (Ret != ERROR_SUCCESS || dwType != REG_SZ)
440  {
441  return;
442  }
443 
444  if (0 == lstrcmpiW(L"WINNT", ProductType))
445  {
446  wprintf(L"Workstation ");
447  }
448  else if (0 == lstrcmpiW(L"LANMANNT", ProductType))
449  {
450  wprintf(L"Server ");
451  }
452  else if (0 == lstrcmpiW(L"SERVERNT", ProductType))
453  {
454  wprintf(L"Advanced Server ");
455  }
456 
457  wprintf(L"%d.%d ", VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion);
458  }
459 
460  /* Display service pack (if any) and build number. */
461 
462  if (4 == VersionInfo.dwMajorVersion &&
463  0 == lstrcmpiW(VersionInfo.szCSDVersion, L"Service Pack 6"))
464  {
465  /* Test for SP6 versus SP6a. */
467  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
468  0, KEY_QUERY_VALUE, &hKey);
469  if (ERROR_SUCCESS == Ret)
470  {
471  wprintf(L"Service Pack 6a (Build %d)\n", VersionInfo.dwBuildNumber & 0xFFFF);
472  }
473  else /* Windows NT 4.0 prior to SP6a */
474  {
475  wprintf(L"%s (Build %d)\n",
476  VersionInfo.szCSDVersion,
477  VersionInfo.dwBuildNumber & 0xFFFF);
478  }
479 
480  RegCloseKey(hKey);
481  }
482  else /* not Windows NT 4.0 */
483  {
484  wprintf(L"%s (Build %d)\n",
485  VersionInfo.szCSDVersion,
486  VersionInfo.dwBuildNumber & 0xFFFF);
487  }
488 
489 
490  break;
491 
492  /* Test for the Windows Me/98/95. A bit silly since we're using Unicode... */
494 
495  if (4 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
496  {
497  wprintf(L"Running on Microsoft Windows 95 ");
498  if (L'C' == VersionInfo.szCSDVersion[1] || L'B' == VersionInfo.szCSDVersion[1])
499  {
500  wprintf(L"OSR2");
501  }
502  }
503 
504  else if (4 == VersionInfo.dwMajorVersion && 10 == VersionInfo.dwMinorVersion)
505  {
506  wprintf(L"Running on Microsoft Windows 98 ");
507  if (L'A' == VersionInfo.szCSDVersion[1])
508  {
509  wprintf(L"SE");
510  }
511  }
512 
513  else if (4 == VersionInfo.dwMajorVersion && 90 == VersionInfo.dwMinorVersion)
514  {
515  wprintf(L"Running on Microsoft Windows Millennium Edition");
516  }
517  wprintf(L"\n");
518  break;
519 
520  case VER_PLATFORM_WIN32s: /* Even silier... */
521 
522  wprintf(L"Running on Microsoft Win32s\n");
523  break;
524  }
525 }
526 
527 static void
529 {
530  wprintf(L"RosPerf %S (Build %S)\n", KERNEL_VERSION_STR, KERNEL_VERSION_BUILD_STR);
531 }
532 
533 static void
535 {
536  HDC Dc;
537 
538  Dc = GetDC(NULL);
539  if (NULL == Dc)
540  {
541  return;
542  }
543 
544  wprintf(L"Display settings %d * %d * %d\n", GetDeviceCaps(Dc, HORZRES),
546 
547  ReleaseDC(NULL, Dc);
548 }
549 
550 static void
552 {
553  PrintAppVersion();
554  PrintOSVersion();
556 }
557 
558 static LRESULT CALLBACK
560 {
561  PAINTSTRUCT Ps;
562  HDC Dc;
563  LRESULT Result;
564 
565  switch (Msg)
566  {
567  case WM_DESTROY:
568  PostQuitMessage(0);
569  Result = 0;
570  break;
571 
572  case WM_PAINT:
573  Dc = BeginPaint(Wnd, &Ps);
574  EndPaint (Wnd, &Ps);
575  Result = 0;
576  break;
577 
578  default:
580  break;
581  }
582 
583  return Result;
584 }
585 
586 static LRESULT CALLBACK
588 {
589  PAINTSTRUCT Ps;
590  HDC Dc;
591  RECT ClientRect, WindowRect;
592  TEXTMETRICW Tm;
593  LRESULT Result;
594  WCHAR Title[80];
595 
596  switch (Msg)
597  {
598  case WM_CREATE:
599  /* Make text fit */
600  Dc = GetDC(Wnd);
601  if (NULL != Dc && GetClientRect(Wnd, &ClientRect) && GetWindowRect(Wnd, &WindowRect)
602  && GetTextMetricsW(Dc, &Tm))
603  {
604  if (Tm.tmHeight != ClientRect.bottom)
605  {
606  SetWindowPos(Wnd, NULL, 0, 0, WindowRect.right - WindowRect.left,
607  (WindowRect.bottom - WindowRect.top) + (Tm.tmHeight - ClientRect.bottom),
609  }
610  }
611  if (NULL != Dc)
612  {
613  ReleaseDC(Wnd, Dc);
614  }
616  break;
617 
618  case WM_PAINT:
619  Dc = BeginPaint(Wnd, &Ps);
620  GetWindowTextW(Wnd, Title, sizeof(Title) / sizeof(Title[0]));
621  TextOutW(Dc, 0, 0, Title, wcslen(Title));
622  EndPaint (Wnd, &Ps);
623  Result = 0;
624  break;
625 
626  default:
628  break;
629  }
630 
631  return Result;
632 }
633 
634 static HWND
636 {
637  WNDCLASSW wc;
638  HWND MainWnd;
639 
640  wc.lpszClassName = L"RosPerfMain";
642  wc.style = 0;
643  wc.hInstance = hInstance;
647  wc.lpszMenuName = NULL;
648  wc.cbClsExtra = 0;
649  wc.cbWndExtra = 0;
650  if (RegisterClassW(&wc) == 0)
651  {
652  fwprintf(stderr, L"Failed to register RosPerfMain (last error %d)\n",
653  GetLastError());
654  return NULL;
655  }
656 
657  wc.lpszClassName = L"RosPerfLabel";
659  wc.style = 0;
660  wc.hInstance = hInstance;
664  wc.lpszMenuName = NULL;
665  wc.cbClsExtra = 0;
666  wc.cbWndExtra = 0;
667  if (RegisterClassW(&wc) == 0)
668  {
669  fwprintf(stderr, L"Failed to register RosPerfLabel (last error %d)\n",
670  GetLastError());
671  return NULL;
672  }
673 
674  MainWnd = CreateWindowW(L"RosPerfMain",
675  L"ReactOS performance test",
677  0,
678  0,
681  NULL,
682  NULL,
683  hInstance,
684  NULL);
685  if (NULL == MainWnd)
686  {
687  fwprintf(stderr, L"Failed to create main window (last error %d)\n",
688  GetLastError());
689  return NULL;
690  }
691 
692  LabelWnd = CreateWindowW(L"RosPerfLabel",
693  L"",
695  0,
696  MAINWND_HEIGHT + 10,
698  20,
699  MainWnd,
700  NULL,
701  hInstance,
702  NULL);
703  if (NULL == LabelWnd)
704  {
705  fwprintf(stderr, L"Failed to create label window (last error 0x%lX)\n",
706  GetLastError());
707  return NULL;
708  }
709 
710  SetActiveWindow(MainWnd);
711 
712  return MainWnd;
713 }
714 
715 static BOOL
716 ProcessCommandLine(PPERF_INFO PerfInfo, unsigned *TestCount, PTEST *Tests)
717 {
718  int ArgC, Arg;
719  LPWSTR *ArgV;
720  LPWSTR EndPtr;
721  PTEST AllTests;
722  BOOL *DoTest;
723  BOOL DoAll;
724  unsigned AllTestCount, i, j;
725 
726  ArgV = CommandLineToArgvW(GetCommandLineW(), &ArgC);
727  if (NULL == ArgV)
728  {
729  fwprintf(stderr, L"CommandLineToArgvW failed\n");
730  return FALSE;
731  }
732 
733  GetTests(&AllTestCount, &AllTests);
734  DoTest = malloc(AllTestCount * sizeof(BOOL));
735  if (NULL == DoTest)
736  {
737  fwprintf(stderr, L"Out of memory\n");
738  return FALSE;
739  }
740  DoAll = TRUE;
741 
742  for (Arg = 1; Arg < ArgC; Arg++)
743  {
744  if (L'/' == ArgV[Arg][0] || L'-' == ArgV[Arg][0])
745  {
746  if (0 == _wcsicmp(ArgV[Arg] + 1, L"repeat"))
747  {
748  if (ArgC <= Arg + 1)
749  {
750  fwprintf(stderr, L"%s needs a repeat count\n", ArgV[Arg]);
751  free(DoTest);
752  GlobalFree(ArgV);
753  return FALSE;
754  }
755  Arg++;
756  PerfInfo->Repeats = wcstoul(ArgV[Arg], &EndPtr, 0);
757  if (L'\0' != *EndPtr || (long) PerfInfo->Repeats <= 0 || ULONG_MAX == PerfInfo->Repeats)
758  {
759  fwprintf(stderr, L"Invalid repeat count %s\n", ArgV[Arg]);
760  free(DoTest);
761  GlobalFree(ArgV);
762  return FALSE;
763  }
764  }
765  else if (0 == _wcsicmp(ArgV[Arg] + 1, L"seconds"))
766  {
767  if (ArgC <= Arg + 1)
768  {
769  fwprintf(stderr, L"%s needs a number of seconds\n", ArgV[Arg]);
770  free(DoTest);
771  GlobalFree(ArgV);
772  return FALSE;
773  }
774  Arg++;
775  PerfInfo->Seconds = wcstoul(ArgV[Arg], &EndPtr, 0);
776  if (L'\0' != *EndPtr || (long) PerfInfo->Seconds < 0 || ULONG_MAX == PerfInfo->Seconds)
777  {
778  fwprintf(stderr, L"Invalid duration %s\n", ArgV[Arg]);
779  free(DoTest);
780  GlobalFree(ArgV);
781  return FALSE;
782  }
783  }
784  else
785  {
786  fwprintf(stderr, L"Unrecognized option %s\n", ArgV[Arg]);
787  free(DoTest);
788  GlobalFree(ArgV);
789  return FALSE;
790  }
791  }
792  else
793  {
794  if (DoAll)
795  {
796  for (i = 0; i < AllTestCount; i++)
797  {
798  DoTest[i] = FALSE;
799  }
800  DoAll = FALSE;
801  }
802  for (i = 0; i < AllTestCount; i++)
803  {
804  if (0 == _wcsicmp(ArgV[Arg], AllTests[i].Option))
805  {
806  DoTest[i] = TRUE;
807  break;
808  }
809  }
810  if (AllTestCount <= i)
811  {
812  fwprintf(stderr, L"Unrecognized test %s\n", ArgV[Arg]);
813  free(DoTest);
814  GlobalFree(ArgV);
815  return FALSE;
816  }
817  }
818  }
819 
820  GlobalFree(ArgV);
821 
822  if (DoAll)
823  {
824  for (i = 0; i < AllTestCount; i++)
825  {
826  DoTest[i] = TRUE;
827  }
828  }
829 
830  *TestCount = 0;
831  for (i = 0; i < AllTestCount; i++)
832  {
833  if (DoTest[i])
834  {
835  (*TestCount)++;
836  }
837  }
838  *Tests = malloc(*TestCount * sizeof(TEST));
839  if (NULL == *Tests)
840  {
841  fwprintf(stderr, L"Out of memory\n");
842  free(DoTest);
843  return FALSE;
844  }
845  j = 0;
846  for (i = 0; i < AllTestCount; i++)
847  {
848  if (DoTest[i])
849  {
850  (*Tests)[j] = AllTests[i];
851  j++;
852  }
853  }
854  free(DoTest);
855 
856  return TRUE;
857 }
858 
859 int WINAPI
861  HINSTANCE hPrevInstance,
862  LPWSTR lpszCmdLine,
863  int nCmdShow)
864 {
865  PTEST Tests;
866  unsigned TestCount;
867  unsigned CurrentTest;
868  RECT Rect;
869  PERF_INFO PerfInfo;
870 
872 
873  PerfInfo.Seconds = 15;
874  PerfInfo.Repeats = 4;
875  PerfInfo.ForegroundColor = RGB(0, 0, 0);
876  PerfInfo.BackgroundColor = RGB(255, 255, 255);
877 
878  if (! ProcessCommandLine(&PerfInfo, &TestCount, &Tests))
879  {
880  exit(1);
881  }
882 
883  PerfInfo.Wnd = CreatePerfWindows(hInstance, &PerfInfo);
884  if (NULL == PerfInfo.Wnd)
885  {
886  exit(1);
887  }
888 
889  GetClientRect(PerfInfo.Wnd, &Rect);
890  PerfInfo.WndWidth = Rect.right - Rect.left;
891  PerfInfo.WndHeight = Rect.bottom - Rect.top;
892  PerfInfo.ForegroundDc = GetDC(PerfInfo.Wnd);
893  PerfInfo.BackgroundDc = GetDC(PerfInfo.Wnd);
894  if (NULL == PerfInfo.ForegroundDc || NULL == PerfInfo.BackgroundDc)
895  {
896  fwprintf(stderr, L"Failed to create device contexts (last error %d)\n",
897  GetLastError());
898  exit(1);
899  }
904 
905  ProcessMessages();
906 
907  /* Move cursor out of the way */
909  SetCursorPos(Rect.right, Rect.bottom);
910 
911  for (CurrentTest = 0; CurrentTest < TestCount; CurrentTest++)
912  {
913  wprintf(L"\n");
914  ProcessTest(Tests + CurrentTest, &PerfInfo);
915  }
916 
917  GlobalFree(Tests);
918 
919  return 0;
920 }
921 
922 /* EOF */
HGDIOBJ WINAPI GetStockObject(_In_ int)
static size_t double int int int * sign
Definition: printf.c:69
#define VER_NT_WORKSTATION
static void ProcessMessages(void)
Definition: rosperf.c:69
#define WS_THICKFRAME
Definition: pedump.c:630
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:265
#define BITSPIXEL
Definition: wingdi.h:719
#define HORZRES
Definition: wingdi.h:715
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:236
#define TRUE
Definition: types.h:120
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
UINT style
Definition: winuser.h:3151
#define ERROR_SUCCESS
Definition: deptool.c:10
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpszCmdLine, int nCmdShow)
Definition: rosperf.c:860
LPCWSTR lpszMenuName
Definition: winuser.h:3159
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static HWND CreatePerfWindows(HINSTANCE hInstance, PPERF_INFO PerfInfo)
Definition: rosperf.c:635
#define RGB(r, g, b)
Definition: precomp.h:62
HWND Wnd
Definition: rosperf.h:24
#define BufLen
Definition: fatfs.h:167
HDC WINAPI GetDC(_In_opt_ HWND)
#define free
Definition: debug_ros.c:5
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define VER_SUITE_BLADE
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
static LRESULT CALLBACK MainWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: rosperf.c:559
BOOL WINAPI UpdateWindow(_In_ HWND)
WCHAR szCSDVersion[128]
Definition: rtltypes.h:247
#define WM_QUIT
Definition: winuser.h:1605
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
LONG top
Definition: windef.h:307
static void PrintOSVersion(void)
Definition: rosperf.c:291
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1648
int cbClsExtra
Definition: winuser.h:3153
#define WHITE_BRUSH
Definition: wingdi.h:901
HDC BackgroundDc
Definition: rosperf.h:30
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
struct @1604 Msg[]
#define IDI_APPLICATION
Definition: winuser.h:699
UINT_PTR WPARAM
Definition: windef.h:207
INT WndHeight
Definition: rosperf.h:32
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1232
#define TICK
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define wprintf(...)
Definition: whoami.c:18
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
LONG right
Definition: windef.h:308
#define VER_SUITE_DATACENTER
#define GOAL
#define VER_SUITE_ENTERPRISE
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4291
#define VER_SUITE_PERSONAL
WPARAM wParam
Definition: combotst.c:138
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static void DisplayStatus(HWND Label, LPCWSTR Message, LPCWSTR Test, int Try)
Definition: rosperf.c:169
#define VER_PLATFORM_WIN32s
Definition: rtltypes.h:234
OSVERSIONINFOA OSVERSIONINFO
Definition: rtltypes.h:289
#define MAINWND_WIDTH
Definition: rosperf.c:50
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
static void ClearWindow(PPERF_INFO PerfInfo)
Definition: rosperf.c:85
#define PS_SOLID
Definition: wingdi.h:585
static void PrintAppVersion(void)
Definition: rosperf.c:528
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HINSTANCE hInstance
Definition: charmap.c:20
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
HWND WINAPI SetActiveWindow(_In_ HWND)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
LPWSTR WINAPI GetCommandLineW(VOID)
Definition: proc.c:2015
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
WNDPROC lpfnWndProc
Definition: winuser.h:3152
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
_Check_return_opt_ _CRTIMP int __cdecl fwprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const wchar_t *_Format,...)
#define VER_NT_DOMAIN_CONTROLLER
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
LPWSTR *WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int *numargs)
Definition: shell32_main.c:79
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
LPCWSTR lpszClassName
Definition: winuser.h:3160
LONG_PTR LPARAM
Definition: windef.h:208
VOID DoTest(HWND hWnd)
Definition: winstation.c:143
#define WM_DESTROY
Definition: winuser.h:1591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
ULONG dwMajorVersion
Definition: rtltypes.h:243
static const WCHAR Title[]
Definition: oid.c:1259
#define d
Definition: ke_i.h:81
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
int cbWndExtra
Definition: winuser.h:3154
__wchar_t WCHAR
Definition: xmlstorage.h:180
COLORREF ForegroundColor
Definition: rosperf.h:27
#define SWP_NOACTIVATE
Definition: winuser.h:1227
static LRESULT CALLBACK LabelWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: rosperf.c:587
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:242
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:2627
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
unsigned long DWORD
Definition: ntddk_ex.h:95
HICON hIcon
Definition: winuser.h:3156
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define WM_PAINT
Definition: winuser.h:1602
CHAR Message[80]
Definition: alive.c:5
ULONG dwBuildNumber
Definition: rtltypes.h:245
static const WCHAR L[]
Definition: oid.c:1250
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
static BOOLEAN Repeat
Definition: dem.c:247
static BOOL ProcessCommandLine(PPERF_INFO PerfInfo, unsigned *TestCount, PTEST *Tests)
Definition: rosperf.c:716
struct _OSVERSIONINFOEXW OSVERSIONINFOEXW
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
ULONG dwPlatformId
Definition: rtltypes.h:246
Status
Definition: gdiplustypes.h:24
HCURSOR hCursor
Definition: winuser.h:3157
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
unsigned Repeats
Definition: rosperf.h:26
#define MAINWND_HEIGHT
Definition: rosperf.c:51
void NullCleanup(void *Context, PPERF_INFO PerfInfo)
Definition: rosperf.c:64
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
HBRUSH hbrBackground
Definition: winuser.h:3158
static void ReportTimes(DWORD Time, int Reps, LPCWSTR Label, BOOL Average)
Definition: rosperf.c:226
Definition: comm.c:64
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#define VERTRES
Definition: wingdi.h:716
static void ProcessTest(PTEST Test, PPERF_INFO PerfInfo)
Definition: rosperf.c:251
#define VER_PLATFORM_WIN32_WINDOWS
Definition: rtltypes.h:235
#define VER_NT_SERVER
static double RoundTo3Digits(double d)
Definition: rosperf.c:180
HINSTANCE hInstance
Definition: winuser.h:3155
COLORREF BackgroundColor
Definition: rosperf.h:28
static unsigned CalibrateTest(PTEST Test, PPERF_INFO PerfInfo)
Definition: rosperf.c:92
ULONG dwMinorVersion
Definition: rtltypes.h:244
#define IDC_ARROW
Definition: winuser.h:682
static void PrintStartupInfo(void)
Definition: rosperf.c:551
#define ENOUGH
HDC ForegroundDc
Definition: rosperf.h:29
#define WM_CREATE
Definition: winuser.h:1590
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
struct tagContext Context
Definition: acpixf.h:1034
FILE * stderr
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
LONG bottom
Definition: windef.h:309
PWCHAR Label
Definition: format.c:70
#define SWP_NOMOVE
Definition: winuser.h:1229
#define malloc
Definition: debug_ros.c:4
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
static HWND LabelWnd
Definition: rosperf.c:53
unsigned NullInit(void **Context, PPERF_INFO PerfInfo, unsigned Reps)
Definition: rosperf.c:56
void GetTests(unsigned *TestCount, PTEST *Tests)
Definition: testlist.c:39
LONG tmHeight
Definition: wingdi.h:2382
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define PM_REMOVE
Definition: winuser.h:1182
static int CurrentTest
Definition: reg.c:155
void exit(int exitcode)
Definition: _exit.c:33
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
#define WS_VISIBLE
Definition: pedump.c:620
static void PrintDisplayInfo(void)
Definition: rosperf.c:534
LPARAM lParam
Definition: combotst.c:139
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct test_data Tests[]
unsigned Seconds
Definition: rosperf.h:25
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
static PLARGE_INTEGER Time
Definition: time.c:105
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
struct Rect Rect
#define ULONG_MAX
Definition: limits.h:44
INT WndWidth
Definition: rosperf.h:31
#define PLANES
Definition: wingdi.h:720
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define SWP_NOOWNERZORDER
Definition: winuser.h:1234
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22