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.

547 lines
9.2 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // File: cact.cxx
  4. //
  5. // Contents: object activation test class
  6. //
  7. // Classes: CActTest
  8. //
  9. // Functions:
  10. //
  11. // History: 23-Nov-92 Ricksa Created
  12. //
  13. //--------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. #include <cact.hxx> // CTestAct
  17. // We need a semaphore to synchronize loads and releases.
  18. CMutexSem mxsLoadRelease;
  19. SAFE_INTERFACE_PTR(XIStream, IStream)
  20. #define XPOS OLESTR("XPOS")
  21. #define YPOS OLESTR("YPOS")
  22. HRESULT ReadPos(IStorage *pstg, LPOLESTR pwszStream, ULONG *pulPos)
  23. {
  24. HRESULT hr;
  25. BEGIN_BLOCK
  26. XIStream xstrm;
  27. // Read the streams for xpos and ypos
  28. hr = pstg->OpenStream(pwszStream, NULL,
  29. STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, &xstrm);
  30. if (FAILED(hr))
  31. {
  32. EXIT_BLOCK;
  33. }
  34. ULONG cb;
  35. hr = xstrm->Read(pulPos, sizeof(*pulPos), &cb);
  36. if (FAILED(hr))
  37. {
  38. EXIT_BLOCK;
  39. }
  40. hr = ResultFromScode(S_OK);
  41. END_BLOCK
  42. return hr;
  43. }
  44. HRESULT WritePos(IStorage *pstg, LPOLESTR pwszStream, ULONG ulPos)
  45. {
  46. HRESULT hr;
  47. BEGIN_BLOCK
  48. XIStream xstrm;
  49. // Read the streams for xpos and ypos
  50. hr = pstg->CreateStream(pwszStream,
  51. STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, NULL, NULL,
  52. &xstrm);
  53. if (FAILED(hr))
  54. {
  55. EXIT_BLOCK;
  56. }
  57. ULONG cb;
  58. hr = xstrm->Write(&ulPos, sizeof(ulPos), &cb);
  59. if (FAILED(hr))
  60. {
  61. EXIT_BLOCK;
  62. }
  63. hr = ResultFromScode(S_OK);
  64. END_BLOCK
  65. return hr;
  66. }
  67. CTestAct::CTestAct(REFCLSID rclsid)
  68. : _rclsid(rclsid), _fDirty(FALSE), _xPos(0), _yPos(0),
  69. _fSaveInprogress(FALSE), _pstg(NULL), _dwRegister(0), _cRefs(1)
  70. {
  71. // Use as a flag for whether a file name has been assigned
  72. _awszCurFile[0] = 0;
  73. GlobalRefs(TRUE);
  74. }
  75. CTestAct::~CTestAct(void)
  76. {
  77. if (_pstg != NULL)
  78. {
  79. // Release the storage because we are done with it
  80. ULONG ulCnt = _pstg->Release();
  81. #if 0
  82. // this test is not valid when running stress
  83. if (ulCnt != 0)
  84. {
  85. DebugBreak();
  86. }
  87. #endif
  88. }
  89. if (_dwRegister)
  90. {
  91. IRunningObjectTable *prot;
  92. GetRunningObjectTable(NULL, &prot);
  93. prot->Revoke(_dwRegister);
  94. prot->Release();
  95. }
  96. GlobalRefs(FALSE);
  97. }
  98. STDMETHODIMP CTestAct::QueryInterface(REFIID iid, void **ppv)
  99. {
  100. HRESULT hr = ResultFromScode(S_OK);
  101. // We support IUnknown, IPersistFile and IBalls
  102. if (IsEqualIID(iid, IID_IUnknown))
  103. {
  104. *ppv = (IBalls *) this;
  105. }
  106. else if (IsEqualIID(iid, IID_IPersistFile))
  107. {
  108. *ppv = (IPersistFile *) this;
  109. }
  110. else if (IsEqualIID(iid, IID_IPersistStorage))
  111. {
  112. *ppv = (IPersistStorage *) this;
  113. }
  114. else if (IsEqualIID(iid, IID_IBalls))
  115. {
  116. *ppv = (IBalls *) this;
  117. }
  118. else
  119. {
  120. *ppv = NULL;
  121. hr = ResultFromScode(E_NOINTERFACE);
  122. }
  123. if (SUCCEEDED(hr))
  124. {
  125. AddRef();
  126. }
  127. return hr;
  128. }
  129. STDMETHODIMP_(ULONG) CTestAct::AddRef(void)
  130. {
  131. InterlockedIncrement(&_cRefs);
  132. return _cRefs;
  133. }
  134. STDMETHODIMP_(ULONG) CTestAct::Release(void)
  135. {
  136. CLock lck(mxsLoadRelease);
  137. if (InterlockedDecrement(&_cRefs) == 0)
  138. {
  139. delete this;
  140. return 0;
  141. }
  142. return _cRefs;
  143. }
  144. STDMETHODIMP CTestAct::GetClassID(LPCLSID lpClassID)
  145. {
  146. *lpClassID = _rclsid;
  147. return ResultFromScode(S_OK);
  148. }
  149. STDMETHODIMP CTestAct::IsDirty()
  150. {
  151. return (_fDirty) ? ResultFromScode(S_OK) : ResultFromScode(S_FALSE);
  152. }
  153. STDMETHODIMP CTestAct::Load(LPCOLESTR lpszFileName, DWORD grfMode)
  154. {
  155. CLock lck(mxsLoadRelease);
  156. HRESULT hr;
  157. BEGIN_BLOCK
  158. hr = StgOpenStorage(lpszFileName, NULL,
  159. STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, NULL, &_pstg);
  160. if (FAILED(hr))
  161. {
  162. #if 0
  163. // this test is not valid when running stress
  164. if (hr == STG_E_LOCKVIOLATION)
  165. {
  166. DebugBreak();
  167. }
  168. #endif
  169. EXIT_BLOCK;
  170. }
  171. // Get the saved xposition
  172. hr = GetData();
  173. if (FAILED(hr))
  174. {
  175. EXIT_BLOCK;
  176. }
  177. // Since everything went Ok save the file name
  178. olestrcpy(_awszCurFile, lpszFileName);
  179. // Create a file moniker for the object.
  180. // Cast to non-constant string.
  181. IMoniker *pmk;
  182. CreateFileMoniker((LPOLESTR)lpszFileName, &pmk);
  183. // Register it in the running object table.
  184. IRunningObjectTable *prot;
  185. GetRunningObjectTable(NULL, &prot);
  186. prot->Register(NULL, (IPersistFile *) this, pmk, &_dwRegister);
  187. // Release the temporary objects
  188. pmk->Release();
  189. prot->Release();
  190. END_BLOCK
  191. return hr;
  192. }
  193. STDMETHODIMP CTestAct::Save(LPCOLESTR lpszFileName, BOOL fRemember)
  194. {
  195. HRESULT hr;
  196. BEGIN_BLOCK
  197. IStorage *pstgNew;
  198. // Save the data
  199. if (olestrcmp(lpszFileName, _awszCurFile) == 0)
  200. {
  201. pstgNew = _pstg;
  202. _fDirty = FALSE;
  203. }
  204. else
  205. {
  206. hr = StgCreateDocfile(lpszFileName,
  207. STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
  208. NULL, &pstgNew);
  209. }
  210. if (FAILED(hr))
  211. {
  212. EXIT_BLOCK;
  213. }
  214. WriteClassStg(pstgNew, _rclsid);
  215. hr = SaveData(pstgNew);
  216. if (FAILED(hr))
  217. {
  218. EXIT_BLOCK;
  219. }
  220. if (fRemember)
  221. {
  222. // Save the file name
  223. olestrcpy(_awszCurFile, lpszFileName);
  224. // Replace the storage
  225. if (_pstg && pstgNew != _pstg)
  226. {
  227. _pstg->Release();
  228. }
  229. _pstg = pstgNew;
  230. _fDirty = FALSE;
  231. }
  232. else
  233. {
  234. pstgNew->Release();
  235. }
  236. _fSaveInprogress = TRUE;
  237. hr = ResultFromScode(S_OK);
  238. END_BLOCK;
  239. return hr;
  240. }
  241. STDMETHODIMP CTestAct::SaveCompleted(LPCOLESTR lpszFileName)
  242. {
  243. _fSaveInprogress = FALSE;
  244. return ResultFromScode(S_OK);
  245. }
  246. STDMETHODIMP CTestAct::GetCurFile(LPOLESTR FAR *lpszFileName)
  247. {
  248. // Allocate a buffer for the file and copy in the data
  249. if (_awszCurFile[0] == 0)
  250. {
  251. return ResultFromScode(S_FALSE);
  252. }
  253. IMalloc *pIMalloc;
  254. HRESULT hr = CoGetMalloc(MEMCTX_TASK, &pIMalloc);
  255. if (SUCCEEDED(hr))
  256. {
  257. *lpszFileName = (OLECHAR *) pIMalloc->Alloc(
  258. olestrlen((_awszCurFile) + 1) * sizeof(OLECHAR));
  259. olestrcpy(*lpszFileName, _awszCurFile);
  260. hr = ResultFromScode(S_OK);
  261. }
  262. return hr;
  263. }
  264. STDMETHODIMP CTestAct::MoveBall(ULONG xPos, ULONG yPos)
  265. {
  266. if (!_fSaveInprogress)
  267. {
  268. _fDirty = TRUE;
  269. _xPos = xPos;
  270. _yPos = yPos;
  271. return S_OK;
  272. }
  273. // Can't change state because a save is still pending
  274. return ResultFromScode(E_UNEXPECTED);
  275. }
  276. STDMETHODIMP CTestAct::GetBallPos(ULONG *xPos, ULONG *yPos)
  277. {
  278. *xPos = _xPos;
  279. *yPos = _yPos;
  280. return S_OK;
  281. }
  282. STDMETHODIMP CTestAct::IsOverLapped(IBalls *pIBall)
  283. {
  284. ULONG xPos;
  285. ULONG yPos;
  286. HRESULT hr = pIBall->GetBallPos(&xPos, &yPos);
  287. if (SUCCEEDED(hr))
  288. {
  289. if ((xPos == _xPos) && (yPos == _yPos))
  290. {
  291. hr = ResultFromScode(S_OK);
  292. }
  293. else
  294. {
  295. hr = ResultFromScode(S_FALSE);
  296. }
  297. }
  298. return hr;
  299. }
  300. STDMETHODIMP CTestAct::IsContainedIn(ICube *pICube)
  301. {
  302. ULONG xPos;
  303. ULONG yPos;
  304. HRESULT hr = pICube->GetCubePos(&xPos, &yPos);
  305. if (SUCCEEDED(hr))
  306. {
  307. if ((xPos == _xPos) && (yPos == _yPos))
  308. {
  309. hr = ResultFromScode(S_OK);
  310. }
  311. else
  312. {
  313. hr = ResultFromScode(S_FALSE);
  314. }
  315. }
  316. return hr;
  317. }
  318. STDMETHODIMP CTestAct::Clone(IBalls **ppIBall)
  319. {
  320. CTestAct *ptballs = new CTestAct(_rclsid);
  321. ptballs->_xPos = _xPos;
  322. ptballs->_yPos = _yPos;
  323. ptballs->_fDirty = _fDirty;
  324. _pstg->AddRef();
  325. ptballs->_pstg = _pstg;
  326. olestrcpy(ptballs->_awszCurFile, _awszCurFile);
  327. return ResultFromScode(S_OK);
  328. }
  329. STDMETHODIMP CTestAct::Echo(IUnknown *punkIn, IUnknown**ppunkOut)
  330. {
  331. *ppunkOut = punkIn;
  332. return S_OK;
  333. }
  334. STDMETHODIMP CTestAct::InitNew(LPSTORAGE pStg)
  335. {
  336. pStg->AddRef();
  337. _pstg = pStg;
  338. WriteClassStg(_pstg, _rclsid);
  339. return ResultFromScode(S_OK);
  340. }
  341. STDMETHODIMP CTestAct::Load(LPSTORAGE pStg)
  342. {
  343. HRESULT hr;
  344. _pstg = pStg;
  345. hr = GetData();
  346. if (SUCCEEDED(hr))
  347. {
  348. _pstg->AddRef();
  349. }
  350. else
  351. {
  352. _pstg = NULL;
  353. }
  354. return hr;
  355. }
  356. STDMETHODIMP CTestAct::Save(
  357. LPSTORAGE pStgSave,
  358. BOOL fSameAsLoad)
  359. {
  360. HRESULT hr;
  361. if (!fSameAsLoad)
  362. {
  363. if (_pstg)
  364. _pstg->Release();
  365. _pstg = pStgSave;
  366. pStgSave->AddRef();
  367. }
  368. else
  369. {
  370. pStgSave = _pstg;
  371. }
  372. WriteClassStg(pStgSave, _rclsid);
  373. hr = SaveData(pStgSave);
  374. _fSaveInprogress = TRUE;
  375. return hr;
  376. }
  377. STDMETHODIMP CTestAct::SaveCompleted(LPSTORAGE pStgSaved)
  378. {
  379. _fSaveInprogress = FALSE;
  380. return ResultFromScode(S_OK);
  381. }
  382. STDMETHODIMP CTestAct::HandsOffStorage(void)
  383. {
  384. // Figure out what to do here!
  385. return ResultFromScode(E_UNEXPECTED);
  386. }
  387. HRESULT CTestAct::GetData(void)
  388. {
  389. HRESULT hr;
  390. BEGIN_BLOCK
  391. // Get the saved xposition
  392. hr = ReadPos(_pstg, XPOS, &_xPos);
  393. if (FAILED(hr))
  394. {
  395. EXIT_BLOCK;
  396. }
  397. // Get the saved yposition
  398. hr = ReadPos(_pstg, YPOS, &_yPos);
  399. END_BLOCK
  400. return hr;
  401. }
  402. HRESULT CTestAct::SaveData(IStorage *pstg)
  403. {
  404. HRESULT hr;
  405. BEGIN_BLOCK
  406. // Get the saved xposition
  407. hr = WritePos(pstg, XPOS, _xPos);
  408. if (FAILED(hr))
  409. {
  410. EXIT_BLOCK;
  411. }
  412. // Get the saved yposition
  413. hr = WritePos(pstg, YPOS, _yPos);
  414. END_BLOCK
  415. return hr;
  416. }