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.

5634 lines
167 KiB

  1. // tmarsh.cxx : various tests related to marshalling...
  2. //
  3. #include <windows.h>
  4. #include <ole2.h>
  5. #include <stdio.h>
  6. #include "tmarshal.h"
  7. #include "tunk.h"
  8. #include <iballs.h>
  9. #include <icube.h>
  10. #include <iloop.h>
  11. #include <stream.hxx> // CStreamOnFile
  12. #include <tstmain.hxx> // fQuiet
  13. // BUGBUG: these should be in a public place somewhere.
  14. DEFINE_OLEGUID(CLSID_Balls, 0x0000013a, 1, 8);
  15. DEFINE_OLEGUID(CLSID_Cubes, 0x0000013b, 1, 8);
  16. DEFINE_OLEGUID(CLSID_LoopSrv, 0x0000013c, 1, 8);
  17. DEFINE_OLEGUID(CLSID_QI, 0x00000140, 0, 8);
  18. DEFINE_OLEGUID(CLSID_QIHANDLER1, 0x00000141, 0, 8);
  19. DEFINE_OLEGUID(IID_IInternalUnknown,0x00000021, 0, 0);
  20. DEFINE_OLEGUID(IID_IStdIdentity, 0x0000001b, 0, 0);
  21. DEFINE_OLEGUID(CLSID_OLEPSFACTORY, 0x00000320, 0, 0);
  22. const GUID CLSID_LoopSrv =
  23. {0x0000013c,0x0001,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  24. // testsrv.exe
  25. const GUID CLSID_TestEmbed =
  26. {0x99999999,0x0000,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x47}};
  27. const GUID CLSID_Async =
  28. {0x00000401,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  29. const GUID CLSID_QI =
  30. {0x00000140,0x0000,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  31. const GUID CLSID_QIHANDLER1 =
  32. {0x00000141,0x0000,0x0008,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  33. //const GUID IID_IMultiQI =
  34. // {0x00000020,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  35. const GUID IID_IInternalUnknown =
  36. {0x00000021,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  37. const GUID IID_IStdIdentity =
  38. {0x0000001b,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  39. const GUID CLSID_OLEPSFACTORY =
  40. {0x00000320,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  41. extern "C" const GUID CLSID_TestEmbed;
  42. // external functions
  43. STDAPI_(LPSTREAM) CreateMemStm(DWORD cb, LPHANDLE phdl);
  44. HRESULT VerifyOBJREFFormat(IStream *pStm, DWORD mshlflags);
  45. DWORD _stdcall RundownClient(void *param);
  46. // APIs exported by OLE32 but not in the header files.
  47. STDAPI CoGetIIDFromMarshaledInterface(IStream *pStm, IID *piid);
  48. // function prototypes - TRUE return means the test passed
  49. BOOL TestMarshalFormat(void);
  50. BOOL TestGetIIDFromMI(void);
  51. BOOL TestLocalInterfaceNormal(void);
  52. BOOL TestUnmarshalGUIDNULL(void);
  53. BOOL TestUnmarshalDifferentIID(void);
  54. BOOL TestUniqueQIPointer(void);
  55. BOOL TestLocalInterfaceTableStrong(void);
  56. BOOL TestLocalInterfaceTableWeak(void);
  57. BOOL TestRemoteInterfaceNormal(void);
  58. BOOL TestRemoteInterfaceTableStrong(void);
  59. BOOL TestNoPing(void);
  60. BOOL TestEcho(void);
  61. BOOL TestMiddleMan(void);
  62. BOOL TestLoop(void);
  63. BOOL TestLockObjectExternal(void);
  64. BOOL TestDisconnectObject(void);
  65. BOOL TestHandler(void);
  66. BOOL TestReleaseMarshalData(void);
  67. BOOL TestCustomMarshalNormal(void);
  68. BOOL TestCustomMarshalTable(void);
  69. BOOL TestGetStandardMarshal(void);
  70. BOOL TestLocalInterfaceDiffMachine(void);
  71. BOOL TestRemoteInterfaceDiffMachine(void);
  72. BOOL TestExpiredOXIDs(void);
  73. BOOL TestNonNDRProxy(void);
  74. BOOL TestTIDAndLID(void);
  75. BOOL TestMarshalSizeMax(void);
  76. BOOL TestMarshalStorage(void);
  77. BOOL TestMultiQINormal(void);
  78. BOOL TestMultiQIHandler(void);
  79. BOOL TestCrossThread(void);
  80. BOOL TestPSClsid(void);
  81. BOOL TestPSClsid2(void);
  82. BOOL TestAsync(void);
  83. BOOL TestRundown(void);
  84. BOOL TestAggregate(void);
  85. BOOL TestCreateRemoteHandler(void);
  86. BOOL TestStorageInterfaceDiffMachine(void);
  87. WCHAR *pwszFileName[] = {L"c:\\mshlfile.1",
  88. L"c:\\mshlfile.2",
  89. L"c:\\mshlfile.3"};
  90. // internal subroutines
  91. void VerifyRHRefCnt(IUnknown *punk, ULONG ulExpectedRefCnt);
  92. void VerifyObjRefCnt(IUnknown *punk, ULONG ulExpectedRefCnt);
  93. TCHAR g_szIniFile[MAX_PATH];
  94. // ----------------------------------------------------------------------
  95. //
  96. // TestMarshal - main test driver
  97. //
  98. // ----------------------------------------------------------------------
  99. BOOL GetProfileValue(TCHAR *pszKeyName, int nDefault)
  100. {
  101. return (GetPrivateProfileInt(TEXT("Marshal Test"),
  102. pszKeyName,
  103. nDefault,
  104. g_szIniFile));
  105. }
  106. // ----------------------------------------------------------------------
  107. //
  108. // TestMarshal - main test driver
  109. //
  110. // ----------------------------------------------------------------------
  111. BOOL TestMarshal(void)
  112. {
  113. BOOL RetVal = TRUE;
  114. // Get file name of .ini file, TMARSHAL.INI in the current directory
  115. GetCurrentDirectory (MAX_PATH, g_szIniFile);
  116. lstrcat(g_szIniFile, TEXT("\\TMARSHAL.INI"));
  117. if (GetProfileValue(TEXT("Format"),1))
  118. RetVal &= TestMarshalFormat();
  119. if (GetProfileValue(TEXT("GetIIDFromMI"),1))
  120. RetVal &= TestGetIIDFromMI();
  121. if (GetProfileValue(TEXT("MarshalSizeMax"),1))
  122. RetVal &= TestMarshalSizeMax();
  123. if (GetProfileValue(TEXT("GetStandardMarshal"),1))
  124. RetVal &= TestGetStandardMarshal();
  125. if (GetProfileValue(TEXT("LocalInterfaceNormal"),1))
  126. RetVal &= TestLocalInterfaceNormal();
  127. if (GetProfileValue(TEXT("UniqueQIPointer"),1))
  128. RetVal &= TestUniqueQIPointer();
  129. if (GetProfileValue(TEXT("LocalInterfaceTableStrong"),1))
  130. RetVal &= TestLocalInterfaceTableStrong();
  131. if (GetProfileValue(TEXT("LocalInterfaceTableWeak"),1))
  132. RetVal &= TestLocalInterfaceTableWeak();
  133. if (GetProfileValue(TEXT("RemoteInterfaceNormal"),1))
  134. RetVal &= TestRemoteInterfaceNormal();
  135. if (GetProfileValue(TEXT("UnmarshalGUIDNULL"),1))
  136. RetVal &= TestUnmarshalGUIDNULL();
  137. if (GetProfileValue(TEXT("UnmarshalDifferentIID"),1))
  138. RetVal &= TestUnmarshalDifferentIID();
  139. if (GetProfileValue(TEXT("RemoteInterfaceTableStrong"),1))
  140. RetVal &= TestRemoteInterfaceTableStrong();
  141. if (GetProfileValue(TEXT("CrossThread"),1))
  142. RetVal &= TestCrossThread();
  143. if (GetProfileValue(TEXT("CustomMarshalNormal"),1))
  144. RetVal &= TestCustomMarshalNormal();
  145. if (GetProfileValue(TEXT("CustomMarshalTable"),1))
  146. RetVal &= TestCustomMarshalTable();
  147. if (GetProfileValue(TEXT("Echo"),1))
  148. RetVal &= TestEcho();
  149. if (GetProfileValue(TEXT("Loop"),1))
  150. RetVal &= TestLoop();
  151. if (GetProfileValue(TEXT("LockObjectExternal"),1))
  152. RetVal &= TestLockObjectExternal();
  153. if (GetProfileValue(TEXT("DisconnectObject"),1))
  154. RetVal &= TestDisconnectObject();
  155. if (GetProfileValue(TEXT("ReleaseMarshalData"),1))
  156. RetVal &= TestReleaseMarshalData();
  157. if (GetProfileValue(TEXT("MultiQINormal"),1))
  158. RetVal &= TestMultiQINormal();
  159. if (GetProfileValue(TEXT("MultiQIHandler"),1))
  160. RetVal &= TestMultiQIHandler();
  161. if (GetProfileValue(TEXT("Handler"),1))
  162. RetVal &= TestHandler();
  163. if (GetProfileValue(TEXT("MiddleMan"),1))
  164. RetVal &= TestMiddleMan();
  165. if (GetProfileValue(TEXT("MarshalStorage"),1))
  166. RetVal &= TestMarshalStorage();
  167. if (GetProfileValue(TEXT("LocalDiffMachine"),1))
  168. RetVal &= TestLocalInterfaceDiffMachine();
  169. if (GetProfileValue(TEXT("RemoteDiffMachine"),1))
  170. RetVal &= TestRemoteInterfaceDiffMachine();
  171. if (GetProfileValue(TEXT("ExpiredOXIDs"),1))
  172. RetVal &= TestExpiredOXIDs();
  173. if (GetProfileValue(TEXT("NonNDRProxy"),1))
  174. RetVal &= TestNonNDRProxy();
  175. if (GetProfileValue(TEXT("TIDAndLID"),1))
  176. RetVal &= TestTIDAndLID();
  177. if (GetProfileValue(TEXT("NoPing"),1))
  178. RetVal &= TestNoPing();
  179. if (GetProfileValue(TEXT("PSClsid"),1))
  180. RetVal &= TestPSClsid();
  181. if (GetProfileValue(TEXT("PSClsid2"),1))
  182. RetVal &= TestPSClsid2();
  183. // -------------------------------------------------------------------
  184. if (GetProfileValue(TEXT("Rundown"),0))
  185. RetVal &= TestRundown();
  186. if (GetProfileValue(TEXT("Async"),0))
  187. RetVal &= TestAsync();
  188. if (GetProfileValue(TEXT("StorageDiffMachine"),0))
  189. RetVal &= TestStorageInterfaceDiffMachine();
  190. if (GetProfileValue(TEXT("Aggregate"),0))
  191. RetVal &= TestAggregate();
  192. if (GetProfileValue(TEXT("CreateRemoteHandler"),0))
  193. RetVal &= TestCreateRemoteHandler();
  194. return RetVal;
  195. }
  196. // ----------------------------------------------------------------------
  197. //
  198. // subroutine to verify that the RH RefCnt is as expected.
  199. //
  200. // ----------------------------------------------------------------------
  201. typedef IMarshal * (* PFNDBG_FINDRH)(IUnknown *punk);
  202. PFNDBG_FINDRH gpfnFindRH = NULL;
  203. HMODULE ghOle32Dll = NULL;
  204. BOOL gfTriedToLoad = FALSE;
  205. void LoadProc()
  206. {
  207. if (!gfTriedToLoad)
  208. {
  209. gfTriedToLoad = TRUE;
  210. ghOle32Dll = LoadLibrary(TEXT("OLE32.DLL"));
  211. if (ghOle32Dll)
  212. {
  213. gpfnFindRH = (PFNDBG_FINDRH) GetProcAddress(ghOle32Dll,
  214. "Dbg_FindRemoteHdlr");
  215. }
  216. }
  217. }
  218. void FreeProc()
  219. {
  220. if (ghOle32Dll)
  221. {
  222. FreeLibrary(ghOle32Dll);
  223. }
  224. }
  225. // ----------------------------------------------------------------------
  226. //
  227. // subroutine to verify that the RH RefCnt is as expected.
  228. //
  229. // ----------------------------------------------------------------------
  230. void VerifyRHRefCnt(IUnknown *punk, ULONG ulExpectedRefCnt)
  231. {
  232. if (gpfnFindRH == NULL)
  233. {
  234. LoadProc();
  235. }
  236. if (gpfnFindRH)
  237. {
  238. // this function is internal to COMPOBJ marshalling.
  239. IMarshal *pIM = (gpfnFindRH)(punk);
  240. if (pIM == NULL)
  241. {
  242. if (ulExpectedRefCnt != 0)
  243. printf ("ERROR: RH RefCnt 0, expected=%x\n", ulExpectedRefCnt);
  244. return;
  245. }
  246. ULONG ulRefCnt = pIM->Release();
  247. if (ulRefCnt != ulExpectedRefCnt)
  248. {
  249. printf ("ERROR: RH RefCnt=%x, expected=%x\n", ulRefCnt, ulExpectedRefCnt);
  250. }
  251. }
  252. }
  253. // ----------------------------------------------------------------------
  254. //
  255. // subroutine to verify that the Object RefCnt is as expected.
  256. //
  257. // ----------------------------------------------------------------------
  258. void VerifyObjRefCnt(IUnknown *punk, ULONG ulExpectedRefCnt)
  259. {
  260. if (ulExpectedRefCnt == 0)
  261. return; // cant verify this
  262. //#if DBG==1
  263. // this function is internal to COMPOBJ marshalling.
  264. punk->AddRef();
  265. ULONG ulRefCnt = punk->Release();
  266. if (ulRefCnt != ulExpectedRefCnt)
  267. {
  268. printf ("ERROR: Object RefCnt=%x, expected=%x\n", ulRefCnt, ulExpectedRefCnt);
  269. }
  270. //#endif
  271. }
  272. // ----------------------------------------------------------------------
  273. //
  274. // MarshalAndRead
  275. //
  276. // ----------------------------------------------------------------------
  277. HRESULT MarshalAndRead(IUnknown *punkIn, BYTE *pbuf, ULONG *pulSize)
  278. {
  279. BOOL RetVal = TRUE;
  280. HRESULT hres;
  281. ULARGE_INTEGER ulSeekEnd;
  282. LARGE_INTEGER lSeekStart;
  283. LISet32(lSeekStart, 0);
  284. IStream *pStm = CreateMemStm(600, NULL);
  285. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  286. VerifyObjRefCnt((IUnknown *)pStm, 1);
  287. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  288. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  289. OUTPUT (" - CoMarshalInterface OK\n");
  290. // get current seek position
  291. hres = pStm->Seek(lSeekStart, STREAM_SEEK_CUR, &ulSeekEnd);
  292. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  293. OUTPUT (" - Seek Current OK\n");
  294. // go back to begining
  295. hres = pStm->Seek(lSeekStart, STREAM_SEEK_SET, NULL);
  296. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  297. OUTPUT (" - Seek Start OK\n");
  298. // read in the data
  299. hres = pStm->Read(pbuf ,ulSeekEnd.LowPart, pulSize);
  300. TEST_FAILED_EXIT(FAILED(hres), "Read on stream failed\n")
  301. OUTPUT (" - Read OK\n");
  302. Cleanup:
  303. // release the stream
  304. pStm->Release();
  305. if (RetVal == TRUE)
  306. return S_OK;
  307. else
  308. return hres;
  309. }
  310. // ----------------------------------------------------------------------
  311. //
  312. // GetTestUnk - return an inproc IUnknown ptr.
  313. //
  314. // ----------------------------------------------------------------------
  315. IUnknown *GetTestUnk()
  316. {
  317. IUnknown *punkIn = (IUnknown *)(IParseDisplayName *) new CTestUnk();
  318. return punkIn;
  319. }
  320. // ----------------------------------------------------------------------
  321. //
  322. // RunThread - runs a thread and waits for it to complete
  323. //
  324. // ----------------------------------------------------------------------
  325. void RunThread(void *param, HANDLE hEvent, LPTHREAD_START_ROUTINE pfn)
  326. {
  327. DWORD dwThrdId;
  328. HANDLE hThrd = CreateThread(NULL, 0, pfn, param, 0, &dwThrdId);
  329. if (hThrd)
  330. {
  331. if (gInitFlag == COINIT_APARTMENTTHREADED)
  332. {
  333. // enter a message pump to accept incoming calls from the
  334. // other thread.
  335. MSG msg;
  336. while (GetMessage(&msg, NULL, 0, 0))
  337. {
  338. DispatchMessage(&msg);
  339. }
  340. }
  341. else
  342. {
  343. // wait for the other thread to run to completion
  344. WaitForSingleObject(hEvent, 0xffffffff);
  345. }
  346. // close the thread handle
  347. CloseHandle(hThrd);
  348. }
  349. }
  350. // ----------------------------------------------------------------------
  351. //
  352. // TestAsync
  353. //
  354. // ----------------------------------------------------------------------
  355. BOOL TestAsync(void)
  356. {
  357. BOOL RetVal = TRUE;
  358. HRESULT hRes = S_OK;
  359. ULONG ulRefCnt = 0;
  360. IUnknown *pUnkSrv = NULL;
  361. IAdviseSink *pAdvSnk = NULL;
  362. OUTPUT ("Starting TestAsync\n");
  363. // create our interface to pass to the remote object.
  364. hRes = CoCreateInstance(CLSID_Async, NULL, CLSCTX_LOCAL_SERVER,
  365. IID_IUnknown, (void **)&pUnkSrv);
  366. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance First failed\n")
  367. OUTPUT (" - QI for IAdviseSink\n");
  368. hRes = pUnkSrv->QueryInterface(IID_IAdviseSink, (void **)&pAdvSnk);
  369. TEST_FAILED_EXIT(FAILED(hRes), "QI for IAdviseSink failed\n")
  370. // now call on the IAdviseSink Interface
  371. pAdvSnk->OnSave();
  372. Sleep(30);
  373. // release the interface
  374. pAdvSnk->Release();
  375. pAdvSnk = NULL;
  376. // ----------------------------------------------------------------------
  377. Cleanup:
  378. OUTPUT (" - Test Complete. Doing Cleanup\n");
  379. // Dump interfaces we are done with
  380. if (pAdvSnk)
  381. {
  382. ulRefCnt = pAdvSnk->Release();
  383. TEST_FAILED(ulRefCnt != 1, "pAdvSnk RefCnt not zero\n");
  384. }
  385. if (pUnkSrv)
  386. {
  387. ulRefCnt = pUnkSrv->Release();
  388. TEST_FAILED(ulRefCnt != 0, "PunkSrv RefCnt not zero\n");
  389. }
  390. return TestResult(RetVal, "TestAsync");
  391. }
  392. // ----------------------------------------------------------------------
  393. //
  394. // test marshal format
  395. //
  396. // ----------------------------------------------------------------------
  397. BOOL TestMarshalFormat(void)
  398. {
  399. BOOL RetVal = TRUE;
  400. BOOL fSame = TRUE;
  401. HRESULT hres;
  402. ULONG ulRefCnt = 0;
  403. IUnknown *punkIn = NULL;
  404. BYTE buf1[600];
  405. BYTE buf2[600];
  406. ULONG ulSize1 = sizeof(buf1);
  407. ULONG ulSize2 = sizeof(buf2);
  408. OUTPUT ("Starting TestMarshalFormat\n");
  409. punkIn = GetTestUnk();
  410. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  411. VerifyObjRefCnt(punkIn, 1);
  412. // ----------------------------------------------------------------------
  413. hres = MarshalAndRead(punkIn, buf1, &ulSize1);
  414. TEST_FAILED_EXIT(FAILED(hres), "MarshalAndRead failed\n")
  415. OUTPUT (" - First MarshalAndRead OK\n");
  416. hres = MarshalAndRead(punkIn, buf2, &ulSize2);
  417. TEST_FAILED_EXIT(FAILED(hres), "MarshalAndRead failed\n")
  418. OUTPUT (" - Second MarshalAndRead OK\n");
  419. TEST_FAILED_EXIT((ulSize1 != ulSize2), "Buffer Sizes Differ\n")
  420. fSame = !memcmp(buf1, buf2, ulSize1);
  421. TEST_FAILED_EXIT(!fSame, "Buffer Contents Differ\n")
  422. OUTPUT (" - Buffers Compare OK\n");
  423. // ----------------------------------------------------------------------
  424. Cleanup:
  425. OUTPUT (" - Test Complete. Doing Cleanup\n");
  426. CoDisconnectObject(punkIn,0);
  427. if (punkIn)
  428. {
  429. ulRefCnt = punkIn->Release();
  430. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  431. }
  432. return TestResult(RetVal, "TestMarshalFormat");
  433. }
  434. // ----------------------------------------------------------------------
  435. //
  436. // test CoGetMarshalSizeMax
  437. //
  438. // ----------------------------------------------------------------------
  439. BOOL TestMarshalSizeMax(void)
  440. {
  441. BOOL RetVal = TRUE;
  442. HRESULT hres;
  443. ULONG ulRefCnt = 0;
  444. IUnknown *punkIn = NULL;
  445. ULONG ulSize = 0;
  446. OUTPUT ("Starting TestMarshalSizeMax\n");
  447. punkIn = GetTestUnk();
  448. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  449. VerifyObjRefCnt(punkIn, 1);
  450. // ----------------------------------------------------------------------
  451. hres = CoGetMarshalSizeMax(&ulSize, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  452. TEST_FAILED_EXIT(FAILED(hres), "CoGetMarshalSizeMax failed\n")
  453. VerifyRHRefCnt(punkIn, 0);
  454. OUTPUT (" - CoGetMarshalSizeMax OK\n");
  455. // ----------------------------------------------------------------------
  456. Cleanup:
  457. OUTPUT (" - Test Complete. Doing Cleanup\n");
  458. if (punkIn)
  459. {
  460. punkIn->Release();
  461. punkIn = NULL;
  462. }
  463. return TestResult(RetVal, "TestMarshalSizeMax");
  464. }
  465. // ----------------------------------------------------------------------
  466. //
  467. // test LOCAL interface MSHLFLAGS_NORMAL
  468. //
  469. // ----------------------------------------------------------------------
  470. BOOL TestLocalInterfaceNormal(void)
  471. {
  472. BOOL RetVal = TRUE;
  473. HRESULT hres;
  474. LPSTREAM pStm = NULL;
  475. ULONG ulRefCnt = 0;
  476. IUnknown *punkIn = NULL;
  477. IUnknown *punkOut = NULL;
  478. IUnknown *punkOut2 = NULL;
  479. LARGE_INTEGER large_int;
  480. LISet32(large_int, 0);
  481. OUTPUT ("Starting TestLocalInterfaceNormal\n");
  482. punkIn = GetTestUnk();
  483. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  484. VerifyObjRefCnt(punkIn, 1);
  485. pStm = CreateMemStm(600, NULL);
  486. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  487. VerifyObjRefCnt((IUnknown *)pStm, 1);
  488. // ----------------------------------------------------------------------
  489. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  490. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  491. VerifyRHRefCnt(punkIn, 1);
  492. OUTPUT (" - CoMarshalInterface OK\n");
  493. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  494. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  495. // since we are unmarshalling in the same process, the RH should go away.
  496. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  497. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  498. VerifyRHRefCnt(punkIn, 0);
  499. VerifyObjRefCnt(punkIn, 2);
  500. // make sure the interface pointers are identical
  501. if (punkIn != punkOut)
  502. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...1st Local Unmarshal\n")
  503. OUTPUT (" - CoUnmarshalInterface OK\n");
  504. // release it and make sure it does not go away - refcnt > 0
  505. ulRefCnt = punkOut->Release();
  506. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero");
  507. punkOut = NULL;
  508. OUTPUT (" - Release OK\n");
  509. // the RH should have gone away, and we should have only the original
  510. // refcnt from creation left on the object.
  511. VerifyObjRefCnt(punkIn, 1);
  512. // ----------------------------------------------------------------------
  513. #if 0
  514. // this test disabled for DCOM since we no longer write into the stream
  515. // to mark the thing as having been unmarshaled. This lets unmarshals
  516. // work with read-only streams.
  517. // test unmarshalling twice. this should fail since we did marshal
  518. // flags normal and already unmarshalled it once.
  519. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  520. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  521. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut2);
  522. TEST_FAILED_EXIT(SUCCEEDED(hres), "CoUnmarshalInterface second time succeeded but should have failed\n")
  523. OUTPUT (" - Second CoUnmarshalInterface OK\n");
  524. // ----------------------------------------------------------------------
  525. // CoReleaseMarshalData should fail because Unmarshall already called it.
  526. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  527. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  528. hres = CoReleaseMarshalData(pStm);
  529. TEST_FAILED_EXIT(SUCCEEDED(hres), "CoReleaseMarshalData succeeded but should have failed.\n")
  530. OUTPUT (" - CoReleaseMarshalData OK\n");
  531. #endif
  532. // ----------------------------------------------------------------------
  533. // marshal again and try CoRelease without having first done an
  534. // unmarshal. this should work.
  535. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  536. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  537. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  538. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  539. OUTPUT (" - CoMarshalInterface OK\n");
  540. VerifyRHRefCnt(punkIn, 1);
  541. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  542. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  543. hres = CoReleaseMarshalData(pStm);
  544. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  545. VerifyRHRefCnt(punkIn, 0);
  546. VerifyObjRefCnt(punkIn, 1);
  547. OUTPUT (" - CoReleaseMarshalData OK\n");
  548. // ----------------------------------------------------------------------
  549. // release the object and try to unmarshal it again. Should fail
  550. // since the object has gone away.
  551. ulRefCnt = punkIn->Release();
  552. TEST_FAILED_EXIT(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  553. punkIn = NULL;
  554. // go back to start of stream
  555. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  556. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  557. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  558. TEST_FAILED_EXIT(SUCCEEDED(hres), "CoUnmarshalInterface should have failed\n")
  559. // ----------------------------------------------------------------------
  560. Cleanup:
  561. OUTPUT (" - Test Complete. Doing Cleanup\n");
  562. // Dump interfaces we are done with
  563. if (pStm)
  564. {
  565. ulRefCnt = pStm->Release();
  566. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  567. }
  568. if (punkOut)
  569. {
  570. ulRefCnt = punkOut->Release();
  571. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  572. }
  573. if (punkOut2)
  574. {
  575. ulRefCnt = punkOut2->Release();
  576. TEST_FAILED(ulRefCnt != 0, "punkOut2 RefCnt not zero\n");
  577. }
  578. if (punkIn)
  579. {
  580. ulRefCnt = punkIn->Release();
  581. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  582. }
  583. return TestResult(RetVal, "TestLocalInterfaceNormal");
  584. }
  585. // ----------------------------------------------------------------------
  586. //
  587. // test LOCAL interface MSHLFLAGS_NORMAL when the object returns a
  588. // differnt interface pointer on each subsequent QI for the same
  589. // interface
  590. //
  591. // ----------------------------------------------------------------------
  592. BOOL TestUniqueQIPointer(void)
  593. {
  594. BOOL RetVal = TRUE;
  595. HRESULT hres;
  596. LPSTREAM pStm = NULL;
  597. ULONG ulRefCnt = 0;
  598. IUnknown *punkIn = NULL;
  599. IUnknown *punkOut = NULL;
  600. ICube *pCubeIn = NULL;
  601. ICube *pCubeOut = NULL;
  602. LARGE_INTEGER large_int;
  603. LISet32(large_int, 0);
  604. OUTPUT ("Starting TestUniqueQIPointer\n");
  605. punkIn = GetTestUnk();
  606. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  607. VerifyObjRefCnt(punkIn, 1);
  608. hres = punkIn->QueryInterface(IID_ICube, (void **)&pCubeIn);
  609. TEST_FAILED_EXIT((pCubeIn == NULL), "QI for IID_ICube failed\n")
  610. VerifyObjRefCnt(punkIn, 2);
  611. pStm = CreateMemStm(600, NULL);
  612. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  613. VerifyObjRefCnt((IUnknown *)pStm, 1);
  614. // ----------------------------------------------------------------------
  615. hres = CoMarshalInterface(pStm, IID_ICube, pCubeIn, 0, NULL, MSHLFLAGS_NORMAL);
  616. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  617. VerifyRHRefCnt(pCubeIn, 1);
  618. OUTPUT (" - CoMarshalInterface OK\n");
  619. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  620. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  621. // since we are unmarshalling in the same process, the RH should go away.
  622. hres = CoUnmarshalInterface(pStm, IID_ICube, (LPVOID FAR*)&pCubeOut);
  623. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  624. VerifyRHRefCnt(pCubeIn, 0);
  625. VerifyRHRefCnt(pCubeOut, 0);
  626. VerifyRHRefCnt(punkIn, 0);
  627. VerifyObjRefCnt(pCubeIn, 1);
  628. VerifyObjRefCnt(pCubeOut, 1);
  629. VerifyObjRefCnt(punkIn, 3);
  630. // make sure the Ctrl Unknown interface pointers are identical
  631. hres = pCubeOut->QueryInterface(IID_IUnknown, (void **)&punkOut);
  632. TEST_FAILED_EXIT((punkOut == NULL), "QI for IID_IUnknown failed\n")
  633. VerifyObjRefCnt(punkOut, 4);
  634. if (punkIn != punkOut)
  635. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...1st Local Unmarshal\n")
  636. OUTPUT (" - CoUnmarshalInterface OK\n");
  637. // attempt a call on the in interface pointer.
  638. hres = pCubeIn->MoveCube(0,0);
  639. TEST_FAILED_EXIT(FAILED(hres), "pCubeIn->MoveCube failed\n")
  640. // release the in-pointer
  641. ulRefCnt = pCubeIn->Release();
  642. TEST_FAILED(ulRefCnt != 0, "pCubeIn RefCnt not zero\n");
  643. pCubeIn = NULL;
  644. // now call on the out interface pointer
  645. hres = pCubeOut->MoveCube(0,0);
  646. TEST_FAILED_EXIT(FAILED(hres), "pCubeOut->MoveCube failed\n")
  647. // release the out-pointer
  648. ulRefCnt = pCubeOut->Release();
  649. TEST_FAILED(ulRefCnt != 0, "pCubeOut RefCnt not zero\n");
  650. pCubeOut = NULL;
  651. Cleanup:
  652. OUTPUT (" - Test Complete. Doing Cleanup\n");
  653. // Dump interfaces we are done with
  654. if (pStm)
  655. {
  656. ulRefCnt = pStm->Release();
  657. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  658. }
  659. if (pCubeIn)
  660. {
  661. ulRefCnt = pCubeIn->Release();
  662. TEST_FAILED(ulRefCnt != 0, "pCubeIn RefCnt not zero\n");
  663. }
  664. if (pCubeOut)
  665. {
  666. ulRefCnt = pCubeOut->Release();
  667. TEST_FAILED(ulRefCnt != 0, "pCubeOut RefCnt not zero\n");
  668. }
  669. if (punkOut)
  670. {
  671. ulRefCnt = punkOut->Release();
  672. TEST_FAILED(ulRefCnt == 0, "punkOut RefCnt not zero\n");
  673. }
  674. if (punkIn)
  675. {
  676. ulRefCnt = punkIn->Release();
  677. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  678. }
  679. return TestResult(RetVal, "TestUniqueQIPointer");
  680. }
  681. // ----------------------------------------------------------------------
  682. //
  683. // test LOCAL interface MSHLFLAGS_TABLESTRONG
  684. //
  685. // ----------------------------------------------------------------------
  686. BOOL TestLocalInterfaceTableStrong(void)
  687. {
  688. BOOL RetVal = TRUE;
  689. HRESULT hres;
  690. LPSTREAM pStm = NULL;
  691. ULONG ulRefCnt = 0;
  692. IUnknown *punkIn = NULL;
  693. IUnknown *punkOut = NULL;
  694. IUnknown *punkOut2 = NULL;
  695. LARGE_INTEGER large_int;
  696. LISet32(large_int, 0);
  697. OUTPUT ("Starting TestLocalInterfaceTableStrong\n");
  698. punkIn = GetTestUnk();
  699. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  700. VerifyObjRefCnt(punkIn, 1);
  701. pStm = CreateMemStm(600, NULL);
  702. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  703. VerifyObjRefCnt((IUnknown *)pStm, 1);
  704. // ----------------------------------------------------------------------
  705. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_TABLESTRONG);
  706. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  707. VerifyRHRefCnt(punkIn, 1);
  708. OUTPUT (" - CoMarshalInterface OK\n");
  709. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  710. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  711. // unmarshalling should leave the RH intact, as it is marshalled for TABLE.
  712. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  713. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  714. VerifyRHRefCnt(punkIn, 1);
  715. // make sure the interface pointers are identical
  716. if (punkIn != punkOut)
  717. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...1st Local Unmarshal\n")
  718. OUTPUT (" - CoUnmarshalInterface OK\n");
  719. // release it and make sure it does not go away - refcnt > 0
  720. ulRefCnt = punkOut->Release();
  721. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero");
  722. punkOut = NULL;
  723. VerifyRHRefCnt(punkIn, 1);
  724. OUTPUT (" - Release OK\n");
  725. // ----------------------------------------------------------------------
  726. // test unmarshalling twice - should work since we used flags table
  727. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  728. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  729. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut2);
  730. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface second time succeeded but should have failed\n")
  731. VerifyRHRefCnt(punkIn, 1);
  732. OUTPUT (" - Second CoUnmarshalInterface OK\n");
  733. // release it and make sure it does not go away - refcnt > 0
  734. ulRefCnt = punkOut2->Release();
  735. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut2 RefCnt is zero");
  736. punkOut2 = NULL;
  737. VerifyRHRefCnt(punkIn, 1);
  738. OUTPUT (" - Release OK\n");
  739. // ----------------------------------------------------------------------
  740. // CoReleaseMarshalData should release the marshalled data TABLESTRONG
  741. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  742. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  743. hres = CoReleaseMarshalData(pStm);
  744. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  745. VerifyRHRefCnt(punkIn, 0);
  746. OUTPUT (" - CoReleaseMarshalData OK\n");
  747. // ----------------------------------------------------------------------
  748. Cleanup:
  749. OUTPUT (" - Test Complete. Doing Cleanup\n");
  750. // Dump interfaces we are done with
  751. if (pStm)
  752. {
  753. ulRefCnt = pStm->Release();
  754. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  755. }
  756. if (punkOut)
  757. {
  758. ulRefCnt = punkOut->Release();
  759. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  760. }
  761. if (punkOut2)
  762. {
  763. ulRefCnt = punkOut2->Release();
  764. TEST_FAILED(ulRefCnt != 0, "punkOut2 RefCnt not zero\n");
  765. }
  766. if (punkIn)
  767. {
  768. ulRefCnt = punkIn->Release();
  769. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  770. }
  771. return TestResult(RetVal, "TestLocalInterfaceTableStrong");
  772. }
  773. // ----------------------------------------------------------------------
  774. //
  775. // test LOCAL interface MSHLFLAGS_TABLEWEAK
  776. //
  777. // ----------------------------------------------------------------------
  778. BOOL TestLocalInterfaceTableWeak(void)
  779. {
  780. BOOL RetVal = TRUE;
  781. HRESULT hres;
  782. LPSTREAM pStm = NULL;
  783. ULONG ulRefCnt = 0;
  784. IUnknown *punkIn = NULL;
  785. IUnknown *punkOut = NULL;
  786. IUnknown *punkOut2 = NULL;
  787. LARGE_INTEGER large_int;
  788. LISet32(large_int, 0);
  789. OUTPUT ("Starting TestLocalInterfaceTableWeak\n");
  790. punkIn = GetTestUnk();
  791. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  792. VerifyObjRefCnt(punkIn, 1);
  793. pStm = CreateMemStm(600, NULL);
  794. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  795. VerifyObjRefCnt((IUnknown *)pStm, 1);
  796. // ----------------------------------------------------------------------
  797. hres = CoMarshalInterface(pStm, IID_IParseDisplayName, punkIn, 0, NULL, MSHLFLAGS_TABLEWEAK);
  798. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  799. VerifyRHRefCnt(punkIn, 1);
  800. OUTPUT (" - CoMarshalInterface OK\n");
  801. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  802. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  803. // unmarshalling should leave the RH intact, as it is marshalled for TABLE.
  804. hres = CoUnmarshalInterface(pStm, IID_IParseDisplayName, (LPVOID FAR*)&punkOut);
  805. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  806. VerifyRHRefCnt(punkIn, 1);
  807. // make sure the interface pointers are identical
  808. if (punkIn != punkOut)
  809. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...1st Local Unmarshal\n")
  810. OUTPUT (" - CoUnmarshalInterface OK\n");
  811. // release it and make sure it does not go away - refcnt > 0
  812. ulRefCnt = punkOut->Release();
  813. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero");
  814. punkOut = NULL;
  815. VerifyRHRefCnt(punkIn, 1);
  816. OUTPUT (" - Release OK\n");
  817. // ----------------------------------------------------------------------
  818. // test unmarshalling twice - should work since we used flags table
  819. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  820. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  821. hres = CoUnmarshalInterface(pStm, IID_IParseDisplayName, (LPVOID FAR*)&punkOut2);
  822. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface second time succeeded but should have failed\n")
  823. VerifyRHRefCnt(punkIn, 1);
  824. // make sure the interface pointers are identical
  825. if (punkIn != punkOut2)
  826. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...2nd Local Unmarshal\n")
  827. OUTPUT (" - Second CoUnmarshalInterface OK\n");
  828. // release it and make sure it does not go away - refcnt > 0
  829. ulRefCnt = punkOut2->Release();
  830. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut2 RefCnt is zero");
  831. punkOut2 = NULL;
  832. VerifyRHRefCnt(punkIn, 1);
  833. OUTPUT (" - Release OK\n");
  834. // ----------------------------------------------------------------------
  835. // CoReleaseMarshalData should release the marshalled data TABLEWEAK
  836. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  837. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  838. hres = CoReleaseMarshalData(pStm);
  839. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  840. VerifyRHRefCnt(punkIn, 0);
  841. VerifyObjRefCnt(punkIn, 1);
  842. OUTPUT (" - CoReleaseMarshalData OK\n");
  843. ulRefCnt = punkIn->Release();
  844. TEST_FAILED_EXIT(ulRefCnt != 0, "punkIn RefCnt is not zero");
  845. punkIn = NULL;
  846. // ----------------------------------------------------------------------
  847. Cleanup:
  848. OUTPUT (" - Test Complete. Doing Cleanup\n");
  849. // Dump interfaces we are done with
  850. if (pStm)
  851. {
  852. ulRefCnt = pStm->Release();
  853. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  854. }
  855. if (punkOut)
  856. {
  857. ulRefCnt = punkOut->Release();
  858. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  859. }
  860. if (punkOut2)
  861. {
  862. ulRefCnt = punkOut2->Release();
  863. TEST_FAILED(ulRefCnt != 0, "punkOut2 RefCnt not zero\n");
  864. }
  865. if (punkIn)
  866. {
  867. ulRefCnt = punkIn->Release();
  868. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  869. }
  870. return TestResult(RetVal, "TestLocalInterfaceTableWeak");
  871. }
  872. // ----------------------------------------------------------------------
  873. //
  874. // test calling CoUmarshalInterface with GUID_NULL
  875. //
  876. // ----------------------------------------------------------------------
  877. // ----------------------------------------------------------------------
  878. //
  879. // Structure passed between apartments.
  880. //
  881. // ----------------------------------------------------------------------
  882. typedef struct tagThreadUnmarshalInfo
  883. {
  884. HANDLE hEvent;
  885. IStream *pStm;
  886. IUnknown *pUnk;
  887. IID iid;
  888. DWORD dwInitFlag;
  889. DWORD dwThreadId;
  890. ULONG RelRefCnt;
  891. HRESULT hr;
  892. } ThreadUnmarshalInfo;
  893. DWORD _stdcall ThreadTestUnmarshal(void *params)
  894. {
  895. ThreadUnmarshalInfo *pInfo = (ThreadUnmarshalInfo *)params;
  896. BOOL RetVal = TRUE;
  897. ULONG ulRefCnt= 0;
  898. IUnknown *punkOut = NULL;
  899. HRESULT hres;
  900. hres = CoInitializeEx(NULL, pInfo->dwInitFlag);
  901. hres = CoUnmarshalInterface(pInfo->pStm, pInfo->iid, (LPVOID FAR*)&punkOut);
  902. TEST_FAILED(FAILED(hres), "CoUnmarshalInterface failed\n")
  903. if (SUCCEEDED(hres))
  904. {
  905. // make sure the interface pointers are identical
  906. if (pInfo->pUnk != NULL && pInfo->pUnk != punkOut)
  907. {
  908. TEST_FAILED(TRUE, "Interface ptrs are wrong\n")
  909. }
  910. else
  911. {
  912. OUTPUT (" - CoUnmarshalInterface OK.\n");
  913. }
  914. // release the interface
  915. ulRefCnt = punkOut->Release();
  916. punkOut = NULL;
  917. TEST_FAILED(ulRefCnt != pInfo->RelRefCnt, "Released punkOut RefCnt is wrong\n");
  918. OUTPUT (" - Release OK\n");
  919. }
  920. pInfo->hr = hres;
  921. CoUninitialize();
  922. // signal the other thread we are done.
  923. // but only if we were called from a different thread
  924. if (pInfo->dwThreadId != 0)
  925. {
  926. if (gInitFlag == COINIT_APARTMENTTHREADED)
  927. {
  928. PostThreadMessage(pInfo->dwThreadId, WM_QUIT, 0, 0);
  929. }
  930. else
  931. {
  932. SetEvent(pInfo->hEvent);
  933. }
  934. }
  935. return 0;
  936. }
  937. BOOL TestUnmarshalGUIDNULL(void)
  938. {
  939. BOOL RetVal = TRUE;
  940. HRESULT hres;
  941. LPSTREAM pStm = NULL;
  942. IUnknown *punkIn = NULL;
  943. ULONG ulRefCnt, i;
  944. HANDLE hEvent = NULL;
  945. ThreadUnmarshalInfo Info;
  946. LARGE_INTEGER large_int;
  947. LISet32(large_int, 0);
  948. OUTPUT ("Starting TestUnmarshalGUIDNULL\n");
  949. // Create a shared memory stream for the marshaled interface
  950. pStm = CreateMemStm(600, NULL);
  951. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  952. // ----------------------------------------------------------------------
  953. for (i=0; i<2; i++)
  954. {
  955. hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  956. TEST_FAILED_EXIT(hEvent == NULL, "CreateEvent failed\n")
  957. punkIn = GetTestUnk();
  958. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  959. VerifyObjRefCnt(punkIn, 1);
  960. // reset the stream ptr
  961. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  962. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  963. // Marshal the interface into the stream
  964. hres = CoMarshalInterface(pStm, IID_IParseDisplayName, punkIn,
  965. 0, 0, MSHLFLAGS_NORMAL);
  966. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  967. VerifyRHRefCnt(punkIn, 1);
  968. OUTPUT (" - CoMarshalInterface OK.\n");
  969. // reset the stream ptr
  970. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  971. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  972. Info.hEvent = hEvent;
  973. Info.pStm = pStm;
  974. Info.iid = GUID_NULL;
  975. Info.dwInitFlag = gInitFlag;
  976. Info.dwThreadId = 0;
  977. if (i==0)
  978. {
  979. // first time, call on same thread, expect original ptr and
  980. // non-zero refcnt after release
  981. Info.pUnk = punkIn;
  982. Info.RelRefCnt = 1;
  983. ThreadTestUnmarshal(&Info);
  984. }
  985. else
  986. {
  987. // second time, call on different thread
  988. if (gInitFlag == COINIT_APARTMENTTHREADED)
  989. {
  990. // apartment thread, expect differnt ptr and
  991. // zero refcnt after release
  992. Info.dwThreadId = GetCurrentThreadId();
  993. Info.pUnk = 0;
  994. Info.RelRefCnt = 0;
  995. }
  996. else
  997. {
  998. // multi-thread, expect same ptr and non-zero refcnt
  999. // after release
  1000. Info.dwThreadId = GetCurrentThreadId();
  1001. Info.pUnk = punkIn;
  1002. Info.RelRefCnt = 1;
  1003. }
  1004. RunThread(&Info, hEvent, ThreadTestUnmarshal);
  1005. CloseHandle(hEvent);
  1006. }
  1007. // release the punkIn.
  1008. ulRefCnt = punkIn->Release();
  1009. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  1010. punkIn = NULL;
  1011. hres = Info.hr;
  1012. OUTPUT (" - Run Complete\n");
  1013. }
  1014. // ----------------------------------------------------------------------
  1015. Cleanup:
  1016. OUTPUT (" - Test Complete. Doing Cleanup\n");
  1017. // Dump interfaces we are done with
  1018. if (pStm)
  1019. {
  1020. ulRefCnt = pStm->Release();
  1021. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  1022. }
  1023. if (punkIn)
  1024. {
  1025. ulRefCnt = punkIn->Release();
  1026. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  1027. }
  1028. return TestResult(RetVal, "TestUnmarshalGUIDNULL");
  1029. }
  1030. // ----------------------------------------------------------------------
  1031. //
  1032. // test calling CoUmarshalInterface with an IID different from
  1033. // the IID that was marshaled.
  1034. //
  1035. // ----------------------------------------------------------------------
  1036. BOOL TestUnmarshalDifferentIID(void)
  1037. {
  1038. BOOL RetVal = TRUE;
  1039. HRESULT hres;
  1040. LPSTREAM pStm = NULL;
  1041. IUnknown *punkIn = NULL;
  1042. ULONG ulRefCnt, i;
  1043. HANDLE hEvent = NULL;
  1044. ThreadUnmarshalInfo Info;
  1045. LARGE_INTEGER large_int;
  1046. LISet32(large_int, 0);
  1047. OUTPUT ("Starting TestUnmarshalDifferentIID\n");
  1048. // Create a shared memory stream for the marshaled interface
  1049. pStm = CreateMemStm(600, NULL);
  1050. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  1051. // ----------------------------------------------------------------------
  1052. for (i=0; i<2; i++)
  1053. {
  1054. hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  1055. TEST_FAILED_EXIT(hEvent == NULL, "CreateEvent failed\n")
  1056. punkIn = GetTestUnk();
  1057. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  1058. VerifyObjRefCnt(punkIn, 1);
  1059. // reset the stream ptr
  1060. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1061. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1062. // Marshal the interface into the stream
  1063. hres = CoMarshalInterface(pStm, IID_IParseDisplayName, punkIn,
  1064. 0, 0, MSHLFLAGS_NORMAL);
  1065. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  1066. VerifyRHRefCnt(punkIn, 1);
  1067. OUTPUT (" - CoMarshalInterface OK.\n");
  1068. // reset the stream ptr
  1069. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1070. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1071. Info.hEvent = hEvent;
  1072. Info.pStm = pStm;
  1073. Info.iid = IID_IOleWindow;
  1074. Info.pUnk = punkIn;
  1075. Info.dwInitFlag = gInitFlag;
  1076. Info.dwThreadId = 0;
  1077. if (i==0)
  1078. {
  1079. // first time, call on same thread, expect different ptr and
  1080. // non-zero refcnt after release
  1081. Info.pUnk = 0;
  1082. Info.RelRefCnt = 1;
  1083. ThreadTestUnmarshal(&Info);
  1084. }
  1085. else
  1086. {
  1087. if (gInitFlag == COINIT_APARTMENTTHREADED)
  1088. {
  1089. // apartment thread, expect differnt ptr and
  1090. // zero refcnt after release
  1091. Info.dwThreadId = GetCurrentThreadId();
  1092. Info.pUnk = 0;
  1093. Info.RelRefCnt = 0;
  1094. }
  1095. else
  1096. {
  1097. // multi-thread, expect same ptr and non-zero refcnt
  1098. // after release
  1099. Info.dwThreadId = GetCurrentThreadId();
  1100. Info.pUnk = 0;
  1101. Info.RelRefCnt = 1;
  1102. }
  1103. RunThread(&Info, hEvent, ThreadTestUnmarshal);
  1104. CloseHandle(hEvent);
  1105. }
  1106. // release the punkIn.
  1107. ulRefCnt = punkIn->Release();
  1108. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  1109. punkIn = NULL;
  1110. hres = Info.hr;
  1111. OUTPUT (" - Run Complete\n");
  1112. }
  1113. // ----------------------------------------------------------------------
  1114. Cleanup:
  1115. OUTPUT (" - Test Complete. Doing Cleanup\n");
  1116. // Dump interfaces we are done with
  1117. if (pStm)
  1118. {
  1119. ulRefCnt = pStm->Release();
  1120. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  1121. }
  1122. if (punkIn)
  1123. {
  1124. ulRefCnt = punkIn->Release();
  1125. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  1126. }
  1127. return TestResult(RetVal, "TestUnmarshalDifferentIID");
  1128. }
  1129. // ----------------------------------------------------------------------
  1130. //
  1131. // test REMOTE interface MSHLFLAGS_NORMAL
  1132. //
  1133. // ----------------------------------------------------------------------
  1134. BOOL TestRemoteInterfaceNormal(void)
  1135. {
  1136. BOOL RetVal = TRUE;
  1137. HRESULT hres;
  1138. LPSTREAM pStm = NULL;
  1139. LPCLASSFACTORY pICF = NULL;
  1140. ULONG ulRefCnt;
  1141. IUnknown *punkOut = NULL;
  1142. IUnknown *punkIn = NULL;
  1143. LARGE_INTEGER large_int;
  1144. LISet32(large_int, 0);
  1145. OUTPUT ("Starting TestRemoteInterfaceNormal\n");
  1146. // Create an IClassFactory Interface.
  1147. DWORD grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  1148. hres = CoGetClassObject(CLSID_Balls,
  1149. grfContext,
  1150. NULL, // pvReserved
  1151. IID_IClassFactory,
  1152. (void **)&pICF);
  1153. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject failed\n")
  1154. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject failed\n")
  1155. VerifyRHRefCnt((IUnknown *)pICF, 1);
  1156. OUTPUT (" - Aquired Remote Class Object.\n");
  1157. // ----------------------------------------------------------------------
  1158. // note, since pICF is a class object, it has special super secret
  1159. // behaviour to make it go away. create an instance, release the
  1160. // class object, then release the instance.
  1161. hres = pICF->CreateInstance(NULL, IID_IUnknown, (void **)&punkIn);
  1162. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  1163. TEST_FAILED_EXIT((punkIn == NULL), "CreateInstance failed\n")
  1164. VerifyRHRefCnt(punkIn, 1);
  1165. OUTPUT (" - Created Instance.\n");
  1166. // release class object
  1167. ulRefCnt = pICF->Release();
  1168. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1169. // VerifyRHRefCnt((IUnknown *)pICF, 0);
  1170. pICF = NULL;
  1171. OUTPUT (" - Released Class Object.\n");
  1172. // ----------------------------------------------------------------------
  1173. // Create a shared memory stream for the marshaled interface
  1174. pStm = CreateMemStm(600, NULL);
  1175. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  1176. // Marshal the interface into the stream
  1177. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  1178. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  1179. OUTPUT (" - CoMarshalInterface OK.\n");
  1180. VerifyRHRefCnt(punkIn, 1);
  1181. // unmarshal the interface. should get the same proxy back.
  1182. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1183. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1184. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  1185. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  1186. VerifyRHRefCnt(punkIn, 2);
  1187. // make sure the interface pointers are identical
  1188. if (punkIn != punkOut)
  1189. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..1st Remote Unmarshal\n")
  1190. OUTPUT (" - CoUnmarshalInterface OK.\n");
  1191. // release the interface
  1192. ulRefCnt = punkOut->Release();
  1193. punkOut = NULL;
  1194. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  1195. VerifyRHRefCnt(punkIn, 1);
  1196. OUTPUT (" - Release OK\n");
  1197. // ----------------------------------------------------------------------
  1198. #if 0
  1199. // test unmarshalling twice. this should fail since we marshalled normal
  1200. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1201. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1202. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  1203. TEST_FAILED_EXIT(SUCCEEDED(hres), "CoUnmarshalInterface succeeded but should have failed\n")
  1204. VerifyRHRefCnt(punkIn, 1);
  1205. OUTPUT (" - Second CoUnmarshalInterface OK.\n");
  1206. punkOut = NULL;
  1207. // ----------------------------------------------------------------------
  1208. // CoReleaseMarshalData should FAIL since we already unmarshalled it
  1209. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1210. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1211. hres = CoReleaseMarshalData(pStm);
  1212. TEST_FAILED_EXIT(SUCCEEDED(hres), "CoReleaseMarshalData succeeded but should have failed.\n")
  1213. VerifyRHRefCnt(punkIn, 1);
  1214. OUTPUT (" - CoReleaseMarshalData OK\n");
  1215. #endif
  1216. // ----------------------------------------------------------------------
  1217. // marshal again and try CoRelease without having first done an
  1218. // unmarshal. this should work.
  1219. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1220. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1221. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  1222. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  1223. VerifyRHRefCnt(punkIn, 1);
  1224. OUTPUT (" - CoMarshalInterface OK\n");
  1225. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1226. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1227. hres = CoReleaseMarshalData(pStm);
  1228. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  1229. VerifyRHRefCnt(punkIn, 1);
  1230. OUTPUT (" - CoReleaseMarshalData OK\n");
  1231. // ----------------------------------------------------------------------
  1232. Cleanup:
  1233. OUTPUT (" - Test Complete. Doing Cleanup\n");
  1234. // Dump interfaces we are done with
  1235. if (pStm)
  1236. {
  1237. ulRefCnt = pStm->Release();
  1238. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  1239. }
  1240. if (pICF)
  1241. {
  1242. ulRefCnt = pICF->Release();
  1243. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1244. }
  1245. if (punkOut)
  1246. {
  1247. ulRefCnt = punkOut->Release();
  1248. TEST_FAILED(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  1249. }
  1250. if (punkIn)
  1251. {
  1252. ulRefCnt = punkIn->Release();
  1253. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  1254. }
  1255. return TestResult(RetVal, "TestRemoteInterfaceNormal");
  1256. }
  1257. // ----------------------------------------------------------------------
  1258. //
  1259. // test REMOTE interface MSHLFLAGS_TABLESTRONG
  1260. //
  1261. // ----------------------------------------------------------------------
  1262. BOOL TestRemoteInterfaceTableStrong(void)
  1263. {
  1264. BOOL RetVal = TRUE;
  1265. HRESULT hres;
  1266. LPSTREAM pStm = NULL;
  1267. LPCLASSFACTORY pICF = NULL;
  1268. ULONG ulRefCnt;
  1269. IUnknown *punkIn = NULL;
  1270. IUnknown *punkOut = NULL;
  1271. LARGE_INTEGER large_int;
  1272. LISet32(large_int, 0);
  1273. OUTPUT ("Starting TestRemoteInterfaceTableStrong\n");
  1274. // Create an IClassFactory Interface.
  1275. DWORD grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  1276. hres = CoGetClassObject(CLSID_Balls,
  1277. grfContext,
  1278. NULL, // pvReserved
  1279. IID_IClassFactory,
  1280. (void **)&pICF);
  1281. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject failed\n")
  1282. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject failed\n")
  1283. OUTPUT (" - Aquired Remote Class Object.\n");
  1284. // ----------------------------------------------------------------------
  1285. // note, since pICF is a class object, it has special super secret
  1286. // behaviour to make it go away. create an instance, release the
  1287. // class object, then release the instance.
  1288. hres = pICF->CreateInstance(NULL, IID_IUnknown, (void **)&punkIn);
  1289. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  1290. TEST_FAILED_EXIT((punkIn == NULL), "CreateInstance failed\n")
  1291. OUTPUT (" - Created Instance.\n");
  1292. // release class object
  1293. ulRefCnt = pICF->Release();
  1294. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1295. pICF = NULL;
  1296. OUTPUT (" - Released Class Object.\n");
  1297. // ----------------------------------------------------------------------
  1298. // Create a shared memory stream for the marshaled moniker
  1299. pStm = CreateMemStm(600, NULL);
  1300. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  1301. // Marshal the interface into the stream
  1302. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_TABLESTRONG);
  1303. TEST_FAILED_EXIT(SUCCEEDED(hres), "CoMarshalInterface succeeded but should have failed\n")
  1304. OUTPUT (" - CoMarshalInterface OK.\n");
  1305. LISet32(large_int, 0);
  1306. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1307. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1308. #if 0
  1309. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  1310. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  1311. // make sure the interface pointers are identical
  1312. if (punkIn != punkOut)
  1313. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..1st Remote Unmarshal\n")
  1314. OUTPUT (" - CoUnmarshalInterface OK.\n");
  1315. // release it
  1316. ulRefCnt = punkOut->Release();
  1317. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  1318. punkOut = NULL;
  1319. OUTPUT (" - Release OK\n");
  1320. // ----------------------------------------------------------------------
  1321. // test unmarshalling twice.
  1322. // this should work since we did marshal flags TABLE_STRONG
  1323. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1324. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1325. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  1326. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  1327. OUTPUT (" - Second CoUnmarshalInterface OK.\n");
  1328. // ----------------------------------------------------------------------
  1329. // CoReleaseMarshalData should WORK for TABLESTRONG interfaces
  1330. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  1331. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  1332. hres = CoReleaseMarshalData(pStm);
  1333. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  1334. OUTPUT (" - CoReleaseMarshalData OK\n");
  1335. // ----------------------------------------------------------------------
  1336. #endif
  1337. Cleanup:
  1338. OUTPUT (" - Test Complete. Doing Cleanup\n");
  1339. // Dump interfaces we are done with
  1340. if (pStm)
  1341. {
  1342. ulRefCnt = pStm->Release();
  1343. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  1344. }
  1345. if (punkOut)
  1346. {
  1347. ulRefCnt = punkOut->Release();
  1348. TEST_FAILED(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  1349. }
  1350. if (punkIn)
  1351. {
  1352. // release instance
  1353. ulRefCnt = punkIn->Release();
  1354. TEST_FAILED(ulRefCnt != 0,"punkIn RefCnt not zero\n");
  1355. }
  1356. return TestResult(RetVal, "TestRemoteInterfaceTableStrong");
  1357. }
  1358. // ----------------------------------------------------------------------
  1359. //
  1360. // test CUSTOM interface MSHLFLAGS_NORMAL --- CODEWORK
  1361. //
  1362. // ----------------------------------------------------------------------
  1363. BOOL TestCustomMarshalNormal(void)
  1364. {
  1365. BOOL RetVal = TRUE;
  1366. return TestResult(RetVal, "TestCustomMarshalNormal");
  1367. }
  1368. // ----------------------------------------------------------------------
  1369. //
  1370. // test CUSTOM interface MSHLFLAGS_TABLESTRONG --- CODEWORK
  1371. //
  1372. // ----------------------------------------------------------------------
  1373. BOOL TestCustomMarshalTable(void)
  1374. {
  1375. BOOL RetVal = TRUE;
  1376. return TestResult(RetVal, "TestCustomMarshalTableStrong");
  1377. }
  1378. // ----------------------------------------------------------------------
  1379. //
  1380. // TestEcho
  1381. //
  1382. // test sending an interface to a remote server and getting the same
  1383. // interface back again. the test is done with once with a local
  1384. // interface and once with a remote interface.
  1385. //
  1386. // Local Interface Remote Interface
  1387. //
  1388. // 1. marshal [in] local marshal [in] remote proxy
  1389. // 2. unmarshal [in] remote unmarshal [in] local proxy
  1390. // 3. marshal [out] remote proxy marshal [out] local
  1391. // 4. unmarshal [in] local proxy unmarshal [out] remote
  1392. //
  1393. // ----------------------------------------------------------------------
  1394. BOOL TestEcho(void)
  1395. {
  1396. BOOL RetVal = TRUE;
  1397. HRESULT hres;
  1398. ULONG ulRefCnt;
  1399. LPCLASSFACTORY pICF = NULL;
  1400. IBalls *pIBalls = NULL;
  1401. IUnknown *punkIn = NULL;
  1402. IUnknown *punkIn2 = NULL;
  1403. IUnknown *punkOut = NULL;
  1404. LARGE_INTEGER large_int;
  1405. LISet32(large_int, 0);
  1406. OUTPUT ("Starting TestEcho\n");
  1407. // Create an IBall ClassFactory Interface.
  1408. DWORD grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  1409. hres = CoGetClassObject(CLSID_Balls,
  1410. grfContext,
  1411. NULL, // pvReserved
  1412. IID_IClassFactory,
  1413. (void **)&pICF);
  1414. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject failed\n")
  1415. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject failed\n")
  1416. OUTPUT (" - Aquired Remote Class Object.\n");
  1417. // ----------------------------------------------------------------------
  1418. // note, since pICF is a class object, it has special super secret
  1419. // behaviour to make it go away. create an instance, release the
  1420. // class object, then release the instance.
  1421. hres = pICF->CreateInstance(NULL, IID_IBalls, (void **)&pIBalls);
  1422. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  1423. TEST_FAILED_EXIT((pIBalls == NULL), "CreateInstance failed\n")
  1424. OUTPUT (" - Created First Instance.\n");
  1425. hres = pICF->CreateInstance(NULL, IID_IUnknown, (void **)&punkIn2);
  1426. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  1427. TEST_FAILED_EXIT((punkIn2 == NULL), "CreateInstance failed\n")
  1428. OUTPUT (" - Created Second Instance.\n");
  1429. // release class object
  1430. ulRefCnt = pICF->Release();
  1431. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1432. pICF = NULL;
  1433. OUTPUT (" - Released Class Object.\n");
  1434. // ----------------------------------------------------------------------
  1435. // create a local interface
  1436. punkIn = GetTestUnk();
  1437. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  1438. VerifyObjRefCnt(punkIn, 1);
  1439. // call a method that echos the local interface right back to us.
  1440. hres = pIBalls->Echo(punkIn, &punkOut);
  1441. TEST_FAILED_EXIT(FAILED(hres), "Echo on IBalls failed\n")
  1442. TEST_FAILED_EXIT((punkOut == NULL), "Echo on IBalls failed\n")
  1443. // make sure the interface pointers are identical
  1444. if (punkIn != punkOut)
  1445. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..Echo\n")
  1446. VerifyObjRefCnt(punkIn, 2);
  1447. VerifyRHRefCnt(punkIn, 0);
  1448. OUTPUT (" - Echo OK.\n");
  1449. // release the out interface
  1450. ulRefCnt = punkOut->Release();
  1451. punkOut = NULL;
  1452. TEST_FAILED_EXIT(ulRefCnt != 1, "punkOut RefCnt is not 1\n");
  1453. OUTPUT (" - Released punkOut OK\n");
  1454. // release the In interface
  1455. ulRefCnt = punkIn->Release();
  1456. punkIn = NULL;
  1457. TEST_FAILED_EXIT(ulRefCnt != 0, "punkIn RefCnt is not zero\n");
  1458. OUTPUT (" - Released punkIn OK\n");
  1459. OUTPUT (" - Echo Local Interface OK\n");
  1460. // ----------------------------------------------------------------------
  1461. // call a method that echos a remote interface right back to us.
  1462. hres = pIBalls->Echo(punkIn2, &punkOut);
  1463. TEST_FAILED_EXIT(FAILED(hres), "Echo on IBalls failed\n")
  1464. TEST_FAILED_EXIT((punkOut == NULL), "Echon on IBalls failed\n")
  1465. // make sure the interface pointers are identical
  1466. if (punkIn2 != punkOut)
  1467. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..Echo\n")
  1468. VerifyObjRefCnt(punkIn2, 2);
  1469. VerifyRHRefCnt(punkIn2, 2);
  1470. OUTPUT (" - Echo OK.\n");
  1471. // release the out interface
  1472. ulRefCnt = punkOut->Release();
  1473. punkOut = NULL;
  1474. TEST_FAILED_EXIT(ulRefCnt != 1, "punkOut RefCnt is not 1\n");
  1475. OUTPUT (" - Released punkOut OK\n");
  1476. // release the In interface
  1477. ulRefCnt = punkIn2->Release();
  1478. punkIn2 = NULL;
  1479. TEST_FAILED_EXIT(ulRefCnt != 0, "punkIn2 RefCnt is not zero\n");
  1480. OUTPUT (" - Released punkIn2 OK\n");
  1481. OUTPUT (" - Echo Remote Interface OK\n");
  1482. // ----------------------------------------------------------------------
  1483. // release the IBalls interface
  1484. ulRefCnt = pIBalls->Release();
  1485. TEST_FAILED_EXIT(ulRefCnt != 0, "pIBalls RefCnt is not zero\n");
  1486. pIBalls = NULL;
  1487. OUTPUT (" - Released IBalls OK\n");
  1488. // ----------------------------------------------------------------------
  1489. Cleanup:
  1490. OUTPUT (" - Test Complete. Doing Cleanup\n");
  1491. // Dump interfaces we are done with
  1492. if (pICF)
  1493. {
  1494. ulRefCnt = pICF->Release();
  1495. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1496. }
  1497. if (punkOut)
  1498. {
  1499. ulRefCnt = punkOut->Release();
  1500. TEST_FAILED(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  1501. }
  1502. if (punkIn)
  1503. {
  1504. ulRefCnt = punkIn->Release();
  1505. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  1506. }
  1507. if (pIBalls)
  1508. {
  1509. ulRefCnt = pIBalls->Release();
  1510. TEST_FAILED(ulRefCnt != 0, "pIBalls RefCnt not zero\n");
  1511. }
  1512. if (punkIn2)
  1513. {
  1514. ulRefCnt = punkIn2->Release();
  1515. TEST_FAILED(ulRefCnt != 0, "punkIn2 RefCnt not zero\n");
  1516. }
  1517. return TestResult(RetVal, "TestEcho");
  1518. }
  1519. // ----------------------------------------------------------------------
  1520. //
  1521. // TestMiddleMan
  1522. //
  1523. // test sending an remote interface to a second different process.
  1524. //
  1525. // 1. marshal [in] remote proxy
  1526. // 2. unmarshal [in] remote proxy
  1527. // 3. marshal [out] remote proxy
  1528. // 4. unmarshal [in] local proxy
  1529. //
  1530. // ----------------------------------------------------------------------
  1531. BOOL TestMiddleMan(void)
  1532. {
  1533. BOOL RetVal = TRUE;
  1534. HRESULT hres;
  1535. ULONG ulRefCnt;
  1536. LPCLASSFACTORY pICF = NULL;
  1537. IBalls *pIBalls = NULL;
  1538. ICube *pICubes = NULL;
  1539. IUnknown *punkIn = NULL;
  1540. IUnknown *punkOut = NULL;
  1541. LARGE_INTEGER large_int;
  1542. LISet32(large_int, 0);
  1543. OUTPUT ("Starting TestMiddleMan\n");
  1544. // Create an IBall ClassFactory Interface.
  1545. DWORD grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  1546. hres = CoGetClassObject(CLSID_Balls,
  1547. grfContext,
  1548. NULL, // pvReserved
  1549. IID_IClassFactory,
  1550. (void **)&pICF);
  1551. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject Balls failed\n")
  1552. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject Balls failed\n")
  1553. OUTPUT (" - Aquired Remote Balls Class Object.\n");
  1554. VerifyObjRefCnt(pICF, 1);
  1555. VerifyRHRefCnt(pICF, 1);
  1556. // ----------------------------------------------------------------------
  1557. // note, since pICF is a class object, it has special super secret
  1558. // behaviour to make it go away. create an instance, release the
  1559. // class object, then release the instance.
  1560. hres = pICF->CreateInstance(NULL, IID_IBalls, (void **)&pIBalls);
  1561. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  1562. TEST_FAILED_EXIT((pIBalls == NULL), "CreateInstance failed\n")
  1563. OUTPUT (" - Created Balls Instance.\n");
  1564. VerifyObjRefCnt(pIBalls, 1);
  1565. VerifyRHRefCnt(pIBalls, 1);
  1566. // release class object
  1567. ulRefCnt = pICF->Release();
  1568. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1569. pICF = NULL;
  1570. OUTPUT (" - Released Balls Class Object.\n");
  1571. // ----------------------------------------------------------------------
  1572. // Create an ICube ClassFactory Interface.
  1573. grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  1574. hres = CoGetClassObject(CLSID_Cubes,
  1575. grfContext,
  1576. NULL, // pvReserved
  1577. IID_IClassFactory,
  1578. (void **)&pICF);
  1579. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject Cubes failed\n")
  1580. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject Cubes failed\n")
  1581. OUTPUT (" - Aquired Remote Cubes Class Object.\n");
  1582. VerifyObjRefCnt(pICF, 1);
  1583. VerifyRHRefCnt(pICF, 1);
  1584. // ----------------------------------------------------------------------
  1585. // note, since pICF is a class object, it has special super secret
  1586. // behaviour to make it go away. create an instance, release the
  1587. // class object, then release the instance.
  1588. hres = pICF->CreateInstance(NULL, IID_ICube, (void **)&pICubes);
  1589. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance Cubes failed\n")
  1590. TEST_FAILED_EXIT((pICubes == NULL), "CreateInstance Cubes failed\n")
  1591. OUTPUT (" - Created Cubes Instance.\n");
  1592. VerifyObjRefCnt(pICubes, 1);
  1593. VerifyRHRefCnt(pICubes, 1);
  1594. // release class object
  1595. ulRefCnt = pICF->Release();
  1596. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1597. pICF = NULL;
  1598. OUTPUT (" - Released Cubes Class Object.\n");
  1599. // ----------------------------------------------------------------------
  1600. // pass the remote cubes interface to the balls interface.
  1601. hres = pIBalls->IsContainedIn(pICubes);
  1602. TEST_FAILED_EXIT(FAILED(hres), "IsContainedIn failed\n")
  1603. VerifyObjRefCnt(pIBalls, 1);
  1604. VerifyRHRefCnt(pIBalls, 1);
  1605. VerifyObjRefCnt(pICubes, 1);
  1606. VerifyRHRefCnt(pICubes, 1);
  1607. OUTPUT (" - IsContainedIn OK.\n");
  1608. // ----------------------------------------------------------------------
  1609. // pass the remote balls interface to the cubes interface.
  1610. hres = pICubes->Contains(pIBalls);
  1611. TEST_FAILED_EXIT(FAILED(hres), "Contains failed\n")
  1612. VerifyObjRefCnt(pIBalls, 1);
  1613. VerifyRHRefCnt(pIBalls, 1);
  1614. VerifyObjRefCnt(pICubes, 1);
  1615. VerifyRHRefCnt(pICubes, 1);
  1616. OUTPUT (" - Contains OK.\n");
  1617. // ----------------------------------------------------------------------
  1618. // echo the remote ICubes interface to the remote IBalls interface
  1619. hres = pICubes->QueryInterface(IID_IUnknown, (void **)&punkIn);
  1620. TEST_FAILED_EXIT(FAILED(hres), "QueryInterface IUnknown failed\n")
  1621. VerifyRHRefCnt(pICubes, 2);
  1622. VerifyObjRefCnt(pICubes, 2);
  1623. OUTPUT (" - QueryInterface OK.\n");
  1624. hres = pIBalls->Echo(punkIn, &punkOut);
  1625. TEST_FAILED_EXIT(FAILED(hres), "Echo on IBalls failed\n")
  1626. TEST_FAILED_EXIT((punkOut == NULL), "Echo on IBalls failed\n")
  1627. // make sure the interface pointers are identical
  1628. if (punkIn != punkOut)
  1629. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..Echo\n")
  1630. VerifyObjRefCnt(punkIn, 3);
  1631. VerifyRHRefCnt(punkIn, 3);
  1632. OUTPUT (" - Echo OK.\n");
  1633. // release the out interface
  1634. ulRefCnt = punkOut->Release();
  1635. punkOut = NULL;
  1636. TEST_FAILED(ulRefCnt != 2, "punkOut RefCnt is not 2\n");
  1637. OUTPUT (" - Released punkOut OK\n");
  1638. // release the In interface
  1639. ulRefCnt = punkIn->Release();
  1640. punkIn = NULL;
  1641. TEST_FAILED(ulRefCnt != 1, "punkIn RefCnt is not 1\n");
  1642. OUTPUT (" - Released punkIn OK\n");
  1643. // ----------------------------------------------------------------------
  1644. // release the ICubes interface
  1645. ulRefCnt = pICubes->Release();
  1646. TEST_FAILED(ulRefCnt != 0, "pICubes RefCnt is not zero\n");
  1647. pICubes = NULL;
  1648. OUTPUT (" - Released ICubes OK\n");
  1649. // ----------------------------------------------------------------------
  1650. // release the IBalls interface
  1651. ulRefCnt = pIBalls->Release();
  1652. TEST_FAILED(ulRefCnt != 0, "pIBalls RefCnt is not zero\n");
  1653. pIBalls = NULL;
  1654. OUTPUT (" - Released IBalls OK\n");
  1655. // ----------------------------------------------------------------------
  1656. Cleanup:
  1657. OUTPUT (" - Test Complete. Doing Cleanup\n");
  1658. // Dump interfaces we are done with
  1659. if (pICF)
  1660. {
  1661. ulRefCnt = pICF->Release();
  1662. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  1663. }
  1664. if (pIBalls)
  1665. {
  1666. ulRefCnt = pIBalls->Release();
  1667. TEST_FAILED(ulRefCnt != 0, "pIBalls RefCnt not zero\n");
  1668. }
  1669. if (pICubes)
  1670. {
  1671. ulRefCnt = pICubes->Release();
  1672. TEST_FAILED(ulRefCnt != 0, "pICubes RefCnt not zero\n");
  1673. }
  1674. return TestResult(RetVal, "TestMiddleMan");
  1675. }
  1676. // ----------------------------------------------------------------------
  1677. //
  1678. // TestLoop
  1679. //
  1680. // tests A calling B calling A calling B etc n times, to see if Rpc
  1681. // can handle this.
  1682. //
  1683. // ----------------------------------------------------------------------
  1684. BOOL TestLoop(void)
  1685. {
  1686. BOOL RetVal = TRUE;
  1687. HRESULT hRes = S_OK;
  1688. ILoop *pLocalLoop = NULL;
  1689. ILoop *pRemoteLoop = NULL;
  1690. OUTPUT ("Starting TestLoop\n");
  1691. // create our interface to pass to the remote object.
  1692. hRes = CoCreateInstance(CLSID_LoopSrv, NULL, CLSCTX_LOCAL_SERVER,
  1693. IID_ILoop, (void **)&pLocalLoop);
  1694. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance First failed\n")
  1695. // create the remote object
  1696. hRes = CoCreateInstance(CLSID_LoopSrv, NULL, CLSCTX_LOCAL_SERVER,
  1697. IID_ILoop, (void **)&pRemoteLoop);
  1698. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance Second failed\n")
  1699. // initialize the two instances
  1700. OUTPUT (" - Initializing Instances\n");
  1701. hRes = pLocalLoop->Init(pRemoteLoop);
  1702. TEST_FAILED_EXIT(FAILED(hRes), "Initialize First failed\n")
  1703. hRes = pRemoteLoop->Init(pLocalLoop);
  1704. TEST_FAILED_EXIT(FAILED(hRes), "Initialize Second failed\n")
  1705. // now start the test
  1706. OUTPUT (" - Running LoopTest\n");
  1707. hRes = pLocalLoop->Loop(10);
  1708. TEST_FAILED(FAILED(hRes), "Loop failed\n")
  1709. // uninitialize the two instances
  1710. OUTPUT (" - Uninitializing Instances\n");
  1711. hRes = pLocalLoop->Uninit();
  1712. TEST_FAILED_EXIT(FAILED(hRes), "Uninitialize First failed\n")
  1713. hRes = pRemoteLoop->Uninit();
  1714. TEST_FAILED_EXIT(FAILED(hRes), "Uninitialize Second failed\n")
  1715. Cleanup:
  1716. // release the two instances
  1717. OUTPUT (" - Releasing Instances\n");
  1718. if (pRemoteLoop)
  1719. pRemoteLoop->Release();
  1720. if (pLocalLoop)
  1721. pLocalLoop->Release();
  1722. return TestResult(RetVal, "TestLoop");
  1723. }
  1724. // ----------------------------------------------------------------------
  1725. //
  1726. // TestMultiQINormal
  1727. //
  1728. // tests IMultiQI interface on Normal proxies
  1729. //
  1730. // ----------------------------------------------------------------------
  1731. ULONG cMisc = 4;
  1732. const IID *iidMisc[] = {
  1733. &IID_IParseDisplayName, &IID_IPersistStorage,
  1734. &IID_IPersistFile, &IID_IStorage,
  1735. &IID_IOleContainer, &IID_IOleItemContainer,
  1736. &IID_IOleInPlaceSite, &IID_IOleInPlaceActiveObject,
  1737. &IID_IOleInPlaceObject, &IID_IOleInPlaceUIWindow,
  1738. &IID_IOleInPlaceFrame, &IID_IOleWindow};
  1739. MULTI_QI arMQI[20];
  1740. MULTI_QI *pMQIResStart = arMQI;
  1741. BOOL TestMultiQINormal(void)
  1742. {
  1743. BOOL RetVal = TRUE;
  1744. HRESULT hRes = S_OK;
  1745. IUnknown *pUnk = NULL;
  1746. IUnknown *pUnk2 = NULL;
  1747. IMultiQI *pMQI = NULL;
  1748. ULONG i = 0, j=0, cRefs = 0;
  1749. MULTI_QI *pMQIRes = NULL;
  1750. // ----------------------------------------------------------------------
  1751. ULONG cSupported = 4;
  1752. const IID *iidSupported[] = {&IID_IUnknown, &IID_IMultiQI,
  1753. &IID_IClientSecurity, &IID_IMarshal,
  1754. &IID_IStdIdentity, &IID_IProxyManager};
  1755. ULONG cUnSupported = 2;
  1756. const IID *iidUnSupported[] = {&IID_IInternalUnknown,
  1757. &IID_IServerSecurity};
  1758. // ----------------------------------------------------------------------
  1759. OUTPUT ("Starting TestMultiQINormal\n");
  1760. // create our interface to pass to the remote object.
  1761. hRes = CoCreateInstance(CLSID_QI, NULL, CLSCTX_LOCAL_SERVER,
  1762. IID_IUnknown, (void **)&pUnk);
  1763. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance QISRV failed\n")
  1764. VerifyObjRefCnt(pUnk, 1);
  1765. VerifyRHRefCnt(pUnk, 1);
  1766. // ----------------------------------------------------------------------
  1767. OUTPUT ("\n - NormalQI for supported interfaces\n");
  1768. // loop through all the supported interfaces doing a normal QI.
  1769. for (i=0; i<cSupported; i++)
  1770. {
  1771. hRes = pUnk->QueryInterface(*iidSupported[i], (void **)&pUnk2);
  1772. TEST_FAILED(FAILED(hRes), "QueryInterface on supported interfaces failed\n")
  1773. if (SUCCEEDED(hRes))
  1774. {
  1775. // release the interface
  1776. VerifyObjRefCnt(pUnk, 2);
  1777. VerifyRHRefCnt(pUnk, 2);
  1778. OUTPUT (" - QI for supported interface OK\n");
  1779. pUnk2->Release();
  1780. }
  1781. }
  1782. OUTPUT ("\n - NormalQI for unsupported interfaces\n");
  1783. // loop through all the unsupported interfaces doing a normal QI.
  1784. for (i=0; i<cUnSupported; i++)
  1785. {
  1786. hRes = pUnk->QueryInterface(*iidUnSupported[i], (void **)&pUnk2);
  1787. TEST_FAILED(SUCCEEDED(hRes), "QueryInterface on unsupported interface succeeded but should have failed\n")
  1788. if (SUCCEEDED(hRes))
  1789. {
  1790. // release the interface
  1791. pUnk2->Release();
  1792. }
  1793. else
  1794. {
  1795. VerifyObjRefCnt(pUnk, 1);
  1796. VerifyRHRefCnt(pUnk, 1);
  1797. OUTPUT (" - QI for unsupported interface OK.\n");
  1798. }
  1799. }
  1800. // should be back to normal (IUnknown)
  1801. VerifyObjRefCnt(pUnk, 1);
  1802. VerifyRHRefCnt(pUnk, 1);
  1803. // ----------------------------------------------------------------------
  1804. hRes = pUnk->QueryInterface(IID_IMultiQI, (void **)&pMQI);
  1805. TEST_FAILED_EXIT(FAILED(hRes), "QI for IMultiQI failed\n")
  1806. VerifyObjRefCnt(pUnk, 2);
  1807. VerifyRHRefCnt(pUnk, 2);
  1808. OUTPUT ("\n - MultiQI for supported interfaces\n");
  1809. // now issue a MultiQI for the supported interfaces
  1810. pMQIRes = pMQIResStart;
  1811. for (i=0; i<cSupported; i++, pMQIRes++)
  1812. {
  1813. pMQIRes->pIID = iidSupported[i];
  1814. pMQIRes->pItf = NULL;
  1815. }
  1816. pMQIRes = pMQIResStart;
  1817. hRes = pMQI->QueryMultipleInterfaces(cSupported, pMQIRes);
  1818. TEST_FAILED(hRes != S_OK, "QueryMultipleInterfaces should have return S_OK\n")
  1819. VerifyObjRefCnt(pUnk, 2 + cSupported);
  1820. VerifyRHRefCnt(pUnk, 2 + cSupported);
  1821. for (i=0; i<cSupported; i++, pMQIRes++)
  1822. {
  1823. TEST_FAILED(pMQIRes->pItf == NULL, "QueryMultipleInterfaces on supported interfaces returned NULL\n")
  1824. TEST_FAILED(FAILED(pMQIRes->hr), "QueryMultipleInterfaces on supported interfaces failed\n")
  1825. if (pMQIRes->pItf != NULL)
  1826. {
  1827. OUTPUT (" - MultiQI for supported interface OK\n");
  1828. pMQIRes->pItf->Release();
  1829. VerifyObjRefCnt(pUnk, 2 + cSupported - (i+1));
  1830. VerifyRHRefCnt(pUnk, 2 + cSupported - (i+1));
  1831. }
  1832. }
  1833. // should be back to normal (IUnknown + IMultiQI)
  1834. VerifyObjRefCnt(pUnk, 2);
  1835. VerifyRHRefCnt(pUnk, 2);
  1836. // ----------------------------------------------------------------------
  1837. OUTPUT ("\n - MultiQI for unsupported interfaces\n");
  1838. // now issue a MultiQI for the unsupported interfaces
  1839. pMQIRes = pMQIResStart;
  1840. for (i=0; i<cUnSupported; i++, pMQIRes++)
  1841. {
  1842. pMQIRes->pIID = iidUnSupported[i];
  1843. pMQIRes->pItf = NULL;
  1844. }
  1845. pMQIRes = pMQIResStart;
  1846. hRes = pMQI->QueryMultipleInterfaces(cUnSupported, pMQIRes);
  1847. TEST_FAILED(hRes != E_NOINTERFACE, "QueryMultipleInterfaces should have return E_NOINTERFACES\n")
  1848. VerifyObjRefCnt(pUnk, 2);
  1849. VerifyRHRefCnt(pUnk, 2);
  1850. for (i=0; i<cUnSupported; i++, pMQIRes++)
  1851. {
  1852. TEST_FAILED(pMQIRes->pItf != NULL, "QueryMultipleInterfaces on supported interfaces returned NULL\n")
  1853. TEST_FAILED(SUCCEEDED(pMQIRes->hr), "QueryMultipleInterfaces on supported interfaces failed\n")
  1854. if (pMQIRes->pItf != NULL)
  1855. {
  1856. pMQIRes->pItf->Release();
  1857. }
  1858. else
  1859. {
  1860. OUTPUT (" - MultiQI for unsupported interface OK\n");
  1861. }
  1862. }
  1863. // should back to normal refcnts (IUnknown + IMultiQI)
  1864. VerifyObjRefCnt(pUnk, 2);
  1865. VerifyRHRefCnt(pUnk, 2);
  1866. // ----------------------------------------------------------------------
  1867. // repeat this test twice, first time goes remote for the misc interfaces,
  1868. // second time finds them already instantiated.
  1869. for (j=0; j<2; j++)
  1870. {
  1871. OUTPUT ("\n - MultiQI for combination of interfaces\n");
  1872. pMQIRes = pMQIResStart;
  1873. for (i=0; i<cMisc; i++, pMQIRes++)
  1874. {
  1875. pMQIRes->pIID = iidMisc[i];
  1876. pMQIRes->pItf = NULL;
  1877. }
  1878. for (i=0; i<cSupported; i++, pMQIRes++)
  1879. {
  1880. pMQIRes->pIID = iidSupported[i];
  1881. pMQIRes->pItf = NULL;
  1882. }
  1883. for (i=0; i<cUnSupported; i++, pMQIRes++)
  1884. {
  1885. pMQIRes->pIID = iidUnSupported[i];
  1886. pMQIRes->pItf = NULL;
  1887. }
  1888. pMQIRes = pMQIResStart;
  1889. hRes = pMQI->QueryMultipleInterfaces(cSupported + cUnSupported + cMisc, pMQIRes);
  1890. TEST_FAILED(hRes != S_FALSE, "QueryMultipleInterfaces should have return S_FALSE\n")
  1891. VerifyObjRefCnt(pUnk, 2 + cSupported + cMisc);
  1892. VerifyRHRefCnt(pUnk, 2 + cSupported + cMisc);
  1893. for (i=0; i<cMisc; i++, pMQIRes++)
  1894. {
  1895. TEST_FAILED(pMQIRes->pItf == NULL, "QueryMultipleInterfaces on supported interfaces returned NULL\n")
  1896. TEST_FAILED(FAILED(pMQIRes->hr), "QueryMultipleInterfaces on supported interfaces failed\n")
  1897. if (pMQIRes->pItf != NULL)
  1898. {
  1899. OUTPUT (" - MultiQI for supported remote interface OK\n");
  1900. pMQIRes->pItf->Release();
  1901. VerifyObjRefCnt(pUnk, 2 + cSupported + cMisc - (i+1));
  1902. VerifyRHRefCnt(pUnk, 2 + cSupported + cMisc - (i+1));
  1903. }
  1904. }
  1905. for (i=0; i<cSupported; i++, pMQIRes++)
  1906. {
  1907. TEST_FAILED(pMQIRes->pItf == NULL, "QueryMultipleInterfaces on supported interfaces returned NULL\n")
  1908. TEST_FAILED(FAILED(pMQIRes->hr), "QueryMultipleInterfaces on supported interfaces failed\n")
  1909. if (pMQIRes->pItf != NULL)
  1910. {
  1911. OUTPUT (" - MultiQI for supported local interface OK\n");
  1912. pMQIRes->pItf->Release();
  1913. VerifyObjRefCnt(pUnk, 2 + cSupported - (i+1));
  1914. VerifyRHRefCnt(pUnk, 2 + cSupported - (i+1));
  1915. }
  1916. }
  1917. for (i=0; i<cUnSupported; i++, pMQIRes++)
  1918. {
  1919. TEST_FAILED(pMQIRes->pItf != NULL, "QueryMultipleInterfaces on supported interfaces returned NULL\n")
  1920. TEST_FAILED(SUCCEEDED(pMQIRes->hr), "QueryMultipleInterfaces on supported interfaces failed\n")
  1921. if (pMQIRes->pItf != NULL)
  1922. {
  1923. pMQIRes->pItf->Release();
  1924. }
  1925. else
  1926. {
  1927. OUTPUT (" - MultiQI for unsupported local interface OK\n");
  1928. }
  1929. }
  1930. // should back to normal refcnts (IUnknown + IMultiQI)
  1931. VerifyObjRefCnt(pUnk, 2);
  1932. VerifyRHRefCnt(pUnk, 2);
  1933. } // for (j=...)
  1934. // ----------------------------------------------------------------------
  1935. Cleanup:
  1936. // release the two instances
  1937. OUTPUT (" - Releasing Instances\n");
  1938. if (pMQI)
  1939. {
  1940. pMQI->Release();
  1941. }
  1942. if (pUnk)
  1943. {
  1944. cRefs = pUnk->Release();
  1945. TEST_FAILED(cRefs != 0, "Last release not zero\n");
  1946. }
  1947. return TestResult(RetVal, "TestMultiQINormal");
  1948. }
  1949. // ----------------------------------------------------------------------
  1950. //
  1951. // TestMultiQIHandler
  1952. //
  1953. // tests IMultiQI interface on Handlers
  1954. //
  1955. // ----------------------------------------------------------------------
  1956. BOOL TestMultiQIHandler(void)
  1957. {
  1958. BOOL RetVal = TRUE;
  1959. HRESULT hRes = S_OK;
  1960. IUnknown *pUnk = NULL;
  1961. IUnknown *pUnk2 = NULL;
  1962. ULONG i = 0;
  1963. MULTI_QI *pMQIRes = NULL;
  1964. // ----------------------------------------------------------------------
  1965. ULONG cSupported = 4;
  1966. const IID *iidSupported[] = {&IID_IUnknown, &IID_IMarshal,
  1967. &IID_IStdIdentity, &IID_IProxyManager};
  1968. ULONG cUnSupported = 4;
  1969. const IID *iidUnSupported[] = {&IID_IInternalUnknown, &IID_IClientSecurity,
  1970. &IID_IServerSecurity, &IID_IMultiQI};
  1971. // ----------------------------------------------------------------------
  1972. OUTPUT ("Starting TestMultiQIHandler\n");
  1973. // create our interface to pass to the remote object.
  1974. hRes = CoCreateInstance(CLSID_QIHANDLER1, NULL, CLSCTX_LOCAL_SERVER,
  1975. IID_IUnknown, (void **)&pUnk);
  1976. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance QIHANDLER1 failed\n")
  1977. // ----------------------------------------------------------------------
  1978. OUTPUT ("\n - NormalQI for supported interfaces\n");
  1979. // loop through all the supported interfaces doing a normal QI.
  1980. for (i=0; i<cSupported; i++)
  1981. {
  1982. hRes = pUnk->QueryInterface(*iidSupported[i], (void **)&pUnk2);
  1983. TEST_FAILED(FAILED(hRes), "QueryInterface on supported interfaces failed\n")
  1984. if (SUCCEEDED(hRes))
  1985. {
  1986. // release the interface
  1987. OUTPUT (" - QI for supported interface OK\n");
  1988. pUnk2->Release();
  1989. }
  1990. }
  1991. OUTPUT ("\n - NormalQI for unsupported interfaces\n");
  1992. // loop through all the unsupported interfaces doing a normal QI.
  1993. for (i=0; i<cUnSupported; i++)
  1994. {
  1995. hRes = pUnk->QueryInterface(*iidUnSupported[i], (void **)&pUnk2);
  1996. TEST_FAILED(SUCCEEDED(hRes), "QueryInterface on unsupported interface succeeded but should have failed\n")
  1997. if (SUCCEEDED(hRes))
  1998. {
  1999. // release the interface
  2000. pUnk2->Release();
  2001. }
  2002. else
  2003. {
  2004. OUTPUT (" - QI for unsupported interface OK.\n");
  2005. }
  2006. }
  2007. // ----------------------------------------------------------------------
  2008. Cleanup:
  2009. // release the two instances
  2010. OUTPUT (" - Releasing Instances\n");
  2011. if (pUnk)
  2012. pUnk->Release();
  2013. return TestResult(RetVal, "TestMultiQIHandler");
  2014. }
  2015. // ----------------------------------------------------------------------
  2016. //
  2017. // TestHandler
  2018. //
  2019. // tests activating a server that has a handler
  2020. //
  2021. // ----------------------------------------------------------------------
  2022. BOOL TestHandler(void)
  2023. {
  2024. BOOL RetVal = TRUE;
  2025. ULONG cRefs = 0;
  2026. HRESULT hRes = S_OK;
  2027. IUnknown *pUnkSrv = NULL;
  2028. IUnknown *pUnkHdl = NULL;
  2029. IRunnableObject *pIRO = NULL;
  2030. IOleObject *pIOO = NULL;
  2031. IDropTarget *pIDT = NULL;
  2032. OUTPUT ("Starting TestHandler\n");
  2033. // create our interface to pass to the remote object.
  2034. hRes = CoCreateInstance(CLSID_TestEmbed, NULL, CLSCTX_LOCAL_SERVER,
  2035. IID_IUnknown, (void **)&pUnkSrv);
  2036. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance LOCAL_SERVER failed\n")
  2037. VerifyObjRefCnt(pUnkSrv, 1);
  2038. OUTPUT (" - CoCreateInstance LOCAL_SERVER succeeded\n");
  2039. OUTPUT (" - QI for IRunnableObject\n");
  2040. hRes = pUnkSrv->QueryInterface(IID_IRunnableObject, (void **)&pIRO);
  2041. TEST_FAILED(SUCCEEDED(hRes), "QI for IRO on LOCAL_SERVER succeeded\n")
  2042. if (pIRO)
  2043. {
  2044. pIRO->Release();
  2045. pIRO = NULL;
  2046. }
  2047. OUTPUT (" - Releasing Instance\n");
  2048. if (pUnkSrv)
  2049. {
  2050. cRefs = pUnkSrv->Release();
  2051. TEST_FAILED(cRefs != 0, "REFCNT wrong on Release\n")
  2052. pUnkSrv = NULL;
  2053. }
  2054. OUTPUT (" - LOCAL_SERVER case complete\n");
  2055. // ----------------------------------------------------------------------
  2056. // create the remote object
  2057. hRes = CoCreateInstance(CLSID_TestEmbed, NULL, CLSCTX_INPROC_HANDLER,
  2058. IID_IUnknown, (void **)&pUnkHdl);
  2059. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance INPROC_HANDLER failed\n")
  2060. VerifyObjRefCnt(pUnkHdl, 1);
  2061. VerifyRHRefCnt(pUnkHdl, 1);
  2062. OUTPUT (" - CoCreateInstance INPROC_HANDLER succeeded\n");
  2063. // ----------------------------------------------------------------------
  2064. // query for some unsupported interface to ensure OLE handles QI
  2065. // when not yet connected to the server.
  2066. OUTPUT (" - QI for IDropTarget\n");
  2067. hRes = pUnkHdl->QueryInterface(IID_IDropTarget, (void **)&pIDT);
  2068. VerifyObjRefCnt(pUnkHdl, 1);
  2069. VerifyRHRefCnt(pUnkHdl, 1);
  2070. TEST_FAILED_EXIT(SUCCEEDED(hRes),
  2071. "QI for IDropTarget on INPROC_HANDLER worked but should have failed!\n")
  2072. // the return value from failed QI on a handler that was never connected
  2073. // must be E_NOINTERFACE
  2074. TEST_FAILED_EXIT(hRes != E_NOINTERFACE,
  2075. "QI for IDropTarget on INPROC_HANDLER did not return E_NOINTERFACE!\n")
  2076. OUTPUT (" - Query for remote Interface before connected OK.\n");
  2077. // ----------------------------------------------------------------------
  2078. // run the remote server
  2079. OUTPUT (" - QI for IRunnableObject\n");
  2080. hRes = pUnkHdl->QueryInterface(IID_IRunnableObject, (void **)&pIRO);
  2081. VerifyObjRefCnt(pUnkHdl, 2);
  2082. VerifyRHRefCnt(pUnkHdl, 2);
  2083. TEST_FAILED_EXIT(FAILED(hRes), "QI for IRO on INPROC_HANDLER failed\n")
  2084. hRes = pIRO->Run(NULL);
  2085. VerifyObjRefCnt(pUnkHdl, 2);
  2086. VerifyRHRefCnt(pUnkHdl, 2);
  2087. TEST_FAILED(FAILED(hRes), "IRO->Run on INPROC_HANDLER failed\n")
  2088. OUTPUT (" - INPROC_HANDLER run OK\n");
  2089. // ----------------------------------------------------------------------
  2090. // test stoping the server
  2091. OUTPUT (" - Stop the Server\n");
  2092. hRes = pUnkHdl->QueryInterface(IID_IOleObject, (void **)&pIOO);
  2093. VerifyObjRefCnt(pUnkHdl, 3);
  2094. VerifyRHRefCnt(pUnkHdl, 3);
  2095. TEST_FAILED_EXIT(FAILED(hRes), "QI for IOleObject on INPROC_HANDLER failed\n")
  2096. hRes = pIOO->Close(OLECLOSE_NOSAVE);
  2097. VerifyObjRefCnt(pUnkHdl, 3);
  2098. VerifyRHRefCnt(pUnkHdl, 3);
  2099. TEST_FAILED(FAILED(hRes), "IOO->Close on INPROC_HANDLER failed\n")
  2100. pIOO->Release();
  2101. pIOO = NULL;
  2102. VerifyObjRefCnt(pUnkHdl, 2);
  2103. VerifyRHRefCnt(pUnkHdl, 2);
  2104. OUTPUT (" - INPROC_HANDLER Close OK\n");
  2105. // ----------------------------------------------------------------------
  2106. // query again for some unsupported interface to ensure OLE handles QI
  2107. // when disconnected from the server.
  2108. OUTPUT (" - QI for IDropTarget\n");
  2109. hRes = pUnkHdl->QueryInterface(IID_IDropTarget, (void **)&pIDT);
  2110. VerifyObjRefCnt(pUnkHdl, 2);
  2111. VerifyRHRefCnt(pUnkHdl, 2);
  2112. TEST_FAILED_EXIT(SUCCEEDED(hRes),
  2113. "QI for IDropTarget on disconnected INPROC_HANDLER worked but should have failed!\n")
  2114. // the return value from failed QI on a handler that has been disconnected
  2115. // must be CO_O_OBJNOTCONNECTED
  2116. TEST_FAILED_EXIT(hRes != CO_E_OBJNOTCONNECTED,
  2117. "QI for IDropTarget on INPROC_HANDLER did not return CO_E_OBJNOTCONNECTED!\n")
  2118. OUTPUT (" - Query for remote Interface after disconnected OK.\n");
  2119. // ----------------------------------------------------------------------
  2120. // test restarting the server
  2121. Sleep(500);
  2122. OUTPUT (" - Run the Server Again\n");
  2123. hRes = pIRO->Run(NULL);
  2124. VerifyObjRefCnt(pUnkHdl, 2);
  2125. VerifyRHRefCnt(pUnkHdl, 2);
  2126. TEST_FAILED(FAILED(hRes), "Second IRO->Run on INPROC_HANDLER failed\n")
  2127. OUTPUT (" - Second INPROC_HANDLER Run OK\n");
  2128. // ----------------------------------------------------------------------
  2129. // test stoping the server
  2130. OUTPUT (" - Stop the Server\n");
  2131. hRes = pUnkHdl->QueryInterface(IID_IOleObject, (void **)&pIOO);
  2132. VerifyObjRefCnt(pUnkHdl, 3);
  2133. VerifyRHRefCnt(pUnkHdl, 3);
  2134. TEST_FAILED_EXIT(FAILED(hRes), "QI for IOleObject on INPROC_HANDLER failed\n")
  2135. hRes = pIOO->Close(OLECLOSE_NOSAVE);
  2136. VerifyObjRefCnt(pUnkHdl, 3);
  2137. VerifyRHRefCnt(pUnkHdl, 3);
  2138. TEST_FAILED(FAILED(hRes), "IOO->Close on INPROC_HANDLER failed\n")
  2139. pIOO->Release();
  2140. pIOO = NULL;
  2141. VerifyObjRefCnt(pUnkHdl, 2);
  2142. VerifyRHRefCnt(pUnkHdl, 2);
  2143. OUTPUT (" - INPROC_HANDLER Close OK\n");
  2144. // ----------------------------------------------------------------------
  2145. // test using weak references
  2146. OUTPUT (" - Call OleSetContainedObject TRUE\n");
  2147. hRes = OleSetContainedObject(pUnkHdl, 1);
  2148. TEST_FAILED(FAILED(hRes), "1st OleSetContainedObject on pUnkHdl failed\n")
  2149. OUTPUT (" - OleSetContainedObject OK\n");
  2150. Sleep(500);
  2151. OUTPUT (" - Run the Server Again\n");
  2152. hRes = pIRO->Run(NULL);
  2153. VerifyObjRefCnt(pUnkHdl, 2);
  2154. VerifyRHRefCnt(pUnkHdl, 2);
  2155. TEST_FAILED(FAILED(hRes), "Third IRO->Run on INPROC_HANDLER failed\n")
  2156. OUTPUT (" - Third INPROC_HANDLER Run OK\n");
  2157. // try making the references strong again
  2158. OUTPUT (" - Call OleSetContainedObject FALSE\n");
  2159. hRes = OleSetContainedObject(pUnkHdl, 0);
  2160. TEST_FAILED(FAILED(hRes), "2nd OleSetContainedObject on pUnkHdl failed\n")
  2161. OUTPUT (" - OleSetContainedObject OK\n");
  2162. // try making the references weak again
  2163. OUTPUT (" - Call OleSetContainedObject TRUE\n");
  2164. hRes = OleSetContainedObject(pUnkHdl, 1);
  2165. TEST_FAILED(FAILED(hRes), "3rd OleSetContainedObject on pUnkHdl failed\n")
  2166. OUTPUT (" - OleSetContainedObject OK\n");
  2167. // ----------------------------------------------------------------------
  2168. // cleanup
  2169. pIRO->Release();
  2170. pIRO = NULL;
  2171. VerifyObjRefCnt(pUnkHdl, 1);
  2172. VerifyRHRefCnt(pUnkHdl, 1);
  2173. // ----------------------------------------------------------------------
  2174. OUTPUT (" - Releasing Instance\n");
  2175. if (pUnkHdl)
  2176. {
  2177. cRefs = pUnkHdl->Release();
  2178. TEST_FAILED(cRefs != 0, "REFCNT wrong on Release\n")
  2179. pUnkHdl = NULL;
  2180. }
  2181. OUTPUT (" - INPROC_HANDLER case complete\n");
  2182. // ----------------------------------------------------------------------
  2183. Cleanup:
  2184. // release the two instances
  2185. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2186. if (pIDT)
  2187. {
  2188. pIDT->Release();
  2189. }
  2190. if (pIRO)
  2191. {
  2192. pIRO->Release();
  2193. }
  2194. if (pIOO)
  2195. {
  2196. pIOO->Release();
  2197. }
  2198. if (pUnkSrv)
  2199. {
  2200. pUnkSrv->Release();
  2201. }
  2202. if (pUnkHdl)
  2203. {
  2204. pUnkHdl->Release();
  2205. }
  2206. return TestResult(RetVal, "TestHandler");
  2207. }
  2208. // ----------------------------------------------------------------------
  2209. //
  2210. // TestGetStandardMarshal
  2211. //
  2212. // test CoGetStandardMarshal API
  2213. //
  2214. // ----------------------------------------------------------------------
  2215. BOOL TestGetStandardMarshal(void)
  2216. {
  2217. BOOL RetVal = TRUE;
  2218. HRESULT hres;
  2219. ULONG ulRefCnt;
  2220. IMarshal *pIM = NULL, *pIM2 = NULL;
  2221. IStream *pStm;
  2222. IUnknown *punkIn = NULL;
  2223. IUnknown *punkOut = NULL;
  2224. LARGE_INTEGER large_int;
  2225. LISet32(large_int, 0);
  2226. OUTPUT ("Starting TestGetStandardMarshal\n");
  2227. punkIn = GetTestUnk();
  2228. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  2229. VerifyObjRefCnt(punkIn, 1);
  2230. pStm = CreateMemStm(600, NULL);
  2231. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  2232. VerifyObjRefCnt((IUnknown *)pStm, 1);
  2233. // ----------------------------------------------------------------------
  2234. hres = CoGetStandardMarshal(IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL, &pIM);
  2235. TEST_FAILED_EXIT(FAILED(hres), "CoGetStandardMarshal failed\n")
  2236. VerifyRHRefCnt(punkIn, 1);
  2237. hres = CoGetStandardMarshal(IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL, &pIM2);
  2238. TEST_FAILED_EXIT(FAILED(hres), "second CoGetStandardMarshal failed\n")
  2239. VerifyRHRefCnt(punkIn, 2);
  2240. TEST_FAILED((pIM != pIM2), "CoGetStandardMarshal returned two different interfaces.\n")
  2241. ulRefCnt = pIM2->Release();
  2242. TEST_FAILED_EXIT(ulRefCnt != 1, "pIM2 RefCnt is wrong");
  2243. pIM2 = NULL;
  2244. hres = CoGetStandardMarshal(IID_IUnknown, NULL, 0, NULL, MSHLFLAGS_NORMAL, &pIM2);
  2245. TEST_FAILED_EXIT(FAILED(hres), "third CoGetStandardMarshal failed\n")
  2246. VerifyRHRefCnt(punkIn, 1);
  2247. OUTPUT (" - CoGetStandardMarshal OK\n");
  2248. // ----------------------------------------------------------------------
  2249. hres = pIM->MarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  2250. TEST_FAILED_EXIT(FAILED(hres), "MarshalInterface failed\n")
  2251. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2252. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2253. // since we are unmarshalling in the same process, the RH should go away.
  2254. hres = pIM->UnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  2255. TEST_FAILED_EXIT(FAILED(hres), "UnmarshalInterface failed\n")
  2256. VerifyRHRefCnt(punkIn, 1);
  2257. // make sure the interface pointers are identical
  2258. if (punkIn != punkOut)
  2259. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...1st Local Unmarshal\n")
  2260. OUTPUT (" - UnmarshalInterface OK\n");
  2261. // release interface and make sure it does not go away - refcnt > 0
  2262. ulRefCnt = punkOut->Release();
  2263. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero");
  2264. punkOut = NULL;
  2265. OUTPUT (" - Release OK\n");
  2266. // ----------------------------------------------------------------------
  2267. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2268. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2269. hres = pIM->MarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  2270. TEST_FAILED_EXIT(FAILED(hres), "MarshalInterface failed\n")
  2271. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2272. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2273. // since we are unmarshalling in the same process, the RH should go away.
  2274. hres = pIM2->UnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  2275. TEST_FAILED_EXIT(FAILED(hres), "UnmarshalInterface failed\n")
  2276. VerifyRHRefCnt(punkIn, 1);
  2277. // make sure the interface pointers are identical
  2278. if (punkIn != punkOut)
  2279. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match...1st Local Unmarshal\n")
  2280. OUTPUT (" - Second UnmarshalInterface OK\n");
  2281. // release interface and make sure it does not go away - refcnt > 0
  2282. ulRefCnt = punkOut->Release();
  2283. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero");
  2284. punkOut = NULL;
  2285. OUTPUT (" - Release OK\n");
  2286. ulRefCnt = pIM2->Release();
  2287. TEST_FAILED_EXIT(ulRefCnt == 0, "pIM2 RefCnt is zero");
  2288. pIM2 = NULL;
  2289. OUTPUT (" - Release OK\n");
  2290. // ----------------------------------------------------------------------
  2291. // release the marshalled data
  2292. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2293. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2294. hres = pIM->MarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  2295. TEST_FAILED_EXIT(FAILED(hres), "MarshalInterface failed\n")
  2296. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2297. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2298. hres = pIM->ReleaseMarshalData(pStm);
  2299. TEST_FAILED_EXIT(FAILED(hres), "Release Marshal Data failed\n.");
  2300. OUTPUT (" - ReleaseMarshalData OK\n");
  2301. // the RH should go away, and we should have only the original
  2302. // refcnt from creation left on the object.
  2303. ulRefCnt = pIM->Release();
  2304. TEST_FAILED_EXIT(ulRefCnt != 0, "pIM RefCnt not zero");
  2305. pIM = NULL;
  2306. // release the original object
  2307. ulRefCnt = punkIn->Release();
  2308. TEST_FAILED_EXIT(ulRefCnt != 0, "punkIn RefCnt not zero");
  2309. punkIn = NULL;
  2310. // ----------------------------------------------------------------------
  2311. Cleanup:
  2312. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2313. // Dump interfaces we are done with
  2314. if (pStm)
  2315. {
  2316. ulRefCnt = pStm->Release();
  2317. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  2318. }
  2319. if (punkOut)
  2320. {
  2321. ulRefCnt = punkOut->Release();
  2322. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  2323. }
  2324. if (punkIn)
  2325. {
  2326. ulRefCnt = punkIn->Release();
  2327. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  2328. }
  2329. return TestResult(RetVal, "TestGetStandardMarshal");
  2330. }
  2331. // ----------------------------------------------------------------------
  2332. //
  2333. // TestLockObjectExternal
  2334. //
  2335. // test CoLockObjectExternal API
  2336. //
  2337. // ----------------------------------------------------------------------
  2338. BOOL TestLockObjectExternal(void)
  2339. {
  2340. BOOL RetVal = TRUE;
  2341. HRESULT hres;
  2342. ULONG ulRefCnt;
  2343. IUnknown *punkIn = NULL;
  2344. IStream *pStm = NULL;
  2345. OUTPUT ("Starting TestLockObjectExternal\n");
  2346. punkIn = GetTestUnk();
  2347. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  2348. VerifyObjRefCnt(punkIn, 1);
  2349. // ----------------------------------------------------------------------
  2350. // test calling it once, then releasing it once
  2351. hres = CoLockObjectExternal(punkIn, TRUE, FALSE);
  2352. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal failed.\n")
  2353. VerifyRHRefCnt(punkIn, 1);
  2354. VerifyObjRefCnt(punkIn, 2);
  2355. OUTPUT (" - CoLockObjectExternal TRUE OK\n");
  2356. hres = CoLockObjectExternal(punkIn, FALSE, FALSE);
  2357. TEST_FAILED_EXIT(FAILED(hres), "second CoLockObjectExternal failed\n")
  2358. VerifyRHRefCnt(punkIn, 0);
  2359. VerifyObjRefCnt(punkIn, 1);
  2360. OUTPUT (" - CoLockObjectExternal FALSE OK\n");
  2361. // ----------------------------------------------------------------------
  2362. // test calling it twice, then releasing it twice
  2363. // the first AddRef inc's the StrongCnt, the RH, and the real object.
  2364. hres = CoLockObjectExternal(punkIn, TRUE, FALSE);
  2365. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal failed.\n")
  2366. VerifyRHRefCnt(punkIn, 1);
  2367. VerifyObjRefCnt(punkIn, 2);
  2368. OUTPUT (" - CoLockObjectExternal TRUE OK\n");
  2369. // the second AddRef inc's the StrongCnt and the RH, but not the
  2370. // real object.
  2371. hres = CoLockObjectExternal(punkIn, TRUE, FALSE);
  2372. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal failed.\n")
  2373. VerifyRHRefCnt(punkIn, 2);
  2374. VerifyObjRefCnt(punkIn, 2);
  2375. OUTPUT (" - CoLockObjectExternal TRUE OK\n");
  2376. // the second release Dec's the StrongCnt and the RH, but not the
  2377. // real object.
  2378. hres = CoLockObjectExternal(punkIn, FALSE, FALSE);
  2379. TEST_FAILED_EXIT(FAILED(hres), "second CoLockObjectExternal failed\n")
  2380. VerifyRHRefCnt(punkIn, 1);
  2381. VerifyObjRefCnt(punkIn, 2);
  2382. OUTPUT (" - CoLockObjectExternal FALSE OK\n");
  2383. // the last Release dec's the StrongCnt, the RH, and the real object.
  2384. hres = CoLockObjectExternal(punkIn, FALSE, FALSE);
  2385. TEST_FAILED_EXIT(FAILED(hres), "second CoLockObjectExternal failed\n")
  2386. VerifyRHRefCnt(punkIn, 0);
  2387. VerifyObjRefCnt(punkIn, 1);
  2388. OUTPUT (" - CoLockObjectExternal FALSE OK\n");
  2389. // ----------------------------------------------------------------------
  2390. // test calling it once, then releasing the punkIn and ensuring
  2391. // the object is still alive.
  2392. hres = CoLockObjectExternal(punkIn, TRUE, FALSE);
  2393. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal failed.\n")
  2394. VerifyRHRefCnt(punkIn, 1);
  2395. VerifyObjRefCnt(punkIn, 2);
  2396. OUTPUT (" - CoLockObjectExternal TRUE OK\n");
  2397. ulRefCnt = punkIn->Release();
  2398. TEST_FAILED(ulRefCnt != 1, "Release returned incorrect value.\n");
  2399. VerifyRHRefCnt(punkIn, 1);
  2400. OUTPUT (" - punkIn->Release OK\n");
  2401. hres = CoLockObjectExternal(punkIn, FALSE, FALSE);
  2402. TEST_FAILED_EXIT(FAILED(hres), "second CoLockObjectExternal failed\n")
  2403. punkIn = NULL;
  2404. OUTPUT (" - CoLockObjectExternal FALSE OK\n");
  2405. // ----------------------------------------------------------------------
  2406. // test calling marshal interface, followed by CLOE(F,T). This
  2407. // should disconnect the object. This is bizarre backward compatibility
  2408. // semantics that some LOTUS apps do rely on.
  2409. punkIn = GetTestUnk();
  2410. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  2411. VerifyObjRefCnt(punkIn, 1);
  2412. pStm = CreateMemStm(600, NULL);
  2413. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  2414. VerifyObjRefCnt((IUnknown *)pStm, 1);
  2415. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL,
  2416. MSHLFLAGS_TABLESTRONG);
  2417. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  2418. VerifyRHRefCnt(punkIn, 1);
  2419. OUTPUT (" - CoMarshalInterface TABLE_STRONG OK\n");
  2420. hres = CoLockObjectExternal(punkIn, FALSE, TRUE);
  2421. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal(F,T) failed\n")
  2422. VerifyObjRefCnt(punkIn, 1);
  2423. VerifyRHRefCnt(punkIn, 0);
  2424. OUTPUT (" - CoLockObjectExternal FALSE TRUE OK\n");
  2425. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL,
  2426. MSHLFLAGS_NORMAL);
  2427. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  2428. VerifyRHRefCnt(punkIn, 1);
  2429. OUTPUT (" - CoMarshalInterface NORMAL OK\n");
  2430. hres = CoLockObjectExternal(punkIn, FALSE, TRUE);
  2431. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal(F,T) failed\n")
  2432. VerifyObjRefCnt(punkIn, 1);
  2433. VerifyRHRefCnt(punkIn, 0);
  2434. OUTPUT (" - CoLockObjectExternal FALSE TRUE OK\n");
  2435. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL,
  2436. MSHLFLAGS_TABLEWEAK);
  2437. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  2438. VerifyRHRefCnt(punkIn, 1);
  2439. OUTPUT (" - CoMarshalInterface TABLEWEAK OK\n");
  2440. // BUGBUG: refcnts seem to be wrong on the following call:
  2441. hres = CoLockObjectExternal(punkIn, FALSE, TRUE);
  2442. TEST_FAILED_EXIT(FAILED(hres), "CoLockObjectExternal(F,T) failed\n")
  2443. VerifyObjRefCnt(punkIn, 1);
  2444. VerifyRHRefCnt(punkIn, 0);
  2445. OUTPUT (" - CoLockObjectExternal FALSE TRUE OK\n");
  2446. punkIn->Release();
  2447. punkIn = NULL;
  2448. Cleanup:
  2449. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2450. // Dump interfaces we are done with
  2451. if (punkIn)
  2452. {
  2453. ulRefCnt = punkIn->Release();
  2454. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  2455. }
  2456. if (pStm)
  2457. {
  2458. pStm->Release();
  2459. }
  2460. return TestResult(RetVal, "TestLockObjectExternal");
  2461. }
  2462. // ----------------------------------------------------------------------
  2463. //
  2464. // TestReleaseMarshalData
  2465. //
  2466. // test CoReleaseMarshalData API
  2467. //
  2468. // ----------------------------------------------------------------------
  2469. BOOL TestReleaseMarshalData(void)
  2470. {
  2471. BOOL RetVal = TRUE;
  2472. HRESULT hres;
  2473. ULONG cRefs;
  2474. IUnknown *punkIn = NULL;
  2475. IStream *pStm = NULL;
  2476. LARGE_INTEGER large_int;
  2477. OUTPUT ("Starting TestReleaseMarshalData\n");
  2478. punkIn = GetTestUnk();
  2479. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  2480. VerifyObjRefCnt(punkIn, 1);
  2481. // Create a shared memory stream for the marshaled object
  2482. pStm = CreateMemStm(600, NULL);
  2483. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  2484. // ----------------------------------------------------------------------
  2485. // try RMD on NORMAL marshal
  2486. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  2487. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed.\n")
  2488. VerifyRHRefCnt(punkIn, 1);
  2489. VerifyObjRefCnt(punkIn, 2);
  2490. OUTPUT (" - MarshalInterface NORMAL OK\n");
  2491. LISet32(large_int, 0);
  2492. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2493. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2494. hres = CoReleaseMarshalData(pStm);
  2495. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  2496. VerifyRHRefCnt(punkIn, 0);
  2497. VerifyObjRefCnt(punkIn, 1);
  2498. OUTPUT (" - CoReleaseMarshalData NORMAL OK\n");
  2499. // try RMD on TABLESTRONG marshal
  2500. LISet32(large_int, 0);
  2501. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2502. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2503. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_TABLESTRONG);
  2504. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed.\n")
  2505. VerifyRHRefCnt(punkIn, 1);
  2506. VerifyObjRefCnt(punkIn, 2);
  2507. OUTPUT (" - MarshalInterface TABLESTRONG OK\n");
  2508. LISet32(large_int, 0);
  2509. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2510. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2511. hres = CoReleaseMarshalData(pStm);
  2512. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  2513. VerifyRHRefCnt(punkIn, 0);
  2514. VerifyObjRefCnt(punkIn, 1);
  2515. OUTPUT (" - CoReleaseMarshalData TABLESTRONG OK\n");
  2516. // try RMD on TABLEWEAK marshal
  2517. LISet32(large_int, 0);
  2518. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2519. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2520. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_TABLEWEAK);
  2521. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed.\n")
  2522. VerifyRHRefCnt(punkIn, 1);
  2523. VerifyObjRefCnt(punkIn, 2);
  2524. OUTPUT (" - MarshalInterface TABLEWEAK OK\n");
  2525. LISet32(large_int, 0);
  2526. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2527. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2528. hres = CoReleaseMarshalData(pStm);
  2529. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  2530. VerifyRHRefCnt(punkIn, 0);
  2531. VerifyObjRefCnt(punkIn, 1);
  2532. OUTPUT (" - CoReleaseMarshalData TABLEWEAK OK\n");
  2533. // ----------------------------------------------------------------------
  2534. Cleanup:
  2535. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2536. // Dump interfaces we are done with
  2537. if (punkIn)
  2538. {
  2539. cRefs = punkIn->Release();
  2540. TEST_FAILED(cRefs != 0, "punkIn RefCnt not zero\n");
  2541. }
  2542. if (pStm)
  2543. {
  2544. pStm->Release();
  2545. }
  2546. return TestResult(RetVal, "TestReleaseMarshalData");
  2547. }
  2548. // ----------------------------------------------------------------------
  2549. //
  2550. // TestDisconnectObject
  2551. //
  2552. // test CoDisconnectObject API
  2553. //
  2554. // ----------------------------------------------------------------------
  2555. BOOL TestDisconnectObject(void)
  2556. {
  2557. BOOL RetVal = TRUE;
  2558. HRESULT hres;
  2559. ULONG ulRefCnt;
  2560. IUnknown *punkIn = NULL;
  2561. IStream *pStm = NULL;
  2562. LARGE_INTEGER large_int;
  2563. OUTPUT ("Starting TestDisconnectObject\n");
  2564. punkIn = GetTestUnk();
  2565. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  2566. VerifyObjRefCnt(punkIn, 1);
  2567. // Create a shared memory stream for the marshaled object
  2568. pStm = CreateMemStm(600, NULL);
  2569. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  2570. // ----------------------------------------------------------------------
  2571. // test calling it without having ever marshalled it.
  2572. hres = CoDisconnectObject(punkIn, 0);
  2573. TEST_FAILED_EXIT(FAILED(hres), "CoDisconnectObject succeeded but should have failed.\n")
  2574. VerifyRHRefCnt(punkIn, 0);
  2575. VerifyObjRefCnt(punkIn, 1);
  2576. OUTPUT (" - first CoDisconnectObject OK\n");
  2577. // test calling after having marshalled it.
  2578. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_TABLEWEAK);
  2579. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed.\n")
  2580. VerifyRHRefCnt(punkIn, 1);
  2581. VerifyObjRefCnt(punkIn, 2);
  2582. OUTPUT (" - CoMarshalInterface OK\n");
  2583. hres = CoDisconnectObject(punkIn, 0);
  2584. TEST_FAILED_EXIT(FAILED(hres), "second CoDisconnectObject failed\n")
  2585. VerifyRHRefCnt(punkIn, 0);
  2586. VerifyObjRefCnt(punkIn, 1);
  2587. OUTPUT (" - second CoDisconnectObject OK\n");
  2588. // now release the marshalled data
  2589. LISet32(large_int, 0);
  2590. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  2591. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  2592. hres = CoReleaseMarshalData(pStm);
  2593. TEST_FAILED_EXIT(FAILED(hres), "CoReleaseMarshalData failed.\n")
  2594. VerifyRHRefCnt(punkIn, 0);
  2595. VerifyObjRefCnt(punkIn, 1);
  2596. OUTPUT (" - CoReleaseMarshalData OK\n");
  2597. // ----------------------------------------------------------------------
  2598. Cleanup:
  2599. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2600. // Dump interfaces we are done with
  2601. if (punkIn)
  2602. {
  2603. ulRefCnt = punkIn->Release();
  2604. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  2605. }
  2606. if (pStm)
  2607. {
  2608. pStm->Release();
  2609. }
  2610. return TestResult(RetVal, "TestDisconnectObject");
  2611. }
  2612. // ----------------------------------------------------------------------
  2613. //
  2614. // TestOXIDs
  2615. //
  2616. // tests A calling B calling A calling B etc n times, to see if Rpc
  2617. // can handle this.
  2618. //
  2619. // ----------------------------------------------------------------------
  2620. BOOL TestExpiredOXIDs(void)
  2621. {
  2622. BOOL RetVal = TRUE;
  2623. HRESULT hRes = S_OK;
  2624. ILoop *pLocalLoop = NULL;
  2625. IClassFactory *pUnk = NULL;
  2626. OUTPUT ("Starting TestExpiredOXIDs\n");
  2627. // start the local server process manually so it stays alive for the
  2628. // duration of the test (even though we dont have an OXIDEntry for it.
  2629. STARTUPINFO startupInfo;
  2630. PROCESS_INFORMATION processInfo;
  2631. memset(&processInfo, 0, sizeof(processInfo));
  2632. memset(&startupInfo, 0, sizeof(startupInfo));
  2633. RetVal = CreateProcess(TEXT("ballsrv.exe"),
  2634. NULL, // command line
  2635. NULL, // security for process
  2636. NULL, // security for thread
  2637. FALSE, // inherit handles
  2638. NORMAL_PRIORITY_CLASS,
  2639. NULL, // environment block
  2640. NULL, // current directory
  2641. &startupInfo,
  2642. &processInfo);
  2643. if (RetVal == FALSE)
  2644. {
  2645. hRes = GetLastError();
  2646. OUTPUT (" - CreateProcess Failed\n");
  2647. }
  2648. else
  2649. {
  2650. // give the process time to register its class object
  2651. Sleep(2000);
  2652. }
  2653. for (ULONG i=0; i<7; i++)
  2654. {
  2655. // create a new instance of a local server that is already running,
  2656. // causing us to reuse the same OXID.
  2657. hRes = CoGetClassObject(CLSID_Balls,
  2658. CLSCTX_LOCAL_SERVER,
  2659. NULL, // pvReserved
  2660. IID_IClassFactory,
  2661. (void **)&pUnk);
  2662. TEST_FAILED_EXIT(FAILED(hRes), "CoGetClassObject ballsrv failed\n")
  2663. // release interface (lets OXIDEntry be placed on the expired list)
  2664. pUnk->Release();
  2665. pUnk = NULL;
  2666. for (ULONG j=0; j<i; j++)
  2667. {
  2668. // create (i) new instances of another class and release them
  2669. // right away. This causes (i) new processes to start and (i)
  2670. // entries of the OXID table expired list to get flushed.
  2671. hRes = CoCreateInstance(CLSID_LoopSrv, NULL, CLSCTX_LOCAL_SERVER,
  2672. IID_ILoop, (void **)&pLocalLoop);
  2673. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance First failed\n")
  2674. pLocalLoop->Release();
  2675. pLocalLoop = NULL;
  2676. }
  2677. }
  2678. Cleanup:
  2679. // release the two instances
  2680. OUTPUT (" - Releasing Instances\n");
  2681. if (pUnk)
  2682. pUnk->Release();
  2683. if (pLocalLoop)
  2684. pLocalLoop->Release();
  2685. // kill the server process
  2686. if (processInfo.hProcess != 0)
  2687. {
  2688. BOOL fKill = TerminateProcess(processInfo.hProcess, 0);
  2689. if (!fKill)
  2690. {
  2691. hRes = GetLastError();
  2692. OUTPUT (" - TermintateProcess Failed\n");
  2693. }
  2694. CloseHandle(processInfo.hThread);
  2695. CloseHandle(processInfo.hProcess);
  2696. }
  2697. return TestResult(RetVal, "TestExpiredOXIDs");
  2698. }
  2699. // ----------------------------------------------------------------------
  2700. //
  2701. // TestAggregate
  2702. //
  2703. // tests creating an RH that is aggregated.
  2704. //
  2705. // ----------------------------------------------------------------------
  2706. BOOL TestAggregate(void)
  2707. {
  2708. BOOL RetVal = TRUE;
  2709. HRESULT hRes = S_OK;
  2710. IUnknown *punkOuter = NULL;
  2711. IUnknown *pUnk = NULL;
  2712. IBalls *pIBall = NULL;
  2713. ULONG ulRefCnt = 0;
  2714. OUTPUT ("Starting TestAggregate\n");
  2715. punkOuter = GetTestUnk();
  2716. TEST_FAILED_EXIT((punkOuter == NULL), "new CTestUnk failed\n")
  2717. VerifyObjRefCnt(punkOuter, 1);
  2718. // create our interface to pass to the remote object.
  2719. hRes = CoCreateInstance(CLSID_Balls, punkOuter, CLSCTX_LOCAL_SERVER,
  2720. IID_IUnknown, (void **)&pUnk);
  2721. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance First failed\n")
  2722. // now release the object
  2723. ulRefCnt = pUnk->Release();
  2724. TEST_FAILED_EXIT(ulRefCnt != 0, "Release failed\n")
  2725. // ----------------------------------------------------------------------
  2726. // create our interface to pass to the remote object.
  2727. hRes = CoCreateInstance(CLSID_Balls, punkOuter, CLSCTX_LOCAL_SERVER,
  2728. IID_IUnknown, (void **)&pUnk);
  2729. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance First failed\n")
  2730. hRes = pUnk->QueryInterface(IID_IBalls, (void **)&pIBall);
  2731. TEST_FAILED_EXIT(FAILED(hRes), "QueryInterface failed\n")
  2732. // now release the interface
  2733. ulRefCnt = pIBall->Release();
  2734. TEST_FAILED_EXIT(ulRefCnt == 0, "Release failed\n")
  2735. // now release the object
  2736. ulRefCnt = pUnk->Release();
  2737. TEST_FAILED_EXIT(ulRefCnt != 0, "Release failed\n")
  2738. // now release the punkOuter
  2739. ulRefCnt = punkOuter->Release();
  2740. TEST_FAILED_EXIT(ulRefCnt != 0, "Release failed\n")
  2741. Cleanup:
  2742. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2743. return TestResult(RetVal, "TestAggregate");
  2744. }
  2745. // ----------------------------------------------------------------------
  2746. //
  2747. // TestCreateRemoteHandler
  2748. //
  2749. // test CoCreateRemoteHandler API and unmarshalling data into it.
  2750. //
  2751. // ----------------------------------------------------------------------
  2752. BOOL TestCreateRemoteHandler(void)
  2753. {
  2754. BOOL RetVal = TRUE;
  2755. HRESULT hres;
  2756. ULONG ulRefCnt;
  2757. IUnknown *punkBall = NULL;
  2758. IUnknown *punkOuter = NULL;
  2759. IClassFactory *pICF = NULL;
  2760. OUTPUT ("Starting TestCreateRemoteHandler\n");
  2761. // create the controlling unknown for the remote object.
  2762. punkOuter = GetTestUnk();
  2763. // ----------------------------------------------------------------------
  2764. // create a remote object that we will aggregate.
  2765. // Create an IBall ClassFactory Interface.
  2766. DWORD grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  2767. hres = CoGetClassObject(CLSID_Balls,
  2768. grfContext,
  2769. NULL, // pvReserved
  2770. IID_IClassFactory,
  2771. (void **)&pICF);
  2772. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject Balls failed\n")
  2773. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject Balls failed\n")
  2774. OUTPUT (" - Aquired Remote Balls Class Object.\n");
  2775. VerifyObjRefCnt(pICF, 1);
  2776. VerifyRHRefCnt(pICF, 1);
  2777. // ----------------------------------------------------------------------
  2778. // note, since pICF is a class object, it has special super secret
  2779. // behaviour to make it go away. create an instance, release the
  2780. // class object, then release the instance.
  2781. hres = pICF->CreateInstance(punkOuter, IID_IUnknown, (void **)&punkBall);
  2782. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  2783. TEST_FAILED_EXIT((punkBall == NULL), "CreateInstance failed\n")
  2784. OUTPUT (" - Created Balls Instance.\n");
  2785. VerifyObjRefCnt(punkBall, 1);
  2786. VerifyRHRefCnt(punkBall, 1);
  2787. // ----------------------------------------------------------------------
  2788. // release class object
  2789. ulRefCnt = pICF->Release();
  2790. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  2791. pICF = NULL;
  2792. OUTPUT (" - Released Balls Class Object.\n");
  2793. // release the remote object handler
  2794. ulRefCnt = punkBall->Release();
  2795. TEST_FAILED_EXIT(ulRefCnt != 0, "punkBall RefCnt not zero");
  2796. punkBall = NULL;
  2797. // release the outer
  2798. ulRefCnt = punkOuter->Release();
  2799. TEST_FAILED_EXIT(ulRefCnt != 0, "punkOuter RefCnt not zero");
  2800. punkOuter = NULL;
  2801. // ----------------------------------------------------------------------
  2802. Cleanup:
  2803. OUTPUT (" - Test Complete. Doing Cleanup\n");
  2804. if (punkBall)
  2805. {
  2806. ulRefCnt = punkBall->Release();
  2807. TEST_FAILED(ulRefCnt != 0, "punkBall RefCnt not zero\n");
  2808. }
  2809. if (punkOuter)
  2810. {
  2811. ulRefCnt = punkOuter->Release();
  2812. TEST_FAILED(ulRefCnt != 0, "punkOuter RefCnt not zero\n");
  2813. }
  2814. return TestResult(RetVal, "TestCreateRemoteHandler");
  2815. }
  2816. // ----------------------------------------------------------------------
  2817. //
  2818. // TestTIDAndLID
  2819. //
  2820. // test the values of TID and MID to ensure they are correct across
  2821. // calls.
  2822. //
  2823. // ----------------------------------------------------------------------
  2824. HRESULT TIDAndLIDSubroutine();
  2825. DWORD _stdcall TIDAndLIDServer(void *param);
  2826. BOOL TestTIDAndLID(void)
  2827. {
  2828. BOOL RetVal = TRUE;
  2829. HRESULT hRes;
  2830. // First, try it across process boundaries.
  2831. hRes = TIDAndLIDSubroutine();
  2832. TEST_FAILED(FAILED(hRes), "TIDAndLID different process failed\n")
  2833. // Next, try it across thread boundaries.
  2834. // Spin a thread to be the server of the TIDAndLID
  2835. HANDLE hEvent[2];
  2836. hEvent[0]= CreateEvent(NULL, FALSE, FALSE, NULL);
  2837. hEvent[1]= CreateEvent(NULL, FALSE, FALSE, NULL);
  2838. DWORD dwThrdId = 0;
  2839. HANDLE hThrd = CreateThread(NULL, 0,
  2840. TIDAndLIDServer,
  2841. &hEvent[0], 0, &dwThrdId);
  2842. if (hThrd)
  2843. {
  2844. // wait for thread to register its class object
  2845. WaitForSingleObject(hEvent[0], 0xffffffff);
  2846. Sleep(0);
  2847. // Now run the whole test again. This time CoGetClassObject should
  2848. // find the server running in the other thread.
  2849. hRes = TIDAndLIDSubroutine();
  2850. TEST_FAILED(FAILED(hRes), "TIDAndLID different process failed\n")
  2851. // signal the other thread to exit
  2852. CloseHandle(hThrd);
  2853. PostThreadMessage(dwThrdId, WM_QUIT, 0, 0);
  2854. // wait for other thread to call CoUninitialize
  2855. WaitForSingleObject(hEvent[1], 0xffffffff);
  2856. CloseHandle(hEvent[0]);
  2857. CloseHandle(hEvent[1]);
  2858. }
  2859. else
  2860. {
  2861. hRes = GetLastError();
  2862. TEST_FAILED(hRes, "CreateThread failed\n")
  2863. }
  2864. return TestResult(RetVal, "TestTIDAndLID");
  2865. }
  2866. HRESULT TIDAndLIDSubroutine()
  2867. {
  2868. BOOL RetVal = TRUE;
  2869. ULONG ulRefCnt;
  2870. ICube *pCube = NULL;
  2871. IUnknown *pUnk = NULL;
  2872. HRESULT hRes;
  2873. // create our interface to pass to the remote object.
  2874. OUTPUT (" - Create Instance of ICube\n");
  2875. hRes = CoCreateInstance(CLSID_Cubes, NULL, CLSCTX_LOCAL_SERVER,
  2876. IID_ICube, (void **)&pCube);
  2877. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance CLSID_Cubes failed\n")
  2878. OUTPUT (" - Instance of ICubes created OK\n");
  2879. pUnk = GetTestUnk();
  2880. hRes = pCube->PrepForInputSyncCall(pUnk);
  2881. TEST_FAILED(FAILED(hRes), "pCube->PreForInputSyncCall failed\n")
  2882. hRes = pCube->InputSyncCall();
  2883. if (gInitFlag == COINIT_APARTMENTTHREADED)
  2884. {
  2885. TEST_FAILED(FAILED(hRes), "pCube->InputSyncCall failed\n")
  2886. }
  2887. else
  2888. {
  2889. TEST_FAILED(SUCCEEDED(hRes), "pCube->InputSyncCall should have failed\n")
  2890. }
  2891. OUTPUT (" - Completed Release inside InputSync call\n");
  2892. OUTPUT (" - Get the current LID information\n");
  2893. UUID lidCaller;
  2894. CoGetCurrentLogicalThreadId(&lidCaller);
  2895. OUTPUT (" - call on ICube interface\n");
  2896. hRes = pCube->SimpleCall(GetCurrentProcessId(),
  2897. GetCurrentThreadId(),
  2898. lidCaller);
  2899. TEST_FAILED(FAILED(hRes), "pCube->SimpleCall failed\n")
  2900. // release the interface
  2901. OUTPUT (" - Release the ICube interface\n");
  2902. ulRefCnt = pCube->Release();
  2903. TEST_FAILED(ulRefCnt != 0, "pCube RefCnt not zero\n");
  2904. pCube = NULL;
  2905. Cleanup:
  2906. OUTPUT (" - Subroutine Complete. Doing Cleanup\n");
  2907. if (pCube != NULL)
  2908. {
  2909. pCube->Release();
  2910. pCube = NULL;
  2911. }
  2912. return hRes;
  2913. }
  2914. // current COINIT flag used on main thread
  2915. extern DWORD gInitFlag;
  2916. DWORD _stdcall TIDAndLIDServer(void *param)
  2917. {
  2918. BOOL RetVal = TRUE;
  2919. HANDLE *pHandle = (HANDLE *) param;
  2920. HANDLE hEvent[2];
  2921. hEvent[0] = *pHandle;
  2922. hEvent[1] = *(pHandle+1);
  2923. OUTPUT (" - TIDAndLIDServer Start\n");
  2924. HRESULT hRes = CoInitializeEx(NULL, gInitFlag);
  2925. TEST_FAILED(FAILED(hRes), "TIDAndLIDServer CoInitialize failed\n")
  2926. if (SUCCEEDED(hRes))
  2927. {
  2928. DWORD dwReg;
  2929. IClassFactory *pICF = new CTestUnkCF();
  2930. if (pICF)
  2931. {
  2932. hRes = CoRegisterClassObject(CLSID_Cubes, pICF,
  2933. CLSCTX_LOCAL_SERVER,
  2934. REGCLS_MULTIPLEUSE, &dwReg);
  2935. TEST_FAILED(FAILED(hRes), "TIDAndLID CoRegisterClassObject failed\n")
  2936. SetEvent(hEvent[0]);
  2937. if (SUCCEEDED(hRes))
  2938. {
  2939. MSG msg;
  2940. while (GetMessage(&msg, NULL, 0, 0))
  2941. {
  2942. DispatchMessage(&msg);
  2943. }
  2944. hRes = CoRevokeClassObject(dwReg);
  2945. TEST_FAILED(FAILED(hRes), "TIDAndLID CoRevokeClassObject failed\n")
  2946. }
  2947. }
  2948. else
  2949. {
  2950. // set the event anyway
  2951. TEST_FAILED(TRUE, "TIDAndLID new CTestUnkCF failed\n")
  2952. SetEvent(hEvent[0]);
  2953. }
  2954. CoUninitialize();
  2955. }
  2956. else
  2957. {
  2958. // wake the other guy anyway
  2959. SetEvent(hEvent[0]);
  2960. }
  2961. // signal we've called CoUninitialize
  2962. SetEvent(hEvent[1]);
  2963. OUTPUT (" - TIDAndLIDServer done\n");
  2964. return hRes;
  2965. }
  2966. // ----------------------------------------------------------------------
  2967. //
  2968. // TestNonNDRProxy
  2969. //
  2970. // test using a non-NDR proxy and stub for ICube interface.
  2971. //
  2972. // ----------------------------------------------------------------------
  2973. BOOL TestNonNDRProxy(void)
  2974. {
  2975. BOOL RetVal = TRUE;
  2976. HRESULT hRes;
  2977. ULONG ulRefCnt;
  2978. ICube *pCube = NULL;
  2979. OUTPUT ("Starting TestNonNDR\n");
  2980. // stomp on the registry to use our custom proxy dll for ICube interface
  2981. BYTE szValueSave[MAX_PATH];
  2982. DWORD cbValue = sizeof(szValueSave);
  2983. DWORD dwType;
  2984. LONG lRes = RegQueryValueEx(HKEY_CLASSES_ROOT,
  2985. TEXT("Interface\\{00000139-0001-0008-C000-000000000046}\\ProxyStubClsid32"),
  2986. NULL,
  2987. &dwType,
  2988. szValueSave,
  2989. &cbValue);
  2990. if (lRes == ERROR_SUCCESS)
  2991. {
  2992. BYTE szValueNew[40];
  2993. strcpy((char *)&szValueNew[0], "{0000013e-0001-0008-C000-000000000046}");
  2994. lRes = RegSetValueEx(HKEY_CLASSES_ROOT,
  2995. TEXT("Interface\\{00000139-0001-0008-C000-000000000046}\\ProxyStubClsid32"),
  2996. NULL,
  2997. dwType,
  2998. szValueNew,
  2999. sizeof(szValueNew));
  3000. }
  3001. // create our interface to pass to the remote object.
  3002. OUTPUT (" - Create Instance of ICube\n");
  3003. hRes = CoCreateInstance(CLSID_Cubes, NULL, CLSCTX_LOCAL_SERVER,
  3004. IID_ICube, (void **)&pCube);
  3005. TEST_FAILED_EXIT(FAILED(hRes), "CoCreateInstance failed\n")
  3006. OUTPUT (" - Instance of ICube created OK\n");
  3007. OUTPUT (" - Make first call on ICube interface\n");
  3008. hRes = pCube->MoveCube(23, 34);
  3009. TEST_FAILED(FAILED(hRes), "ICube->MoveCube failed\n")
  3010. // release the interface
  3011. OUTPUT (" - Release the ICube interface\n");
  3012. ulRefCnt = pCube->Release();
  3013. TEST_FAILED(ulRefCnt != 0, "pCube RefCnt not zero\n");
  3014. pCube = NULL;
  3015. // ----------------------------------------------------------------------
  3016. Cleanup:
  3017. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3018. // restore the registry to use real proxy dll for ICube interface
  3019. if (lRes == ERROR_SUCCESS)
  3020. {
  3021. lRes = RegSetValueEx(HKEY_CLASSES_ROOT,
  3022. TEXT("Interface\\{00000139-0001-0008-C000-000000000046}\\ProxyStubClsid32"),
  3023. NULL,
  3024. dwType,
  3025. szValueSave,
  3026. cbValue);
  3027. }
  3028. return TestResult(RetVal, "TestNonNDR");
  3029. }
  3030. // ----------------------------------------------------------------------
  3031. //
  3032. // test rundown
  3033. //
  3034. // - build 9 objects
  3035. // - marshal 3 NORMAL, 3 TABLE_STRONG, 3 TABLE_WEAK.
  3036. // - start 3 clients that each do 3 things...
  3037. // Unmarshal Objects
  3038. // Call Method on each object
  3039. // Release Objects
  3040. // each client has a sleep before one of the operations to let rundown
  3041. // happen.
  3042. // - CoDisconnectObject each of the 9 objects
  3043. //
  3044. // ----------------------------------------------------------------------
  3045. BOOL TestRundown(void)
  3046. {
  3047. BOOL RetVal = TRUE;
  3048. BOOL fSame = TRUE;
  3049. ULONG k = 0;
  3050. HRESULT hres;
  3051. IStream *pstm[3] = {NULL, NULL, NULL};
  3052. IUnknown *punk[9] = {NULL, NULL, NULL,
  3053. NULL, NULL, NULL,
  3054. NULL, NULL, NULL};
  3055. DWORD mshlflags[3] = {MSHLFLAGS_NORMAL,
  3056. MSHLFLAGS_TABLESTRONG,
  3057. MSHLFLAGS_TABLEWEAK};
  3058. MSG msg;
  3059. DWORD dwEndTime;
  3060. OUTPUT ("Starting TestRundown\n");
  3061. // create 9 objects to play with
  3062. OUTPUT ("Creating Nine Objects\n");
  3063. for (ULONG i=0; i<9; i++)
  3064. {
  3065. punk[i] = GetTestUnk();
  3066. TEST_FAILED_EXIT((punk[i] == NULL), "new CTestUnk failed\n")
  3067. VerifyObjRefCnt(punk[i], 1);
  3068. }
  3069. // create 3 streams on files
  3070. OUTPUT ("Creating Three Streams\n");
  3071. for (i=0; i<3; i++)
  3072. {
  3073. pstm[i] = (IStream *) new CStreamOnFile(pwszFileName[i] ,hres, FALSE);
  3074. TEST_FAILED_EXIT((pstm[i] == NULL), "new CStreamOnFile failed\n")
  3075. TEST_FAILED_EXIT(FAILED(hres), "CStreamOnFile failed\n")
  3076. VerifyObjRefCnt(pstm[i], 1);
  3077. }
  3078. // ----------------------------------------------------------------------
  3079. // marshal the nine objects into 3 different streams on files.
  3080. OUTPUT ("Marshal Nine Objects into Three Streams\n");
  3081. // loop on stream
  3082. for (i=0; i<3; i++)
  3083. {
  3084. // loop on marshal flags
  3085. for (ULONG j=0; j<3; j++)
  3086. {
  3087. hres = CoMarshalInterface(pstm[i], IID_IParseDisplayName, punk[k++],
  3088. 0, NULL, mshlflags[j]);
  3089. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3090. }
  3091. }
  3092. // release the streams
  3093. OUTPUT ("Releasing the streams\n");
  3094. for (i=0; i<3; i++)
  3095. {
  3096. pstm[i]->Release();
  3097. pstm[i] = NULL;
  3098. }
  3099. // start the 3 client processes
  3100. OUTPUT ("Start Three Client Processes\n");
  3101. #if 0
  3102. for (i=0; i<3; i++)
  3103. {
  3104. DWORD dwThrdId = 0;
  3105. HANDLE hThrd = CreateThread(NULL, 0,
  3106. RundownClient,
  3107. (void *)i,
  3108. 0, &dwThrdId);
  3109. if (hThrd)
  3110. {
  3111. CloseHandle(hThrd);
  3112. }
  3113. else
  3114. {
  3115. hres = GetLastError();
  3116. TEST_FAILED_EXIT(hres, "CreateThread failed\n")
  3117. }
  3118. }
  3119. #endif
  3120. // sleep for some time to let the clients run
  3121. OUTPUT ("Waiting 12 minutes to let clients run\n");
  3122. dwEndTime = GetTickCount() + 780000;
  3123. while (GetTickCount() < dwEndTime)
  3124. {
  3125. if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
  3126. {
  3127. if (GetMessage(&msg, NULL, 0, 0))
  3128. DispatchMessage(&msg);
  3129. }
  3130. else
  3131. {
  3132. Sleep(250);
  3133. }
  3134. }
  3135. // ----------------------------------------------------------------------
  3136. Cleanup:
  3137. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3138. // disconnect the nine objects
  3139. OUTPUT ("Disconnecting Nine Objects\n");
  3140. for (i=0; i<9; i++)
  3141. {
  3142. if (punk[i] != NULL)
  3143. {
  3144. hres = CoDisconnectObject(punk[i], 0);
  3145. punk[i] = NULL;
  3146. TEST_FAILED(FAILED(hres), "CoDisconnectObject failed\n")
  3147. }
  3148. }
  3149. // release the streams
  3150. OUTPUT ("Releasing the streams\n");
  3151. for (i=0; i<3; i++)
  3152. {
  3153. if (pstm[i] != NULL)
  3154. {
  3155. pstm[i]->Release();
  3156. pstm[i] = NULL;
  3157. }
  3158. }
  3159. return TestResult(RetVal, "TestRundown");
  3160. }
  3161. // ----------------------------------------------------------------------
  3162. //
  3163. // test rundown worker thread
  3164. //
  3165. // starts a thread that will do...
  3166. // Unmarshal Objects
  3167. // Call Method on each object
  3168. // Release Objects
  3169. //
  3170. // perform a sleep before one of the operations to let rundown
  3171. // happen.
  3172. //
  3173. // ----------------------------------------------------------------------
  3174. DWORD _stdcall RundownClient(void *param)
  3175. {
  3176. BOOL RetVal = TRUE;
  3177. ULONG i = 0;
  3178. HRESULT hres;
  3179. IStream *pstm = NULL;
  3180. IBindCtx *pbctx = NULL;
  3181. IParseDisplayName *punk[3] = {NULL, NULL, NULL};
  3182. OUTPUT (" Starting RundownClient\n");
  3183. // get the filename from the passed in parameter
  3184. DWORD dwThreadNum = (DWORD)param;
  3185. hres = CoInitialize(NULL);
  3186. TEST_FAILED_EXIT(FAILED(hres), "CoInitialzie failed\n")
  3187. // create a stream on the file
  3188. OUTPUT (" - CreateStreamOnFile\n");
  3189. pstm = (IStream *) new CStreamOnFile(pwszFileName[dwThreadNum], hres, TRUE);
  3190. TEST_FAILED_EXIT((pstm == NULL), "CStreamOnFile failed\n")
  3191. TEST_FAILED_EXIT(FAILED(hres), "CStreamOnFile failed\n")
  3192. VerifyObjRefCnt(pstm, 1);
  3193. // ----------------------------------------------------------------------
  3194. if (dwThreadNum == 2)
  3195. Sleep(5000);
  3196. // unmarshal the interfaces
  3197. OUTPUT (" - Unmarshal the interfaces\n");
  3198. for (i=0; i<3; i++)
  3199. {
  3200. hres = CoUnmarshalInterface(pstm, IID_IParseDisplayName,
  3201. (void **)&punk[i]);
  3202. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  3203. }
  3204. OUTPUT (" - Unmarshaled the interfaces OK.\n");
  3205. // ----------------------------------------------------------------------
  3206. if (dwThreadNum == 1)
  3207. Sleep(5000);
  3208. hres = CreateBindCtx(0, &pbctx);
  3209. TEST_FAILED_EXIT(FAILED(hres), "CreateBindCtx failed\n")
  3210. // call the objects
  3211. for (i=0; i<3; i++)
  3212. {
  3213. ULONG cbEaten = 0;
  3214. IMoniker *pmnk = NULL;
  3215. hres = punk[i]->ParseDisplayName(pbctx, pwszFileName[dwThreadNum],
  3216. &cbEaten, &pmnk);
  3217. TEST_FAILED(FAILED(hres), "call on object failed\n")
  3218. if (pmnk)
  3219. {
  3220. pmnk->Release();
  3221. }
  3222. }
  3223. OUTPUT (" - Called the interfaces OK.\n");
  3224. pbctx->Release();
  3225. // ----------------------------------------------------------------------
  3226. if (dwThreadNum == 0)
  3227. Sleep(5000);
  3228. // ----------------------------------------------------------------------
  3229. Cleanup:
  3230. OUTPUT (" - Rundown Thread Complete. Doing Cleanup\n");
  3231. // release the objects
  3232. for (i=0; i<3; i++)
  3233. {
  3234. if (punk[i] != NULL)
  3235. {
  3236. punk[i]->Release();
  3237. punk[i] = NULL;
  3238. }
  3239. }
  3240. OUTPUT (" - Released the interfaces OK.\n");
  3241. // release the stream
  3242. pstm->Release();
  3243. CoUninitialize();
  3244. return TestResult(RetVal, "TestRundown");
  3245. }
  3246. // ----------------------------------------------------------------------
  3247. //
  3248. // TestMarshalStorage
  3249. //
  3250. // test marshalling a docfile
  3251. //
  3252. // ----------------------------------------------------------------------
  3253. BOOL TestMarshalStorage(void)
  3254. {
  3255. BOOL RetVal = TRUE;
  3256. HRESULT hres;
  3257. ULONG ulRefCnt;
  3258. IStorage *pStgIn = NULL;
  3259. IStorage *pStgOut = NULL;
  3260. IStream *pStm = NULL;
  3261. LARGE_INTEGER large_int;
  3262. LISet32(large_int, 0);
  3263. OUTPUT ("Starting TestMarshalStorage\n");
  3264. // create a docfile
  3265. hres = StgCreateDocfile(L"foo.bar",
  3266. STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
  3267. 0, &pStgIn);
  3268. TEST_FAILED_EXIT(FAILED(hres), "StgCreateDocFile failed\n")
  3269. // create a stream to marshal the storage into
  3270. pStm = CreateMemStm(600, NULL);
  3271. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  3272. VerifyObjRefCnt((IUnknown *)pStm, 1);
  3273. // ----------------------------------------------------------------------
  3274. // marshal the interface
  3275. hres = CoMarshalInterface(pStm, IID_IStorage, pStgIn, 0, NULL, MSHLFLAGS_NORMAL);
  3276. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3277. OUTPUT (" - CoMarshalInterface OK\n");
  3278. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3279. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3280. // since we are unmarshalling in the same process, the RH should go away.
  3281. hres = CoUnmarshalInterface(pStm, IID_IStorage, (LPVOID FAR*)&pStgOut);
  3282. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  3283. // make sure the interface pointers are identical
  3284. if (pStgIn != pStgOut)
  3285. OUTPUT("WARNING: CoUnmarshalInterface Local...ptrs dont match\n")
  3286. else
  3287. OUTPUT (" - CoUnmarshalInterface OK\n");
  3288. // release it and make sure it does not go away - refcnt > 0
  3289. ulRefCnt = pStgOut->Release();
  3290. pStgOut = NULL;
  3291. TEST_FAILED(ulRefCnt == 0, "pStgOut RefCnt is not zero");
  3292. OUTPUT (" - Release OK\n");
  3293. // the RH should have gone away, and we should have only the original
  3294. // refcnt from creation left on the object.
  3295. VerifyObjRefCnt(pStgIn, 1);
  3296. // ----------------------------------------------------------------------
  3297. Cleanup:
  3298. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3299. if (pStgIn)
  3300. {
  3301. ulRefCnt = pStgIn->Release();
  3302. TEST_FAILED(ulRefCnt != 0, "pStgIn RefCnt not zero\n");
  3303. }
  3304. if (pStgOut)
  3305. {
  3306. ulRefCnt = pStgOut->Release();
  3307. TEST_FAILED(ulRefCnt != 0, "pStgOut RefCnt not zero\n");
  3308. }
  3309. if (pStm)
  3310. {
  3311. ulRefCnt = pStm->Release();
  3312. TEST_FAILED(ulRefCnt != 0, "pStm RefCnt not zero\n");
  3313. }
  3314. return TestResult(RetVal, "TestMarshalStorage");
  3315. }
  3316. // ----------------------------------------------------------------------
  3317. //
  3318. // test LOCAL interface MSHLFLAGS_NORMAL, MSHCTX_DIFFERENTMACHINE
  3319. //
  3320. // ----------------------------------------------------------------------
  3321. BOOL TestStorageInterfaceDiffMachine(void)
  3322. {
  3323. BOOL RetVal = TRUE;
  3324. HRESULT hres;
  3325. LPSTREAM pStm = NULL;
  3326. ULONG ulRefCnt = 0;
  3327. IStorage *pStgIn = NULL;
  3328. IStorage *pStgOut = NULL;
  3329. LARGE_INTEGER large_int;
  3330. LISet32(large_int, 0);
  3331. OUTPUT ("Starting TestStorageInterfaceDiffMachine\n");
  3332. // create a docfile
  3333. hres = StgCreateDocfile(L"foo.bar",
  3334. STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
  3335. 0, &pStgIn);
  3336. TEST_FAILED_EXIT(FAILED(hres), "CreateDocfile failed\n")
  3337. pStm = CreateMemStm(600, NULL);
  3338. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  3339. VerifyObjRefCnt((IUnknown *)pStm, 1);
  3340. // ----------------------------------------------------------------------
  3341. hres = CoMarshalInterface(pStm, IID_IStorage, pStgIn,
  3342. MSHCTX_DIFFERENTMACHINE, 0,
  3343. MSHLFLAGS_NORMAL);
  3344. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3345. VerifyRHRefCnt(pStgIn, 1);
  3346. OUTPUT (" - CoMarshalInterface OK\n");
  3347. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3348. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3349. hres = CoUnmarshalInterface(pStm, IID_IStorage, (LPVOID FAR*)&pStgOut);
  3350. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  3351. VerifyRHRefCnt(pStgIn, 0);
  3352. // release them
  3353. ulRefCnt = pStgOut->Release();
  3354. pStgOut = NULL;
  3355. OUTPUT (" - Release OK\n");
  3356. ulRefCnt = pStgIn->Release();
  3357. pStgIn = NULL;
  3358. OUTPUT (" - Release OK\n");
  3359. // ----------------------------------------------------------------------
  3360. Cleanup:
  3361. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3362. if (pStgIn)
  3363. {
  3364. ulRefCnt = pStgIn->Release();
  3365. TEST_FAILED(ulRefCnt != 0, "pStgIn RefCnt not zero\n");
  3366. }
  3367. if (pStgOut)
  3368. {
  3369. ulRefCnt = pStgOut->Release();
  3370. TEST_FAILED(ulRefCnt != 0, "pStgOut RefCnt not zero\n");
  3371. }
  3372. if (pStm)
  3373. {
  3374. ulRefCnt = pStm->Release();
  3375. TEST_FAILED(ulRefCnt != 0, "pStm RefCnt not zero\n");
  3376. }
  3377. return TestResult(RetVal, "TestStorageInterfaceDiffMachine");
  3378. }
  3379. // ----------------------------------------------------------------------
  3380. //
  3381. // test REMOTE interface MSHLFLAGS_NORMAL, MSHCTX_DIFFERENTMACHINE
  3382. //
  3383. // ----------------------------------------------------------------------
  3384. BOOL TestRemoteInterfaceDiffMachine(void)
  3385. {
  3386. BOOL RetVal = TRUE;
  3387. HRESULT hres;
  3388. LPSTREAM pStm = NULL;
  3389. LPCLASSFACTORY pICF = NULL;
  3390. ULONG ulRefCnt;
  3391. IUnknown *punkOut = NULL;
  3392. IUnknown *punkIn = NULL;
  3393. LARGE_INTEGER large_int;
  3394. LISet32(large_int, 0);
  3395. OUTPUT ("Starting TestRemoteInterfaceDifferentMachine\n");
  3396. // Create an IClassFactory Interface.
  3397. DWORD grfContext=CLSCTX_LOCAL_SERVER; // handler/server/local server
  3398. hres = CoGetClassObject(CLSID_Balls,
  3399. grfContext,
  3400. NULL, // pvReserved
  3401. IID_IClassFactory,
  3402. (void **)&pICF);
  3403. TEST_FAILED_EXIT(FAILED(hres), "CoGetClassObject failed\n")
  3404. TEST_FAILED_EXIT((pICF == NULL), "CoGetClassObject failed\n")
  3405. VerifyRHRefCnt((IUnknown *)pICF, 1);
  3406. OUTPUT (" - Aquired Remote Class Object.\n");
  3407. // ----------------------------------------------------------------------
  3408. // note, since pICF is a class object, it has special super secret
  3409. // behaviour to make it go away. create an instance, release the
  3410. // class object, then release the instance.
  3411. hres = pICF->CreateInstance(NULL, IID_IUnknown, (void **)&punkIn);
  3412. TEST_FAILED_EXIT(FAILED(hres), "CreateInstance failed\n")
  3413. TEST_FAILED_EXIT((punkIn == NULL), "CreateInstance failed\n")
  3414. VerifyRHRefCnt(punkIn, 1);
  3415. OUTPUT (" - Created Instance.\n");
  3416. // release class object
  3417. ulRefCnt = pICF->Release();
  3418. TEST_FAILED(ulRefCnt != 0, "pICF RefCnt not zero\n");
  3419. // VerifyRHRefCnt((IUnknown *)pICF, 0);
  3420. pICF = NULL;
  3421. OUTPUT (" - Released Class Object.\n");
  3422. // ----------------------------------------------------------------------
  3423. // Create a shared memory stream for the marshaled interface
  3424. pStm = CreateMemStm(600, NULL);
  3425. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  3426. // Marshal the interface into the stream
  3427. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn,
  3428. MSHCTX_DIFFERENTMACHINE, 0,
  3429. MSHLFLAGS_NORMAL);
  3430. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3431. OUTPUT (" - CoMarshalInterface OK.\n");
  3432. VerifyRHRefCnt(punkIn, 1);
  3433. // unmarshal the interface. should get the same proxy back.
  3434. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3435. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3436. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  3437. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  3438. VerifyRHRefCnt(punkIn, 2);
  3439. // make sure the interface pointers are identical
  3440. if (punkIn != punkOut)
  3441. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..1st Remote Unmarshal\n")
  3442. OUTPUT (" - CoUnmarshalInterface OK.\n");
  3443. // release the interface
  3444. ulRefCnt = punkOut->Release();
  3445. punkOut = NULL;
  3446. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  3447. VerifyRHRefCnt(punkIn, 1);
  3448. OUTPUT (" - Release OK\n");
  3449. // ----------------------------------------------------------------------
  3450. Cleanup:
  3451. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3452. // Dump interfaces we are done with
  3453. if (pStm)
  3454. {
  3455. ulRefCnt = pStm->Release();
  3456. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  3457. }
  3458. if (punkOut)
  3459. {
  3460. ulRefCnt = punkOut->Release();
  3461. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  3462. }
  3463. if (punkIn)
  3464. {
  3465. ulRefCnt = punkIn->Release();
  3466. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  3467. }
  3468. return TestResult(RetVal, "TestRemoteInterfaceDiffMachine");
  3469. }
  3470. // ----------------------------------------------------------------------
  3471. //
  3472. // test LOCAL interface MSHLFLAGS_NORMAL, MSHCTX_DIFFERENTMACHINE
  3473. //
  3474. // ----------------------------------------------------------------------
  3475. BOOL TestLocalInterfaceDiffMachine(void)
  3476. {
  3477. BOOL RetVal = TRUE;
  3478. HRESULT hres;
  3479. LPSTREAM pStm = NULL;
  3480. LPCLASSFACTORY pICF = NULL;
  3481. ULONG ulRefCnt;
  3482. IUnknown *punkOut = NULL;
  3483. IUnknown *punkIn = NULL;
  3484. LARGE_INTEGER large_int;
  3485. LISet32(large_int, 0);
  3486. OUTPUT ("Starting TestLocalInterfaceDifferentMachine\n");
  3487. punkIn = GetTestUnk();
  3488. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  3489. VerifyObjRefCnt(punkIn, 1);
  3490. // ----------------------------------------------------------------------
  3491. // Create a shared memory stream for the marshaled interface
  3492. pStm = CreateMemStm(600, NULL);
  3493. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  3494. // Marshal the interface into the stream
  3495. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn,
  3496. MSHCTX_DIFFERENTMACHINE, 0,
  3497. MSHLFLAGS_NORMAL);
  3498. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3499. OUTPUT (" - CoMarshalInterface OK.\n");
  3500. VerifyRHRefCnt(punkIn, 1);
  3501. // unmarshal the interface. should get the same proxy back.
  3502. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3503. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3504. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  3505. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  3506. VerifyRHRefCnt(punkIn, 0);
  3507. // make sure the interface pointers are identical
  3508. if (punkIn != punkOut)
  3509. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..1st Local Unmarshal\n")
  3510. OUTPUT (" - CoUnmarshalInterface OK.\n");
  3511. // release the interface
  3512. ulRefCnt = punkOut->Release();
  3513. punkOut = NULL;
  3514. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  3515. VerifyRHRefCnt(punkIn, 0);
  3516. OUTPUT (" - Release OK\n");
  3517. // ----------------------------------------------------------------------
  3518. Cleanup:
  3519. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3520. // Dump interfaces we are done with
  3521. if (pStm)
  3522. {
  3523. ulRefCnt = pStm->Release();
  3524. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  3525. }
  3526. if (punkOut)
  3527. {
  3528. ulRefCnt = punkOut->Release();
  3529. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  3530. }
  3531. if (punkIn)
  3532. {
  3533. ulRefCnt = punkIn->Release();
  3534. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  3535. }
  3536. return TestResult(RetVal, "TestLocalInterfaceDiffMachine");
  3537. }
  3538. // ----------------------------------------------------------------------
  3539. //
  3540. // test NOPING with MSHLFLAGS NORMAL, TABLEWEAK and TABLESTRONG
  3541. //
  3542. // CodeWork: ensure SORF_FLAG set correctly.
  3543. // ensure precedence rules are followed.
  3544. // ensure protocol is followed.
  3545. //
  3546. // ----------------------------------------------------------------------
  3547. typedef struct tagNoPingThreadInfo
  3548. {
  3549. HANDLE hEvent;
  3550. IStream *pStm;
  3551. HRESULT hr;
  3552. } NoPingThreadInfo;
  3553. DWORD _stdcall NoPingThread(void *param);
  3554. BOOL TestNoPing(void)
  3555. {
  3556. BOOL RetVal = TRUE;
  3557. HRESULT hres;
  3558. LPSTREAM pStm = NULL;
  3559. ULONG ulRefCnt, i;
  3560. IUnknown *punkOut = NULL;
  3561. IUnknown *punkIn = NULL;
  3562. IUnknown *punk[5] = {NULL, NULL, NULL, NULL, NULL};
  3563. NoPingThreadInfo npInfo;
  3564. DWORD dwThrdId = 0;
  3565. HANDLE hThrd;
  3566. IMarshal *pIM = NULL;
  3567. LARGE_INTEGER large_int;
  3568. LISet32(large_int, 0);
  3569. OUTPUT ("Starting TestNoPing\n");
  3570. punkIn = GetTestUnk();
  3571. TEST_FAILED_EXIT((punkIn == NULL), "new CTestUnk failed\n")
  3572. VerifyObjRefCnt(punkIn, 1);
  3573. // ----------------------------------------------------------------------
  3574. // Create a shared memory stream for the marshaled interface
  3575. pStm = CreateMemStm(600, NULL);
  3576. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  3577. // marshal it NORMAL, TABLEWEAK and TABLESTRONG with the NOPING flag
  3578. // set, and unmarshal each in the server apartment.
  3579. for (i=0; i<3; i++)
  3580. {
  3581. // Marshal the interface into the stream
  3582. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn,
  3583. 0, 0, (i | MSHLFLAGS_NOPING));
  3584. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3585. OUTPUT (" - CoMarshalInterface OK.\n");
  3586. VerifyRHRefCnt(punkIn, 1);
  3587. // verify the marshal format
  3588. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3589. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3590. hres = VerifyOBJREFFormat(pStm, (i | MSHLFLAGS_NOPING));
  3591. TEST_FAILED_EXIT(FAILED(hres), "VerifyOBJREFFormat failed\n")
  3592. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3593. // unmarshal the interface. should get the same proxy back.
  3594. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3595. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3596. hres = CoUnmarshalInterface(pStm, IID_IUnknown, (LPVOID FAR*)&punkOut);
  3597. TEST_FAILED_EXIT(FAILED(hres), "CoUnmarshalInterface failed\n")
  3598. // make sure the interface pointers are identical
  3599. if (punkIn != punkOut)
  3600. TEST_FAILED_EXIT(TRUE, "Interface ptrs dont match..1st Local Unmarshal\n")
  3601. OUTPUT (" - CoUnmarshalInterface OK.\n");
  3602. // check the refcnt on the stdid
  3603. if (i == 0)
  3604. {
  3605. // normal case, stdid should have been cleaned up
  3606. VerifyRHRefCnt(punkIn, 0);
  3607. }
  3608. else
  3609. {
  3610. // table case, stdid should still exist
  3611. VerifyRHRefCnt(punkIn, 1);
  3612. }
  3613. // release the interface
  3614. ulRefCnt = punkOut->Release();
  3615. punkOut = NULL;
  3616. TEST_FAILED_EXIT(ulRefCnt == 0, "punkOut RefCnt is zero\n");
  3617. VerifyRHRefCnt(punkIn, (i == 0) ? 0 : 1);
  3618. OUTPUT (" - Release OK\n");
  3619. if (i > 0)
  3620. {
  3621. // need to release marshal data on table marshaled interfaces
  3622. // reset the stream
  3623. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3624. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3625. hres = CoReleaseMarshalData(pStm);
  3626. TEST_FAILED_EXIT(FAILED(hres), "ReleaseMarshalData failed\n")
  3627. }
  3628. // reset the stream
  3629. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3630. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3631. }
  3632. // check the precedence rules
  3633. // Whatever an interface is first marshaled as is what sets the
  3634. // PING / NOPING flags. Marshal first as normal then noping and
  3635. // expect a normal 2nd marshal. Then marshal first as noping then
  3636. // normal and expect a noping 2nd marshal.
  3637. for (i=0; i<2; i++)
  3638. {
  3639. DWORD mshlflags1 = (i==0) ? MSHLFLAGS_NORMAL : MSHLFLAGS_NOPING;
  3640. DWORD mshlflags2 = (i==0) ? MSHLFLAGS_NOPING : MSHLFLAGS_NORMAL;
  3641. // Marshal the interface into the stream
  3642. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn,
  3643. 0, 0, mshlflags1);
  3644. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3645. OUTPUT (" - CoMarshalInterface OK.\n");
  3646. VerifyRHRefCnt(punkIn, 1);
  3647. // verify the marshal format
  3648. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3649. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3650. hres = VerifyOBJREFFormat(pStm, mshlflags1);
  3651. TEST_FAILED_EXIT(FAILED(hres), "VerifyOBJREFFormat failed\n")
  3652. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3653. // marshal it again, with the opposite flags then check the value
  3654. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3655. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3656. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn,
  3657. 0, 0, mshlflags2);
  3658. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3659. OUTPUT (" - CoMarshalInterface OK.\n");
  3660. VerifyRHRefCnt(punkIn, 1);
  3661. // verify the marshal format
  3662. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3663. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3664. hres = VerifyOBJREFFormat(pStm, mshlflags1);
  3665. TEST_FAILED_EXIT(FAILED(hres), "VerifyOBJREFFormat failed\n")
  3666. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3667. // release the marshaled data
  3668. hres = CoDisconnectObject(punkIn, 0);
  3669. TEST_FAILED_EXIT(FAILED(hres), "CoDisconnectObject failed\n")
  3670. OUTPUT (" - CoDisconnectObject OK.\n");
  3671. // reset the stream
  3672. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3673. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3674. // check CoGetStandardMarshal.
  3675. hres = CoGetStandardMarshal(IID_IUnknown, punkIn, 0, 0,
  3676. mshlflags1, &pIM);
  3677. TEST_FAILED_EXIT(FAILED(hres), "CoGetStandardMarshal failed\n")
  3678. OUTPUT (" - CoGetStandardMarshal OK.\n");
  3679. // Marshal the interface into the stream
  3680. hres = pIM->MarshalInterface(pStm, IID_IUnknown, punkIn,
  3681. 0, 0, mshlflags2);
  3682. TEST_FAILED_EXIT(FAILED(hres), "pIM->MarshalInterface failed\n")
  3683. OUTPUT (" - pIM->MarshalInterface OK.\n");
  3684. // verify the marshal format
  3685. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3686. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3687. hres = VerifyOBJREFFormat(pStm, mshlflags1);
  3688. TEST_FAILED_EXIT(FAILED(hres), "VerifyOBJREFFormat failed\n")
  3689. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3690. // release the IMarshal
  3691. pIM->Release();
  3692. // release the marshal data
  3693. hres = CoDisconnectObject(punkIn, 0);
  3694. TEST_FAILED_EXIT(FAILED(hres), "CoDisconnectObject failed\n")
  3695. OUTPUT (" - CoDisconnectObject OK.\n");
  3696. // reset the stream
  3697. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3698. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3699. }
  3700. // marshal 3 objects, NORMAL, TABLEWEAK, and TABLESTRONG, then
  3701. // pass the stream to another apartment and unmarshal them.
  3702. for (i=0; i<3; i++)
  3703. {
  3704. punk[i] = GetTestUnk();
  3705. TEST_FAILED_EXIT((punk[i] == NULL), "new CTestUnk failed\n")
  3706. VerifyObjRefCnt(punk[i], 1);
  3707. // Marshal the interface into the stream
  3708. hres = CoMarshalInterface(pStm, IID_IUnknown, punk[i],
  3709. 0, 0, (i | MSHLFLAGS_NOPING));
  3710. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3711. OUTPUT (" - CoMarshalInterface OK.\n");
  3712. VerifyRHRefCnt(punk[i], 1);
  3713. }
  3714. // marshal one more object, NOPING
  3715. punk[i] = GetTestUnk();
  3716. TEST_FAILED_EXIT((punk[i] == NULL), "new CTestUnk failed\n")
  3717. VerifyObjRefCnt(punk[i], 1);
  3718. // Marshal the interface into the stream
  3719. hres = CoMarshalInterface(pStm, IID_IUnknown, punk[i],
  3720. 0, 0, (MSHLFLAGS_NORMAL | MSHLFLAGS_NOPING));
  3721. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3722. OUTPUT (" - CoMarshalInterface OK.\n");
  3723. VerifyRHRefCnt(punk[i], 1);
  3724. // marshal a second interface on the same object as PING
  3725. hres = CoMarshalInterface(pStm, IID_IParseDisplayName, punk[i],
  3726. 0, 0, MSHLFLAGS_NORMAL);
  3727. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3728. OUTPUT (" - CoMarshalInterface OK.\n");
  3729. VerifyRHRefCnt(punk[i], 2);
  3730. // pass one more interface that does custom marshaling delegating
  3731. // to standard marshaling and replacing the PING option with NOPING.
  3732. i++;
  3733. punk[i] = (IUnknown *) new CTestUnkMarshal();
  3734. TEST_FAILED_EXIT((punk[i] == NULL), "new CTestUnkMarshal failed\n")
  3735. VerifyObjRefCnt(punk[i], 1);
  3736. // Marshal the interface into the stream
  3737. hres = CoMarshalInterface(pStm, IID_IUnknown, punk[i],
  3738. 0, 0, MSHLFLAGS_NORMAL);
  3739. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3740. OUTPUT (" - CoMarshalInterface OK.\n");
  3741. VerifyRHRefCnt(punk[i], 2);
  3742. // reset the stream seek ptr
  3743. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3744. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3745. for (i=0; i<6; i++)
  3746. {
  3747. // verify the marshal format
  3748. hres = VerifyOBJREFFormat(pStm, (i | MSHLFLAGS_NOPING));
  3749. TEST_FAILED_EXIT(FAILED(hres), "VerifyOBJREFFormat failed\n")
  3750. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3751. }
  3752. // reset the stream seek ptr
  3753. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3754. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3755. // create thread and wait for it to complete
  3756. npInfo.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3757. npInfo.pStm = pStm;
  3758. npInfo.hr = S_OK;
  3759. hThrd = CreateThread(NULL, 0, NoPingThread,
  3760. &npInfo, 0, &dwThrdId);
  3761. if (hThrd)
  3762. {
  3763. // wait for thread to register run to completetion. Note that
  3764. // we dont have to provide a message pump because with the NOPING
  3765. // flag set the other thread should never call back to get or release
  3766. // any references.
  3767. WaitForSingleObject(npInfo.hEvent, 0xffffffff);
  3768. Sleep(0);
  3769. CloseHandle(npInfo.hEvent);
  3770. // close the thread handle
  3771. CloseHandle(hThrd);
  3772. }
  3773. // cleanup the leftover objects.
  3774. for (i=0; i<5; i++)
  3775. {
  3776. hres = CoDisconnectObject(punk[i], 0);
  3777. TEST_FAILED_EXIT(FAILED(hres), "CoDisconnectObject failed\n")
  3778. OUTPUT (" - CoDisconnectObject OK.\n");
  3779. }
  3780. // ----------------------------------------------------------------------
  3781. Cleanup:
  3782. OUTPUT (" - Test Complete. Doing Cleanup\n");
  3783. // Dump interfaces we are done with
  3784. if (pStm)
  3785. {
  3786. ulRefCnt = pStm->Release();
  3787. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  3788. }
  3789. if (punkOut)
  3790. {
  3791. ulRefCnt = punkOut->Release();
  3792. TEST_FAILED(ulRefCnt != 0, "punkOut RefCnt not zero\n");
  3793. }
  3794. if (punkIn)
  3795. {
  3796. ulRefCnt = punkIn->Release();
  3797. TEST_FAILED(ulRefCnt != 0, "punkIn RefCnt not zero\n");
  3798. }
  3799. for (i=0; i<5; i++)
  3800. {
  3801. if (punk[i] != NULL)
  3802. {
  3803. ulRefCnt = punk[i]->Release();
  3804. TEST_FAILED(ulRefCnt != 0, "punk[i] RefCnt not zero\n");
  3805. }
  3806. }
  3807. return TestResult(RetVal, "TestNoPing");
  3808. }
  3809. // ----------------------------------------------------------------------
  3810. //
  3811. // Thread SubRoutine for testing NOPING.
  3812. //
  3813. // ----------------------------------------------------------------------
  3814. DWORD _stdcall NoPingThread(void *param)
  3815. {
  3816. BOOL RetVal = TRUE;
  3817. IUnknown *punk = NULL;
  3818. ULONG i = 0;
  3819. NoPingThreadInfo *npInfo = (NoPingThreadInfo *) param;
  3820. OUTPUT (" - NoPingThread Start\n");
  3821. HRESULT hRes = CoInitializeEx(NULL, gInitFlag);
  3822. TEST_FAILED(FAILED(hRes), "NoPingThread CoInitialize failed\n")
  3823. // Create a shared memory stream for the marshaled interface
  3824. IStream *pStm = CreateMemStm(600, NULL);
  3825. if (pStm == NULL)
  3826. {
  3827. TEST_FAILED((pStm == NULL), "CreateMemStm failed\n")
  3828. hRes = E_OUTOFMEMORY;
  3829. }
  3830. LARGE_INTEGER large_int;
  3831. LISet32(large_int, 0);
  3832. if (SUCCEEDED(hRes))
  3833. {
  3834. // unmarshal the interfaces
  3835. for (i=0; i<6; i++)
  3836. {
  3837. REFIID riid = (i==4) ? IID_IParseDisplayName : IID_IUnknown;
  3838. hRes = CoUnmarshalInterface(npInfo->pStm, riid, (void **)&punk);
  3839. TEST_FAILED(FAILED(hRes), "NoPingThread CoUnmarshalInterface failed\n")
  3840. OUTPUT(" - NoPingThread CoUnmarshalInterface done\n");
  3841. if (SUCCEEDED(hRes))
  3842. {
  3843. if (i==3)
  3844. {
  3845. // try remarshaling NOPING client as normal. Should end up
  3846. // as NOPING.
  3847. hRes = CoMarshalInterface(pStm, IID_IUnknown, punk,
  3848. 0, 0, MSHLFLAGS_NORMAL);
  3849. TEST_FAILED(FAILED(hRes), "CoMarshalInterface failed\n")
  3850. OUTPUT (" - CoMarshalInterface OK.\n");
  3851. // reset the stream seek ptr
  3852. hRes = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3853. TEST_FAILED(FAILED(hRes), "Seek on shared stream failed\n")
  3854. // verify the marshal format
  3855. hRes = VerifyOBJREFFormat(pStm, MSHLFLAGS_NOPING);
  3856. TEST_FAILED(FAILED(hRes), "VerifyOBJREFFormat failed\n")
  3857. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3858. }
  3859. punk->Release();
  3860. punk = NULL;
  3861. OUTPUT(" - NoPingThread Release done\n");
  3862. }
  3863. }
  3864. // uninit OLE
  3865. CoUninitialize();
  3866. }
  3867. if (pStm)
  3868. {
  3869. // release stream we created above
  3870. pStm->Release();
  3871. }
  3872. OUTPUT (" - NoPingThread Exit\n");
  3873. npInfo->hr = hRes;
  3874. SetEvent(npInfo->hEvent);
  3875. return RetVal;
  3876. }
  3877. // ----------------------------------------------------------------------
  3878. //
  3879. // test marshaling between apartments in the same process using
  3880. // MSHLFLAGS_NORMAL, MSHLFLAGS_TABLEWEAK, and MSHLFLAGS_TABLESTRONG
  3881. //
  3882. // ----------------------------------------------------------------------
  3883. typedef struct tagCrossThreadCallInfo
  3884. {
  3885. HANDLE hEvent;
  3886. IStream *pStm;
  3887. DWORD dwInitFlag;
  3888. DWORD dwThreadId;
  3889. HRESULT hr;
  3890. } CrossThreadCallInfo;
  3891. DWORD _stdcall CrossThreadCalls(void *param);
  3892. DWORD _stdcall CrossThreadLoops(void *param);
  3893. DWORD _stdcall CrossThreadActivate(void *param);
  3894. BOOL TestCrossThread(void)
  3895. {
  3896. BOOL RetVal = TRUE;
  3897. HRESULT hres;
  3898. LPSTREAM pStm = NULL;
  3899. ULONG ulRefCnt, i, j;
  3900. IUnknown *punk[3] = {NULL, NULL, NULL};
  3901. IUnknown *pUnk;
  3902. ILoop *pLocalLoop = NULL;
  3903. CrossThreadCallInfo ctInfo;
  3904. DWORD dwThrdId = 0;
  3905. HANDLE hThrd;
  3906. DWORD mshlflags[3] = {MSHLFLAGS_NORMAL,
  3907. MSHLFLAGS_TABLEWEAK,
  3908. MSHLFLAGS_TABLESTRONG};
  3909. DWORD dwInitFlags[4] = {COINIT_APARTMENTTHREADED,
  3910. COINIT_APARTMENTTHREADED,
  3911. COINIT_MULTITHREADED,
  3912. COINIT_MULTITHREADED};
  3913. LARGE_INTEGER large_int;
  3914. LISet32(large_int, 0);
  3915. OUTPUT ("Starting TestCrossThread\n");
  3916. // Create a shared memory stream for the marshaled interface
  3917. pStm = CreateMemStm(600, NULL);
  3918. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  3919. // ----------------------------------------------------------------------
  3920. for (j=0; j<4; j++)
  3921. {
  3922. // reset the stream seek ptr
  3923. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3924. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3925. // marshal an interface NORMAL, TABLEWEAK and TABLESTRONG
  3926. // and unmarshal each in another apartment.
  3927. for (i=0; i<3; i++)
  3928. {
  3929. punk[i] = GetTestUnk();
  3930. TEST_FAILED_EXIT((punk[i] == NULL), "new CTestUnkCube failed\n")
  3931. VerifyObjRefCnt(punk[i], 1);
  3932. // Marshal the interface into the stream
  3933. hres = CoMarshalInterface(pStm, IID_ICube, punk[i],
  3934. 0, 0, mshlflags[i]);
  3935. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  3936. OUTPUT (" - CoMarshalInterface OK.\n");
  3937. VerifyRHRefCnt(punk[i], 1);
  3938. }
  3939. // reset the stream seek ptr
  3940. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3941. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3942. for (i=0; i<3; i++)
  3943. {
  3944. hres = VerifyOBJREFFormat(pStm, mshlflags[i]);
  3945. TEST_FAILED_EXIT(FAILED(hres), "VerifyOBJREFFormat failed\n")
  3946. OUTPUT (" - VerifyOBJREFFormat OK.\n");
  3947. }
  3948. // reset the stream seek ptr
  3949. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3950. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3951. // create thread and wait for it to complete
  3952. ctInfo.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3953. ctInfo.pStm = pStm;
  3954. ctInfo.dwInitFlag = dwInitFlags[j];
  3955. ctInfo.dwThreadId = GetCurrentThreadId();
  3956. ctInfo.hr = S_OK;
  3957. RunThread(&ctInfo, ctInfo.hEvent, CrossThreadCalls);
  3958. CloseHandle(ctInfo.hEvent);
  3959. // cleanup the leftover objects.
  3960. for (i=0; i<3; i++)
  3961. {
  3962. hres = CoDisconnectObject(punk[i], 0);
  3963. punk[i] = NULL;
  3964. TEST_FAILED_EXIT(FAILED(hres), "CoDisconnectObject failed\n")
  3965. OUTPUT (" - CoDisconnectObject OK.\n");
  3966. }
  3967. }
  3968. // ----------------------------------------------------------------------
  3969. // Now test out doing activation from different apartments.
  3970. // create thread and wait for it to complete
  3971. for (j=0; j<2; j++)
  3972. {
  3973. ctInfo.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3974. ctInfo.pStm = NULL;
  3975. ctInfo.dwInitFlag = dwInitFlags[j];
  3976. ctInfo.dwThreadId = GetCurrentThreadId();
  3977. ctInfo.hr = S_OK;
  3978. RunThread(&ctInfo, ctInfo.hEvent, CrossThreadActivate);
  3979. CloseHandle(ctInfo.hEvent);
  3980. // create an interface
  3981. hres = CoCreateInstance(CLSID_LoopSrv, NULL, CLSCTX_LOCAL_SERVER,
  3982. IID_ILoop, (void **)&pLocalLoop);
  3983. TEST_FAILED(FAILED(hres), "CoCreateInstance Second failed\n")
  3984. if (SUCCEEDED(hres))
  3985. {
  3986. pLocalLoop->Release();
  3987. }
  3988. }
  3989. // ----------------------------------------------------------------------
  3990. // Now test doing nested calls between apartments.
  3991. #if 0
  3992. for (j=0; j<2; j++)
  3993. {
  3994. // reset the stream seek ptr
  3995. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  3996. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  3997. pUnk = GetTestUnk();
  3998. TEST_FAILED_EXIT((pUnk == NULL), "new GetTestUnk failed\n")
  3999. VerifyObjRefCnt(pUnk, 1);
  4000. // Marshal the interface into the stream
  4001. hres = CoMarshalInterface(pStm, IID_ILoop, pUnk,
  4002. 0, 0, MSHLFLAGS_NORMAL);
  4003. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  4004. OUTPUT (" - CoMarshalInterface OK.\n");
  4005. VerifyRHRefCnt(pUnk, 1);
  4006. // reset the stream seek ptr
  4007. hres = pStm->Seek(large_int, STREAM_SEEK_SET, NULL);
  4008. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  4009. ctInfo.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  4010. ctInfo.pStm = pStm;
  4011. ctInfo.dwInitFlag = dwInitFlags[j];
  4012. ctInfo.dwThreadId = GetCurrentThreadId();
  4013. ctInfo.hr = S_OK;
  4014. RunThread(&ctInfo, ctInfo.hEvent, CrossThreadLoops);
  4015. CloseHandle(ctInfo.hEvent);
  4016. pUnk->Release();
  4017. }
  4018. #endif
  4019. // ----------------------------------------------------------------------
  4020. Cleanup:
  4021. OUTPUT (" - Test Complete. Doing Cleanup\n");
  4022. // Dump interfaces we are done with
  4023. if (pStm)
  4024. {
  4025. ulRefCnt = pStm->Release();
  4026. TEST_FAILED(ulRefCnt != 0, "Stream RefCnt not zero\n");
  4027. }
  4028. for (i=0; i<3; i++)
  4029. {
  4030. if (punk[i] != NULL)
  4031. {
  4032. ulRefCnt = punk[i]->Release();
  4033. TEST_FAILED(ulRefCnt != 0, "punk[i] RefCnt not zero\n");
  4034. }
  4035. }
  4036. return TestResult(RetVal, "TestCrossThread");
  4037. }
  4038. // ----------------------------------------------------------------------
  4039. //
  4040. // Thread SubRoutine for testing CROSSTHREAD calls.
  4041. //
  4042. // ----------------------------------------------------------------------
  4043. DWORD _stdcall CrossThreadCalls(void *param)
  4044. {
  4045. BOOL RetVal = TRUE;
  4046. ICube *pCube = NULL;
  4047. IOleWindow *pIOW = NULL;
  4048. IAdviseSink *pIAS = NULL;
  4049. ULONG i = 0;
  4050. // get the execution parameters
  4051. CrossThreadCallInfo *ctInfo = (CrossThreadCallInfo *) param;
  4052. OUTPUT (" - CrossThreadCalls Start\n");
  4053. // initialize COM
  4054. HRESULT hRes = CoInitializeEx(NULL, ctInfo->dwInitFlag);
  4055. TEST_FAILED(FAILED(hRes), "CrossThreadCalls CoInitializeEx failed\n")
  4056. if (SUCCEEDED(hRes))
  4057. {
  4058. // unmarshal the interfaces
  4059. for (i=0; i<3; i++)
  4060. {
  4061. hRes = CoUnmarshalInterface(ctInfo->pStm, IID_ICube, (void **)&pCube);
  4062. TEST_FAILED(FAILED(hRes), "CrossThread CoUnmarshalInterface failed\n")
  4063. OUTPUT(" - CrossThread CoUnmarshalInterface done\n");
  4064. if (SUCCEEDED(hRes))
  4065. {
  4066. // test a synchronous method call between apartments
  4067. // (also checks the lid & tid)
  4068. UUID lidCaller;
  4069. CoGetCurrentLogicalThreadId(&lidCaller);
  4070. hRes = pCube->SimpleCall(GetCurrentProcessId(),
  4071. GetCurrentThreadId(),
  4072. lidCaller);
  4073. TEST_FAILED(FAILED(hRes), "pCube->SimpleCall failed\n")
  4074. OUTPUT(" - Synchronous call done\n");
  4075. // test an input-sync method call between apartments
  4076. hRes = pCube->QueryInterface(IID_IOleWindow, (void **)&pIOW);
  4077. if (SUCCEEDED(hRes))
  4078. {
  4079. HWND hWnd;
  4080. hRes = pIOW->GetWindow(&hWnd);
  4081. // input sync is only allowed between two apartment
  4082. // threaded apartments.
  4083. if (ctInfo->dwInitFlag == gInitFlag)
  4084. {
  4085. TEST_FAILED(FAILED(hRes), "pIOW->GetWindow failed\n");
  4086. }
  4087. else
  4088. {
  4089. TEST_FAILED(SUCCEEDED(hRes), "pIOW->GetWindow should have failed\n");
  4090. }
  4091. pIOW->Release();
  4092. OUTPUT(" - Input-Synchronous call done\n");
  4093. }
  4094. // test an async method call between apartments
  4095. hRes = pCube->QueryInterface(IID_IAdviseSink, (void **)&pIAS);
  4096. if (SUCCEEDED(hRes))
  4097. {
  4098. // no return code to check
  4099. pIAS->OnViewChange(1,2);
  4100. pIAS->Release();
  4101. OUTPUT(" - ASynchronous call done\n");
  4102. }
  4103. // release the object
  4104. pCube->Release();
  4105. pCube = NULL;
  4106. OUTPUT(" - CrossThread Calls and Release done\n");
  4107. }
  4108. }
  4109. // uninit OLE
  4110. CoUninitialize();
  4111. }
  4112. OUTPUT (" - CrossThreadCalls Exit\n");
  4113. ctInfo->hr = hRes;
  4114. // signal the other thread we are done.
  4115. if (gInitFlag == COINIT_APARTMENTTHREADED)
  4116. {
  4117. PostThreadMessage(ctInfo->dwThreadId, WM_QUIT, 0, 0);
  4118. }
  4119. else
  4120. {
  4121. SetEvent(ctInfo->hEvent);
  4122. }
  4123. return hRes;
  4124. }
  4125. // ----------------------------------------------------------------------
  4126. //
  4127. // Thread SubRoutine for testing CROSSTHREAD activation
  4128. //
  4129. // ----------------------------------------------------------------------
  4130. DWORD _stdcall CrossThreadActivate(void *param)
  4131. {
  4132. BOOL RetVal = TRUE;
  4133. ILoop *pLocalLoop = NULL;
  4134. // get the execution parameters
  4135. CrossThreadCallInfo *ctInfo = (CrossThreadCallInfo *) param;
  4136. OUTPUT (" - CrossThreadActivate Start\n");
  4137. // initialize COM
  4138. HRESULT hRes = CoInitializeEx(NULL, ctInfo->dwInitFlag);
  4139. TEST_FAILED(FAILED(hRes), "CrossThreadActivate CoInitializeEx failed\n")
  4140. if (SUCCEEDED(hRes))
  4141. {
  4142. // create an interface
  4143. hRes = CoCreateInstance(CLSID_LoopSrv, NULL, CLSCTX_LOCAL_SERVER,
  4144. IID_ILoop, (void **)&pLocalLoop);
  4145. TEST_FAILED(FAILED(hRes), "CoCreateInstance First failed\n")
  4146. if (SUCCEEDED(hRes))
  4147. {
  4148. pLocalLoop->Release();
  4149. }
  4150. // uninit OLE
  4151. CoUninitialize();
  4152. }
  4153. OUTPUT (" - CrossThreadActivate Exit\n");
  4154. ctInfo->hr = hRes;
  4155. // signal the other thread we are done.
  4156. if (gInitFlag == COINIT_APARTMENTTHREADED)
  4157. {
  4158. PostThreadMessage(ctInfo->dwThreadId, WM_QUIT, 0, 0);
  4159. }
  4160. else
  4161. {
  4162. SetEvent(ctInfo->hEvent);
  4163. }
  4164. return hRes;
  4165. }
  4166. #if 0
  4167. // ----------------------------------------------------------------------
  4168. //
  4169. // Thread SubRoutine for testing CROSSTHREAD calls.
  4170. //
  4171. // ----------------------------------------------------------------------
  4172. DWORD _stdcall CrossThreadLoops(void *param)
  4173. {
  4174. BOOL RetVal = TRUE;
  4175. ILoop *pLoop = NULL;
  4176. IUnknown *punk = NULL;
  4177. ILoop *pLoopLocal = NULL;
  4178. // get the execution parameters
  4179. CrossThreadCallInfo *ctInfo = (CrossThreadCallInfo *) param;
  4180. OUTPUT (" - CrossThreadLoops Start\n");
  4181. // initialize COM
  4182. HRESULT hRes = CoInitializeEx(NULL, ctInfo->dwInitFlag);
  4183. TEST_FAILED(FAILED(hRes), "CrossThreadLoops CoInitializeEx failed\n")
  4184. if (SUCCEEDED(hRes))
  4185. {
  4186. punk = GetTestUnk();
  4187. punk->QueryInterface(IID_ILoop, (void **)&pLoopLocal);
  4188. punk->Release();
  4189. // unmarshal the interface
  4190. hRes = CoUnmarshalInterface(ctInfo->pStm, IID_ILoop, (void **)&pLoop);
  4191. TEST_FAILED(FAILED(hRes), "CrossThreadLoop CoUnmarshalInterface failed\n")
  4192. OUTPUT(" - CrossThreadLoop CoUnmarshalInterface done\n");
  4193. if (SUCCEEDED(hRes))
  4194. {
  4195. // test nested synchronous method calls between apartments
  4196. hRes = pLoop->Init(pLoopLocal);
  4197. TEST_FAILED(FAILED(hRes), "pLoop->Init failed\n")
  4198. if (SUCCEEDED(hRes))
  4199. {
  4200. hRes = pLoop->Loop(5);
  4201. TEST_FAILED(FAILED(hRes), "pLoop->Loop failed\n")
  4202. hRes = pLoop->Uninit();
  4203. TEST_FAILED(FAILED(hRes), "pLoop->Uninit failed\n")
  4204. }
  4205. pLoop->Release();
  4206. pLoop = NULL;
  4207. OUTPUT(" - CrossThreadLoop Calls and Release done\n");
  4208. }
  4209. // uninit OLE
  4210. CoUninitialize();
  4211. }
  4212. OUTPUT (" - CrossThreadLoops Exit\n");
  4213. ctInfo->hr = hRes;
  4214. // signal the other thread we are done.
  4215. if (gInitFlag == COINIT_APARTMENTTHREADED)
  4216. {
  4217. PostThreadMessage(ctInfo->dwThreadId, WM_QUIT, 0, 0);
  4218. }
  4219. else
  4220. {
  4221. SetEvent(ctInfo->hEvent);
  4222. }
  4223. return hRes;
  4224. }
  4225. #endif
  4226. // ----------------------------------------------------------------------
  4227. //
  4228. // Test calling CoGetPSClsid and CoRegisterPSClsid
  4229. //
  4230. // ----------------------------------------------------------------------
  4231. BOOL TestPSClsid(void)
  4232. {
  4233. BOOL RetVal = TRUE;
  4234. HRESULT hRes;
  4235. CLSID clsidOriginal, clsidNew;
  4236. OUTPUT ("Starting TestPSClsid\n");
  4237. // ----------------------------------------------------------------------
  4238. // get the PSClsid that is currently registered for this interface.
  4239. hRes = CoGetPSClsid(IID_IViewObject, &clsidOriginal);
  4240. TEST_FAILED(FAILED(hRes), "Failed 1st CoGetPSClsid\n");
  4241. OUTPUT (" - Done 1st CoGetPSClsid\n");
  4242. // Set a new PSClsid for this interface for this process. Note that
  4243. // if we have used the interface before, we will get an error back,
  4244. // otherwise, this will succeed.
  4245. hRes = CoRegisterPSClsid(IID_IViewObject, CLSID_Balls);
  4246. TEST_FAILED(FAILED(hRes), "Failed 1st CoGRegisterPSClsid\n");
  4247. OUTPUT (" - Done 1st CoRegisterPSClsid\n");
  4248. // now get the PSClsid that is registered for this interface. This
  4249. // should match the value we just passed in.
  4250. hRes = CoGetPSClsid(IID_IViewObject, &clsidNew);
  4251. TEST_FAILED(FAILED(hRes), "Failed 2nd CoGetPSClsid\n");
  4252. OUTPUT (" - Done 2nd CoGetPSClsid\n");
  4253. if (memcmp(&clsidNew, &CLSID_Balls, sizeof(CLSID)))
  4254. {
  4255. TEST_FAILED(TRUE, "Failed Compare of CLSIDs\n");
  4256. }
  4257. // now try to register it again. This should fail since it has
  4258. // already been registered.
  4259. hRes = CoRegisterPSClsid(IID_IViewObject, clsidOriginal);
  4260. TEST_FAILED(FAILED(hRes), "Failed 2nd CoGRegisterPSClsid\n");
  4261. OUTPUT (" - Done 2nd CoRegisterPSClsid\n");
  4262. // now get the PSClsid that is registered for this interface. This
  4263. // should match the value we just passed in.
  4264. hRes = CoGetPSClsid(IID_IViewObject, &clsidNew);
  4265. TEST_FAILED(FAILED(hRes), "Failed 3rd CoGetPSClsid\n");
  4266. OUTPUT (" - Done 3rd CoGetPSClsid\n");
  4267. if (memcmp(&clsidNew, &clsidOriginal, sizeof(CLSID)))
  4268. {
  4269. TEST_FAILED(TRUE, "Failed 2nd Compare of CLSIDs\n");
  4270. }
  4271. // ----------------------------------------------------------------------
  4272. OUTPUT (" - Test Complete. Doing Cleanup\n");
  4273. return TestResult(RetVal, "TestPSClsid");
  4274. }
  4275. // ----------------------------------------------------------------------
  4276. //
  4277. // Test calling CoGetPSClsid for a LONG IID/PSCLSID pair.
  4278. //
  4279. // ----------------------------------------------------------------------
  4280. BOOL TestPSClsid2(void)
  4281. {
  4282. BOOL RetVal = TRUE;
  4283. HRESULT hRes = S_OK;
  4284. CLSID clsidOriginal;
  4285. OUTPUT ("Starting TestPSClsid2\n");
  4286. // ----------------------------------------------------------------------
  4287. // get the PSClsid that is currently registered for this interface.
  4288. hRes = CoGetPSClsid(IID_IViewObject, &clsidOriginal);
  4289. TEST_FAILED(FAILED(hRes), "Failed 1st CoGetPSClsid\n");
  4290. OUTPUT (" - Done 1st CoGetPSClsid\n");
  4291. if (!IsEqualGUID(clsidOriginal, CLSID_OLEPSFACTORY))
  4292. {
  4293. TEST_FAILED(FAILED(hRes), "CoGetPSClsid returned wrong value\n");
  4294. }
  4295. // ----------------------------------------------------------------------
  4296. OUTPUT (" - Test Complete. Doing Cleanup\n");
  4297. return TestResult(RetVal, "TestPSClsid2");
  4298. }
  4299. // ----------------------------------------------------------------------
  4300. //
  4301. // TestGetIIDFromMI
  4302. //
  4303. // ----------------------------------------------------------------------
  4304. BOOL TestGetIIDFromMI(void)
  4305. {
  4306. BOOL RetVal = TRUE;
  4307. HRESULT hres;
  4308. IUnknown *punkIn = NULL;
  4309. IID iid;
  4310. OUTPUT ("Starting TestGetIIDFromMI\n");
  4311. // ----------------------------------------------------------------------
  4312. ULARGE_INTEGER ulSeekEnd;
  4313. LARGE_INTEGER lSeekStart;
  4314. LISet32(lSeekStart, 0);
  4315. IStream *pStm = CreateMemStm(600, NULL);
  4316. TEST_FAILED_EXIT((pStm == NULL), "CreateMemStm failed\n")
  4317. VerifyObjRefCnt((IUnknown *)pStm, 1);
  4318. punkIn = GetTestUnk();
  4319. hres = CoMarshalInterface(pStm, IID_IUnknown, punkIn, 0, NULL, MSHLFLAGS_NORMAL);
  4320. TEST_FAILED_EXIT(FAILED(hres), "CoMarshalInterface failed\n")
  4321. OUTPUT (" - CoMarshalInterface OK\n");
  4322. // go back to begining
  4323. hres = pStm->Seek(lSeekStart, STREAM_SEEK_SET, NULL);
  4324. TEST_FAILED_EXIT(FAILED(hres), "Seek on shared stream failed\n")
  4325. OUTPUT (" - Seek Start OK\n");
  4326. #if 0 // BUGBUG: RICKHI
  4327. // get the IID from the stream, and ensure it matches the IID we
  4328. // marshaled. Also, ensure the stream is left where it was. This
  4329. // is accomplished by calling CRMD on the stream.
  4330. hres = CoGetIIDFromMarshaledInterface(pStm, &iid);
  4331. TEST_FAILED(FAILED(hres), "CoGetIIDFromMarshaledInterface failed\n")
  4332. OUTPUT (" - CoGetIIDFromMarshaledInterface Done\n");
  4333. if (!IsEqualIID(IID_IUnknown, iid))
  4334. {
  4335. TEST_FAILED(TRUE, "IID read does not match IID marshaled\n")
  4336. }
  4337. #endif
  4338. // release the marshaled interface
  4339. hres = CoReleaseMarshalData(pStm);
  4340. TEST_FAILED(FAILED(hres), "CoReleaseMarshalData failed\n")
  4341. OUTPUT (" - CoReleaseMarshalData Done\n");
  4342. // ----------------------------------------------------------------------
  4343. Cleanup:
  4344. if (punkIn)
  4345. {
  4346. punkIn->Release();
  4347. punkIn = NULL;
  4348. }
  4349. OUTPUT (" - Test Complete. Doing Cleanup\n");
  4350. return TestResult(RetVal, "TestGetIIDFromMI");
  4351. }
  4352.