ReactOS  0.4.13-dev-39-g8b6696f
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 #define BUFSIZE 160
294  OSVERSIONINFOEXW VersionInfo;
295  BOOL OsVersionInfoEx;
296  HKEY hKey;
297  WCHAR ProductType[BUFSIZE];
298  DWORD BufLen;
299  LONG Ret;
300  unsigned RosVersionLen;
301  LPWSTR RosVersion;
302 
303  /* Try calling GetVersionEx using the OSVERSIONINFOEX structure.
304  * If that fails, try using the OSVERSIONINFO structure. */
305 
306  ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFOEXW));
307  VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
308 
309  OsVersionInfoEx = GetVersionExW((OSVERSIONINFOW *) &VersionInfo);
310  if (! OsVersionInfoEx)
311  {
312  VersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
313  if (! GetVersionExW((OSVERSIONINFOW *) &VersionInfo))
314  {
315  return;
316  }
317  }
318 
319  RosVersion = VersionInfo.szCSDVersion + wcslen(VersionInfo.szCSDVersion) + 1;
320  RosVersionLen = sizeof(VersionInfo.szCSDVersion) / sizeof(VersionInfo.szCSDVersion[0]) -
321  (RosVersion - VersionInfo.szCSDVersion);
322  if (7 <= RosVersionLen && 0 == _wcsnicmp(RosVersion, L"ReactOS", 7))
323  {
324  wprintf(L"Running on %s\n", RosVersion);
325  return;
326  }
327 
328  switch (VersionInfo.dwPlatformId)
329  {
330  /* Test for the Windows NT product family. */
332 
333  /* Test for the specific product. */
334  if (5 == VersionInfo.dwMajorVersion && 2 == VersionInfo.dwMinorVersion)
335  {
336  wprintf(L"Running on Microsoft Windows Server 2003, ");
337  }
338  else if (5 == VersionInfo.dwMajorVersion && 1 == VersionInfo.dwMinorVersion)
339  {
340  wprintf(L"Running on Microsoft Windows XP ");
341  }
342  else if (5 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
343  {
344  wprintf(L"Running on Microsoft Windows 2000 ");
345  }
346  else if (VersionInfo.dwMajorVersion <= 4 )
347  {
348  wprintf(L"Running on Microsoft Windows NT ");
349  }
350 
351  /* Test for specific product on Windows NT 4.0 SP6 and later. */
352  if (OsVersionInfoEx)
353  {
354  /* Test for the workstation type. */
355  if (VER_NT_WORKSTATION == VersionInfo.wProductType)
356  {
357  if (4 == VersionInfo.dwMajorVersion)
358  {
359  wprintf(L"Workstation 4.0 ");
360  }
361  else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_PERSONAL))
362  {
363  wprintf(L"Home Edition ");
364  }
365  else
366  {
367  wprintf(L"Professional ");
368  }
369  }
370 
371  /* Test for the server type. */
372  else if (VER_NT_SERVER == VersionInfo.wProductType ||
373  VER_NT_DOMAIN_CONTROLLER == VersionInfo.wProductType)
374  {
375  if (5 == VersionInfo.dwMajorVersion && 2 == VersionInfo.dwMinorVersion)
376  {
377  if (0 != (VersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
378  {
379  wprintf(L"Datacenter Edition ");
380  }
381  else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
382  {
383  wprintf(L"Enterprise Edition ");
384  }
385  else if (VER_SUITE_BLADE == VersionInfo.wSuiteMask)
386  {
387  wprintf(L"Web Edition ");
388  }
389  else
390  {
391  wprintf(L"Standard Edition ");
392  }
393  }
394 
395  else if (5 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
396  {
397  if (0 != (VersionInfo.wSuiteMask & VER_SUITE_DATACENTER))
398  {
399  wprintf(L"Datacenter Server ");
400  }
401  else if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
402  {
403  wprintf(L"Advanced Server " );
404  }
405  else
406  {
407  wprintf(L"Server " );
408  }
409  }
410 
411  else /* Windows NT 4.0 */
412  {
413  if (0 != (VersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE))
414  {
415  wprintf(L"Server 4.0, Enterprise Edition ");
416  }
417  else
418  {
419  wprintf(L"Server 4.0 ");
420  }
421  }
422  }
423  }
424  else /* Test for specific product on Windows NT 4.0 SP5 and earlier */
425  {
426  BufLen = BUFSIZE;
427 
429  L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
430  0, KEY_QUERY_VALUE, &hKey);
431  if (ERROR_SUCCESS != Ret)
432  {
433  return;
434  }
435 
436  Ret = RegQueryValueExW(hKey, L"ProductType", NULL, NULL,
437  (LPBYTE) ProductType, &BufLen);
438  if (ERROR_SUCCESS != Ret || BUFSIZE < BufLen)
439  {
440  return;
441  }
442 
443  RegCloseKey(hKey);
444 
445  if (0 == lstrcmpiW(L"WINNT", ProductType))
446  {
447  wprintf(L"Workstation ");
448  }
449  else if (0 == lstrcmpiW(L"LANMANNT", ProductType))
450  {
451  wprintf(L"Server ");
452  }
453  else if (0 == lstrcmpiW(L"SERVERNT", ProductType))
454  {
455  wprintf(L"Advanced Server ");
456  }
457 
458  wprintf(L"%d.%d ", VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion);
459  }
460 
461  /* Display service pack (if any) and build number. */
462 
463  if (4 == VersionInfo.dwMajorVersion &&
464  0 == lstrcmpiW(VersionInfo.szCSDVersion, L"Service Pack 6"))
465  {
466  /* Test for SP6 versus SP6a. */
468  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
469  0, KEY_QUERY_VALUE, &hKey);
470  if (ERROR_SUCCESS == Ret)
471  {
472  wprintf(L"Service Pack 6a (Build %d)\n", VersionInfo.dwBuildNumber & 0xFFFF);
473  }
474  else /* Windows NT 4.0 prior to SP6a */
475  {
476  wprintf(L"%s (Build %d)\n",
477  VersionInfo.szCSDVersion,
478  VersionInfo.dwBuildNumber & 0xFFFF);
479  }
480 
481  RegCloseKey(hKey);
482  }
483  else /* not Windows NT 4.0 */
484  {
485  wprintf(L"%s (Build %d)\n",
486  VersionInfo.szCSDVersion,
487  VersionInfo.dwBuildNumber & 0xFFFF);
488  }
489 
490 
491  break;
492 
493  /* Test for the Windows Me/98/95. A bit silly since we're using Unicode... */
495 
496  if (4 == VersionInfo.dwMajorVersion && 0 == VersionInfo.dwMinorVersion)
497  {
498  wprintf(L"Running on Microsoft Windows 95 ");
499  if (L'C' == VersionInfo.szCSDVersion[1] || L'B' == VersionInfo.szCSDVersion[1])
500  {
501  wprintf(L"OSR2");
502  }
503  }
504 
505  else if (4 == VersionInfo.dwMajorVersion && 10 == VersionInfo.dwMinorVersion)
506  {
507  wprintf(L"Running on Microsoft Windows 98 ");
508  if (L'A' == VersionInfo.szCSDVersion[1])
509  {
510  wprintf(L"SE");
511  }
512  }
513 
514  else if (4 == VersionInfo.dwMajorVersion && 90 == VersionInfo.dwMinorVersion)
515  {
516  wprintf(L"Running on Microsoft Windows Millennium Edition");
517  }
518  wprintf(L"\n");
519  break;
520 
521  case VER_PLATFORM_WIN32s: /* Even silier... */
522 
523  wprintf(L"Running on Microsoft Win32s\n");
524  break;
525  }
526 }
527 
528 static void
530 {
531  wprintf(L"RosPerf %S (Build %S)\n", KERNEL_VERSION_STR, KERNEL_VERSION_BUILD_STR);
532 }
533 
534 static void
536 {
537  HDC Dc;
538 
539  Dc = GetDC(NULL);
540  if (NULL == Dc)
541  {
542  return;
543  }
544 
545  wprintf(L"Display settings %d * %d * %d\n", GetDeviceCaps(Dc, HORZRES),
547 
548  ReleaseDC(NULL, Dc);
549 }
550 
551 static void
553 {
554  PrintAppVersion();
555  PrintOSVersion();
557 }
558 
559 static LRESULT CALLBACK
561 {
562  PAINTSTRUCT Ps;
563  HDC Dc;
564  LRESULT Result;
565 
566  switch (Msg)
567  {
568  case WM_DESTROY:
569  PostQuitMessage(0);
570  Result = 0;
571  break;
572 
573  case WM_PAINT:
574  Dc = BeginPaint(Wnd, &Ps);
575  EndPaint (Wnd, &Ps);
576  Result = 0;
577  break;
578 
579  default:
581  break;
582  }
583 
584  return Result;
585 }
586 
587 static LRESULT CALLBACK
589 {
590  PAINTSTRUCT Ps;
591  HDC Dc;
592  RECT ClientRect, WindowRect;
593  TEXTMETRICW Tm;
594  LRESULT Result;
595  WCHAR Title[80];
596 
597  switch (Msg)
598  {
599  case WM_CREATE:
600  /* Make text fit */
601  Dc = GetDC(Wnd);
602  if (NULL != Dc && GetClientRect(Wnd, &ClientRect) && GetWindowRect(Wnd, &WindowRect)
603  && GetTextMetricsW(Dc, &Tm))
604  {
605  if (Tm.tmHeight != ClientRect.bottom)
606  {
607  SetWindowPos(Wnd, NULL, 0, 0, WindowRect.right - WindowRect.left,
608  (WindowRect.bottom - WindowRect.top) + (Tm.tmHeight - ClientRect.bottom),
610  }
611  }
612  if (NULL != Dc)
613  {
614  ReleaseDC(Wnd, Dc);
615  }
617  break;
618 
619  case WM_PAINT:
620  Dc = BeginPaint(Wnd, &Ps);
621  GetWindowTextW(Wnd, Title, sizeof(Title) / sizeof(Title[0]));
622  TextOutW(Dc, 0, 0, Title, wcslen(Title));
623  EndPaint (Wnd, &Ps);
624  Result = 0;
625  break;
626 
627  default:
629  break;
630  }
631 
632  return Result;
633 }
634 
635 static HWND
637 {
638  WNDCLASSW wc;
639  HWND MainWnd;
640 
641  wc.lpszClassName = L"RosPerfMain";
643  wc.style = 0;
644  wc.hInstance = hInstance;
648  wc.lpszMenuName = NULL;
649  wc.cbClsExtra = 0;
650  wc.cbWndExtra = 0;
651  if (RegisterClassW(&wc) == 0)
652  {
653  fwprintf(stderr, L"Failed to register RosPerfMain (last error %d)\n",
654  GetLastError());
655  return NULL;
656  }
657 
658  wc.lpszClassName = L"RosPerfLabel";
660  wc.style = 0;
661  wc.hInstance = hInstance;
665  wc.lpszMenuName = NULL;
666  wc.cbClsExtra = 0;
667  wc.cbWndExtra = 0;
668  if (RegisterClassW(&wc) == 0)
669  {
670  fwprintf(stderr, L"Failed to register RosPerfLabel (last error %d)\n",
671  GetLastError());
672  return NULL;
673  }
674 
675  MainWnd = CreateWindowW(L"RosPerfMain",
676  L"ReactOS performance test",
678  0,
679  0,
682  NULL,
683  NULL,
684  hInstance,
685  NULL);
686  if (NULL == MainWnd)
687  {
688  fwprintf(stderr, L"Failed to create main window (last error %d)\n",
689  GetLastError());
690  return NULL;
691  }
692 
693  LabelWnd = CreateWindowW(L"RosPerfLabel",
694  L"",
696  0,
697  MAINWND_HEIGHT + 10,
699  20,
700  MainWnd,
701  NULL,
702  hInstance,
703  NULL);
704  if (NULL == LabelWnd)
705  {
706  fwprintf(stderr, L"Failed to create label window (last error 0x%lX)\n",
707  GetLastError());
708  return NULL;
709  }
710 
711  SetActiveWindow(MainWnd);
712 
713  return MainWnd;
714 }
715 
716 static BOOL
717 ProcessCommandLine(PPERF_INFO PerfInfo, unsigned *TestCount, PTEST *Tests)
718 {
719  int ArgC, Arg;
720  LPWSTR *ArgV;
721  LPWSTR EndPtr;
722  PTEST AllTests;
723  BOOL *DoTest;
724  BOOL DoAll;
725  unsigned AllTestCount, i, j;
726 
727  ArgV = CommandLineToArgvW(GetCommandLineW(), &ArgC);
728  if (NULL == ArgV)
729  {
730  fwprintf(stderr, L"CommandLineToArgvW failed\n");
731  return FALSE;
732  }
733 
734  GetTests(&AllTestCount, &AllTests);
735  DoTest = malloc(AllTestCount * sizeof(BOOL));
736  if (NULL == DoTest)
737  {
738  fwprintf(stderr, L"Out of memory\n");
739  return FALSE;
740  }
741  DoAll = TRUE;
742 
743  for (Arg = 1; Arg < ArgC; Arg++)
744  {
745  if (L'/' == ArgV[Arg][0] || L'-' == ArgV[Arg][0])
746  {
747  if (0 == _wcsicmp(ArgV[Arg] + 1, L"repeat"))
748  {
749  if (ArgC <= Arg + 1)
750  {
751  fwprintf(stderr, L"%s needs a repeat count\n", ArgV[Arg]);
752  free(DoTest);
753  GlobalFree(ArgV);
754  return FALSE;
755  }
756  Arg++;
757  PerfInfo->Repeats = wcstoul(ArgV[Arg], &EndPtr, 0);
758  if (L'\0' != *EndPtr || (long) PerfInfo->Repeats <= 0 || ULONG_MAX == PerfInfo->Repeats)
759  {
760  fwprintf(stderr, L"Invalid repeat count %s\n", ArgV[Arg]);
761  free(DoTest);
762  GlobalFree(ArgV);
763  return FALSE;
764  }
765  }
766  else if (0 == _wcsicmp(ArgV[Arg] + 1, L"seconds"))
767  {
768  if (ArgC <= Arg + 1)
769  {
770  fwprintf(stderr, L"%s needs a number of seconds\n", ArgV[Arg]);
771  free(DoTest);
772  GlobalFree(ArgV);
773  return FALSE;
774  }
775  Arg++;
776  PerfInfo->Seconds = wcstoul(ArgV[Arg], &EndPtr, 0);
777  if (L'\0' != *EndPtr || (long) PerfInfo->Seconds < 0 || ULONG_MAX == PerfInfo->Seconds)
778  {
779  fwprintf(stderr, L"Invalid duration %s\n", ArgV[Arg]);
780  free(DoTest);
781  GlobalFree(ArgV);
782  return FALSE;
783  }
784  }
785  else
786  {
787  fwprintf(stderr, L"Unrecognized option %s\n", ArgV[Arg]);
788  free(DoTest);
789  GlobalFree(ArgV);
790  return FALSE;
791  }
792  }
793  else
794  {
795  if (DoAll)
796  {
797  for (i = 0; i < AllTestCount; i++)
798  {
799  DoTest[i] = FALSE;
800  }
801  DoAll = FALSE;
802  }
803  for (i = 0; i < AllTestCount; i++)
804  {
805  if (0 == _wcsicmp(ArgV[Arg], AllTests[i].Option))
806  {
807  DoTest[i] = TRUE;
808  break;
809  }
810  }
811  if (AllTestCount <= i)
812  {
813  fwprintf(stderr, L"Unrecognized test %s\n", ArgV[Arg]);
814  free(DoTest);
815  GlobalFree(ArgV);
816  return FALSE;
817  }
818  }
819  }
820 
821  GlobalFree(ArgV);
822 
823  if (DoAll)
824  {
825  for (i = 0; i < AllTestCount; i++)
826  {
827  DoTest[i] = TRUE;
828  }
829  }
830 
831  *TestCount = 0;
832  for (i = 0; i < AllTestCount; i++)
833  {
834  if (DoTest[i])
835  {
836  (*TestCount)++;
837  }
838  }
839  *Tests = malloc(*TestCount * sizeof(TEST));
840  if (NULL == *Tests)
841  {
842  fwprintf(stderr, L"Out of memory\n");
843  free(DoTest);
844  return FALSE;
845  }
846  j = 0;
847  for (i = 0; i < AllTestCount; i++)
848  {
849  if (DoTest[i])
850  {
851  (*Tests)[j] = AllTests[i];
852  j++;
853  }
854  }
855  free(DoTest);
856 
857  return TRUE;
858 }
859 
860 int WINAPI
862  HINSTANCE hPrevInstance,
863  LPWSTR lpszCmdLine,
864  int nCmdShow)
865 {
866  PTEST Tests;
867  unsigned TestCount;
868  unsigned CurrentTest;
869  RECT Rect;
870  PERF_INFO PerfInfo;
871 
873 
874  PerfInfo.Seconds = 15;
875  PerfInfo.Repeats = 4;
876  PerfInfo.ForegroundColor = RGB(0, 0, 0);
877  PerfInfo.BackgroundColor = RGB(255, 255, 255);
878 
879  if (! ProcessCommandLine(&PerfInfo, &TestCount, &Tests))
880  {
881  exit(1);
882  }
883 
884  PerfInfo.Wnd = CreatePerfWindows(hInstance, &PerfInfo);
885  if (NULL == PerfInfo.Wnd)
886  {
887  exit(1);
888  }
889 
890  GetClientRect(PerfInfo.Wnd, &Rect);
891  PerfInfo.WndWidth = Rect.right - Rect.left;
892  PerfInfo.WndHeight = Rect.bottom - Rect.top;
893  PerfInfo.ForegroundDc = GetDC(PerfInfo.Wnd);
894  PerfInfo.BackgroundDc = GetDC(PerfInfo.Wnd);
895  if (NULL == PerfInfo.ForegroundDc || NULL == PerfInfo.BackgroundDc)
896  {
897  fwprintf(stderr, L"Failed to create device contexts (last error %d)\n",
898  GetLastError());
899  exit(1);
900  }
905 
906  ProcessMessages();
907 
908  /* Move cursor out of the way */
910  SetCursorPos(Rect.right, Rect.bottom);
911 
912  for (CurrentTest = 0; CurrentTest < TestCount; CurrentTest++)
913  {
914  wprintf(L"\n");
915  ProcessTest(Tests + CurrentTest, &PerfInfo);
916  }
917 
918  GlobalFree(Tests);
919 
920  return 0;
921 }
922 
923 /* EOF */
HGDIOBJ WINAPI GetStockObject(_In_ int)
static size_t double int int int * sign
Definition: printf.c:64
#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:3129
#define ERROR_SUCCESS
Definition: deptool.c:10
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpszCmdLine, int nCmdShow)
Definition: rosperf.c:861
LPCWSTR lpszMenuName
Definition: winuser.h:3137
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static HWND CreatePerfWindows(HINSTANCE hInstance, PPERF_INFO PerfInfo)
Definition: rosperf.c:636
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:560
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:445
LONG top
Definition: windef.h:292
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:1635
int cbClsExtra
Definition: winuser.h:3131
#define WHITE_BRUSH
Definition: wingdi.h:901
HDC BackgroundDc
Definition: rosperf.h:30
struct @1567 Msg[]
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
#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:291
#define SWP_NOZORDER
Definition: winuser.h:1232
#define TICK
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define wprintf(...)
Definition: whoami.c:18
#define BUFSIZE
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
LONG right
Definition: windef.h:293
#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:4185
#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:529
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:52
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:2043
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
WNDPROC lpfnWndProc
Definition: winuser.h:3130
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:76
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:3138
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:4134
int cbWndExtra
Definition: winuser.h:3132
__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:588
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:242
#define RGB(r, g, b)
Definition: wingdi.h:2918
#define WINAPI
Definition: msvc.h:8
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:3134
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:717
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:3135
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:1378
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
HBRUSH hbrBackground
Definition: winuser.h:3136
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:3133
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:552
#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:1012
FILE * stderr
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
LONG bottom
Definition: windef.h:294
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:2361
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:535
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