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.

401 lines
11 KiB

  1. //---------------------------------------------------------------------------
  2. // UxBud.cpp - quick cmdline test for uxtheme.dll
  3. //---------------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "uxbud.h"
  6. //---------------------------------------------------------------------------
  7. BOOL fQuiet = FALSE;
  8. HANDLE hFileOutput = NULL;
  9. TESTINFO *pTestInfo;
  10. int iTestCount;
  11. //---------------------------------------------------------------------------
  12. void Output(LPCSTR pszFormat, ...)
  13. {
  14. //---- writes to both "uxbud.log" and console ----
  15. va_list args;
  16. va_start(args, pszFormat);
  17. //---- format caller's string ----
  18. CHAR szBigBuff[256];
  19. StringCchVPrintfA(szBigBuff, ARRAYSIZE(szBigBuff), pszFormat, args);
  20. if (hFileOutput != INVALID_HANDLE_VALUE)
  21. {
  22. //---- expand all LF to CR/LF ----
  23. CHAR szBuff2[512];
  24. CHAR *s = szBigBuff;
  25. CHAR *p = szBuff2;
  26. while (*s)
  27. {
  28. if (*s == '\n')
  29. {
  30. *p++ = '\r';
  31. }
  32. *p++ = *s++;
  33. }
  34. *p = 0; // zero terminate szBuff2
  35. //---- write expanded buff to log file ----
  36. DWORD dw;
  37. WriteFile(hFileOutput, szBuff2, strlen(szBuff2), &dw, NULL);
  38. }
  39. if (! fQuiet)
  40. printf(szBigBuff);
  41. va_end(args);
  42. }
  43. //-----------------------------------------------------------------
  44. BOOL ReportResults(BOOL fPassed, HRESULT hr, LPCWSTR pszTestName)
  45. {
  46. Output("%S ", pszTestName);
  47. if (fPassed)
  48. {
  49. Output("PASSED\n\n");
  50. }
  51. else
  52. {
  53. if (hr == S_OK)
  54. hr = GetLastError();
  55. WCHAR szBuff[2*MAX_PATH];
  56. if (THEME_PARSING_ERROR(hr))
  57. {
  58. PARSE_ERROR_INFO Info = {sizeof(Info)};
  59. HRESULT hr2 = GetThemeParseErrorInfo(&Info);
  60. if (SUCCEEDED(hr2))
  61. {
  62. StringCchCopyW(szBuff, ARRAYSIZE(szBuff), Info.szMsg);
  63. }
  64. else
  65. {
  66. StringCchPrintfW(szBuff, ARRAYSIZE(szBuff), L"Unknown parsing error");
  67. }
  68. }
  69. else
  70. {
  71. // normal win32 error
  72. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, szBuff, ARRAYSIZE(szBuff), NULL);
  73. }
  74. Output("FAILED [%S]\n\n", pszTestName, szBuff);
  75. }
  76. return fPassed;
  77. }
  78. //---------------------------------------------------------------------------
  79. BOOL RunCmd(LPCWSTR pszExeName, LPCWSTR pszParams, BOOL fHide, BOOL fDisplayParams,
  80. BOOL fWait)
  81. {
  82. HANDLE hInst;
  83. BOOL fRanOk = FALSE;
  84. STARTUPINFO si;
  85. memset(&si, 0, sizeof(si));
  86. si.cb = sizeof(STARTUPINFO);
  87. si.dwFlags = STARTF_FORCEOFFFEEDBACK; // don't mess with our cursor
  88. if (fHide)
  89. {
  90. si.dwFlags |= STARTF_USESHOWWINDOW; // hide window
  91. si.wShowWindow = SW_HIDE;
  92. }
  93. PROCESS_INFORMATION pi;
  94. TCHAR szBuff[2*_MAX_PATH];
  95. if (pszParams)
  96. StringCchPrintfW(szBuff, ARRAYSIZE(szBuff), _T("%s %s"), pszExeName, pszParams);
  97. else
  98. {
  99. StringCchCopyW(szBuff, ARRAYSIZE(szBuff), pszExeName);
  100. }
  101. BOOL bSuccess = CreateProcess(NULL, szBuff, NULL, NULL,
  102. FALSE, 0, NULL, NULL, &si, &pi);
  103. if (! bSuccess)
  104. goto exit;
  105. hInst = pi.hProcess;
  106. if (! hInst)
  107. goto exit;
  108. if (fWait)
  109. {
  110. //---- wait for process to terminate ----
  111. DWORD dwVal;
  112. dwVal = WaitForSingleObject(hInst, INFINITE);
  113. if (dwVal != WAIT_OBJECT_0)
  114. goto exit;
  115. DWORD dwExitCode;
  116. if (! GetExitCodeProcess(hInst, &dwExitCode))
  117. goto exit;
  118. if (dwExitCode)
  119. goto exit;
  120. }
  121. fRanOk = TRUE;
  122. exit:
  123. if (fWait) // being used for the test...
  124. {
  125. if (fDisplayParams)
  126. Output(" RunCmd: %S (ranok=%d)\n", szBuff, fRanOk);
  127. else
  128. Output(" RunCmd: %S <params> (ranok=%d)\n", pszExeName, fRanOk);
  129. }
  130. CloseHandle(hInst);
  131. return fRanOk;
  132. }
  133. //---------------------------------------------------------------------------
  134. BOOL TestAll()
  135. {
  136. DWORD dwStartTicks = GetTickCount();
  137. for (int i=0; i < iTestCount; i++)
  138. {
  139. pTestInfo[i].pfnTest();
  140. }
  141. DWORD dwTicks = GetTickCount() - dwStartTicks;
  142. if (! fQuiet)
  143. printf("Total test time: %d secs\n", dwTicks/1000);
  144. return TRUE;
  145. }
  146. //---------------------------------------------------------------------------
  147. void PrintTests()
  148. {
  149. printf("available tests: \n");
  150. for (int i=0; i < iTestCount; i++)
  151. {
  152. printf(" %s \t(%s)\n", pTestInfo[i].pszName, pTestInfo[i].pszDesc);
  153. }
  154. printf("\n");
  155. }
  156. //---------------------------------------------------------------------------
  157. void PrintHelp()
  158. {
  159. printf("\nusage\n");
  160. printf(" uxbud [ <options> ] \n\n");
  161. printf("UxBud will run a set of quick tests to verify basic \"uxtheme.dll\"\n");
  162. printf("functionality. If no options are specified, one pass over the normal\n");
  163. printf("set of tests will be run and the \"uxbud.log\" file created will be \n");
  164. printf("compared against the known good \"uxbud.ok\" log file. This will result\n");
  165. printf("in an overall PASS or FAIL msg at the end of the uxbud run.\n\n");
  166. printf("<options>:\n\n");
  167. printf(" -r <number> (to specify a repeat factor)\n");
  168. printf(" -q (to run in quiet mode\n");
  169. printf(" -? (to print this usage msg\n");
  170. printf(" <test> (to run a specific test\n\n");
  171. PrintTests();
  172. }
  173. //---------------------------------------------------------------------------
  174. BOOL HandleOptions(LPTSTR pszCmdLine, TESTPROC *ppfnTest, int *piRepeat, BOOL *pfQuiet, int *piRetVal)
  175. {
  176. BOOL fContinue = TRUE;
  177. USES_CONVERSION;
  178. *piRetVal = 0;
  179. if ((! pszCmdLine) || (! *pszCmdLine)) // no options
  180. return TRUE;
  181. LPCSTR p = W2A(pszCmdLine);
  182. while ((p) && (*p))
  183. {
  184. while (isspace(*p))
  185. p++;
  186. //---- process switches ----
  187. if ((*p == '/') || (*p == '-'))
  188. {
  189. p++;
  190. if ((*p == 'r') || (*p == 'R')) // repeat factor
  191. {
  192. p++;
  193. while (isspace(*p))
  194. p++;
  195. sscanf(p, "%d", piRepeat);
  196. //---- skip over the scanned number ----
  197. while (isdigit(*p))
  198. p++;
  199. }
  200. else if ((*p == 'q') || (*p == 'Q')) // quiet mode
  201. {
  202. p++;
  203. *pfQuiet = TRUE;
  204. }
  205. else if (*p == '?') // cmdline help
  206. {
  207. p++;
  208. PrintHelp();
  209. fContinue = FALSE;
  210. break;
  211. }
  212. }
  213. else // test name specified
  214. {
  215. for (int i=0; i < iTestCount; i++)
  216. {
  217. if (lstrcmpiA(p, pTestInfo[i].pszName)==0)
  218. {
  219. *ppfnTest = pTestInfo[i].pfnTest;
  220. break;
  221. }
  222. }
  223. if (i == iTestCount) // not found
  224. {
  225. printf("\nError - unrecognized test: %s\n\n", p);
  226. PrintTests();
  227. *piRetVal = 1;
  228. fContinue = FALSE;
  229. }
  230. break;
  231. }
  232. }
  233. return fContinue;
  234. }
  235. //---------------------------------------------------------------------------
  236. BOOL FileCompare(LPCWSTR pszName1, LPCWSTR pszName2)
  237. {
  238. BOOL fSame = FALSE;
  239. HANDLE hFile1 = NULL;
  240. HANDLE hFile2 = NULL;
  241. CHAR *pszBuff1 = NULL;
  242. CHAR *pszBuff2= NULL;
  243. DWORD dw1, dw2;
  244. //---- open files ----
  245. hFile1 = CreateFile(pszName1, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  246. if (hFile1 == INVALID_HANDLE_VALUE)
  247. goto exit;
  248. hFile2 = CreateFile(pszName2, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  249. if (hFile2 == INVALID_HANDLE_VALUE)
  250. goto exit;
  251. DWORD dwSize1, dwSize2;
  252. dwSize1 = GetFileSize(hFile1, NULL);
  253. dwSize2 = GetFileSize(hFile1, NULL);
  254. if ((! dwSize1) || (dwSize1 != dwSize2))
  255. goto exit;
  256. pszBuff1 = new CHAR[dwSize1];
  257. if (! pszBuff1)
  258. goto exit;
  259. pszBuff2 = new CHAR[dwSize1];
  260. if (! pszBuff2)
  261. goto exit;
  262. ReadFile(hFile1, pszBuff1, dwSize1, &dw1, NULL);
  263. ReadFile(hFile2, pszBuff2, dwSize1, &dw2, NULL);
  264. if ((dw1 != dwSize1) || (dw2 != dwSize1))
  265. goto exit;
  266. if (memcmp(pszBuff1, pszBuff2, dwSize1)!=0)
  267. goto exit;
  268. fSame = TRUE;
  269. exit:
  270. delete [] pszBuff1;
  271. delete [] pszBuff2;
  272. CloseHandle(hFile1);
  273. CloseHandle(hFile2);
  274. return fSame;
  275. }
  276. //---------------------------------------------------------------------------
  277. extern "C" WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE previnst,
  278. LPTSTR pszCmdLine, int nShowCmd)
  279. {
  280. //---- default run params ----
  281. int iRepeat = 1;
  282. int iRetVal = 0;
  283. TESTPROC pfnTest = TestAll;
  284. GetTestInfo(&pTestInfo, &iTestCount);
  285. if (! HandleOptions(pszCmdLine, &pfnTest, &iRepeat, &fQuiet, &iRetVal))
  286. return iRetVal;
  287. //---- create the log file ----
  288. hFileOutput = CreateFile(L"uxbud.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
  289. if (hFileOutput == INVALID_HANDLE_VALUE)
  290. {
  291. printf("\nError - could not open uxbud.log output file\n");
  292. return 1;
  293. }
  294. printf("\nUxBud - quick (under 3 mins) test for uxtheme.dll (version 1.0)\n\n");
  295. if (iRepeat > 1)
  296. Output("REPEAT FACTOR=%d\n\n", iRepeat);
  297. //---- run the needed test ----
  298. for (int i=0; i < iRepeat; i++)
  299. {
  300. if (iRepeat > 1)
  301. Output("TEST PASS: %d\n\n", i);
  302. pfnTest();
  303. }
  304. //---- close the log file ----
  305. if (hFileOutput)
  306. CloseHandle(hFileOutput);
  307. if ((iRepeat == 1) && (pfnTest == TestAll)) // standard run
  308. {
  309. if (FileCompare(L"uxbud.log", L"uxbud.ok"))
  310. {
  311. printf("*** UxBud PASSED ****\n");
  312. }
  313. else
  314. {
  315. printf("\nFailure detected - running: windiff uxbud.ok uxbud.log...)\n\n");
  316. printf("*** UxBud FAILED ****\n");
  317. RunCmd(L"windiff", L"uxbud.ok uxbud.log", TRUE, FALSE, FALSE);
  318. }
  319. }
  320. return 0;
  321. }
  322. //---------------------------------------------------------------------------