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

542 lines
15 KiB

  1. //---------------------------------------------------------------------------
  2. // tests.cpp - tests for uxbud
  3. //---------------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "uxbud.h"
  6. #include "tests.h"
  7. #include "winuserp.h"
  8. #include "wingdip.h"
  9. //---------------------------------------------------------------------------
  10. #define MAX_PRINT_FILE_SIZE 512
  11. //---------------------------------------------------------------------------
  12. int GetStockAvailCount()
  13. {
  14. //---- slow but better than nothing! ----
  15. int iCount=0;
  16. HANDLE *pHandles = new HANDLE[10000];
  17. if (pHandles)
  18. {
  19. //---- create a bunch of stock bitmaps ----
  20. while (1)
  21. {
  22. HBITMAP hBitmap = CreateBitmap(1, 1, 1, 24, NULL);
  23. if (! hBitmap)
  24. {
  25. MessageBox(NULL, L"CreateBitmap() failed", L"bummer, man!", MB_OK);
  26. break;
  27. }
  28. hBitmap = SetBitmapAttributes(hBitmap, SBA_STOCK);
  29. if (! hBitmap)
  30. {
  31. //---- finally used up all avail stock bitmaps ----
  32. break;
  33. }
  34. pHandles[iCount++] = hBitmap;
  35. }
  36. //---- free a bunch of stock bitmaps ----
  37. for (int i=0; i < iCount; i++)
  38. {
  39. HBITMAP hBitmap = ClearBitmapAttributes((HBITMAP)pHandles[i], SBA_STOCK);
  40. if (! hBitmap)
  41. {
  42. MessageBox(NULL, L"SetBitmapAttributes() failed to reset stock", L"bummer, man!", MB_OK);
  43. }
  44. else
  45. {
  46. DeleteObject(hBitmap);
  47. }
  48. }
  49. delete [] pHandles;
  50. }
  51. else
  52. {
  53. MessageBox(NULL, L"cannot allocate 10K handle array", L"bummer, man!", MB_OK);
  54. }
  55. return iCount;
  56. }
  57. //---------------------------------------------------------------------------
  58. BOOL ZapDir(LPCWSTR pszDirName)
  59. {
  60. //---- does this guy exist? ----
  61. DWORD dwMask = GetFileAttributes(pszDirName);
  62. BOOL fExists = (dwMask != 0xffffffff);
  63. if (! fExists)
  64. return TRUE; // not an error
  65. //---- delete all files or subdirs within the dir ----
  66. HANDLE hFile;
  67. WIN32_FIND_DATA wfd;
  68. BOOL bFile = TRUE;
  69. WCHAR szSearchPattern[MAX_PATH];
  70. wsprintf(szSearchPattern, L"%s\\*.*", pszDirName);
  71. for (hFile=FindFirstFile(szSearchPattern, &wfd); (hFile != INVALID_HANDLE_VALUE) && (bFile);
  72. bFile=FindNextFile(hFile, &wfd))
  73. {
  74. if ((lstrcmp(wfd.cFileName, TEXT("."))==0) || (lstrcmp(wfd.cFileName, TEXT(".."))==0))
  75. continue;
  76. WCHAR szFullName[MAX_PATH];
  77. wsprintf(szFullName, L"%s\\%s", pszDirName, wfd.cFileName);
  78. if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  79. {
  80. if (! ZapDir(szFullName))
  81. return FALSE;
  82. }
  83. else
  84. {
  85. if (! DeleteFile(szFullName))
  86. return FALSE;
  87. }
  88. }
  89. FindClose(hFile);
  90. //---- this requires an empty dir ----
  91. return RemoveDirectory(pszDirName);
  92. }
  93. //---------------------------------------------------------------------------
  94. BOOL TestFile(LPCWSTR pszFileName)
  95. {
  96. DWORD dwMask = GetFileAttributes(pszFileName);
  97. BOOL fExists = (dwMask != 0xffffffff);
  98. Output(" TestFile(%S)=%s\n", pszFileName, (fExists) ? "true" : "false");
  99. return fExists;
  100. }
  101. //---------------------------------------------------------------------------
  102. BOOL PrintFileContents(LPCSTR pszTitle, LPCWSTR pszFileName)
  103. {
  104. HANDLE hFile = NULL;
  105. DWORD dw;
  106. CHAR szBuff[MAX_PRINT_FILE_SIZE];
  107. BOOL fRead = FALSE;
  108. //---- open files ----
  109. hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  110. if (hFile == INVALID_HANDLE_VALUE)
  111. goto exit;
  112. ReadFile(hFile, szBuff, MAX_PRINT_FILE_SIZE, &dw, NULL);
  113. if (! dw)
  114. goto exit;
  115. szBuff[dw] = 0; // null terminate string
  116. fRead = TRUE;
  117. Output(" %s: %s\n", pszTitle, szBuff);
  118. exit:
  119. Output(" PrintFileContents: %S (fRead=%d)\n", pszFileName, fRead);
  120. CloseHandle(hFile);
  121. return fRead;
  122. }
  123. //---------------------------------------------------------------------------
  124. BOOL ErrorTester(LPCSTR pszCallTitle, HRESULT hr)
  125. {
  126. WCHAR szErrBuff[2*MAX_PATH];
  127. HRESULT hr2;
  128. BOOL fGotMsg = FALSE;
  129. if (SUCCEEDED(hr))
  130. {
  131. //---- error - should have FAILED ----
  132. Output(" Error - %s Succeeded (expected error)\n");
  133. goto exit;
  134. }
  135. hr2 = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, szErrBuff, ARRAYSIZE(szErrBuff), NULL);
  136. if (FAILED(hr2))
  137. {
  138. wsprintf(szErrBuff, L"Cannot format error=0x%x (FormatError=0x%x)", hr, hr2);
  139. }
  140. Output(" %s returned hr=0x%x, error: %S\n", pszCallTitle, hr, szErrBuff);
  141. fGotMsg = TRUE;
  142. exit:
  143. return fGotMsg;
  144. }
  145. //---------------------------------------------------------------------------
  146. BOOL CompareFiles(LPCWSTR pszName1, LPCWSTR pszName2)
  147. {
  148. BOOL fSame = FileCompare(pszName1, pszName2);
  149. Output(" Compare(%S, %S) = %s\n", pszName1, pszName2,
  150. (fSame) ? "same" : "different");
  151. return fSame;
  152. }
  153. //---------------------------------------------------------------------------
  154. //---------------------------------------------------------------------------
  155. //---------------------------------------------------------------------------
  156. BOOL LoadTest()
  157. {
  158. Output("LoadTest\n");
  159. BOOL fPassed = FALSE;
  160. HRESULT hr = S_OK;
  161. //---- open and close a theme file a few times; ensure working set doesn't ----
  162. //---- grow much for this process or for theme service ----
  163. for (int i=0; i < 6; i++)
  164. {
  165. Output(" LoadTest: pass %d\n", i);
  166. //---- load the luna theme ----
  167. HTHEMEFILE hThemeFile;
  168. //---- use "luna.msstyles" ----
  169. WCHAR szName[MAX_PATH];
  170. GetWindowsDirectoryW(szName, MAX_PATH);
  171. wcscat(szName, L"\\resources\\themes\\luna\\luna.msstyles");
  172. //---- load for local (not global) use to avoid stock brush/bitmap issues ----
  173. HRESULT hr = OpenThemeFile(szName, NULL, NULL, &hThemeFile, FALSE);
  174. if (FAILED(hr))
  175. goto exit;
  176. hr = CloseThemeFile(hThemeFile);
  177. if (FAILED(hr))
  178. goto exit;
  179. }
  180. fPassed = TRUE;
  181. exit:
  182. return ReportResults(fPassed, hr, L"LoadTest");
  183. }
  184. //---------------------------------------------------------------------------
  185. BOOL ApplyTest()
  186. {
  187. BOOL fPassed = FALSE;
  188. HTHEMEFILE hThemeFile;
  189. WCHAR szName[MAX_PATH];
  190. HRESULT hr;
  191. Output("ApplyTest\n");
  192. //---- apply "classic", "professional", and "luna" themes a few times ----
  193. for (int i=0; i < 3; i++)
  194. {
  195. Output(" ApplyTest: pass %d\n", i);
  196. //---- apply "classic" ----
  197. Output(" Classic\n");
  198. ApplyTheme(NULL, 0, NULL);
  199. Sleep(500);
  200. //---- load PROFESSIONAL theme ----
  201. Output(" PROFESSIONAL\n");
  202. GetWindowsDirectoryW(szName, MAX_PATH);
  203. wcscat(szName, L"\\resources\\themes\\professional\\professional.msstyles");
  204. hr = OpenThemeFile(szName, NULL, NULL, &hThemeFile, TRUE);
  205. if (FAILED(hr))
  206. goto exit;
  207. //---- apply PROFESSIONAL ----
  208. hr = ApplyTheme(hThemeFile, AT_LOAD_SYSMETRICS, NULL);
  209. if (FAILED(hr))
  210. goto exit;
  211. Sleep(500);
  212. hr = CloseThemeFile(hThemeFile);
  213. if (FAILED(hr))
  214. goto exit;
  215. //---- load LUNA theme ----
  216. Output(" LUNA\n");
  217. GetWindowsDirectoryW(szName, MAX_PATH);
  218. wcscat(szName, L"\\resources\\themes\\luna\\luna.msstyles");
  219. hr = OpenThemeFile(szName, NULL, NULL, &hThemeFile, TRUE);
  220. if (FAILED(hr))
  221. goto exit;
  222. //---- apply LUNA theme ----
  223. hr = ApplyTheme(hThemeFile, AT_LOAD_SYSMETRICS, NULL);
  224. if (FAILED(hr))
  225. goto exit;
  226. Sleep(500);
  227. hr = CloseThemeFile(hThemeFile);
  228. if (FAILED(hr))
  229. goto exit;
  230. Output(" ApplyTest: after applying Luna, StockAvailCount=%d\n", GetStockAvailCount());
  231. }
  232. fPassed = TRUE;
  233. exit:
  234. return ReportResults(fPassed, hr, L"ApplyTest");
  235. }
  236. //---------------------------------------------------------------------------
  237. BOOL PackTest()
  238. {
  239. BOOL fPassed = FALSE;
  240. WCHAR szParams[512];
  241. WCHAR szWinDir[MAX_PATH];
  242. HRESULT hr = S_OK;
  243. Output("PackTest\n");
  244. //---- unpack professional.msstyles ----
  245. if (! ZapDir(L"professional"))
  246. goto exit;
  247. CreateDirectory(L"professional", NULL);
  248. GetWindowsDirectory(szWinDir, ARRAYSIZE(szWinDir));
  249. wsprintf(szParams, L"/a /u %s\\resources\\themes\\professional\\professional.msstyles", szWinDir);
  250. //---- run unpack in "professional" subdir ----
  251. SetCurrentDirectory(L"professional");
  252. BOOL fRunOk = RunCmd(L"packthem", szParams, TRUE, FALSE);
  253. SetCurrentDirectory(L"..");
  254. if (! fRunOk)
  255. goto exit;
  256. if (! TestFile(L"professional\\default.ini"))
  257. goto exit;
  258. //---- pack it up ----
  259. if (! RunCmd(L"packthem", L"professional", TRUE, TRUE))
  260. goto exit;
  261. if (! TestFile(L"professional\\professional.msstyles"))
  262. goto exit;
  263. fPassed = TRUE;
  264. exit:
  265. return ReportResults(fPassed, hr, L"PackTest");
  266. }
  267. //---------------------------------------------------------------------------
  268. BOOL PackErrTest()
  269. {
  270. BOOL fPassed = FALSE;
  271. HRESULT hr = S_OK;
  272. Output("PackErrTest\n");
  273. //---- run packthem on dir with missing "themes.ini" file ----
  274. if (! ZapDir(L"TestTheme"))
  275. goto exit;
  276. CreateDirectory(L"TestTheme", NULL);
  277. if (! RunCmd(L"packthem", L"/e TestTheme", TRUE, TRUE))
  278. goto exit;
  279. if (! TestFile(L"packthem.err"))
  280. goto exit;
  281. if (! PrintFileContents("Packthem Missing File: ", L"packthem.err"))
  282. goto exit;
  283. //---- run packthem on dir with bad syntax "themes.ini" file ----
  284. CopyFile(L".\\TestTheme.ini", L".\\TestTheme\\themes.ini", TRUE);
  285. if (! RunCmd(L"packthem", L"/e TestTheme", TRUE, TRUE))
  286. goto exit;
  287. if (! TestFile(L"packthem.err"))
  288. goto exit;
  289. if (! PrintFileContents("Packthem Bad Syntax: ", L"packthem.err"))
  290. goto exit;
  291. fPassed = TRUE;
  292. exit:
  293. return ReportResults(fPassed, hr, L"PackErrTest");
  294. }
  295. //---------------------------------------------------------------------------
  296. BOOL ApiErrTest()
  297. {
  298. Output("ApiErrTest\n");
  299. BOOL fPassed = FALSE;
  300. WCHAR szErrBuff[2*MAX_PATH];
  301. COLORREF crValue;
  302. HRESULT hr;
  303. HTHEMEFILE hThemeFile;
  304. //---- GetThemeColor() with bad HTHEME ----
  305. hr = GetThemeColor(NULL, 1, 1, TMT_TEXTCOLOR, &crValue);
  306. ErrorTester("GetThemeColor()", hr);
  307. //---- OpenThemeFile() with corrupt file ----
  308. hr = OpenThemeFile(L"rcdll.dll", NULL, NULL, &hThemeFile, FALSE);
  309. ErrorTester("OpenThemeFile()", hr);
  310. fPassed = TRUE;
  311. return ReportResults(fPassed, hr, L"ApiErrTest");
  312. }
  313. //---------------------------------------------------------------------------
  314. BOOL ImageConTest()
  315. {
  316. BOOL fPassed = FALSE;
  317. HRESULT hr = S_OK;
  318. Output("ImageConTest\n");
  319. DeleteFile(L"image.bmp");
  320. if (! RunCmd(L"imagecon", L"image.png image.bmp", TRUE, TRUE))
  321. goto exit;
  322. if (! TestFile(L"image.bmp"))
  323. goto exit;
  324. fPassed = TRUE;
  325. exit:
  326. return ReportResults(fPassed, hr, L"ImageConTest");
  327. }
  328. //---------------------------------------------------------------------------
  329. BOOL BinaryTest()
  330. {
  331. BOOL fPassed = FALSE;
  332. BOOL fFailed = FALSE;
  333. Output("BinaryTest\n");
  334. //---- load the professional theme ----
  335. HTHEMEFILE hThemeFile;
  336. //---- use "profesional.msstyles" ----
  337. WCHAR szName[MAX_PATH];
  338. GetWindowsDirectoryW(szName, MAX_PATH);
  339. wcscat(szName, L"\\resources\\themes\\professional\\professional.msstyles");
  340. //---- load for local (not global) use to avoid stock brush/bitmap issues ----
  341. HRESULT hr = OpenThemeFile(szName, NULL, NULL, &hThemeFile, FALSE);
  342. if (FAILED(hr))
  343. {
  344. Output(" OpenThemeFile() failed with hr=0x%x\n", hr);
  345. goto exit;
  346. }
  347. //---- dump out the properties to "PropDump.txt" ----
  348. hr = DumpLoadedThemeToTextFile(hThemeFile, L"PropDump.txt", FALSE, FALSE);
  349. if (FAILED(hr))
  350. {
  351. Output(" DumpLoadedThemeToTextFile() failed with hr=0x%x\n", hr);
  352. goto exit;
  353. }
  354. //---- compare to known good file ----
  355. if (! CompareFiles(L"PropDump.ok", L"PropDump.txt"))
  356. fFailed = TRUE;
  357. //---- dump out the packed object to "ObjDump.txt" ----
  358. hr = DumpLoadedThemeToTextFile(hThemeFile, L"ObjDump.txt", TRUE, FALSE);
  359. if (FAILED(hr))
  360. {
  361. Output(" DumpLoadedThemeToTextFile() failed with hr=0x%x\n", hr);
  362. goto exit;
  363. }
  364. //---- compare to known good file ----
  365. if (! CompareFiles(L"ObjDump.ok", L"ObjDump.txt"))
  366. fFailed = TRUE;
  367. if (! fFailed)
  368. fPassed = TRUE;
  369. exit:
  370. return ReportResults(fPassed, hr, L"BinaryTest");
  371. }
  372. //---------------------------------------------------------------------------
  373. WCHAR *BitmapNames[] =
  374. {
  375. L"BorderFill",
  376. L"BorderFill-R",
  377. L"ImageFile",
  378. L"ImageFile-R",
  379. L"Glyph",
  380. L"Glyph-R",
  381. L"MultiImage",
  382. L"MultiImage-R",
  383. L"Text",
  384. L"Text-R",
  385. L"Borders",
  386. L"Borders-R",
  387. L"SourceSizing",
  388. L"SourceSizing-R",
  389. };
  390. //---------------------------------------------------------------------------
  391. BOOL DrawingTest()
  392. {
  393. BOOL fPassed = FALSE;
  394. BOOL fFailed = FALSE;
  395. HRESULT hr = S_OK;
  396. Output("DrawingTest\n");
  397. //---- run "clipper -c" to produce drawing bitmaps ----
  398. if (! RunCmd(L"clipper", L"-c", FALSE, TRUE))
  399. goto exit;
  400. //---- compare bitmaps to known good files ----
  401. int iCount = ARRAYSIZE(BitmapNames);
  402. for (int i=0; i < iCount; i++)
  403. {
  404. WCHAR szOkName[MAX_PATH];
  405. WCHAR szTestName[MAX_PATH];
  406. wsprintf(szOkName, L"%s.bok", BitmapNames[i]);
  407. wsprintf(szTestName, L"%s.bmp", BitmapNames[i]);
  408. if (! CompareFiles(szOkName, szTestName))
  409. fFailed = TRUE;
  410. }
  411. if (! fFailed)
  412. fPassed = TRUE;
  413. exit:
  414. return ReportResults(fPassed, hr, L"DrawingTest");
  415. }
  416. //---------------------------------------------------------------------------
  417. TESTINFO TestInfo[] =
  418. {
  419. {DrawingTest, "drawing", "test out low level drawing"},
  420. {PackTest, "pack", "test out theme file packing & unpacking"},
  421. {PackErrTest, "packerr", "test out err msgs from theme file packing"},
  422. {BinaryTest, "binary", "dump out text from binary theme data"},
  423. {LoadTest, "load", "test loading and unloading of theme files"},
  424. {ApplyTest, "apply", "test global loading & setting of themes"},
  425. {ApiErrTest, "apierr", "test err msgs from api calls"},
  426. //{ApiTest, "api", "test uxtheme public api"},
  427. //{PrivateTest, "private", "test private api calls"},
  428. {ImageConTest, "imagecon", "test out theme file packing & unpacking"},
  429. };
  430. //---------------------------------------------------------------------------
  431. BOOL GetTestInfo(TESTINFO **ppTestInfo, int *piCount)
  432. {
  433. *ppTestInfo = TestInfo;
  434. *piCount = ARRAYSIZE(TestInfo);
  435. return TRUE;
  436. }
  437. //---------------------------------------------------------------------------