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.

512 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: tutils.cxx
  7. //
  8. // Contents: Generic utilities for tests
  9. //
  10. // History: 06-Aug-93 DrewB Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "pch.cxx"
  14. #pragma hdrstop
  15. static BOOL fExitOnFail = TRUE;
  16. BOOL GetExitOnFail(void)
  17. {
  18. return fExitOnFail;
  19. }
  20. void SetExitOnFail(BOOL set)
  21. {
  22. fExitOnFail = set;
  23. }
  24. // Print out an error message and terminate
  25. void Fail(char *fmt, ...)
  26. {
  27. va_list args;
  28. args = va_start(args, fmt);
  29. fprintf(stderr, "** Fatal error **: ");
  30. vfprintf(stderr, fmt, args);
  31. va_end(args);
  32. EndTest(1);
  33. }
  34. typedef struct
  35. {
  36. SCODE sc;
  37. char *text;
  38. } StatusCodeText;
  39. static StatusCodeText scodes[] =
  40. {
  41. S_OK, "S_OK",
  42. S_FALSE, "S_FALSE",
  43. STG_E_INVALIDFUNCTION, "STG_E_INVALIDFUNCTION",
  44. STG_E_FILENOTFOUND, "STG_E_FILENOTFOUND",
  45. STG_E_PATHNOTFOUND, "STG_E_PATHNOTFOUND",
  46. STG_E_TOOMANYOPENFILES, "STG_E_TOOMANYOPENFILES",
  47. STG_E_ACCESSDENIED, "STG_E_ACCESSDENIED",
  48. STG_E_INVALIDHANDLE, "STG_E_INVALIDHANDLE",
  49. STG_E_INSUFFICIENTMEMORY, "STG_E_INSUFFICIENTMEMORY",
  50. STG_E_INVALIDPOINTER, "STG_E_INVALIDPOINTER",
  51. STG_E_NOMOREFILES, "STG_E_NOMOREFILES",
  52. STG_E_DISKISWRITEPROTECTED, "STG_E_DISKISWRITEPROTECTED",
  53. STG_E_SEEKERROR, "STG_E_SEEKERROR",
  54. STG_E_WRITEFAULT, "STG_E_WRITEFAULT",
  55. STG_E_READFAULT, "STG_E_READFAULT",
  56. STG_E_SHAREVIOLATION, "STG_E_SHAREVIOLATION",
  57. STG_E_LOCKVIOLATION, "STG_E_LOCKVIOLATION",
  58. STG_E_FILEALREADYEXISTS, "STG_E_FILEALREADYEXISTS",
  59. STG_E_INVALIDPARAMETER, "STG_E_INVALIDPARAMETER",
  60. STG_E_MEDIUMFULL, "STG_E_MEDIUMFULL",
  61. STG_E_ABNORMALAPIEXIT, "STG_E_ABNORMALAPIEXIT",
  62. STG_E_INVALIDHEADER, "STG_E_INVALIDHEADER",
  63. STG_E_INVALIDNAME, "STG_E_INVALIDNAME",
  64. STG_E_UNKNOWN, "STG_E_UNKNOWN",
  65. STG_E_UNIMPLEMENTEDFUNCTION, "STG_E_UNIMPLEMENTEDFUNCTION",
  66. STG_E_INVALIDFLAG, "STG_E_INVALIDFLAG",
  67. STG_E_INUSE, "STG_E_INUSE",
  68. STG_E_NOTCURRENT, "STG_E_NOTCURRENT",
  69. STG_E_REVERTED, "STG_E_REVERTED",
  70. STG_E_CANTSAVE, "STG_E_CANTSAVE",
  71. STG_E_OLDFORMAT, "STG_E_OLDFORMAT",
  72. STG_E_OLDDLL, "STG_E_OLDDLL",
  73. STG_E_SHAREREQUIRED, "STG_E_SHAREREQUIRED",
  74. STG_E_NOTFILEBASEDSTORAGE, "STG_E_NOTFILEBASEDSTORAGE",
  75. STG_E_EXTANTMARSHALLINGS, "STG_E_EXTANTMARSHALLINGS",
  76. STG_S_CONVERTED, "STG_S_CONVERTED"
  77. };
  78. #define NSCODETEXT (sizeof(scodes)/sizeof(scodes[0]))
  79. // Convert a status code to text
  80. char *ScText(SCODE sc)
  81. {
  82. int i;
  83. for (i = 0; i<NSCODETEXT; i++)
  84. if (scodes[i].sc == sc)
  85. return scodes[i].text;
  86. return "<Unknown SCODE>";
  87. }
  88. // Output a call result and check for failure
  89. HRESULT Result(HRESULT hr, char *fmt, ...)
  90. {
  91. SCODE sc;
  92. va_list args;
  93. va_start(args, fmt);
  94. vprintf(fmt, args);
  95. va_end(args);
  96. sc = GetScode(hr);
  97. printf(" - %s (0x%lX)\n", ScText(sc), sc);
  98. if (FAILED(sc) && fExitOnFail)
  99. Fail("Unexpected call failure\n");
  100. return hr;
  101. }
  102. // Perform Result() when the expectation is failure
  103. HRESULT IllResult(HRESULT hr, char *fmt, ...)
  104. {
  105. SCODE sc;
  106. va_list args;
  107. va_start(args, fmt);
  108. vprintf(fmt, args);
  109. va_end(args);
  110. sc = GetScode(hr);
  111. printf(" - %s (0x%lX)\n", ScText(sc), sc);
  112. if (SUCCEEDED(sc) && fExitOnFail)
  113. Fail("Unexpected call success\n");
  114. return hr;
  115. }
  116. char *TcsText(TCHAR *ptcs)
  117. {
  118. static char buf[256];
  119. TTOA(ptcs, buf, 256);
  120. return buf;
  121. }
  122. char *FileTimeText(FILETIME *pft)
  123. {
  124. static char buf[80];
  125. struct tm ctm;
  126. #ifndef FLAT
  127. WORD dosdate, dostime;
  128. if (CoFileTimeToDosDateTime(pft, &dosdate, &dostime))
  129. {
  130. ctm.tm_sec = (dostime & 31)*2;
  131. ctm.tm_min = (dostime >> 5) & 63;
  132. ctm.tm_hour = dostime >> 11;
  133. ctm.tm_mday = dosdate & 31;
  134. ctm.tm_mon = ((dosdate >> 5) & 15)-1;
  135. ctm.tm_year = (dosdate >> 9)+80;
  136. ctm.tm_wday = 0;
  137. #else
  138. SYSTEMTIME st;
  139. if (FileTimeToSystemTime(pft, &st))
  140. {
  141. ctm.tm_sec = st.wSecond;
  142. ctm.tm_min = st.wMinute;
  143. ctm.tm_hour = st.wHour;
  144. ctm.tm_mday = st.wDay;
  145. ctm.tm_mon = st.wMonth-1;
  146. ctm.tm_year = st.wYear-1900;
  147. ctm.tm_wday = st.wDayOfWeek;
  148. #endif
  149. ctm.tm_yday = 0;
  150. ctm.tm_isdst = 0;
  151. strcpy(buf, asctime(&ctm));
  152. buf[strlen(buf)-1] = 0;
  153. }
  154. else
  155. sprintf(buf, "<FILETIME %08lX:%08lX>", pft->dwHighDateTime,
  156. pft->dwLowDateTime);
  157. return buf;
  158. }
  159. #pragma pack(1)
  160. struct SplitGuid
  161. {
  162. DWORD dw1;
  163. WORD w1;
  164. WORD w2;
  165. BYTE b[8];
  166. };
  167. #pragma pack()
  168. char *GuidText(GUID *pguid)
  169. {
  170. static char buf[39];
  171. SplitGuid *psg = (SplitGuid *)pguid;
  172. sprintf(buf, "{%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  173. psg->dw1, psg->w1, psg->w2, psg->b[0], psg->b[1], psg->b[2],
  174. psg->b[3], psg->b[4], psg->b[5], psg->b[6], psg->b[7]);
  175. return buf;
  176. }
  177. #define CROW 16
  178. void BinText(ULONG cbSize, BYTE *pb)
  179. {
  180. ULONG cb, i;
  181. while (cbSize > 0)
  182. {
  183. cb = min(CROW, cbSize);
  184. cbSize -= cb;
  185. for (i = 0; i<cb; i++)
  186. printf(" %02X", pb[i]);
  187. for (i = cb; i<CROW; i++)
  188. printf(" ");
  189. printf(" '");
  190. for (i = 0; i<cb; i++)
  191. if (pb[i] >= 0x20 && pb[i] <= 0x7f)
  192. putchar(pb[i]);
  193. else
  194. putchar('.');
  195. pb += cb;
  196. printf("'\n");
  197. }
  198. }
  199. TCHAR *TestFile(TCHAR *ptcsName, char *pszFile)
  200. {
  201. char achFn[MAX_PATH];
  202. char *dir, *file;
  203. int len;
  204. dir = getenv("DFDATA");
  205. if (dir)
  206. strcpy(achFn, dir);
  207. else
  208. strcpy(achFn, ".");
  209. len = strlen(achFn);
  210. if (achFn[len-1] != '\\')
  211. achFn[len++] = '\\';
  212. if (pszFile)
  213. {
  214. strcpy(achFn+len, pszFile);
  215. }
  216. else
  217. {
  218. file = getenv("DFFILE");
  219. if (file)
  220. strcpy(achFn+len, file);
  221. else
  222. strcpy(achFn+len, "TEST.DFL");
  223. }
  224. ATOT(achFn, ptcsName, MAX_PATH);
  225. return ptcsName+len;
  226. }
  227. #if WIN32 == 300
  228. char *TestFormat(DWORD *pdwFmt, DWORD *pgrfMode)
  229. {
  230. char *fmt;
  231. fmt = getenv("STGFMT");
  232. if (fmt == NULL || !strcmp(fmt, "doc"))
  233. {
  234. fmt = "document";
  235. *pdwFmt = STGFMT_DOCUMENT;
  236. }
  237. else if (!strcmp(fmt, "file"))
  238. {
  239. fmt = "file";
  240. *pdwFmt = STGFMT_FILE;
  241. }
  242. else
  243. {
  244. fmt = "directory";
  245. *pdwFmt = STGFMT_DIRECTORY;
  246. *pgrfMode &= ~STGM_CREATE;
  247. }
  248. return fmt;
  249. }
  250. #endif
  251. BOOL CompareStatStg(STATSTG *pstat1, STATSTG *pstat2)
  252. {
  253. if (wcscmp(pstat1->pwcsName, pstat2->pwcsName) != 0)
  254. {
  255. printf("Names compared wrong: %ws and %ws\n",
  256. pstat1->pwcsName, pstat2->pwcsName);
  257. return FALSE;
  258. }
  259. if (pstat1->type != pstat2->type)
  260. {
  261. printf("Types compares wrong on %ws and %ws: %lu and %lu\n",
  262. pstat1->pwcsName,
  263. pstat2->pwcsName,
  264. pstat2->type,
  265. pstat2->type);
  266. return FALSE;
  267. }
  268. if (!IsEqualIID(pstat1->clsid, pstat2->clsid))
  269. {
  270. printf("Class IDs for %ws and %ws compared bad\n",
  271. pstat1->pwcsName,
  272. pstat2->pwcsName);
  273. return FALSE;
  274. }
  275. if (pstat1->type == STGTY_STREAM)
  276. {
  277. if ((pstat1->cbSize).QuadPart != (pstat2->cbSize).QuadPart)
  278. {
  279. printf("Sizes for %ws and %ws compared bad: %lu and %lu\n",
  280. pstat1->pwcsName,
  281. pstat2->pwcsName,
  282. (pstat1->cbSize).LowPart,
  283. (pstat2->cbSize).LowPart);
  284. return FALSE;
  285. }
  286. }
  287. //Also check statebits and timestamps?
  288. return TRUE;
  289. }
  290. BOOL CompareStreams(IStream *pstm1, IStream *pstm2)
  291. {
  292. const ULONG BUFSIZE = 4096;
  293. BYTE buffer1[BUFSIZE];
  294. BYTE buffer2[BUFSIZE];
  295. ULONG cbRead1;
  296. ULONG cbRead2;
  297. STATSTG stat1;
  298. STATSTG stat2;
  299. LARGE_INTEGER li;
  300. li.QuadPart = 0;
  301. pstm1->Seek(li, STREAM_SEEK_SET, NULL);
  302. pstm2->Seek(li, STREAM_SEEK_SET, NULL);
  303. do
  304. {
  305. SCODE sc;
  306. sc = pstm1->Read(buffer1, BUFSIZE, &cbRead1);
  307. if (FAILED(sc))
  308. {
  309. printf("Read failed with %lx\n", sc);
  310. return FALSE;
  311. }
  312. sc = pstm2->Read(buffer2, BUFSIZE, &cbRead2);
  313. if (FAILED(sc))
  314. {
  315. printf("Read failed with %lx\n", sc);
  316. return FALSE;
  317. }
  318. if ((cbRead1 != cbRead2) || (memcmp(buffer1, buffer2, cbRead1) != 0))
  319. {
  320. if (cbRead1 != cbRead2)
  321. {
  322. printf("Stream compare returned different bytes read: %lu and %lu\n",
  323. cbRead1,
  324. cbRead2);
  325. }
  326. else
  327. {
  328. printf("Data mismatch.\n");
  329. }
  330. return FALSE;
  331. }
  332. }
  333. while (cbRead1 == BUFSIZE);
  334. return TRUE;
  335. }
  336. BOOL CompareStorages(IStorage *pstg1, IStorage *pstg2)
  337. {
  338. SCODE sc1, sc2, sc;
  339. IStorage *pstgChild1, *pstgChild2;
  340. IStream *pstmChild1, *pstmChild2;
  341. IEnumSTATSTG *penum1, *penum2;
  342. STATSTG stat1, stat2;
  343. pstg1->EnumElements(0, 0, 0, &penum1);
  344. pstg2->EnumElements(0, 0, 0, &penum2);
  345. do
  346. {
  347. ULONG celtFetched1, celtFetched2;
  348. sc1 = penum1->Next(1, &stat1, &celtFetched1);
  349. if (FAILED(sc1))
  350. {
  351. printf("EnumElements 1 failed with %lx\n", sc1);
  352. return FALSE;
  353. }
  354. sc2 = penum2->Next(1, &stat2, &celtFetched2);
  355. if (FAILED(sc2) || (celtFetched1 != celtFetched2) || (sc1 != sc2))
  356. {
  357. if (FAILED(sc2))
  358. {
  359. printf("EnumElements 2 failed with %lx\n", sc2);
  360. }
  361. else
  362. {
  363. printf("Return code mismatch: %lx and %lx\n", sc1, sc2);
  364. }
  365. return FALSE;
  366. }
  367. if (celtFetched1 == 0)
  368. {
  369. //We're done.
  370. return TRUE;
  371. }
  372. if (!CompareStatStg(&stat1, &stat2))
  373. {
  374. return FALSE;
  375. }
  376. //Items have compared OK so far. Now compare contents.
  377. if (stat1.type == STGTY_STREAM)
  378. {
  379. sc = pstg1->OpenStream(stat1.pwcsName,
  380. 0,
  381. STGM_DIRECT |
  382. STGM_READ | STGM_SHARE_EXCLUSIVE,
  383. 0,
  384. &pstmChild1);
  385. if (FAILED(sc))
  386. {
  387. printf("OpenStream on pstg1 for %ws failed with %lx\n",
  388. stat1.pwcsName,
  389. sc);
  390. return FALSE;
  391. }
  392. sc = pstg2->OpenStream(stat2.pwcsName,
  393. 0,
  394. STGM_DIRECT |
  395. STGM_READ | STGM_SHARE_EXCLUSIVE,
  396. 0,
  397. &pstmChild2);
  398. if (FAILED(sc))
  399. {
  400. printf("OpenStream on pstg2 for %ws failed with %lx\n",
  401. stat2.pwcsName,
  402. sc);
  403. return FALSE;
  404. }
  405. if (!CompareStreams(pstmChild1, pstmChild2))
  406. {
  407. printf("Stream compare on %ws and %ws failed.\n",
  408. stat1.pwcsName,
  409. stat2.pwcsName);
  410. return FALSE;
  411. }
  412. pstmChild1->Release();
  413. pstmChild2->Release();
  414. }
  415. else
  416. {
  417. //Compare storages
  418. sc = pstg1->OpenStorage(stat1.pwcsName,
  419. NULL,
  420. STGM_DIRECT | STGM_READ |
  421. STGM_SHARE_EXCLUSIVE,
  422. NULL,
  423. 0,
  424. &pstgChild1);
  425. if (FAILED(sc))
  426. {
  427. printf("OpenStorage on pstg1 for %ws failed with %lx\n",
  428. stat1.pwcsName,
  429. sc);
  430. return FALSE;
  431. }
  432. sc = pstg2->OpenStorage(stat2.pwcsName,
  433. NULL,
  434. STGM_DIRECT | STGM_READ |
  435. STGM_SHARE_EXCLUSIVE,
  436. NULL,
  437. 0,
  438. &pstgChild2);
  439. if (FAILED(sc))
  440. {
  441. printf("OpenStorage on pstg2 for %ws failed with %lx\n",
  442. stat2.pwcsName,
  443. sc);
  444. return FALSE;
  445. }
  446. if (!CompareStorages(pstgChild1, pstgChild2))
  447. {
  448. printf("CompareStorages failed for %ws and %ws\n",
  449. stat1.pwcsName,
  450. stat2.pwcsName);
  451. return FALSE;
  452. }
  453. pstgChild1->Release();
  454. pstgChild2->Release();
  455. }
  456. //printf("Object %ws compared OK.\n", stat1.pwcsName);
  457. CoTaskMemFree(stat1.pwcsName);
  458. CoTaskMemFree(stat2.pwcsName);
  459. } while (sc1 != S_FALSE);
  460. return TRUE;
  461. }