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.

636 lines
19 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: tests.cxx
  7. //
  8. // Contents: DRT tests
  9. //
  10. //---------------------------------------------------------------
  11. #ifdef _WIN32
  12. // for win32 env, we use dll's and therefore have to define the GUIDs
  13. #define INITGUID
  14. #endif
  15. #include "headers.cxx"
  16. #include "tests.hxx"
  17. #include "ilb.hxx"
  18. void t_create(void)
  19. {
  20. WStorage *pstgRoot, *pstgChild, *pstgChild2;
  21. WStream *pstm;
  22. DECLARE_OLESTR(ocsChild, "Child");
  23. DECLARE_OLESTR(ocsChild2, "Child2");
  24. DECLARE_OLESTR(ocsStream, "Stream");
  25. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE,
  26. 0, &pstgRoot);
  27. pstgRoot->CreateStorage(ocsChild, STGP(WSTG_READWRITE), 0, 0,
  28. &pstgChild);
  29. pstgChild->CreateStorage(ocsChild2, STGP(WSTG_READWRITE), 0, 0,
  30. &pstgChild2);
  31. pstgChild2->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0,
  32. &pstm);
  33. pstm->Unwrap();
  34. pstgChild2->Commit(0);
  35. pstgChild2->Unwrap();
  36. pstgChild->Commit(0);
  37. pstgChild->Unwrap();
  38. VerifyStructure(pstgRoot->GetI(), "dChild(dChild2(sStream))");
  39. pstgRoot->Unwrap();
  40. }
  41. void t_open(void)
  42. {
  43. WStorage *pstgRoot, *pstgChild, *pstgChild2;
  44. WStream *pstm;
  45. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE,
  46. 0, &pstgRoot);
  47. CreateStructure(pstgRoot->GetI(), "dChild(dChild2(sStream))");
  48. pstgRoot->Commit(0);
  49. pstgRoot->Unwrap();
  50. DECLARE_OLESTR(ocsChild, "Child");
  51. DECLARE_OLESTR(ocsChild2, "Child2");
  52. DECLARE_OLESTR(ocsStream, "Stream");
  53. WStgOpenStorage(DRTDF, NULL, ROOTP(WSTG_READWRITE), NULL,
  54. 0, &pstgRoot);
  55. pstgRoot->OpenStorage(ocsChild, NULL, STGP(WSTG_READWRITE), NULL, 0,
  56. &pstgChild);
  57. pstgChild->OpenStorage(ocsChild2, NULL, STGP(WSTG_READWRITE), NULL, 0,
  58. &pstgChild2);
  59. pstgChild2->OpenStream(ocsStream, NULL, STMP(WSTG_READWRITE), 0,
  60. &pstm);
  61. pstm->Unwrap();
  62. pstgChild2->Unwrap();
  63. pstgChild->Unwrap();
  64. pstgRoot->Unwrap();
  65. }
  66. void t_addref(void)
  67. {
  68. WStorage *pstg;
  69. WStream *pstm;
  70. ULONG ul;
  71. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE,
  72. 0, &pstg);
  73. DECLARE_OLESTR(ocsChild, "Child");
  74. DECLARE_OLESTR(ocsChild2, "Child2");
  75. DECLARE_OLESTR(ocsStream, "Stream");
  76. pstg->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0, &pstm);
  77. #ifndef FLAT
  78. if ((ul = pstm->AddRef()) != 2)
  79. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  80. if ((ul = pstm->Release()) != 1)
  81. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  82. pstm->Unwrap();
  83. if ((ul = pstg->AddRef()) != 2)
  84. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  85. if ((ul = pstg->Release()) != 1)
  86. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  87. #else
  88. if ((ul = pstm->AddRef()) <= 0)
  89. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  90. if ((ul = pstm->Release()) <= 0)
  91. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  92. pstm->Unwrap();
  93. if ((ul = pstg->AddRef()) <= 0)
  94. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  95. if ((ul = pstg->Release()) <= 0)
  96. error(EXIT_BADSC, "Wrong reference count - %lu\n", ul);
  97. #endif
  98. pstg->Unwrap();
  99. }
  100. void t_dmodify(void)
  101. {
  102. WStorage *pstgRoot, *pstgChild, *pstgChild2;
  103. WStream *pstm;
  104. ULONG cbSize1, cbSize2;
  105. DECLARE_OLESTR(ocsChild, "Child");
  106. DECLARE_OLESTR(ocsChild2, "Child2");
  107. DECLARE_OLESTR(ocsStream, "Stream");
  108. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE,
  109. 0, &pstgRoot);
  110. pstgRoot->CreateStorage(ocsChild, STGP(WSTG_READWRITE), 0,
  111. 0, &pstgChild);
  112. pstgChild->CreateStorage(ocsChild2, STGP(WSTG_READWRITE), 0,
  113. 0, &pstgChild2);
  114. pstgChild2->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0, &pstm);
  115. pstm->Unwrap();
  116. VerifyStructure(pstgChild2->GetI(), "sStream");
  117. // Test renaming a closed stream
  118. DECLARE_OLESTR(ocsRenamedStream, "RenamedStream");
  119. pstgChild2->RenameElement(ocsStream, ocsRenamedStream);
  120. VerifyStructure(pstgChild2->GetI(), "sRenamedStream");
  121. // Test destroying a stream
  122. pstgChild2->DestroyElement(ocsRenamedStream);
  123. pstgChild2->Unwrap();
  124. VerifyStructure(pstgChild->GetI(), "dChild2()");
  125. // Test renaming a storage
  126. DECLARE_OLESTR(ocsRenamedChild, "RenamedChild");
  127. pstgChild->RenameElement(ocsChild2, ocsRenamedChild);
  128. pstgChild->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0,
  129. &pstm);
  130. pstm->Unwrap();
  131. pstgChild->DestroyElement(ocsStream);
  132. // Test SetElementTimes
  133. FILETIME tm;
  134. STATSTG stat;
  135. tm.dwLowDateTime = 0x12345678;
  136. tm.dwHighDateTime = 0x01bcdef0;
  137. // Set when element not open
  138. pstgChild->SetElementTimes(ocsRenamedChild, &tm, NULL, NULL);
  139. pstgChild->SetElementTimes(ocsRenamedChild, NULL, &tm, NULL);
  140. pstgChild->SetElementTimes(ocsRenamedChild, NULL, NULL, &tm);
  141. pstgChild->OpenStorage(ocsRenamedChild, NULL, STMP(WSTG_READWRITE),
  142. NULL, 0, &pstgChild2);
  143. pstgChild2->Stat(&stat, STATFLAG_NONAME);
  144. if (!IsEqualTime(stat.ctime, tm) ||
  145. !IsEqualTime(stat.mtime, tm))
  146. error(EXIT_BADSC, "Times don't match those set by SetElementTimes\n");
  147. // Test SetClass and SetStateBits
  148. pstgChild2->SetClass(IID_IStorage);
  149. fExitOnFail = FALSE;
  150. pstgChild2->SetStateBits(0xff00ff00, 0xffffffff);
  151. pstgChild2->SetStateBits(0x00880088, 0xeeeeeeee);
  152. fExitOnFail = TRUE;
  153. pstgChild2->Stat(&stat, STATFLAG_NONAME);
  154. if (!IsEqualCLSID(stat.clsid, IID_IStorage))
  155. error(EXIT_BADSC, "Class ID set improperly\n");
  156. if (stat.grfStateBits != 0x11881188)
  157. errorprint("State bits set improperly: has %lX vs. %lX\n",
  158. stat.grfStateBits, 0x11881188);
  159. pstgChild2->Unwrap();
  160. pstgChild->Unwrap();
  161. VerifyStructure(pstgRoot->GetI(), "dChild(dRenamedChild())");
  162. pstgRoot->Revert();
  163. VerifyStructure(pstgRoot->GetI(), "dChild(dRenamedChild())");
  164. pstgRoot->Commit(0);
  165. VerifyStructure(pstgRoot->GetI(), "dChild(dRenamedChild())");
  166. pstgRoot->DestroyElement(ocsChild);
  167. VerifyStructure(pstgRoot->GetI(), "");
  168. // Verify that space is reclaimed after modifications
  169. pstgRoot->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0, &pstm);
  170. pstm->SetSize(65536);
  171. pstm->Unwrap();
  172. cbSize1 = Length(DRTDF);
  173. pstgRoot->DestroyElement(ocsStream);
  174. pstgRoot->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0, &pstm);
  175. pstm->SetSize(65536);
  176. pstm->Unwrap();
  177. cbSize2 = Length(DRTDF);
  178. if (cbSize1 != cbSize2)
  179. error(EXIT_BADSC, "Space is not being reclaimed, original %lu, "
  180. "now %lu\n", cbSize1, cbSize2);
  181. pstgRoot->Unwrap();
  182. WStgCreateDocfile(NULL, ROOTP(WSTG_READWRITE) | WSTG_CREATE |
  183. WSTG_DELETEONRELEASE, 0, &pstgRoot);
  184. // removal cases
  185. // 1) no right child
  186. CreateStructure(pstgRoot->GetI(), "d64,d32");
  187. VerifyStructure(pstgRoot->GetI(), "d64,d32");
  188. DECLARE_OLESTR(ocs64, "64");
  189. pstgRoot->DestroyElement(ocs64);
  190. VerifyStructure(pstgRoot->GetI(), "d32");
  191. // 2) right child has no left child
  192. CreateStructure(pstgRoot->GetI(), "d64");
  193. VerifyStructure(pstgRoot->GetI(), "d32,d64");
  194. DECLARE_OLESTR(ocs32, "32");
  195. pstgRoot->DestroyElement(ocs32);
  196. VerifyStructure(pstgRoot->GetI(), "d64");
  197. // 3) right child has left child
  198. CreateStructure(pstgRoot->GetI(), "d96,d80");
  199. VerifyStructure(pstgRoot->GetI(), "d64,d80,d96");
  200. pstgRoot->DestroyElement(ocs64);
  201. VerifyStructure(pstgRoot->GetI(), "d80,d96");
  202. // 4) right child's left child has children
  203. CreateStructure(pstgRoot->GetI(), "d88,d84,d92");
  204. VerifyStructure(pstgRoot->GetI(), "d80,d84,d88,d92,d96");
  205. DECLARE_OLESTR(ocs80, "80");
  206. pstgRoot->DestroyElement(ocs80);
  207. VerifyStructure(pstgRoot->GetI(), "d84,d88,d92,d96");
  208. pstgRoot->Unwrap();
  209. }
  210. void t_stat(void)
  211. {
  212. WStorage *pstgRoot, *pstgChild;
  213. WStream *pstm;
  214. STATSTG stat;
  215. DECLARE_OLESTR(ocsChild, "Child");
  216. DECLARE_OLESTR(ocsStream, "Stream");
  217. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE,
  218. 0, &pstgRoot);
  219. pstgRoot->CreateStorage(ocsChild, STGP(WSTG_READWRITE), 0, 0,
  220. &pstgChild);
  221. pstgChild->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0, &pstm);
  222. pstm->Stat(&stat, 0);
  223. VerifyStat(&stat, ocsStream, STGTY_STREAM, STMP(WSTG_READWRITE));
  224. drtMemFree(stat.pwcsName);
  225. pstm->Stat(&stat, STATFLAG_NONAME);
  226. VerifyStat(&stat, NULL, STGTY_STREAM, STMP(WSTG_READWRITE));
  227. pstm->Unwrap();
  228. pstgChild->Stat(&stat, 0);
  229. VerifyStat(&stat, ocsChild, STGTY_STORAGE, STGP(WSTG_READWRITE));
  230. drtMemFree(stat.pwcsName);
  231. pstgChild->Stat(&stat, STATFLAG_NONAME);
  232. VerifyStat(&stat, NULL, STGTY_STORAGE, STGP(WSTG_READWRITE));
  233. pstgChild->Unwrap();
  234. pstgRoot->Stat(&stat, 0);
  235. OLECHAR atcFullPath[_MAX_PATH+1];
  236. GetFullPath(DRTDF, atcFullPath, _MAX_PATH+1);
  237. VerifyStat(&stat, atcFullPath, STGTY_STORAGE, ROOTP(WSTG_READWRITE));
  238. drtMemFree(stat.pwcsName);
  239. pstgRoot->Stat(&stat, STATFLAG_NONAME);
  240. VerifyStat(&stat, NULL, STGTY_STORAGE, ROOTP(WSTG_READWRITE));
  241. pstgRoot->Unwrap();
  242. }
  243. static char NUMBERS[] = "12345678901234567890123456789012345678901234567890";
  244. void t_stream(void)
  245. {
  246. WStorage *pstg;
  247. WStream *pstm, *pstmC;
  248. char buf[sizeof(NUMBERS)*2];
  249. ULONG cb, ulPos;
  250. DECLARE_OLESTR(ocsStream, "Stream");
  251. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE, 0, &pstg);
  252. pstg->CreateStream(ocsStream, STMP(WSTG_READWRITE), 0, 0, &pstm);
  253. pstm->Write(NUMBERS, sizeof(NUMBERS), &cb);
  254. pstm->Commit(0);
  255. pstm->Seek(0, WSTM_SEEK_SET, &ulPos);
  256. if (ulPos != 0)
  257. error(EXIT_BADSC, "Incorrect seek, ptr is %lu\n", ulPos);
  258. pstm->Read(buf, sizeof(NUMBERS), &cb);
  259. if (strcmp(buf, NUMBERS))
  260. error(EXIT_BADSC, "Incorrect stream contents\n");
  261. pstm->SetSize(sizeof(NUMBERS)/2);
  262. pstm->Seek(0, WSTM_SEEK_SET, NULL);
  263. fExitOnFail = FALSE;
  264. pstm->Read(buf, sizeof(NUMBERS), &cb);
  265. fExitOnFail = TRUE;
  266. if (cb != sizeof(NUMBERS)/2)
  267. error(EXIT_BADSC, "SetSize failed to size stream properly\n");
  268. if (memcmp(buf, NUMBERS, sizeof(NUMBERS)/2))
  269. error(EXIT_BADSC, "SetSize corrupted contents\n");
  270. pstm->Clone(&pstmC);
  271. pstm->Seek(0, WSTM_SEEK_SET, NULL);
  272. pstm->CopyTo(pstmC, sizeof(NUMBERS)/2, NULL, NULL);
  273. pstm->Seek(0, WSTM_SEEK_SET, NULL);
  274. pstm->CopyTo(pstmC, sizeof(NUMBERS)&~1, NULL, NULL);
  275. pstm->Seek(0, WSTM_SEEK_SET, NULL);
  276. pstm->Read(buf, (sizeof(NUMBERS)&~1)*2, &cb);
  277. if (memcmp(buf, NUMBERS, sizeof(NUMBERS)/2) ||
  278. memcmp(buf+sizeof(NUMBERS)/2, NUMBERS, sizeof(NUMBERS)/2) ||
  279. memcmp(buf+(sizeof(NUMBERS)&~1), NUMBERS, sizeof(NUMBERS)/2) ||
  280. memcmp(buf+3*(sizeof(NUMBERS)/2), NUMBERS, sizeof(NUMBERS)/2))
  281. error(EXIT_BADSC, "Stream contents incorrect\n");
  282. pstmC->Unwrap();
  283. pstm->Unwrap();
  284. pstg->Unwrap();
  285. }
  286. // Number of entries for enumeration test
  287. #define ENUMENTRIES 10
  288. // Flag indicating a name has already shown up in enumeration,
  289. // must not conflict with STGTY_*
  290. #define ENTRY_SEEN 0x100
  291. // Check the validity of an enumeration element
  292. static void elt_check(STATSTG *pstat, CStrList *psl)
  293. {
  294. SStrEntry *pse;
  295. pse = psl->Find(pstat->pwcsName);
  296. if (pse == NULL)
  297. error(EXIT_BADSC, "Spurious element '%s'\n", pstat->pwcsName);
  298. else if ((pse->user.dw & ~ENTRY_SEEN) != pstat->type)
  299. error(EXIT_BADSC, "Element '%s' has wrong type - "
  300. "has %lX vs. %lX\n", pstat->pwcsName, pstat->type,
  301. pse->user.dw & ~ENTRY_SEEN);
  302. else if (pse->user.dw & ENTRY_SEEN)
  303. error(EXIT_BADSC, "Element '%s' has already been seen\n",
  304. pstat->pwcsName);
  305. pse->user.dw |= ENTRY_SEEN;
  306. }
  307. // Do final validity checks for enumeration
  308. static void enum_list_check(CStrList *psl)
  309. {
  310. SStrEntry *pse;
  311. for (pse = psl->GetHead(); pse; pse = pse->pseNext)
  312. {
  313. if ((pse->user.dw & ENTRY_SEEN) == 0)
  314. error(EXIT_BADSC, "Element '%s' not found\n", pse->atc);
  315. pse->user.dw &= ~ENTRY_SEEN;
  316. }
  317. }
  318. void t_enum(void)
  319. {
  320. int i;
  321. char pchName[CWCSTORAGENAME];
  322. OLECHAR atcName[CWCSTORAGENAME];
  323. WStorage *pstg, *pstg2;
  324. WStream *pstm;
  325. SStrEntry *pse;
  326. CStrList sl;
  327. // Create some entries to enumerate
  328. WStgCreateDocfile(DRTDF, ROOTP(WSTG_READWRITE) | WSTG_CREATE, 0, &pstg);
  329. for (i = 0; i<ENUMENTRIES; i++)
  330. {
  331. sprintf(pchName, "Name%d", rand());
  332. STOT(pchName, atcName, strlen(pchName)+1);
  333. pse = sl.Add(atcName);
  334. if (rand()%100 < 50)
  335. {
  336. pse->user.dw = STGTY_STORAGE;
  337. pstg->CreateStorage(atcName, STGP(WSTG_READWRITE), 0, 0, &pstg2);
  338. pstg2->Unwrap();
  339. }
  340. else
  341. {
  342. pse->user.dw = STGTY_STREAM;
  343. pstg->CreateStream(atcName, STMP(WSTG_READWRITE), 0, 0, &pstm);
  344. pstm->Unwrap();
  345. }
  346. }
  347. WEnumSTATSTG *penm;
  348. STATSTG stat[2*ENUMENTRIES];
  349. SCODE sc;
  350. // Test plain, single element enumeration
  351. pstg->EnumElements(0, NULL, 0, &penm);
  352. for (;;)
  353. {
  354. sc = DfGetScode(penm->Next(1, stat, NULL));
  355. if (sc == S_FALSE)
  356. break;
  357. elt_check(stat, &sl);
  358. drtMemFree(stat->pwcsName);
  359. }
  360. enum_list_check(&sl);
  361. ULONG cFound;
  362. // Test rewind and multiple element enumeration with too many elements
  363. penm->Reset();
  364. sc = DfGetScode(penm->Next(ENUMENTRIES*2, stat, &cFound));
  365. if (sc != S_FALSE)
  366. error(EXIT_BADSC, "Enumerator returned %s (%lX) instead of "
  367. "S_FALSE\n", ScText(sc), sc);
  368. if (cFound != ENUMENTRIES)
  369. error(EXIT_BADSC, "Enumerator found %lu entries instead of "
  370. "%d entries\n", cFound, ENUMENTRIES);
  371. for (; cFound > 0; cFound--)
  372. {
  373. elt_check(&stat[cFound-1], &sl);
  374. drtMemFree(stat[cFound-1].pwcsName);
  375. }
  376. enum_list_check(&sl);
  377. // Test skip and multiple enumeration with exact number of elements
  378. penm->Reset();
  379. penm->Skip(ENUMENTRIES/2);
  380. sc = DfGetScode(penm->Next(ENUMENTRIES-ENUMENTRIES/2, stat, &cFound));
  381. if (sc != S_OK)
  382. error(EXIT_BADSC, "Enumerator returned %s (%lX) instead of "
  383. "S_OK\n", ScText(sc), sc);
  384. if (cFound != ENUMENTRIES-ENUMENTRIES/2)
  385. error(EXIT_BADSC, "Enumerator found %lu entries instead of "
  386. "%d entries\n", cFound, ENUMENTRIES-ENUMENTRIES/2);
  387. for (; cFound > 0; cFound--)
  388. {
  389. elt_check(&stat[cFound-1], &sl);
  390. drtMemFree(stat[cFound-1].pwcsName);
  391. }
  392. sc = DfGetScode(penm->Next(1, stat, NULL));
  393. if (sc != S_FALSE)
  394. error(EXIT_BADSC, "Enumerator returned %s (%lX) instead of "
  395. "S_FALSE\n", ScText(sc), sc);
  396. penm->Unwrap();
  397. pstg->Unwrap();
  398. }
  399. #define SCT_CLASSID IID_ILockBytes
  400. #define SCT_STATEBITS 0xfef1f0f0
  401. void t_stgcopyto(void)
  402. {
  403. WStorage *pstgFrom, *pstgTo;
  404. STATSTG statFrom, statTo;
  405. WStgCreateDocfile(NULL, ROOTP(WSTG_READWRITE) | WSTG_CREATE |
  406. WSTG_DELETEONRELEASE, 0, &pstgFrom);
  407. pstgFrom->Stat(&statFrom, 0);
  408. // Set some interesting values to make sure they're copied
  409. pstgFrom->SetClass(SCT_CLASSID);
  410. fExitOnFail = FALSE;
  411. pstgFrom->SetStateBits(SCT_STATEBITS, 0xffffffff);
  412. fExitOnFail = TRUE;
  413. WStgCreateDocfile(NULL, ROOTP(WSTG_READWRITE) | WSTG_CREATE |
  414. WSTG_DELETEONRELEASE, 0, &pstgTo);
  415. CreateStructure(pstgFrom->GetI(), "dA(dB(dC(sA,sB,sC),sCs),sBs),sAs");
  416. CreateStructure(pstgTo->GetI(), "dA(dY(sZ),sBs)");
  417. pstgFrom->CopyTo(0, NULL, NULL, pstgTo);
  418. VerifyStructure(pstgTo->GetI(),
  419. "dA(dB(dC(sA,sB,sC),sCs),dY(sZ),sBs),sAs");
  420. pstgTo->Stat(&statTo, 0);
  421. if (!IsEqualCLSID(statTo.clsid, SCT_CLASSID))
  422. error(EXIT_BADSC, "Class ID mismatch after copy\n");
  423. if (statTo.grfStateBits != SCT_STATEBITS)
  424. errorprint("State bits mismatch: has %lX vs. %lX\n",
  425. statTo.grfStateBits, SCT_STATEBITS);
  426. pstgFrom->Unwrap();
  427. pstgTo->Unwrap();
  428. if (Exists(statFrom.pwcsName))
  429. error(EXIT_BADSC, "Storage '%s' not deleted\n", statFrom.pwcsName);
  430. drtMemFree(statFrom.pwcsName);
  431. if (Exists(statTo.pwcsName))
  432. error(EXIT_BADSC, "Storage '%s' not deleted\n", statTo.pwcsName);
  433. drtMemFree(statTo.pwcsName);
  434. }
  435. void t_stgmisc(void)
  436. {
  437. WStorage *pstg;
  438. SCODE sc;
  439. STATSTG stat;
  440. // Can't make this call in transacted mode because we want
  441. // the storage signature to make it into the file right away
  442. WStgCreateDocfile(DRTDF, WSTG_READWRITE | WSTG_CREATE |
  443. WSTG_SHARE_EXCLUSIVE, 0, &pstg);
  444. sc = DfGetScode(WStgIsStorageFile(DRTDF));
  445. if (sc == S_FALSE)
  446. error(EXIT_BADSC, "Open file - Should be a storage object\n");
  447. pstg->Unwrap();
  448. sc = DfGetScode(WStgIsStorageFile(DRTDF));
  449. if (sc == S_FALSE)
  450. error(EXIT_BADSC, "Closed file - Should be a storage object\n");
  451. WStgCreateDocfile(NULL, ROOTP(WSTG_READWRITE) | WSTG_CREATE |
  452. WSTG_DELETEONRELEASE, 0, &pstg);
  453. pstg->Stat(&stat, 0);
  454. if (!Exists(stat.pwcsName))
  455. error(EXIT_BADSC, "Storage '%s' not created\n", stat.pwcsName);
  456. pstg->Unwrap();
  457. if (Exists(stat.pwcsName))
  458. error(EXIT_BADSC, "Storage '%s' not deleted on release\n",
  459. stat.pwcsName);
  460. drtMemFree(stat.pwcsName);
  461. }
  462. void t_ilb(void)
  463. {
  464. WStorage *pstg;
  465. SCODE sc;
  466. // create an ILockBytes
  467. ILockBytes *pilb = new CMapBytes();
  468. if (pilb == NULL)
  469. error(EXIT_BADSC, "Unable to allocate an ILockBytes\n");
  470. // create a storage on the ILockBytes
  471. WStgCreateDocfileOnILockBytes(pilb,
  472. WSTG_READWRITE |
  473. WSTG_CREATE |
  474. WSTG_SHARE_EXCLUSIVE,
  475. 0, &pstg);
  476. // verify the ILockBytes
  477. sc = DfGetScode(WStgIsStorageILockBytes(pilb));
  478. if (sc == S_FALSE)
  479. error(EXIT_BADSC, "Open ILockBytes - Should be a storage object\n");
  480. // release the storage
  481. pstg->Unwrap();
  482. // verify the ILockBytes
  483. sc = DfGetScode(WStgIsStorageILockBytes(pilb));
  484. if (sc == S_FALSE)
  485. error(EXIT_BADSC, "Released ILockBytes - Should be a storage object\n");
  486. // open the ILockBytes
  487. WStgOpenStorageOnILockBytes(pilb, NULL, ROOTP(WSTG_READWRITE),
  488. NULL, 0, &pstg);
  489. // release the storage
  490. pstg->Unwrap();
  491. // release the ILockBytes
  492. pilb->Release();
  493. }
  494. void t_movecopy(void)
  495. {
  496. WStorage *pstgFrom, *pstgTo;
  497. STATSTG statFrom, statTo;
  498. // create a source
  499. WStgCreateDocfile(NULL, ROOTP(WSTG_READWRITE) | WSTG_CREATE |
  500. WSTG_DELETEONRELEASE, 0, &pstgFrom);
  501. pstgFrom->Stat(&statFrom, 0);
  502. // create a destination
  503. WStgCreateDocfile(NULL, ROOTP(WSTG_READWRITE) | WSTG_CREATE |
  504. WSTG_DELETEONRELEASE, 0, &pstgTo);
  505. pstgTo->Stat(&statTo, 0);
  506. // populate source
  507. CreateStructure(pstgFrom->GetI(), "dA(dB(dC(sA,sB,sC),sCs),sBs),sAs");
  508. DECLARE_OLESTR(ocsM, "M");
  509. DECLARE_OLESTR(ocsA, "A");
  510. // move a storage
  511. pstgFrom->MoveElementTo(ocsA, pstgTo, ocsM, STGMOVE_MOVE);
  512. VerifyStructure(pstgFrom->GetI(),
  513. "sAs");
  514. VerifyStructure(pstgTo->GetI(),
  515. "dM(dB(dC(sA,sB,sC),sCs),sBs)");
  516. // copy a stream
  517. DECLARE_OLESTR(ocsBs, "Bs");
  518. DECLARE_OLESTR(ocsAs, "As");
  519. pstgFrom->MoveElementTo(ocsAs, pstgTo, ocsBs, STGMOVE_COPY);
  520. VerifyStructure(pstgFrom->GetI(),
  521. "sAs");
  522. VerifyStructure(pstgTo->GetI(),
  523. "dM(dB(dC(sA,sB,sC),sCs),sBs),sBs");
  524. pstgFrom->Unwrap();
  525. pstgTo->Unwrap();
  526. if (Exists(statFrom.pwcsName))
  527. error(EXIT_BADSC, "Storage '%s' not deleted\n", statFrom.pwcsName);
  528. drtMemFree(statFrom.pwcsName);
  529. if (Exists(statTo.pwcsName))
  530. error(EXIT_BADSC, "Storage '%s' not deleted\n", statTo.pwcsName);
  531. drtMemFree(statTo.pwcsName);
  532. }