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

3217 lines
92 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: expdf.cxx
  7. //
  8. // Contents: Exposed DocFile implementation
  9. //
  10. // History: 20-Jan-92 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <exphead.cxx>
  14. #pragma hdrstop
  15. #include <expdf.hxx>
  16. #include <expst.hxx>
  17. #include <expiter.hxx>
  18. #include <pbstream.hxx>
  19. #include <lock.hxx>
  20. #include <marshl.hxx>
  21. #include <logfile.hxx>
  22. #include <rpubdf.hxx>
  23. #include <expparam.hxx>
  24. #include <olepfn.hxx>
  25. #include <ole2sp.h>
  26. #include <ole2com.h>
  27. #if WIN32 == 300
  28. IMPLEMENT_UNWIND(CSafeAccess);
  29. IMPLEMENT_UNWIND(CSafeSem);
  30. #endif
  31. extern WCHAR const wcsContents[];
  32. //+--------------------------------------------------------------
  33. //
  34. // Member: CExposedDocFile::CExposedDocFile, public
  35. //
  36. // Synopsis: Constructor
  37. //
  38. // Arguments: [pdf] - Public DocFile
  39. // [pdfb] - DocFile basis
  40. // [ppc] - Context
  41. //
  42. // History: 20-Jan-92 DrewB Created
  43. //
  44. //---------------------------------------------------------------
  45. CExposedDocFile::CExposedDocFile(CPubDocFile *pdf,
  46. CDFBasis *pdfb,
  47. CPerContext *ppc)
  48. : CPropertySetStorage(MAPPED_STREAM_QI),
  49. _PropertyBagEx( DFlagsToMode( pdf->GetDFlags() ))
  50. {
  51. olDebugOut((DEB_ITRACE, "In CExposedDocFile::CExposedDocFile("
  52. "%p, %p, %p)\n", pdf, pdfb, ppc));
  53. _ppc = ppc;
  54. _pdf = P_TO_BP(CBasedPubDocFilePtr, pdf);
  55. _pdfb = P_TO_BP(CBasedDFBasisPtr, pdfb);
  56. _pdfb->vAddRef();
  57. _cReferences = 1;
  58. _sig = CEXPOSEDDOCFILE_SIG;
  59. #if WIN32 >= 300
  60. _pIAC = NULL;
  61. #endif
  62. // Initialize CPropertySetStorage and CPropertyBagEx
  63. CPropertySetStorage::Init( static_cast<IStorage*>(this), static_cast<IBlockingLock*>(this),
  64. FALSE ); // fControlLifetimes (=> Don't addref)
  65. _PropertyBagEx.Init( static_cast<IPropertySetStorage*>(this), // Not addref-ed
  66. static_cast<IBlockingLock*>(this) ); // Not addref-ed
  67. //
  68. // CoQueryReleaseObject needs to have the address of the exposed docfiles
  69. // query interface routine.
  70. //
  71. if (adwQueryInterfaceTable[QI_TABLE_CExposedDocFile] == 0)
  72. {
  73. adwQueryInterfaceTable[QI_TABLE_CExposedDocFile] =
  74. **(DWORD **)((IStorage *)this);
  75. }
  76. #ifdef COORD
  77. _ulLock = _cbSizeBase = _cbSizeOrig = 0;
  78. _sigMSF = 0;
  79. #endif
  80. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::CExposedDocFile\n"));
  81. }
  82. SCODE CExposedDocFile::InitMarshal(DWORD dwAsyncFlags,
  83. IDocfileAsyncConnectionPoint *pdacp)
  84. {
  85. return _cpoint.InitMarshal(this, dwAsyncFlags, pdacp);
  86. }
  87. //+--------------------------------------------------------------
  88. //
  89. // Member: CExposedDocFile::~CExposedDocFile, public
  90. //
  91. // Synopsis: Destructor
  92. //
  93. // History: 23-Jan-92 DrewB Created
  94. //
  95. //---------------------------------------------------------------
  96. CExposedDocFile::~CExposedDocFile(void)
  97. {
  98. BOOL fClose = FALSE;
  99. olDebugOut((DEB_ITRACE, "In CExposedDocFile::~CExposedDocFile\n"));
  100. olAssert(_cReferences == 0);
  101. //In order to call into the tree, we need to take the mutex.
  102. //The mutex may get deleted in _ppc->Release(), so we can't
  103. //release it here. The mutex actually gets released in
  104. //CPerContext::Release() or in the CPerContext destructor.
  105. //If _ppc is NULL, we're partially constructed and don't need to
  106. //worry.
  107. SCODE sc;
  108. #if WIN32 >= 300
  109. if (_pIAC != NULL)
  110. {
  111. _pIAC->Release();
  112. _pIAC = NULL;
  113. }
  114. #endif
  115. #if !defined(MULTIHEAP)
  116. // TakeSem and ReleaseSem are moved to the Release Method
  117. // so that the deallocation for this object is protected
  118. if (_ppc)
  119. {
  120. sc = TakeSem();
  121. SetWriteAccess();
  122. olAssert(SUCCEEDED(sc));
  123. }
  124. #ifdef ASYNC
  125. IDocfileAsyncConnectionPoint *pdacp = _cpoint.GetMarshalPoint();
  126. #endif
  127. #endif //MULTIHEAP
  128. if (_pdf)
  129. {
  130. // If we're the last reference on a root object
  131. // we close the context because all children will become
  132. // reverted so it is no longer necessary
  133. if (_pdf->GetRefCount() == 1 && _pdf->IsRoot())
  134. fClose = TRUE;
  135. _pdf->CPubDocFile::vRelease();
  136. }
  137. if (_pdfb)
  138. _pdfb->CDFBasis::vRelease();
  139. #if !defined(MULTIHEAP)
  140. if (_ppc)
  141. {
  142. if (fClose)
  143. _ppc->Close();
  144. if (_ppc->Release() > 0)
  145. ReleaseSem(sc);
  146. }
  147. #ifdef ASYNC
  148. //Mutex has been released, so we can release the connection point
  149. // without fear of deadlock.
  150. if (pdacp != NULL)
  151. pdacp->Release();
  152. #endif
  153. #endif // MULTIHEAP
  154. _sig = CEXPOSEDDOCFILE_SIGDEL;
  155. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::~CExposedDocFile\n"));
  156. }
  157. //+--------------------------------------------------------------
  158. //
  159. // Member: CExposedDocFile::Release, public
  160. //
  161. // Synopsis: Releases resources for a CExposedDocFile
  162. //
  163. // Returns: Appropriate status code
  164. //
  165. // History: 20-Jan-92 DrewB Created
  166. //
  167. //---------------------------------------------------------------
  168. STDMETHODIMP_(ULONG) CExposedDocFile::Release(void)
  169. {
  170. LONG lRet;
  171. olLog(("%p::In CExposedDocFile::Release()\n", this));
  172. olDebugOut((DEB_TRACE, "In CExposedDocFile::Release()\n"));
  173. if (FAILED(Validate()))
  174. return 0;
  175. olAssert(_cReferences > 0);
  176. lRet = InterlockedDecrement(&_cReferences);
  177. if (lRet == 0)
  178. {
  179. SCODE sc = S_OK;
  180. sc = _PropertyBagEx.Commit( STGC_DEFAULT );
  181. olAssert(SUCCEEDED(sc));
  182. sc = _PropertyBagEx.ShutDown();
  183. olAssert(SUCCEEDED(sc));
  184. #ifdef MULTIHEAP
  185. CSafeMultiHeap smh(_ppc);
  186. CPerContext *ppc = _ppc;
  187. if (_ppc)
  188. {
  189. sc = TakeSem();
  190. SetWriteAccess();
  191. olAssert(SUCCEEDED(sc));
  192. }
  193. #ifdef ASYNC
  194. IDocfileAsyncConnectionPoint *pdacp = _cpoint.GetMarshalPoint();
  195. #endif
  196. BOOL fClose = (_pdf) && (_pdf->GetRefCount()==1) && _pdf->IsRoot();
  197. #endif //MULTIHEAP
  198. delete this;
  199. #ifdef MULTIHEAP
  200. if (ppc)
  201. {
  202. if (fClose)
  203. ppc->Close();
  204. if (ppc->Release() == 0)
  205. g_smAllocator.Uninit();
  206. else
  207. if (SUCCEEDED(sc)) ppc->UntakeSem();
  208. }
  209. #ifdef ASYNC
  210. //Mutex has been released, so we can release the connection point
  211. // without fear of deadlock.
  212. if (pdacp != NULL)
  213. pdacp->Release();
  214. #endif
  215. #endif
  216. }
  217. else if (lRet < 0)
  218. lRet = 0;
  219. olDebugOut((DEB_TRACE, "Out CExposedDocFile::Release %p() => %lu\n",
  220. this, lRet));
  221. olLog(("%p::Out CExposedDocFile::Release(). ret == %lu\n", this, lRet));
  222. FreeLogFile();
  223. return (ULONG)lRet;
  224. }
  225. //+--------------------------------------------------------------
  226. //
  227. // Member: CExposedDocFile::CheckCopyTo, private
  228. //
  229. // Synopsis: Checks for CopyTo legality
  230. //
  231. // Returns: Appropriate status code
  232. //
  233. // History: 07-Jul-92 DrewB Created
  234. //
  235. //---------------------------------------------------------------
  236. inline SCODE CExposedDocFile::CheckCopyTo(void)
  237. {
  238. return _pdfb->GetCopyBase() != NULL &&
  239. _pdf->IsAtOrAbove(_pdfb->GetCopyBase()) ?
  240. STG_E_ACCESSDENIED : S_OK;
  241. }
  242. //+--------------------------------------------------------------
  243. //
  244. // Member: CExposedDocFile::ConvertInternalStream, private
  245. //
  246. // Synopsis: Converts an internal stream to a storage
  247. //
  248. // Arguments: [pwcsName] - Name
  249. // [pdfExp] - Destination docfile
  250. //
  251. // Returns: Appropriate status code
  252. //
  253. // History: 23-Jun-92 DrewB Created
  254. //
  255. //---------------------------------------------------------------
  256. static WCHAR const wcsIllegalName[] = {'\\', '\0'};
  257. SCODE CExposedDocFile::ConvertInternalStream(CExposedDocFile *pdfExp)
  258. {
  259. CPubStream *pstFrom, *pstTo;
  260. SCODE sc;
  261. CDfName const dfnIllegal(wcsIllegalName);
  262. CDfName const dfnContents(wcsContents);
  263. olDebugOut((DEB_ITRACE, "In CExposedDocFile::ConvertInternalStream(%p)\n",
  264. pdfExp));
  265. olChk(_pdf->GetStream(&dfnIllegal, DF_READWRITE | DF_DENYALL, &pstFrom));
  266. olChkTo(EH_pstFrom, pdfExp->GetPub()->CreateStream(&dfnContents,
  267. DF_WRITE | DF_DENYALL,
  268. &pstTo));
  269. olChkTo(EH_pstTo, CopySStreamToSStream(pstFrom->GetSt(),
  270. pstTo->GetSt()));
  271. olChkTo(EH_pstTo, _pdf->DestroyEntry(&dfnIllegal, FALSE));
  272. sc = S_OK;
  273. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::ConvertInternalStream\n"));
  274. // Fall through
  275. EH_pstTo:
  276. pstTo->CPubStream::vRelease();
  277. EH_pstFrom:
  278. pstFrom->CPubStream::vRelease();
  279. EH_Err:
  280. return sc;
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Member: CExposedDocFile::CreateEntry, private
  285. //
  286. // Synopsis: Creates elements, used in CreateStream, CreateStorage.
  287. //
  288. // Arguments: [pdfn] - Name
  289. // [dwType] - Entry type
  290. // [grfMode] - Access mode
  291. // [ppv] - Object return
  292. //
  293. // Returns: Appropriate status code
  294. //
  295. // Modifies: [ppv]
  296. //
  297. // History: 18-Dec-92 DrewB Created
  298. //
  299. //----------------------------------------------------------------------------
  300. SCODE CExposedDocFile::CreateEntry(CDfName const *pdfn,
  301. DWORD dwType,
  302. DWORD grfMode,
  303. void **ppv)
  304. {
  305. SCODE sc;
  306. SEntryBuffer eb;
  307. BOOL fRenamed = FALSE;
  308. CPubStream *pst;
  309. CExposedStream *pstExp;
  310. CPubDocFile *pdf;
  311. CExposedDocFile *pdfExp;
  312. olDebugOut((DEB_ITRACE, "In CExposedDocFile::CreateEntry:%p("
  313. "%p, %lX, %lX, %p)\n", this, pdfn, dwType, grfMode, ppv));
  314. olChk(EnforceSingle(grfMode));
  315. // 3/11/93 - Demand scratch when opening/creating transacted
  316. if ((grfMode & STGM_TRANSACTED) == STGM_TRANSACTED)
  317. {
  318. olChk(_ppc->GetDirty()->InitScratch());
  319. }
  320. if (grfMode & (STGM_CREATE | STGM_CONVERT))
  321. {
  322. if (FAILED(sc = _pdf->IsEntry(pdfn, &eb)))
  323. {
  324. if (sc != STG_E_FILENOTFOUND)
  325. olErr(EH_Err, sc);
  326. }
  327. else if (eb.dwType == dwType && (grfMode & STGM_CREATE))
  328. olChk(_pdf->DestroyEntry(pdfn, FALSE));
  329. else if (eb.dwType == STGTY_STREAM && (grfMode & STGM_CONVERT) &&
  330. dwType == STGTY_STORAGE)
  331. {
  332. CDfName const dfnIllegal(wcsIllegalName);
  333. olChk(_pdf->RenameEntry(pdfn, &dfnIllegal));
  334. fRenamed = TRUE;
  335. }
  336. else
  337. olErr(EH_Err, STG_E_FILEALREADYEXISTS);
  338. }
  339. if (REAL_STGTY(dwType) == STGTY_STREAM)
  340. {
  341. olChk(_pdf->CreateStream(pdfn, ModeToDFlags(grfMode), &pst));
  342. olMemTo(EH_pst, pstExp = new (_pdfb->GetMalloc()) CExposedStream);
  343. olChkTo(EH_pstExp, pstExp->Init(pst, BP_TO_P(CDFBasis *, _pdfb),
  344. _ppc, NULL));
  345. _ppc->AddRef();
  346. #ifdef ASYNC
  347. if (_cpoint.IsInitialized())
  348. {
  349. olChkTo(EH_connSt, pstExp->InitConnection(&_cpoint));
  350. }
  351. #endif
  352. *ppv = pstExp;
  353. }
  354. else
  355. {
  356. olAssert(REAL_STGTY(dwType) == STGTY_STORAGE);
  357. olChk(_pdf->CreateDocFile(pdfn, ModeToDFlags(grfMode), &pdf));
  358. olMemTo(EH_pdf, pdfExp = new (_pdfb->GetMalloc())
  359. CExposedDocFile(pdf, BP_TO_P(CDFBasis *, _pdfb), _ppc));
  360. _ppc->AddRef();
  361. if (_cpoint.IsInitialized())
  362. {
  363. olChkTo(EH_pdfExpInit, pdfExp->InitConnection(&_cpoint));
  364. }
  365. // If we've renamed the original stream for conversion, convert
  366. if (fRenamed)
  367. {
  368. olChkTo(EH_pdfExpInit, ConvertInternalStream(pdfExp));
  369. sc = STG_S_CONVERTED;
  370. }
  371. *ppv = pdfExp;
  372. }
  373. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::CreateEntry\n"));
  374. return sc;
  375. EH_connSt:
  376. pstExp->Release();
  377. goto EH_Del;
  378. EH_pstExp:
  379. delete pstExp;
  380. EH_pst:
  381. pst->CPubStream::vRelease();
  382. goto EH_Del;
  383. EH_pdfExpInit:
  384. pdfExp->Release();
  385. goto EH_Del;
  386. EH_pdf:
  387. pdf->CPubDocFile::vRelease();
  388. // Fall through
  389. EH_Del:
  390. olVerSucc(_pdf->DestroyEntry(pdfn, TRUE));
  391. EH_Err:
  392. return sc;
  393. }
  394. //+---------------------------------------------------------------------------
  395. //
  396. // Member: CExposedDocFile::OpenEntry, private
  397. //
  398. // Synopsis: Opens elements, used in OpenStream, OpenStorage.
  399. //
  400. // Arguments: [pdfn] - Name
  401. // [dwType] - Entry type
  402. // [grfMode] - Access mode
  403. // [ppv] - Object return
  404. //
  405. // Returns: Appropriate status code
  406. //
  407. // Modifies: [ppv]
  408. //
  409. // History: 18-Dec-92 DrewB Created
  410. //
  411. //----------------------------------------------------------------------------
  412. SCODE CExposedDocFile::OpenEntry(CDfName const *pdfn,
  413. DWORD dwType,
  414. DWORD grfMode,
  415. void **ppv)
  416. {
  417. SCODE sc;
  418. CPubDocFile *pdf;
  419. CExposedDocFile *pdfExp;
  420. CPubStream *pst;
  421. CExposedStream *pstExp;
  422. olDebugOut((DEB_ITRACE, "In CExposedDocFile::OpenEntry:%p("
  423. "%p, %lX, %lX, %p)\n", this, pdfn, dwType, grfMode, ppv));
  424. olChk(EnforceSingle(grfMode));
  425. // 3/11/93 - Demand scratch when opening/creating transacted
  426. if ((grfMode & STGM_TRANSACTED) == STGM_TRANSACTED)
  427. {
  428. olChk(_ppc->GetDirty()->InitScratch());
  429. }
  430. if (REAL_STGTY(dwType) == STGTY_STREAM)
  431. {
  432. olChk(_pdf->GetStream(pdfn, ModeToDFlags(grfMode), &pst));
  433. olMemTo(EH_pst, pstExp = new (_pdfb->GetMalloc()) CExposedStream);
  434. olChkTo(EH_pstExp, pstExp->Init(pst, BP_TO_P(CDFBasis *, _pdfb),
  435. _ppc, NULL));
  436. _ppc->AddRef();
  437. if (_cpoint.IsInitialized())
  438. {
  439. olChkTo(EH_connSt, pstExp->InitConnection(&_cpoint));
  440. }
  441. *ppv = pstExp;
  442. }
  443. else
  444. {
  445. olAssert(REAL_STGTY(dwType) == STGTY_STORAGE);
  446. olChk(_pdf->GetDocFile(pdfn, ModeToDFlags(grfMode), &pdf));
  447. olMemTo(EH_pdf, pdfExp = new (_pdfb->GetMalloc())
  448. CExposedDocFile(pdf, BP_TO_P(CDFBasis *, _pdfb), _ppc));
  449. _ppc->AddRef();
  450. if (_cpoint.IsInitialized())
  451. {
  452. olChkTo(EH_connDf, pdfExp->InitConnection(&_cpoint));
  453. }
  454. *ppv = pdfExp;
  455. }
  456. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::OpenEntry\n"));
  457. return S_OK;
  458. EH_connSt:
  459. pstExp->Release();
  460. return sc;
  461. EH_pstExp:
  462. delete pstExp;
  463. // Fall through to clean up CPubStream
  464. EH_pst:
  465. pst->CPubStream::vRelease();
  466. return sc;
  467. EH_connDf:
  468. pdfExp->Release();
  469. return sc;
  470. EH_pdf:
  471. pdf->CPubDocFile::vRelease();
  472. // Fall through
  473. EH_Err:
  474. return sc;
  475. }
  476. //+--------------------------------------------------------------
  477. //
  478. // Member: CExposedDocFile::CreateStream, public
  479. //
  480. // Synopsis: Creates a stream
  481. //
  482. // Arguments: [pwcsName] - Name
  483. // [grfMode] - Permissions
  484. // [reserved1]
  485. // [reserved2]
  486. // [ppstm] - Stream return
  487. //
  488. // Returns: Appropriate status code
  489. //
  490. // Modifies: [ppstm]
  491. //
  492. // History: 20-Jan-92 DrewB Created
  493. //
  494. //---------------------------------------------------------------
  495. _OLESTDMETHODIMP CExposedDocFile::CreateStream(WCHAR const *pwcsName,
  496. DWORD grfMode,
  497. DWORD reserved1,
  498. DWORD reserved2,
  499. IStream **ppstm)
  500. {
  501. SCODE sc;
  502. SAFE_SEM;
  503. SAFE_ACCESS;
  504. SafeCExposedStream pestm;
  505. CDfName dfn;
  506. olDebugOut((DEB_TRACE, "In CExposedDocFile::CreateStream("
  507. "%ws, %lX, %lu, %lu, %p)\n", pwcsName, grfMode, reserved1,
  508. reserved2, ppstm));
  509. olLog(("%p::In CExposedDocFile::CreateStream(%ws, %lX, %lu, %lu, %p)\n",
  510. this, pwcsName, grfMode, reserved1, reserved2, ppstm));
  511. OL_VALIDATE(CreateStream(pwcsName,
  512. grfMode,
  513. reserved1,
  514. reserved2,
  515. ppstm));
  516. olChk(Validate());
  517. BEGIN_PENDING_LOOP;
  518. olChk(TakeSafeSem());
  519. olChk(CheckCopyTo());
  520. SafeWriteAccess();
  521. #ifdef DIRECTWRITERLOCK
  522. olChk(ValidateWriteAccess());
  523. #endif
  524. dfn.Set(pwcsName);
  525. sc = CreateEntry(&dfn, STGTY_STREAM, grfMode, (void **)&pestm);
  526. END_PENDING_LOOP;
  527. if (SUCCEEDED(sc))
  528. TRANSFER_INTERFACE(pestm, IStream, ppstm);
  529. olDebugOut((DEB_TRACE, "Out CExposedDocFile::CreateStream => %p\n",
  530. *ppstm));
  531. EH_Err:
  532. olLog(("%p::Out CExposedDocFile::CreateStream(). "
  533. "*ppstm == %p, ret == %lx\n", this, *ppstm, sc));
  534. return _OLERETURN(sc);
  535. }
  536. //+--------------------------------------------------------------
  537. //
  538. // Member: CExposedDocFile::OpenStream, public
  539. //
  540. // Synopsis: Opens an existing stream
  541. //
  542. // Arguments: [pwcsName] - Name
  543. // [reserved1]
  544. // [grfMode] - Permissions
  545. // [reserved2]
  546. // [ppstm] - Stream return
  547. //
  548. // Returns: Appropriate status code
  549. //
  550. // Modifies: [ppstm]
  551. //
  552. // History: 20-Jan-92 DrewB Created
  553. //
  554. //---------------------------------------------------------------
  555. _OLESTDMETHODIMP CExposedDocFile::OpenStream(WCHAR const *pwcsName,
  556. void *reserved1,
  557. DWORD grfMode,
  558. DWORD reserved2,
  559. IStream **ppstm)
  560. {
  561. SCODE sc;
  562. SAFE_SEM;
  563. SAFE_ACCESS;
  564. SafeCExposedStream pestm;
  565. CDfName dfn;
  566. olDebugOut((DEB_TRACE, "In CExposedDocFile::OpenStream("
  567. "%ws, %p, %lX, %lu, %p)\n", pwcsName, reserved1,
  568. grfMode, reserved2, ppstm));
  569. olLog(("%p::In CExposedDocFile::OpenStream(%ws, %lu %lX, %lu, %p)\n",
  570. this, pwcsName, reserved1, grfMode, reserved2, ppstm));
  571. OL_VALIDATE(OpenStream(pwcsName,
  572. reserved1,
  573. grfMode,
  574. reserved2,
  575. ppstm));
  576. olChk(Validate());
  577. BEGIN_PENDING_LOOP;
  578. olChk(TakeSafeSem());
  579. SafeReadAccess();
  580. dfn.Set(pwcsName);
  581. sc = OpenEntry(&dfn, STGTY_STREAM, grfMode, (void **)&pestm);
  582. END_PENDING_LOOP;
  583. if (SUCCEEDED(sc))
  584. TRANSFER_INTERFACE(pestm, IStream, ppstm);
  585. olDebugOut((DEB_TRACE, "Out CExposedDocFile::OpenStream => %p\n",
  586. *ppstm));
  587. EH_Err:
  588. olLog(("%p::Out CExposedDocFile::OpenStream(). "
  589. "*ppstm == %p, ret == %lx\n", this, *ppstm, sc));
  590. return _OLERETURN(sc);
  591. }
  592. //+--------------------------------------------------------------
  593. //
  594. // Member: CExposedDocFile::CreateStorage, public
  595. //
  596. // Synopsis: Creates an embedded DocFile
  597. //
  598. // Arguments: [pwcsName] - Name
  599. // [grfMode] - Permissions
  600. // [reserved1]
  601. // [reserved2]
  602. // [ppstg] - New DocFile return
  603. //
  604. // Returns: Appropriate status code
  605. //
  606. // Modifies: [ppstg]
  607. //
  608. // History: 20-Jan-92 DrewB Created
  609. //
  610. //---------------------------------------------------------------
  611. _OLESTDMETHODIMP CExposedDocFile::CreateStorage(
  612. WCHAR const *pwcsName,
  613. DWORD grfMode,
  614. DWORD reserved1,
  615. LPSTGSECURITY reserved2,
  616. IStorage **ppstg)
  617. {
  618. SCODE sc;
  619. SAFE_SEM;
  620. SAFE_ACCESS;
  621. SafeCExposedDocFile pedf;
  622. CDfName dfn;
  623. olLog(("%p::In CExposedDocFile::CreateStorage(%ws, %lX, %lu, %lu, %p)\n",
  624. this, pwcsName, grfMode, reserved1, reserved2, ppstg));
  625. olDebugOut((DEB_TRACE, "In CExposedDocFile::CreateStorage:%p("
  626. "%ws, %lX, %lu, %lu, %p)\n", this, pwcsName, grfMode,
  627. reserved1, reserved2, ppstg));
  628. OL_VALIDATE(CreateStorage(pwcsName,
  629. grfMode,
  630. reserved1,
  631. reserved2,
  632. ppstg));
  633. olChk(Validate());
  634. BEGIN_PENDING_LOOP;
  635. olChk(TakeSafeSem());
  636. olChk(CheckCopyTo());
  637. SafeWriteAccess();
  638. #ifdef DIRECTWRITERLOCK
  639. olChk(ValidateWriteAccess());
  640. #endif
  641. dfn.Set(pwcsName);
  642. sc = CreateEntry(&dfn, STGTY_STORAGE, grfMode, (void **)&pedf);
  643. END_PENDING_LOOP;
  644. if (SUCCEEDED(sc))
  645. TRANSFER_INTERFACE(pedf, IStorage, ppstg);
  646. olDebugOut((DEB_TRACE, "Out CExposedDocFile::CreateStorage => %p\n",
  647. *ppstg));
  648. EH_Err:
  649. olLog(("%p::Out CExposedDocFile::CreateStorage(). "
  650. "*ppstg == %p, ret == %lX\n", this, *ppstg, sc));
  651. return _OLERETURN(sc);
  652. }
  653. //+--------------------------------------------------------------
  654. //
  655. // Member: CExposedDocFile::OpenStorage, public
  656. //
  657. // Synopsis: Gets an existing embedded DocFile
  658. //
  659. // Arguments: [pwcsName] - Name
  660. // [pstgPriority] - Priority reopens
  661. // [grfMode] - Permissions
  662. // [snbExclude] - Priority reopens
  663. // [reserved]
  664. // [ppstg] - DocFile return
  665. //
  666. // Returns: Appropriate status code
  667. //
  668. // Modifies: [ppstg]
  669. //
  670. // History: 20-Jan-92 DrewB Created
  671. //
  672. //---------------------------------------------------------------
  673. _OLESTDMETHODIMP CExposedDocFile::OpenStorage(WCHAR const *pwcsName,
  674. IStorage *pstgPriority,
  675. DWORD grfMode,
  676. SNBW snbExclude,
  677. DWORD reserved,
  678. IStorage **ppstg)
  679. {
  680. SCODE sc;
  681. SAFE_SEM;
  682. SAFE_ACCESS;
  683. SafeCExposedDocFile pdfExp;
  684. CDfName dfn;
  685. olLog(("%p::In CExposedDocFile::OpenStorage(%ws, %p, %lX, %p, %lu, %p)\n",
  686. this, pwcsName, pstgPriority, grfMode, snbExclude, reserved,
  687. ppstg));
  688. olDebugOut((DEB_TRACE, "In CExposedDocFile::OpenStorage:%p("
  689. "%ws, %p, %lX, %p, %lu, %p)\n", this, pwcsName, pstgPriority,
  690. grfMode, snbExclude, reserved, ppstg));
  691. OL_VALIDATE(OpenStorage(pwcsName,
  692. pstgPriority,
  693. grfMode,
  694. snbExclude,
  695. reserved,
  696. ppstg));
  697. olChk(Validate());
  698. if (snbExclude != NULL)
  699. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  700. BEGIN_PENDING_LOOP;
  701. olChk(TakeSafeSem());
  702. SafeReadAccess();
  703. dfn.Set(pwcsName);
  704. sc = OpenEntry(&dfn, STGTY_STORAGE, grfMode, (void **)&pdfExp);
  705. END_PENDING_LOOP;
  706. if (SUCCEEDED(sc))
  707. {
  708. TRANSFER_INTERFACE(pdfExp, IStorage, ppstg);
  709. }
  710. olDebugOut((DEB_TRACE, "Out CExposedDocFile::OpenStorage => %p\n",
  711. *ppstg));
  712. EH_Err:
  713. olLog(("%p::Out CExposedDocFile::OpenStorage(). "
  714. "*ppstg == %p, ret == %lX\n", this, *ppstg, sc));
  715. return _OLERETURN(sc);
  716. }
  717. //+---------------------------------------------------------------------------
  718. //
  719. // Member: CExposedDocFile::MakeCopyFlags, public
  720. //
  721. // Synopsis: Translates IID array into bit fields
  722. //
  723. // Arguments: [ciidExclude] - Count of IIDs
  724. // [rgiidExclude] - IIDs not to copy
  725. //
  726. // Returns: Appropriate status code
  727. //
  728. // History: 23-Dec-92 DrewB Created
  729. //
  730. //----------------------------------------------------------------------------
  731. DWORD CExposedDocFile::MakeCopyFlags(DWORD ciidExclude,
  732. IID const *rgiidExclude)
  733. {
  734. DWORD dwCopyFlags;
  735. olDebugOut((DEB_ITRACE, "In CExposedDocFile::MakeCopyFlags(%lu, %p)\n",
  736. ciidExclude, rgiidExclude));
  737. // Copy everything by default
  738. dwCopyFlags = COPY_ALL;
  739. for (; ciidExclude > 0; ciidExclude--, rgiidExclude++)
  740. if (IsEqualIID(*rgiidExclude, IID_IStorage))
  741. dwCopyFlags &= ~COPY_STORAGES;
  742. else if (IsEqualIID(*rgiidExclude, IID_IStream))
  743. dwCopyFlags &= ~COPY_STREAMS;
  744. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::MakeCopyFlags\n"));
  745. return dwCopyFlags;
  746. }
  747. //+--------------------------------------------------------------
  748. //
  749. // Member: CExposedDocFile::CopyTo, public
  750. //
  751. // Synopsis: Makes a copy of a DocFile
  752. //
  753. // Arguments: [ciidExclude] - Length of rgiid array
  754. // [rgiidExclude] - Array of IIDs to exclude
  755. // [snbExclude] - Names to exclude
  756. // [pstgDest] - Parent of copy
  757. //
  758. // Returns: Appropriate status code
  759. //
  760. // History: 20-Jan-92 DrewB Created
  761. //
  762. //---------------------------------------------------------------
  763. _OLESTDMETHODIMP CExposedDocFile::CopyTo(DWORD ciidExclude,
  764. IID const *rgiidExclude,
  765. SNBW snbExclude,
  766. IStorage *pstgDest)
  767. {
  768. SCODE sc;
  769. #ifdef MULTIHEAP
  770. CSafeMultiHeap smh(_ppc);
  771. #endif
  772. SAFE_SEM;
  773. DWORD i;
  774. olLog(("%p::In CExposedDocFile::CopyTo(%lu, %p, %p, %p)\n",
  775. this, ciidExclude, rgiidExclude, snbExclude, pstgDest));
  776. olDebugOut((DEB_TRACE, "In CExposedDocFile::CopyTo(%lu, %p, %p, %p)\n",
  777. ciidExclude, rgiidExclude, snbExclude, pstgDest));
  778. OL_VALIDATE(CopyTo(ciidExclude,
  779. rgiidExclude,
  780. snbExclude,
  781. pstgDest));
  782. olChk(Validate());
  783. BEGIN_PENDING_LOOP;
  784. olChk(TakeSafeSem());
  785. olChk(_pdf->CheckReverted());
  786. olAssert(_pdfb->GetCopyBase() == NULL);
  787. _pdfb->SetCopyBase(BP_TO_P(CPubDocFile *, _pdf));
  788. // Flush all descendant property set buffers so that their
  789. // underlying Streams (which are about to be copied) are
  790. // up to date.
  791. SetWriteAccess();
  792. olChkTo(EH_Loop, _pdf->FlushBufferedData(0));
  793. ClearWriteAccess();
  794. // Perform the copy.
  795. sc = CopyDocFileToIStorage(_pdf->GetDF(), pstgDest, snbExclude,
  796. MakeCopyFlags(ciidExclude, rgiidExclude));
  797. EH_Loop:
  798. _pdfb->SetCopyBase(NULL);
  799. END_PENDING_LOOP;
  800. olDebugOut((DEB_TRACE, "Out CExposedDocFile::CopyTo\n"));
  801. EH_Err:
  802. _pdfb->SetCopyBase(NULL);
  803. olLog(("%p::Out ExposedDocFile::CopyTo(). ret == %lX\n", this, sc));
  804. return _OLERETURN(sc);
  805. }
  806. //+--------------------------------------------------------------
  807. //
  808. // Member: CExposedDocFile::Commit, public
  809. //
  810. // Synopsis: Commits transacted changes
  811. //
  812. // Arguments: [dwFlags] - DFC_*
  813. //
  814. // Returns: Appropriate status code
  815. //
  816. // History: 20-Jan-92 DrewB Created
  817. //
  818. //---------------------------------------------------------------
  819. STDMETHODIMP CExposedDocFile::Commit(DWORD dwFlags)
  820. {
  821. SCODE sc;
  822. SAFE_SEM;
  823. SAFE_ACCESS;
  824. olLog(("%p::In CExposedDocFile::Commit(%lX)\n",this, dwFlags));
  825. olDebugOut((DEB_TRACE, "In CExposedDocFile::Commit(%lX)\n", dwFlags));
  826. OL_VALIDATE(Commit(dwFlags));
  827. olChk(Validate());
  828. BEGIN_PENDING_LOOP;
  829. olChk( _PropertyBagEx.Commit( dwFlags ));
  830. olChk(TakeSafeSem());
  831. SafeWriteAccess();
  832. #ifdef DIRECTWRITERLOCK
  833. if (_pdf->GetTransactedDepth() <= 1) // topmost transacted level or direct
  834. {
  835. if (_pdfb->DirectWriterMode() && (*_ppc->GetRecursionCount()) == 0)
  836. olChk(STG_E_ACCESSDENIED);
  837. }
  838. #endif
  839. olChkTo(EH_Loop, _pdf->Commit(dwFlags));
  840. #if WIN32 >= 300
  841. if (SUCCEEDED(sc) && _pIAC != NULL)
  842. sc = _pIAC->CommitAccessRights(0);
  843. #endif
  844. EH_Loop:
  845. END_PENDING_LOOP;
  846. olDebugOut((DEB_TRACE, "Out CExposedDocFile::Commit\n"));
  847. EH_Err:
  848. olLog(("%p::Out CExposedDocFile::Commit(). ret == %lx\n",this, sc));
  849. return ResultFromScode(sc);
  850. }
  851. //+--------------------------------------------------------------
  852. //
  853. // Member: CExposedDocFile::Revert, public
  854. //
  855. // Synopsis: Reverts transacted changes
  856. //
  857. // Returns: Appropriate status code
  858. //
  859. // History: 20-Jan-92 DrewB Created
  860. //
  861. //---------------------------------------------------------------
  862. STDMETHODIMP CExposedDocFile::Revert(void)
  863. {
  864. SCODE sc;
  865. SAFE_SEM;
  866. SAFE_ACCESS;
  867. olLog(("%p::In CExposedDocFile::Revert()\n", this));
  868. olDebugOut((DEB_TRACE, "In CExposedDocFile::Revert\n"));
  869. OL_VALIDATE(Revert());
  870. olChk(Validate());
  871. BEGIN_PENDING_LOOP;
  872. olChk(TakeSafeSem());
  873. SafeWriteAccess();
  874. olChkTo(EH_Loop, _pdf->Revert());
  875. #if WIN32 >= 300
  876. if (SUCCEEDED(sc) && _pIAC != NULL)
  877. sc = _pIAC->RevertAccessRights();
  878. #endif
  879. EH_Loop:
  880. END_PENDING_LOOP;
  881. olDebugOut((DEB_TRACE, "Out CExposedDocFile::Revert\n"));
  882. EH_Err:
  883. olLog(("%p::Out CExposedDocFile::Revert(). ret == %lx\n", this, sc));
  884. return ResultFromScode(sc);
  885. }
  886. //+--------------------------------------------------------------
  887. //
  888. // Member: CExposedDocFile::EnumElements, public
  889. //
  890. // Synopsis: Starts an iterator
  891. //
  892. // Arguments: [reserved1]
  893. // [reserved2]
  894. // [reserved3]
  895. // [ppenm] - Enumerator return
  896. //
  897. // Returns: Appropriate status code
  898. //
  899. // Modifies: [ppenm]
  900. //
  901. // History: 20-Jan-92 DrewB Created
  902. //
  903. //---------------------------------------------------------------
  904. STDMETHODIMP CExposedDocFile::EnumElements(DWORD reserved1,
  905. void *reserved2,
  906. DWORD reserved3,
  907. IEnumSTATSTG **ppenm)
  908. {
  909. SCODE sc;
  910. SAFE_SEM;
  911. SAFE_ACCESS;
  912. SafeCExposedIterator pdiExp;
  913. CDfName dfnTmp;
  914. olLog(("%p::In CExposedDocFile::EnumElements(%lu, %p, %lu, %p)\n",
  915. this, reserved1, reserved2, reserved3, ppenm));
  916. olDebugOut((DEB_TRACE, "In CExposedDocFile::EnumElements(%p)\n",
  917. ppenm));
  918. OL_VALIDATE(EnumElements(reserved1,
  919. reserved2,
  920. reserved3,
  921. ppenm));
  922. olChk(Validate());
  923. //ASYNC Note: It doesn't appear that there's any way that this
  924. // function can fail with STG_E_PENDING, so we don't need a pending
  925. // loop here.
  926. olChk(TakeSafeSem());
  927. if (!P_READ(_pdf->GetDFlags()))
  928. olErr(EH_Err, STG_E_ACCESSDENIED);
  929. olChk(_pdf->CheckReverted());
  930. SafeReadAccess();
  931. pdiExp.Attach(new CExposedIterator(BP_TO_P(CPubDocFile *, _pdf),
  932. &dfnTmp,
  933. BP_TO_P(CDFBasis *, _pdfb),
  934. _ppc));
  935. olMem((CExposedIterator *)pdiExp);
  936. _ppc->AddRef();
  937. #ifdef ASYNC
  938. if (_cpoint.IsInitialized())
  939. {
  940. olChkTo(EH_Exp, pdiExp->InitConnection(&_cpoint));
  941. }
  942. #endif
  943. TRANSFER_INTERFACE(pdiExp, IEnumSTATSTG, ppenm);
  944. olDebugOut((DEB_TRACE, "Out CExposedDocFile::EnumElements => %p\n",
  945. *ppenm));
  946. EH_Err:
  947. olLog(("%p::Out CExposedDocFile::EnumElements(). ret == %lx\n",this, sc));
  948. return ResultFromScode(sc);
  949. EH_Exp:
  950. pdiExp->Release();
  951. return ResultFromScode(sc);
  952. }
  953. //+--------------------------------------------------------------
  954. //
  955. // Member: CExposedDocFile::DestroyElement, public
  956. //
  957. // Synopsis: Permanently deletes an element of a DocFile
  958. //
  959. // Arguments: [pwcsName] - Name of element
  960. //
  961. // Returns: Appropriate status code
  962. //
  963. // History: 20-Jan-92 DrewB Created
  964. //
  965. //---------------------------------------------------------------
  966. _OLESTDMETHODIMP CExposedDocFile::DestroyElement(WCHAR const *pwcsName)
  967. {
  968. SCODE sc;
  969. SAFE_SEM;
  970. SAFE_ACCESS;
  971. CDfName dfn;
  972. olLog(("%p::In CExposedDocFile::DestroyElement(%ws)\n", this, pwcsName));
  973. olDebugOut((DEB_TRACE, "In CExposedDocFile::DestroyElement(%ws)\n",
  974. pwcsName));
  975. OL_VALIDATE(DestroyElement(pwcsName));
  976. olChk(Validate());
  977. dfn.Set(pwcsName);
  978. BEGIN_PENDING_LOOP;
  979. olChk(TakeSafeSem());
  980. SafeWriteAccess();
  981. #ifdef DIRECTWRITERLOCK
  982. olChk(ValidateWriteAccess());
  983. #endif
  984. sc = _pdf->DestroyEntry(&dfn, FALSE);
  985. END_PENDING_LOOP;
  986. olDebugOut((DEB_TRACE, "Out CExposedDocFile::DestroyElement\n"));
  987. EH_Err:
  988. olLog(("%p::Out CExposedDocFile::DestroyElement(). ret == %lx\n",
  989. this, sc));
  990. return _OLERETURN(sc);
  991. }
  992. _OLESTDMETHODIMP CExposedDocFile::MoveElementTo(WCHAR const *pwcsName,
  993. IStorage *pstgParent,
  994. OLECHAR const *ptcsNewName,
  995. DWORD grfFlags)
  996. {
  997. SCODE sc;
  998. #ifdef MULTIHEAP
  999. CSafeMultiHeap smh(_ppc);
  1000. #endif
  1001. olLog(("%p::In CExposedDocFile::MoveElementTo("
  1002. "%ws, %p, " OLEFMT ", %lu)\n",
  1003. this, pwcsName, pstgParent, ptcsNewName, grfFlags));
  1004. olDebugOut((DEB_TRACE, "In CExposedDocFile::MoveElementTo("
  1005. "%ws, %p, " OLEFMT ", %lu)\n",
  1006. pwcsName, pstgParent, ptcsNewName, grfFlags));
  1007. OL_VALIDATE(MoveElementTo(pwcsName,
  1008. pstgParent,
  1009. ptcsNewName,
  1010. grfFlags));
  1011. olChk(Validate());
  1012. #ifdef ASYNC
  1013. //ASYNC Note: We don't use the normal pending loop macros here because
  1014. // we have no safe sem and need to pass a NULL.
  1015. do
  1016. {
  1017. #endif
  1018. sc = MoveElementWorker(pwcsName,
  1019. pstgParent,
  1020. ptcsNewName,
  1021. grfFlags);
  1022. #ifdef ASYNC
  1023. if (!ISPENDINGERROR(sc))
  1024. {
  1025. break;
  1026. }
  1027. else
  1028. {
  1029. SCODE sc2;
  1030. sc2 = _cpoint.Notify(sc,
  1031. _ppc->GetBase(),
  1032. _ppc,
  1033. NULL);
  1034. if (sc2 != S_OK)
  1035. {
  1036. return ResultFromScode(sc2);
  1037. }
  1038. }
  1039. } while (TRUE);
  1040. #endif
  1041. EH_Err:
  1042. olLog(("%p::Out CExposedDocFile::MoveElementTo(). ret == %lx\n",
  1043. this, sc));
  1044. return _OLERETURN(sc);
  1045. }
  1046. //+--------------------------------------------------------------
  1047. //
  1048. // Member: CExposedDocFile::MoveElementToWorker, public
  1049. //
  1050. // Synopsis: Move an element of a DocFile to an IStorage
  1051. //
  1052. // Arguments: [pwcsName] - Current name
  1053. // [ptcsNewName] - New name
  1054. //
  1055. // Returns: Appropriate status code
  1056. //
  1057. // Algorithm: Open source as storage or stream (whatever works)
  1058. // Create appropriate destination
  1059. // Copy source to destination
  1060. // Set create time of destination equal to create time of source
  1061. // If appropriate, delete source
  1062. //
  1063. // History: 10-Nov-92 AlexT Created
  1064. //
  1065. //---------------------------------------------------------------
  1066. SCODE CExposedDocFile::MoveElementWorker(WCHAR const *pwcsName,
  1067. IStorage *pstgParent,
  1068. OLECHAR const *ptcsNewName,
  1069. DWORD grfFlags)
  1070. {
  1071. IUnknown *punksrc = NULL;
  1072. SCODE sc;
  1073. IUnknown *punkdst;
  1074. IStorage *pstgsrc;
  1075. STATSTG statstg;
  1076. BOOL fCreate = TRUE;
  1077. // Determine source type
  1078. sc = GetScode(OpenStorage(pwcsName, NULL,
  1079. STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE,
  1080. NULL, NULL, &pstgsrc));
  1081. if (SUCCEEDED(sc))
  1082. {
  1083. HRESULT hr;
  1084. // It's a storage
  1085. punksrc = pstgsrc;
  1086. IStorage *pstgdst;
  1087. olHChkTo(EH_UnkSrc, pstgsrc->Stat(&statstg, STATFLAG_NONAME));
  1088. hr = pstgParent->CreateStorage(ptcsNewName,
  1089. STGM_DIRECT | STGM_WRITE |
  1090. STGM_SHARE_EXCLUSIVE | STGM_FAILIFTHERE,
  1091. 0, 0, &pstgdst);
  1092. if (DfGetScode(hr) == STG_E_FILEALREADYEXISTS &&
  1093. grfFlags == STGMOVE_COPY)
  1094. {
  1095. fCreate = FALSE;
  1096. //If we're opening an existing thing for merging, we need
  1097. // read and write permissions so we can traverse the tree.
  1098. hr = pstgParent->OpenStorage(ptcsNewName, NULL,
  1099. STGM_DIRECT | STGM_READWRITE |
  1100. STGM_SHARE_EXCLUSIVE, NULL,
  1101. 0, &pstgdst);
  1102. }
  1103. olHChkTo(EH_UnkSrc, hr);
  1104. punkdst = pstgdst;
  1105. sc = DfGetScode(pstgsrc->CopyTo(0, NULL, NULL, pstgdst));
  1106. }
  1107. else if (sc == STG_E_FILENOTFOUND)
  1108. {
  1109. // Try opening it as a stream
  1110. HRESULT hr;
  1111. IStream *pstmsrc, *pstmdst;
  1112. olHChk(OpenStream(pwcsName, NULL,
  1113. STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE,
  1114. NULL, &pstmsrc));
  1115. // It's a stream
  1116. punksrc = pstmsrc;
  1117. olHChkTo(EH_UnkSrc, pstmsrc->Stat(&statstg, STATFLAG_NONAME));
  1118. hr = pstgParent->CreateStream(ptcsNewName,
  1119. STGM_DIRECT | STGM_WRITE |
  1120. STGM_SHARE_EXCLUSIVE |
  1121. STGM_FAILIFTHERE,
  1122. 0, 0, &pstmdst);
  1123. if (DfGetScode(hr) == STG_E_FILEALREADYEXISTS &&
  1124. grfFlags == STGMOVE_COPY)
  1125. {
  1126. ULARGE_INTEGER uli;
  1127. uli.QuadPart = 0;
  1128. fCreate = FALSE;
  1129. //Try to open it instead
  1130. //Note: We do this instead of doing a CreateStream with
  1131. // STGM_CREATE because CreateStream can open over an already
  1132. // open stream, which leads to problems when the destination
  1133. // and the source are the same.
  1134. olHChkTo(EH_UnkSrc, pstgParent->OpenStream(ptcsNewName,
  1135. 0,
  1136. STGM_DIRECT |
  1137. STGM_WRITE |
  1138. STGM_SHARE_EXCLUSIVE,
  1139. 0,
  1140. &pstmdst));
  1141. sc = pstmdst->SetSize(uli);
  1142. if (FAILED(sc))
  1143. {
  1144. pstmdst->Release();
  1145. olErr(EH_UnkSrc, sc);
  1146. }
  1147. }
  1148. else
  1149. olHChkTo(EH_UnkSrc, hr);
  1150. punkdst = pstmdst;
  1151. ULARGE_INTEGER cb;
  1152. ULISetLow (cb, 0xffffffff);
  1153. ULISetHigh(cb, 0xffffffff);
  1154. sc = DfGetScode(pstmsrc->CopyTo(pstmdst, cb, NULL, NULL));
  1155. }
  1156. else
  1157. olChk(sc);
  1158. punkdst->Release();
  1159. if (SUCCEEDED(sc))
  1160. {
  1161. // Make destination create time match source create time
  1162. // Note that we don't really care if this call succeeded.
  1163. pstgParent->SetElementTimes(ptcsNewName, &statstg.ctime,
  1164. NULL, NULL);
  1165. //OK to ignore failure from DestroyElement
  1166. if ((grfFlags & STGMOVE_COPY) == STGMOVE_MOVE)
  1167. DestroyElement(pwcsName);
  1168. }
  1169. else
  1170. {
  1171. // The copy/move failed, so get rid of the partial result.
  1172. //Only do a delete if the object was newly created.
  1173. if (fCreate)
  1174. pstgParent->DestroyElement(ptcsNewName);
  1175. }
  1176. olDebugOut((DEB_TRACE, "Out CExposedDocFile::MoveElementTo\n"));
  1177. // Fall through
  1178. EH_UnkSrc:
  1179. if (punksrc)
  1180. punksrc->Release();
  1181. EH_Err:
  1182. return sc;
  1183. }
  1184. //+--------------------------------------------------------------
  1185. //
  1186. // Member: CExposedDocFile::RenameElement, public
  1187. //
  1188. // Synopsis: Renames an element of a DocFile
  1189. //
  1190. // Arguments: [pwcsName] - Current name
  1191. // [pwcsNewName] - New name
  1192. //
  1193. // Returns: Appropriate status code
  1194. //
  1195. // History: 20-Jan-92 DrewB Created
  1196. //
  1197. //---------------------------------------------------------------
  1198. _OLESTDMETHODIMP CExposedDocFile::RenameElement(WCHAR const *pwcsName,
  1199. WCHAR const *pwcsNewName)
  1200. {
  1201. SCODE sc;
  1202. SAFE_SEM;
  1203. SAFE_ACCESS;
  1204. CDfName dfnOld, dfnNew;
  1205. olLog(("%p::In CExposedDocFile::RenameElement(%ws, %ws)\n",
  1206. this, pwcsName, pwcsNewName));
  1207. olDebugOut((DEB_TRACE, "In CExposedDocFile::RenameElement(%ws, %ws)\n",
  1208. pwcsName, pwcsNewName));
  1209. OL_VALIDATE(RenameElement(pwcsName,
  1210. pwcsNewName));
  1211. olChk(Validate());
  1212. dfnOld.Set(pwcsName);
  1213. dfnNew.Set(pwcsNewName);
  1214. BEGIN_PENDING_LOOP;
  1215. olChk(TakeSafeSem());
  1216. SafeWriteAccess();
  1217. #ifdef DIRECTWRITERLOCK
  1218. olChk(ValidateWriteAccess());
  1219. #endif
  1220. sc = _pdf->RenameEntry(&dfnOld, &dfnNew);
  1221. END_PENDING_LOOP;
  1222. olDebugOut((DEB_TRACE, "Out CExposedDocFile::RenameElement\n"));
  1223. EH_Err:
  1224. olLog(("%p::Out CExposedDocFile::RenameElement(). ret == %lx\n",
  1225. this, sc));
  1226. return _OLERETURN(sc);
  1227. }
  1228. //+--------------------------------------------------------------
  1229. //
  1230. // Member: CExposedDocFile::SetElementTimes, public
  1231. //
  1232. // Synopsis: Sets element time stamps
  1233. //
  1234. // Arguments: [pwcsName] - Name
  1235. // [pctime] - create time
  1236. // [patime] - access time
  1237. // [pmtime] - modify time
  1238. //
  1239. // Returns: Appropriate status code
  1240. //
  1241. // History: 05-Oct-92 AlexT Created
  1242. //
  1243. //---------------------------------------------------------------
  1244. _OLESTDMETHODIMP CExposedDocFile::SetElementTimes(WCHAR const *pwcsName,
  1245. FILETIME const *pctime,
  1246. FILETIME const *patime,
  1247. FILETIME const *pmtime)
  1248. {
  1249. SCODE sc;
  1250. SAFE_SEM;
  1251. SAFE_ACCESS;
  1252. CDfName dfn;
  1253. CDfName *pdfn = NULL;
  1254. FILETIME ctime, atime, mtime;
  1255. olLog(("%p::In CExposedDocFile::SetElementTimes(%ws, %p, %p, %p)\n",
  1256. this, pwcsName, pctime, patime, pmtime));
  1257. olDebugOut((DEB_TRACE, "In CExposedDocFile::SetElementTimes:%p("
  1258. "%ws, %p, %p, %p)\n", this, pwcsName, pctime, patime, pmtime));
  1259. OL_VALIDATE(SetElementTimes(pwcsName,
  1260. pctime,
  1261. patime,
  1262. pmtime));
  1263. olChk(Validate());
  1264. // Probe arguments and make local copies if necessary
  1265. if (pctime)
  1266. {
  1267. ctime = *pctime;
  1268. pctime = &ctime;
  1269. }
  1270. if (patime)
  1271. {
  1272. atime = *patime;
  1273. patime = &atime;
  1274. }
  1275. if (pmtime)
  1276. {
  1277. mtime = *pmtime;
  1278. pmtime = &mtime;
  1279. }
  1280. if (pwcsName != NULL)
  1281. {
  1282. dfn.Set(pwcsName);
  1283. pdfn = &dfn;
  1284. }
  1285. BEGIN_PENDING_LOOP;
  1286. olChk(TakeSafeSem());
  1287. SafeWriteAccess();
  1288. #ifdef DIRECTWRITERLOCK
  1289. olChk(ValidateWriteAccess());
  1290. #endif
  1291. sc = _pdf->SetElementTimes(pdfn, pctime, patime, pmtime);
  1292. END_PENDING_LOOP;
  1293. olDebugOut((DEB_TRACE, "Out CExposedDocFile::SetElementTimes\n"));
  1294. EH_Err:
  1295. olLog(("%p::Out CExposedDocFile::SetElementTimes(). ret == %lx\n",
  1296. this, sc));
  1297. return _OLERETURN(sc);
  1298. }
  1299. //+--------------------------------------------------------------
  1300. //
  1301. // Member: CExposedDocFile::SetClass, public
  1302. //
  1303. // Synopsis: Sets storage class
  1304. //
  1305. // Arguments: [clsid] - class id
  1306. //
  1307. // Returns: Appropriate status code
  1308. //
  1309. // History: 05-Oct-92 AlexT Created
  1310. //
  1311. //---------------------------------------------------------------
  1312. STDMETHODIMP CExposedDocFile::SetClass(REFCLSID rclsid)
  1313. {
  1314. SCODE sc;
  1315. SAFE_SEM;
  1316. SAFE_ACCESS;
  1317. CLSID clsid;
  1318. olLog(("%p::In CExposedDocFile::SetClass(?)\n", this));
  1319. olDebugOut((DEB_TRACE, "In CExposedDocFile::SetClass:%p(?)\n", this));
  1320. OL_VALIDATE(SetClass(rclsid));
  1321. olChk(Validate());
  1322. clsid = rclsid;
  1323. BEGIN_PENDING_LOOP;
  1324. olChk(TakeSafeSem());
  1325. SafeWriteAccess();
  1326. #ifdef DIRECTWRITERLOCK
  1327. olChk(ValidateWriteAccess());
  1328. #endif
  1329. sc = _pdf->SetClass(clsid);
  1330. END_PENDING_LOOP;
  1331. olDebugOut((DEB_TRACE, "Out CExposedDocFile::SetClass\n"));
  1332. EH_Err:
  1333. olLog(("%p::Out CExposedDocFile::SetClass(). ret == %lx\n",
  1334. this, sc));
  1335. return ResultFromScode(sc);
  1336. }
  1337. //+--------------------------------------------------------------
  1338. //
  1339. // Member: CExposedDocFile::SetStateBits, public
  1340. //
  1341. // Synopsis: Sets state bits
  1342. //
  1343. // Arguments: [grfStateBits] - state bits
  1344. // [grfMask] - state bits mask
  1345. //
  1346. // Returns: Appropriate status code
  1347. //
  1348. // History: 05-Oct-92 AlexT Created
  1349. //
  1350. //---------------------------------------------------------------
  1351. STDMETHODIMP CExposedDocFile::SetStateBits(DWORD grfStateBits, DWORD grfMask)
  1352. {
  1353. SCODE sc;
  1354. SAFE_SEM;
  1355. SAFE_ACCESS;
  1356. olLog(("%p::In CExposedDocFile::SetStateBits(%lu, %lu)\n", this,
  1357. grfStateBits, grfMask));
  1358. olDebugOut((DEB_TRACE, "In CExposedDocFile::SetStateBits:%p("
  1359. "%lu, %lu)\n", this, grfStateBits, grfMask));
  1360. OL_VALIDATE(SetStateBits(grfStateBits, grfMask));
  1361. olChk(Validate());
  1362. BEGIN_PENDING_LOOP;
  1363. olChk(TakeSafeSem());
  1364. SafeWriteAccess();
  1365. #ifdef DIRECTWRITERLOCK
  1366. olChk(ValidateWriteAccess());
  1367. #endif
  1368. sc = _pdf->SetStateBits(grfStateBits, grfMask);
  1369. END_PENDING_LOOP;
  1370. olDebugOut((DEB_TRACE, "Out CExposedDocFile::SetStateBits\n"));
  1371. EH_Err:
  1372. olLog(("%p::Out CExposedDocFile::SetStateBits(). ret == %lx\n",
  1373. this, sc));
  1374. return ResultFromScode(sc);
  1375. }
  1376. //+--------------------------------------------------------------
  1377. //
  1378. // Member: CExposedDocFile::Stat, public
  1379. //
  1380. // Synopsis: Fills in a buffer of information about this object
  1381. //
  1382. // Arguments: [pstatstg] - Buffer
  1383. //
  1384. // Returns: Appropriate status code
  1385. //
  1386. // Modifies: [pstatstg]
  1387. //
  1388. // History: 24-Mar-92 DrewB Created
  1389. //
  1390. //---------------------------------------------------------------
  1391. _OLESTDMETHODIMP CExposedDocFile::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
  1392. {
  1393. SAFE_SEM;
  1394. SAFE_ACCESS;
  1395. SCODE sc;
  1396. STATSTGW stat;
  1397. olLog(("%p::In CExposedDocFile::Stat(%p)\n", this, pstatstg));
  1398. olDebugOut((DEB_TRACE, "In CExposedDocFile::Stat(%p)\n", pstatstg));
  1399. OL_VALIDATE(Stat(pstatstg, grfStatFlag));
  1400. BEGIN_PENDING_LOOP;
  1401. olChk(TakeSafeSem());
  1402. SafeReadAccess();
  1403. sc = _pdf->Stat(&stat, grfStatFlag);
  1404. END_PENDING_LOOP;
  1405. if (SUCCEEDED(sc))
  1406. {
  1407. TRY
  1408. {
  1409. *pstatstg = stat;
  1410. pstatstg->type = STGTY_STORAGE;
  1411. ULISet32(pstatstg->cbSize, 0);
  1412. pstatstg->grfLocksSupported = 0;
  1413. pstatstg->STATSTG_dwStgFmt = 0;
  1414. }
  1415. CATCH(CException, e)
  1416. {
  1417. UNREFERENCED_PARM(e);
  1418. if (stat.pwcsName)
  1419. TaskMemFree(stat.pwcsName);
  1420. }
  1421. END_CATCH
  1422. }
  1423. olDebugOut((DEB_TRACE, "Out CExposedDocFile::Stat\n"));
  1424. EH_Err:
  1425. olLog(("%p::Out CExposedDocFile::Stat(). *pstatstg == %p ret == %lx\n",
  1426. this, *pstatstg, sc));
  1427. return _OLERETURN(sc);
  1428. }
  1429. //+--------------------------------------------------------------
  1430. //
  1431. // Member: CExposedDocFile::AddRef, public
  1432. //
  1433. // Synopsis: Increments the ref count
  1434. //
  1435. // Returns: Appropriate status code
  1436. //
  1437. // History: 16-Mar-92 DrewB Created
  1438. //
  1439. //---------------------------------------------------------------
  1440. STDMETHODIMP_(ULONG) CExposedDocFile::AddRef(void)
  1441. {
  1442. ULONG ulRet;
  1443. olLog(("%p::In CExposedDocFile::AddRef()\n", this));
  1444. olDebugOut((DEB_TRACE, "In CExposedDocFile::AddRef()\n"));
  1445. if (FAILED(Validate()))
  1446. return 0;
  1447. InterlockedIncrement(&_cReferences);
  1448. ulRet = _cReferences;
  1449. olDebugOut((DEB_TRACE, "Out CExposedDocFile::AddRef %p()=> %lu\n",
  1450. this, _cReferences));
  1451. olLog(("%p::Out CExposedDocFile::AddRef(). ret == %lu\n", this, ulRet));
  1452. return ulRet;
  1453. }
  1454. //+--------------------------------------------------------------
  1455. //
  1456. // Member: CExposedDocFile::QueryInterface, public
  1457. //
  1458. // Synopsis: Returns an object for the requested interface
  1459. //
  1460. // Arguments: [iid] - Interface ID
  1461. // [ppvObj] - Object return
  1462. //
  1463. // Returns: Appropriate status code
  1464. //
  1465. // Modifies: [ppvObj]
  1466. //
  1467. // History: 26-Mar-92 DrewB Created
  1468. //
  1469. //---------------------------------------------------------------
  1470. STDMETHODIMP CExposedDocFile::QueryInterface(REFIID iid, void **ppvObj)
  1471. {
  1472. SCODE sc;
  1473. #ifdef MULTIHEAP
  1474. CSafeMultiHeap smh(_ppc);
  1475. #endif
  1476. olLog(("%p::In CExposedDocFile::QueryInterface(?, %p)\n",
  1477. this, ppvObj));
  1478. olDebugOut((DEB_TRACE, "In CExposedDocFile::QueryInterface(?, %p)\n",
  1479. ppvObj));
  1480. OL_VALIDATE(QueryInterface(iid, ppvObj));
  1481. olChk(Validate());
  1482. olChk(_pdf->CheckReverted());
  1483. sc = S_OK;
  1484. if (IsEqualIID(iid, IID_IStorage) || IsEqualIID(iid, IID_IUnknown))
  1485. {
  1486. *ppvObj = (IStorage *)this;
  1487. CExposedDocFile::AddRef();
  1488. }
  1489. else if (IsEqualIID(iid, IID_IMarshal))
  1490. {
  1491. if (P_PRIORITY(_pdf->GetDFlags()) && _pdf->IsRoot())
  1492. olErr(EH_Err, E_NOINTERFACE);
  1493. //If the ILockBytes we'd need to marshal doesn't support IMarshal
  1494. // then we want to do standard marshalling on the storage, mostly
  1495. // to prevent deadlock problems but also because you'll get better
  1496. // performance. So check, then do the right thing.
  1497. IMarshal *pim;
  1498. ILockBytes *plkb;
  1499. plkb = _ppc->GetOriginal();
  1500. if (plkb == NULL)
  1501. {
  1502. plkb = _ppc->GetBase();
  1503. }
  1504. sc = plkb->QueryInterface(IID_IMarshal, (void **)&pim);
  1505. if (FAILED(sc))
  1506. {
  1507. olErr(EH_Err, E_NOINTERFACE);
  1508. }
  1509. pim->Release();
  1510. #ifdef MULTIHEAP
  1511. if (_ppc->GetHeapBase() == NULL)
  1512. olErr (EH_Err, E_NOINTERFACE);
  1513. #endif
  1514. *ppvObj = (IMarshal *)this;
  1515. CExposedDocFile::AddRef();
  1516. }
  1517. else if (IsEqualIID(iid, IID_IRootStorage))
  1518. {
  1519. #ifdef COORD
  1520. if ((!_pdf->IsRoot()) && (!_pdf->IsCoord()))
  1521. #else
  1522. if (!_pdf->IsRoot())
  1523. #endif
  1524. olErr(EH_Err, E_NOINTERFACE);
  1525. *ppvObj = (IRootStorage *)this;
  1526. CExposedDocFile::AddRef();
  1527. }
  1528. #ifdef NEWPROPS
  1529. else if (IsEqualIID(iid, IID_IPropertySetStorage))
  1530. {
  1531. *ppvObj = (IPropertySetStorage *)this;
  1532. CExposedDocFile::AddRef();
  1533. }
  1534. #endif
  1535. #ifdef ASYNC
  1536. else if (IsEqualIID(iid, IID_IConnectionPointContainer) &&
  1537. _cpoint.IsInitialized())
  1538. {
  1539. *ppvObj = (IConnectionPointContainer *)this;
  1540. CExposedDocFile::AddRef();
  1541. }
  1542. #endif
  1543. #if WIN32 >= 300
  1544. else if (_pdf->IsRoot() && IsEqualIID(iid, IID_IAccessControl))
  1545. {
  1546. ILockBytes *piLB = _pdf->GetBaseMS()->GetILB();
  1547. olAssert((piLB != NULL));
  1548. SCODE scode = S_OK;
  1549. if (_pIAC == NULL) // use existing _pIAC if available
  1550. scode = piLB->QueryInterface(IID_IAccessControl,(void **)&_pIAC);
  1551. if (SUCCEEDED(scode))
  1552. {
  1553. *ppvObj = (IAccessControl *)this;
  1554. CExposedDocFile::AddRef();
  1555. }
  1556. else sc = E_NOINTERFACE;
  1557. }
  1558. #endif
  1559. #ifdef DIRECTWRITERLOCK
  1560. else if (_pdf->IsRoot() && IsEqualIID(iid, IID_IDirectWriterLock) &&
  1561. _pdfb->DirectWriterMode())
  1562. {
  1563. *ppvObj = (IDirectWriterLock *) this;
  1564. CExposedDocFile::AddRef();
  1565. }
  1566. #endif // DIRECTWRITERLOCK
  1567. else if( IsEqualIID( iid, IID_IPropertyBagEx ))
  1568. {
  1569. *ppvObj = static_cast<IPropertyBagEx*>(&_PropertyBagEx);
  1570. CExposedDocFile::AddRef();
  1571. }
  1572. else if( IsEqualIID( iid, IID_IPropertyBag ))
  1573. {
  1574. *ppvObj = static_cast<IPropertyBag*>(&_PropertyBagEx);
  1575. CExposedDocFile::AddRef();
  1576. }
  1577. else
  1578. sc = E_NOINTERFACE;
  1579. olDebugOut((DEB_TRACE, "Out CExposedDocFile::QueryInterface => %p\n",
  1580. *ppvObj));
  1581. EH_Err:
  1582. olLog(("%p::Out CExposedDocFile::QueryInterface(). "
  1583. "*ppvObj == %p ret == %lx\n", this, *ppvObj, sc));
  1584. return ResultFromScode(sc);
  1585. }
  1586. //+--------------------------------------------------------------
  1587. //
  1588. // Method: CExposedDocFile::CopySStreamToIStream, private
  1589. //
  1590. // Synopsis: Copies a PSStream to an IStream
  1591. //
  1592. // Arguments: [psstFrom] - SStream
  1593. // [pstTo] - IStream
  1594. //
  1595. // Returns: Appropriate status code
  1596. //
  1597. // History: 07-May-92 DrewB Created
  1598. // 26-Jun-92 AlexT Moved to CExposedDocFile
  1599. // so we can call SetReadAccess
  1600. //
  1601. //---------------------------------------------------------------
  1602. SCODE CExposedDocFile::CopySStreamToIStream(PSStream *psstFrom,
  1603. IStream *pstTo)
  1604. {
  1605. BYTE *pbBuffer;
  1606. SCODE sc;
  1607. #ifdef LARGE_STREAMS
  1608. ULONGLONG cbPos;
  1609. ULONG cbRead, cbWritten;
  1610. #else
  1611. ULONG cbRead, cbWritten, cbPos, cbSizeLow;
  1612. #endif
  1613. ULONG ulBufferSize;
  1614. ULARGE_INTEGER cbSize;
  1615. cbSize.QuadPart = 0;
  1616. ulBufferSize = (_pdfb->GetOpenFlags() & DF_LARGE) ?
  1617. LARGESTREAMBUFFERSIZE : STREAMBUFFERSIZE;
  1618. // This is part of CopyTo and therefore we are allowed to
  1619. // fail with out-of-memory
  1620. olChk(GetBuffer(STREAMBUFFERSIZE, ulBufferSize, &pbBuffer, &ulBufferSize));
  1621. // Set destination size for contiguity
  1622. SetReadAccess();
  1623. #ifdef LARGE_STREAMS
  1624. psstFrom->GetSize(&cbSize.QuadPart);
  1625. #else
  1626. psstFrom->GetSize(&cbSize.LowPart);
  1627. cbSize.HighPart = 0;
  1628. #endif
  1629. ClearReadAccess();
  1630. // Don't need to SetReadAccess here because pstTo is an IStream
  1631. olHChk(pstTo->SetSize(cbSize));
  1632. // Copy between streams
  1633. cbPos = 0;
  1634. for (;;)
  1635. {
  1636. SetReadAccess();
  1637. olChk(psstFrom->ReadAt(cbPos, pbBuffer, ulBufferSize,
  1638. (ULONG STACKBASED *)&cbRead));
  1639. ClearReadAccess();
  1640. if (cbRead == 0) // EOF
  1641. break;
  1642. // Don't need to SetReadAccess here because pstTo is an IStream
  1643. olHChk(pstTo->Write(pbBuffer, cbRead, &cbWritten));
  1644. if (cbRead != cbWritten)
  1645. olErr(EH_Err, STG_E_WRITEFAULT);
  1646. cbPos += cbWritten;
  1647. }
  1648. sc = S_OK;
  1649. EH_Err:
  1650. DfMemFree(pbBuffer);
  1651. return sc;
  1652. }
  1653. //+--------------------------------------------------------------
  1654. //
  1655. // Method: CExposedDocFile::CopyDocFileToIStorage, private
  1656. //
  1657. // Synopsis: Copies a docfile's contents to an IStorage
  1658. //
  1659. // Arguments: [pdfFrom] - From
  1660. // [pstgTo] - To
  1661. // [snbExclude] - Names to not copy
  1662. // [dwCopyFlags] - Bitwise flags for types of objects to copy
  1663. //
  1664. // Returns: Appropriate status code
  1665. //
  1666. // History: 07-May-92 DrewB Created
  1667. // 26-Jun-92 AlexT Moved to CExposedDocFile
  1668. // so we can call SetReadAccess
  1669. //
  1670. //---------------------------------------------------------------
  1671. // Variables used by CopyDocFileToIStorage that we
  1672. // want to allocate dynamically rather than eating stack space
  1673. struct SCopyVars : public CLocalAlloc
  1674. {
  1675. PSStream *psstFrom;
  1676. IStream *pstTo;
  1677. PDocFile *pdfFromChild;
  1678. IStorage *pstgToChild;
  1679. DWORD grfStateBits;
  1680. CLSID clsid;
  1681. CDfName dfnKey;
  1682. SIterBuffer ib;
  1683. OLECHAR atcName[CWCSTORAGENAME];
  1684. };
  1685. SCODE CExposedDocFile::CopyDocFileToIStorage(PDocFile *pdfFrom,
  1686. IStorage *pstgTo,
  1687. SNBW snbExclude,
  1688. DWORD dwCopyFlags)
  1689. {
  1690. SCODE sc;
  1691. SCopyVars *pcv = NULL;
  1692. olDebugOut((DEB_ITRACE, "In CopyDocFileToIStorage:%p(%p, %p, %p, %lX)\n",
  1693. this, pdfFrom, pstgTo, snbExclude, dwCopyFlags));
  1694. // Allocate variables dynamically to conserve stack space since
  1695. // this is a recursive call
  1696. olMem(pcv = new SCopyVars);
  1697. SetReadAccess();
  1698. sc = pdfFrom->GetClass(&pcv->clsid);
  1699. ClearReadAccess();
  1700. olChk(sc);
  1701. // Assume STG_E_INVALIDFUNCTION means that the destination storage
  1702. // doesn't support class IDs
  1703. sc = GetScode(pstgTo->SetClass(pcv->clsid));
  1704. if (FAILED(sc) && sc != STG_E_INVALIDFUNCTION)
  1705. olErr(EH_Err, sc);
  1706. SetReadAccess();
  1707. sc = pdfFrom->GetStateBits(&pcv->grfStateBits);
  1708. ClearReadAccess();
  1709. olChk(sc);
  1710. sc = GetScode(pstgTo->SetStateBits(pcv->grfStateBits, 0xffffffff));
  1711. if (FAILED(sc) && sc != STG_E_INVALIDFUNCTION)
  1712. olErr(EH_Err, sc);
  1713. for (;;)
  1714. {
  1715. SetReadAccess();
  1716. sc = pdfFrom->FindGreaterEntry(&pcv->dfnKey, &pcv->ib, NULL);
  1717. ClearReadAccess();
  1718. if (sc == STG_E_NOMOREFILES)
  1719. break;
  1720. else if (FAILED(sc))
  1721. olErr(EH_pdfi, sc);
  1722. pcv->dfnKey.Set(&pcv->ib.dfnName);
  1723. if (snbExclude && NameInSNB(&pcv->ib.dfnName, snbExclude) == S_OK)
  1724. continue;
  1725. if ((pcv->ib.type == STGTY_STORAGE &&
  1726. (dwCopyFlags & COPY_STORAGES) == 0) ||
  1727. (pcv->ib.type == STGTY_STREAM &&
  1728. (dwCopyFlags & COPY_STREAMS) == 0))
  1729. continue;
  1730. switch(pcv->ib.type)
  1731. {
  1732. case STGTY_STORAGE:
  1733. // Embedded DocFile, create destination and recurse
  1734. SetReadAccess();
  1735. sc = pdfFrom->GetDocFile(&pcv->ib.dfnName, DF_READ,
  1736. pcv->ib.type, &pcv->pdfFromChild);
  1737. ClearReadAccess();
  1738. olChkTo(EH_pdfi, sc);
  1739. // Not optimally efficient, but reduces #ifdef's
  1740. lstrcpyW(pcv->atcName, (WCHAR *)pcv->ib.dfnName.GetBuffer());
  1741. // Don't need to SetReadAccess here because pstgTo is an IStorage.
  1742. #ifdef MULTIHEAP
  1743. {
  1744. CSafeMultiHeap smh(_ppc);
  1745. // if pstgTo is an IStorage proxy, then returned IStorage
  1746. // can be custom marshaled and allocator state is lost
  1747. #endif
  1748. sc = DfGetScode(pstgTo->CreateStorage(pcv->atcName, STGM_WRITE |
  1749. STGM_SHARE_EXCLUSIVE |
  1750. STGM_FAILIFTHERE,
  1751. 0, 0, &pcv->pstgToChild));
  1752. if (sc == STG_E_FILEALREADYEXISTS)
  1753. //We need read and write permissions so we can traverse
  1754. // the destination IStorage
  1755. olHChkTo(EH_Get, pstgTo->OpenStorage(pcv->atcName, NULL,
  1756. STGM_READWRITE |
  1757. STGM_SHARE_EXCLUSIVE,
  1758. NULL, 0,
  1759. &pcv->pstgToChild));
  1760. else if (FAILED(sc))
  1761. olErr(EH_Get, sc);
  1762. #ifdef MULTIHEAP
  1763. }
  1764. #endif
  1765. olChkTo(EH_Create,
  1766. CopyDocFileToIStorage(pcv->pdfFromChild, pcv->pstgToChild,
  1767. NULL, dwCopyFlags));
  1768. pcv->pdfFromChild->Release();
  1769. pcv->pstgToChild->Release();
  1770. break;
  1771. case STGTY_STREAM:
  1772. SetReadAccess();
  1773. sc = pdfFrom->GetStream(&pcv->ib.dfnName, DF_READ,
  1774. pcv->ib.type, &pcv->psstFrom);
  1775. ClearReadAccess();
  1776. olChkTo(EH_pdfi, sc);
  1777. // Not optimally efficient, but reduces #ifdef's
  1778. lstrcpyW(pcv->atcName, (WCHAR *)pcv->ib.dfnName.GetBuffer());
  1779. // Don't need to SetReadAccess here because pstgTo is an IStorage.
  1780. #ifdef MULTIHEAP
  1781. {
  1782. CSafeMultiHeap smh(_ppc);
  1783. // if pstgTo is an IStorage proxy, then returned IStream
  1784. // can be custom marshaled and allocator state is lost
  1785. #endif
  1786. olHChkTo(EH_Get,
  1787. pstgTo->CreateStream(pcv->atcName, STGM_WRITE |
  1788. STGM_SHARE_EXCLUSIVE |
  1789. STGM_CREATE,
  1790. 0, 0, &pcv->pstTo));
  1791. #ifdef MULTIHEAP
  1792. }
  1793. #endif
  1794. olChkTo(EH_Create,
  1795. CopySStreamToIStream(pcv->psstFrom, pcv->pstTo));
  1796. pcv->psstFrom->Release();
  1797. pcv->pstTo->Release();
  1798. break;
  1799. default:
  1800. olAssert(!aMsg("Unknown type in CopyDocFileToIStorage"));
  1801. break;
  1802. }
  1803. }
  1804. olDebugOut((DEB_ITRACE, "Out CopyDocFileToIStorage\n"));
  1805. sc = S_OK;
  1806. EH_pdfi:
  1807. EH_Err:
  1808. delete pcv;
  1809. return sc;
  1810. EH_Create:
  1811. if (pcv->ib.type == STGTY_STORAGE)
  1812. pcv->pstgToChild->Release();
  1813. else
  1814. pcv->pstTo->Release();
  1815. olVerSucc(pstgTo->DestroyElement(pcv->atcName));
  1816. EH_Get:
  1817. if (pcv->ib.type == STGTY_STORAGE)
  1818. pcv->pdfFromChild->Release();
  1819. else
  1820. pcv->psstFrom->Release();
  1821. goto EH_Err;
  1822. }
  1823. //+--------------------------------------------------------------
  1824. //
  1825. // Member: CExposedDocFile::Unmarshal, public
  1826. //
  1827. // Synopsis: Creates a duplicate DocFile from parts
  1828. //
  1829. // Arguments: [pstm] - Marshal stream
  1830. // [ppv] - Object return
  1831. // [mshlflags] - Marshal flags
  1832. //
  1833. // Returns: Appropriate status code
  1834. //
  1835. // Modifies: [ppv]
  1836. //
  1837. // History: 26-Feb-92 DrewB Created
  1838. //
  1839. //---------------------------------------------------------------
  1840. SCODE CExposedDocFile::Unmarshal(IStream *pstm,
  1841. void **ppv,
  1842. DWORD mshlflags)
  1843. {
  1844. SCODE sc;
  1845. CDfMutex mtx;
  1846. CPerContext *ppc;
  1847. CPubDocFile *pdf;
  1848. CGlobalContext *pgc;
  1849. CDFBasis *pdfb;
  1850. CExposedDocFile *pedf;
  1851. IStorage *pstgStd = NULL;
  1852. ULONG_PTR df;
  1853. #ifdef ASYNC
  1854. DWORD dwAsyncFlags;
  1855. IDocfileAsyncConnectionPoint *pdacp;
  1856. #endif
  1857. #ifdef POINTER_IDENTITY
  1858. CMarshalList *pml;
  1859. #endif
  1860. olDebugOut((DEB_ITRACE, "In CExposedDocFile::Unmarshal(%p, %p)\n",
  1861. pstm, ppv));
  1862. #ifdef MULTIHEAP
  1863. void *pvBaseOld;
  1864. void *pvBaseNew;
  1865. ContextId cntxid;
  1866. CPerContext pcSharedMemory (NULL); // bootstrap object
  1867. #endif
  1868. //First unmarshal the standard marshalled version
  1869. sc = CoUnmarshalInterface(pstm, IID_IStorage, (void**)&pstgStd);
  1870. if (FAILED(sc))
  1871. {
  1872. // assume that entire standard marshaling stream has been read
  1873. olAssert (pstgStd == NULL);
  1874. sc = S_OK;
  1875. }
  1876. #ifdef MULTIHEAP
  1877. sc = UnmarshalSharedMemory(pstm, mshlflags, &pcSharedMemory, &cntxid);
  1878. if (!SUCCEEDED(sc))
  1879. {
  1880. #ifdef POINTER_IDENTITY
  1881. UnmarshalPointer(pstm, (void **) &pedf);
  1882. #endif
  1883. UnmarshalPointer(pstm, (void **)&pdf);
  1884. UnmarshalPointer(pstm, (void **)&pdfb);
  1885. UnmarshalPointer(pstm, (void **)&df);
  1886. #ifdef ASYNC
  1887. ReleaseContext(pstm, TRUE, P_INDEPENDENT(df) != 0, mshlflags);
  1888. ReleaseConnection(pstm, mshlflags);
  1889. #else
  1890. ReleaseContext(pstm, P_INDEPENDENT(df), mshlflags);
  1891. #endif
  1892. olChkTo(EH_std, sc);
  1893. }
  1894. pvBaseOld = DFBASEPTR;
  1895. #endif
  1896. #ifdef POINTER_IDENTITY
  1897. olChkTo(EH_mem, UnmarshalPointer(pstm, (void **) &pedf));
  1898. #endif
  1899. olChkTo(EH_mem, UnmarshalPointer(pstm, (void **)&pdf));
  1900. olChkTo(EH_mem, CPubDocFile::Validate(pdf));
  1901. olChkTo(EH_pdf, UnmarshalPointer(pstm, (void **)&pdfb));
  1902. olChkTo(EH_pdfb, UnmarshalPointer(pstm, (void **) &df));
  1903. olChkTo(EH_pdfb, UnmarshalPointer(pstm, (void **)&pgc));
  1904. olChkTo(EH_pgc, ValidateBuffer(pgc, sizeof(CGlobalContext)));
  1905. //So far, nothing has called into the tree so we don't really need
  1906. // to be holding the tree mutex. The UnmarshalContext call does
  1907. // call into the tree, though, so we need to make sure this is
  1908. // threadsafe. We'll do this my getting the mutex name from the
  1909. // CGlobalContext, then creating a new CDfMutex object. While
  1910. // this is obviously not optimal, since it's possible we could
  1911. // reuse an existing CDfMutex, the reuse strategy isn't threadsafe
  1912. // since we can't do a lookup without the possibility of the thing
  1913. // we're looking for being released by another thread.
  1914. TCHAR atcMutexName[CONTEXT_MUTEX_NAME_LENGTH];
  1915. pgc->GetMutexName(atcMutexName);
  1916. olChkTo(EH_pgc, mtx.Init(atcMutexName));
  1917. olChkTo(EH_pgc, mtx.Take(INFINITE));
  1918. //At this point we're holding the mutex.
  1919. #ifdef MULTIHEAP
  1920. #ifdef ASYNC
  1921. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1922. pgc,
  1923. &ppc,
  1924. mshlflags,
  1925. TRUE,
  1926. P_INDEPENDENT(pdf->GetDFlags()),
  1927. cntxid,
  1928. pdf->IsRoot()));
  1929. #else
  1930. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1931. pgc,
  1932. &ppc,
  1933. mshlflags,
  1934. P_INDEPENDENT(pdf->GetDFlags()),
  1935. cntxid,
  1936. pdf->IsRoot()));
  1937. #endif
  1938. if ((pvBaseNew = DFBASEPTR) != pvBaseOld)
  1939. {
  1940. pdf = (CPubDocFile*) ((ULONG_PTR)pdf - (ULONG_PTR)pvBaseOld
  1941. + (ULONG_PTR)pvBaseNew);
  1942. pedf = (CExposedDocFile*) ((ULONG_PTR)pedf - (ULONG_PTR)pvBaseOld
  1943. + (ULONG_PTR)pvBaseNew);
  1944. pdfb = (CDFBasis*) ((ULONG_PTR)pdfb - (ULONG_PTR)pvBaseOld
  1945. + (ULONG_PTR)pvBaseNew);
  1946. }
  1947. #else
  1948. #ifdef ASYNC
  1949. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1950. pgc,
  1951. &ppc,
  1952. mshlflags,
  1953. TRUE,
  1954. P_INDEPENDENT(pdf->GetDFlags()),
  1955. pdf->IsRoot()));
  1956. #else
  1957. olChkTo(EH_mtx, UnmarshalContext(pstm,
  1958. pgc,
  1959. &ppc,
  1960. mshlflags,
  1961. P_INDEPENDENT(pdf->GetDFlags()),
  1962. pdf->IsRoot()));
  1963. #endif //ASYNC
  1964. #endif
  1965. #ifdef ASYNC
  1966. olChkTo(EH_mtx, UnmarshalConnection(pstm,
  1967. &dwAsyncFlags,
  1968. &pdacp,
  1969. mshlflags));
  1970. #endif
  1971. // if we use up 1Gig of address space, use standard unmarshaling
  1972. if (gs_iSharedHeaps > (DOCFILE_SM_LIMIT / DOCFILE_SM_SIZE))
  1973. olErr (EH_ppc, STG_E_INSUFFICIENTMEMORY);
  1974. #ifdef POINTER_IDENTITY
  1975. olAssert (pedf != NULL);
  1976. pml = (CMarshalList *) pedf;
  1977. // Warning: these checks must remain valid across processes
  1978. if (SUCCEEDED(pedf->Validate()) && pedf->GetPub() == pdf)
  1979. {
  1980. pedf = (CExposedDocFile *) pml->FindMarshal(GetCurrentContextId());
  1981. }
  1982. else
  1983. {
  1984. pml = NULL;
  1985. pedf = NULL;
  1986. }
  1987. // exposed object is not found or has been deleted
  1988. if (pedf == NULL)
  1989. {
  1990. #endif
  1991. olMemTo(EH_ppc, pedf = new (pdfb->GetMalloc())
  1992. CExposedDocFile(pdf, pdfb, ppc));
  1993. olChkTo(EH_exp, pedf->InitMarshal(dwAsyncFlags, pdacp));
  1994. //InitMarshal adds a reference.
  1995. if (pdacp)
  1996. pdacp->Release();
  1997. #ifdef POINTER_IDENTITY
  1998. if (pml) pml->AddMarshal(pedf);
  1999. pdf->vAddRef(); // CExposedDocFile ctor does not AddRef
  2000. }
  2001. else
  2002. {
  2003. pdfb->SetAccess(ppc);
  2004. pedf->AddRef(); // reuse this object
  2005. ppc->Release(); // reuse percontext
  2006. }
  2007. #else
  2008. pdf->vAddRef();
  2009. #endif
  2010. *ppv = (void *)pedf;
  2011. #ifdef MULTIHEAP
  2012. if (pvBaseOld != pvBaseNew)
  2013. {
  2014. pcSharedMemory.SetThreadAllocatorState(NULL);
  2015. g_smAllocator.Uninit(); // delete the extra mapping
  2016. }
  2017. g_smAllocator.SetState(NULL, NULL, 0, NULL, NULL);
  2018. #endif
  2019. mtx.Release();
  2020. //We're returning the custom marshalled version, so we don't need
  2021. //the std marshalled one anymore.
  2022. if (pstgStd != NULL)
  2023. pstgStd->Release();
  2024. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::Unmarshal => %p\n", *ppv));
  2025. return S_OK;
  2026. EH_exp:
  2027. pedf->Release();
  2028. goto EH_Err;
  2029. EH_ppc:
  2030. ppc->Release();
  2031. EH_mtx:
  2032. mtx.Release();
  2033. goto EH_Err;
  2034. EH_pgc:
  2035. CoReleaseMarshalData(pstm); // release the ILockBytes
  2036. CoReleaseMarshalData(pstm); // release the ILockBytes
  2037. if (P_INDEPENDENT(pdf->GetDFlags()))
  2038. CoReleaseMarshalData(pstm); // release the ILockBytes
  2039. #ifdef ASYNC
  2040. ReleaseConnection(pstm, mshlflags);
  2041. #endif
  2042. EH_pdfb:
  2043. EH_pdf:
  2044. EH_mem:
  2045. EH_Err:
  2046. #ifdef MULTIHEAP
  2047. pcSharedMemory.SetThreadAllocatorState(NULL);
  2048. g_smAllocator.Uninit(); // delete the file mapping in error case
  2049. g_smAllocator.SetState(NULL, NULL, 0, NULL, NULL);
  2050. #endif
  2051. EH_std:
  2052. if (pstgStd != NULL)
  2053. {
  2054. //We can return the standard marshalled version and still succeed.
  2055. *ppv = pstgStd;
  2056. return S_OK;
  2057. }
  2058. return sc;
  2059. }
  2060. //+--------------------------------------------------------------
  2061. //
  2062. // Member: CExposedDocFile::GetUnmarshalClass, public
  2063. //
  2064. // Synopsis: Returns the class ID
  2065. //
  2066. // Arguments: [riid] - IID of object
  2067. // [pv] - Unreferenced
  2068. // [dwDestContext] - Unreferenced
  2069. // [pvDestContext] - Unreferenced
  2070. // [mshlflags] - Unreferenced
  2071. // [pcid] - CLSID return
  2072. //
  2073. // Returns: Appropriate status code
  2074. //
  2075. // Modifies: [pcid]
  2076. //
  2077. // History: 04-May-92 DrewB Created
  2078. //
  2079. //---------------------------------------------------------------
  2080. STDMETHODIMP CExposedDocFile::GetUnmarshalClass(REFIID riid,
  2081. void *pv,
  2082. DWORD dwDestContext,
  2083. LPVOID pvDestContext,
  2084. DWORD mshlflags,
  2085. LPCLSID pcid)
  2086. {
  2087. SCODE sc;
  2088. #ifdef MULTIHEAP
  2089. CSafeMultiHeap smh(_ppc);
  2090. #endif
  2091. olLog(("%p::In CExposedDocFile::GetUnmarshalClass("
  2092. "riid, %p, %lu, %p, %lu, %p)\n",
  2093. this, pv, dwDestContext, pvDestContext, mshlflags, pcid));
  2094. olDebugOut((DEB_TRACE, "In CExposedDocFile::GetUnmarshalClass:%p("
  2095. "riid, %p, %lu, %p, %lu, %p)\n", this,
  2096. pv, dwDestContext, pvDestContext, mshlflags, pcid));
  2097. UNREFERENCED_PARM(pv);
  2098. UNREFERENCED_PARM(mshlflags);
  2099. olChk(ValidateOutBuffer(pcid, sizeof(CLSID)));
  2100. memset(pcid, 0, sizeof(CLSID));
  2101. olChk(ValidateIid(riid));
  2102. olChk(Validate());
  2103. olChk(_pdf->CheckReverted());
  2104. if ((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  2105. {
  2106. IMarshal *pmsh;
  2107. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  2108. dwDestContext, pvDestContext,
  2109. mshlflags, &pmsh)))
  2110. {
  2111. sc = GetScode(pmsh->GetUnmarshalClass(riid, pv, dwDestContext,
  2112. pvDestContext, mshlflags,
  2113. pcid));
  2114. pmsh->Release();
  2115. }
  2116. }
  2117. else if (pvDestContext != NULL)
  2118. {
  2119. sc = STG_E_INVALIDPARAMETER;
  2120. }
  2121. else
  2122. {
  2123. olChk(VerifyIid(riid, IID_IStorage));
  2124. *pcid = CLSID_DfMarshal;
  2125. }
  2126. olDebugOut((DEB_TRACE, "Out CExposedDocFile::GetUnmarshalClass\n"));
  2127. EH_Err:
  2128. olLog(("%p::Out CExposedDocFile::GetUnmarshalClass(). ret = %lx\n",
  2129. this, sc));
  2130. return ResultFromScode(sc);
  2131. }
  2132. //+--------------------------------------------------------------
  2133. //
  2134. // Member: CExposedDocFile::GetMarshalSizeMax, public
  2135. //
  2136. // Synopsis: Returns the size needed for the marshal buffer
  2137. //
  2138. // Arguments: [riid] - IID of object being marshaled
  2139. // [pv] - Unreferenced
  2140. // [dwDestContext] - Unreferenced
  2141. // [pvDestContext] - Unreferenced
  2142. // [mshlflags] - Unreferenced
  2143. // [pcbSize] - Size return
  2144. //
  2145. // Returns: Appropriate status code
  2146. //
  2147. // Modifies: [pcbSize]
  2148. //
  2149. // History: 04-May-92 DrewB Created
  2150. //
  2151. //---------------------------------------------------------------
  2152. STDMETHODIMP CExposedDocFile::GetMarshalSizeMax(REFIID riid,
  2153. void *pv,
  2154. DWORD dwDestContext,
  2155. LPVOID pvDestContext,
  2156. DWORD mshlflags,
  2157. LPDWORD pcbSize)
  2158. {
  2159. SCODE sc;
  2160. #ifdef MULTIHEAP
  2161. CSafeMultiHeap smh(_ppc);
  2162. #endif
  2163. UNREFERENCED_PARM(pv);
  2164. olLog(("%p::In CExposedDocFile::GetMarshalSizeMax("
  2165. "riid, %p, %lu, %p, %lu, %p)\n",
  2166. this, pv, dwDestContext, pvDestContext, mshlflags, pcbSize));
  2167. olDebugOut((DEB_TRACE, "In CExposedDocFile::GetMarshalSizeMax:%p("
  2168. "riid, %p, %lu, %p, %lu, %p)\n", this,
  2169. pv, dwDestContext, pvDestContext, mshlflags, pcbSize));
  2170. olChk(Validate());
  2171. olChk(_pdf->CheckReverted());
  2172. if ((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  2173. {
  2174. IMarshal *pmsh;
  2175. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  2176. dwDestContext, pvDestContext,
  2177. mshlflags, &pmsh)))
  2178. {
  2179. sc = GetScode(pmsh->GetMarshalSizeMax(riid, pv, dwDestContext,
  2180. pvDestContext, mshlflags,
  2181. pcbSize));
  2182. pmsh->Release();
  2183. }
  2184. }
  2185. else if (pvDestContext != NULL)
  2186. {
  2187. sc = STG_E_INVALIDPARAMETER;
  2188. }
  2189. else
  2190. {
  2191. sc = GetStdMarshalSize(riid,
  2192. IID_IStorage,
  2193. dwDestContext,
  2194. pvDestContext,
  2195. mshlflags, pcbSize,
  2196. sizeof(CPubDocFile *)+sizeof(CDFBasis *)+
  2197. sizeof(DFLAGS),
  2198. #ifdef ASYNC
  2199. &_cpoint,
  2200. TRUE,
  2201. #endif
  2202. _ppc, P_INDEPENDENT(_pdf->GetDFlags()));
  2203. DWORD cbSize = 0;
  2204. IMarshal *pmsh;
  2205. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  2206. dwDestContext, pvDestContext,
  2207. mshlflags, &pmsh)))
  2208. {
  2209. sc = GetScode(pmsh->GetMarshalSizeMax(riid, pv, dwDestContext,
  2210. pvDestContext, mshlflags,
  2211. &cbSize));
  2212. pmsh->Release();
  2213. *pcbSize += cbSize;
  2214. }
  2215. }
  2216. olDebugOut((DEB_TRACE, "Out CExposedDocFile::GetMarshalSizeMax\n"));
  2217. EH_Err:
  2218. olLog(("%p::Out CExposedDocFile::GetMarshalSizeMax()."
  2219. "*pcbSize == %lu, ret == %lx\n", this, *pcbSize, sc));
  2220. return ResultFromScode(sc);
  2221. }
  2222. //+--------------------------------------------------------------
  2223. //
  2224. // Member: CExposedDocFile::MarshalInterface, public
  2225. //
  2226. // Synopsis: Marshals a given object
  2227. //
  2228. // Arguments: [pstStm] - Stream to write marshal data into
  2229. // [riid] - Interface to marshal
  2230. // [pv] - Unreferenced
  2231. // [dwDestContext] - Unreferenced
  2232. // [pvDestContext] - Unreferenced
  2233. // [mshlflags] - Unreferenced
  2234. //
  2235. // Returns: Appropriate status code
  2236. //
  2237. // History: 04-May-92 DrewB Created
  2238. //
  2239. //---------------------------------------------------------------
  2240. STDMETHODIMP CExposedDocFile::MarshalInterface(IStream *pstStm,
  2241. REFIID riid,
  2242. void *pv,
  2243. DWORD dwDestContext,
  2244. LPVOID pvDestContext,
  2245. DWORD mshlflags)
  2246. {
  2247. SCODE sc;
  2248. #ifdef MULTIHEAP
  2249. CSafeMultiHeap smh(_ppc);
  2250. #endif
  2251. olLog(("%p::In CExposedDocFile::MarshalInterface("
  2252. "%p, riid, %p, %lu, %p, %lu). Context == %lX\n",
  2253. this, pstStm, pv, dwDestContext,
  2254. pvDestContext, mshlflags,(ULONG)GetCurrentContextId()));
  2255. olDebugOut((DEB_TRACE, "In CExposedDocFile::MarshalInterface:%p("
  2256. "%p, riid, %p, %lu, %p, %lu)\n", this, pstStm, pv,
  2257. dwDestContext, pvDestContext, mshlflags));
  2258. UNREFERENCED_PARM(pv);
  2259. olChk(Validate());
  2260. olChk(_pdf->CheckReverted());
  2261. if ((dwDestContext != MSHCTX_LOCAL) && (dwDestContext != MSHCTX_INPROC))
  2262. {
  2263. IMarshal *pmsh;
  2264. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  2265. dwDestContext, pvDestContext,
  2266. mshlflags, &pmsh)))
  2267. {
  2268. sc = GetScode(pmsh->MarshalInterface(pstStm, riid, pv,
  2269. dwDestContext, pvDestContext,
  2270. mshlflags));
  2271. pmsh->Release();
  2272. }
  2273. }
  2274. else if (pvDestContext != NULL)
  2275. {
  2276. sc = STG_E_INVALIDPARAMETER;
  2277. }
  2278. else
  2279. {
  2280. olChk(StartMarshal(pstStm, riid, IID_IStorage, mshlflags));
  2281. //Always standard marshal, in case we get an error during
  2282. //unmarshalling of the custom stuff.
  2283. {
  2284. IMarshal *pmsh;
  2285. if (SUCCEEDED(sc = CoGetStandardMarshal(riid, (IUnknown *)pv,
  2286. dwDestContext, pvDestContext,
  2287. mshlflags, &pmsh)))
  2288. {
  2289. sc = GetScode(pmsh->MarshalInterface(pstStm, riid, pv,
  2290. dwDestContext, pvDestContext,
  2291. mshlflags));
  2292. pmsh->Release();
  2293. }
  2294. olChk(sc);
  2295. }
  2296. #ifdef MULTIHEAP
  2297. olChk(MarshalSharedMemory(pstStm, _ppc));
  2298. #endif
  2299. #ifdef POINTER_IDENTITY
  2300. olChk(MarshalPointer(pstStm, (CExposedDocFile*) GetNextMarshal()));
  2301. #endif
  2302. olChk(MarshalPointer(pstStm, BP_TO_P(CPubDocFile *, _pdf)));
  2303. olChk(MarshalPointer(pstStm, BP_TO_P(CDFBasis *, _pdfb)));
  2304. olChk(MarshalPointer(pstStm, (void *) LongToPtr(_pdf->GetDFlags()) ));
  2305. #ifdef ASYNC
  2306. olChk(MarshalContext(pstStm,
  2307. _ppc,
  2308. dwDestContext,
  2309. pvDestContext,
  2310. mshlflags,
  2311. TRUE,
  2312. P_INDEPENDENT(_pdf->GetDFlags())));
  2313. sc = MarshalConnection(pstStm,
  2314. &_cpoint,
  2315. dwDestContext,
  2316. pvDestContext,
  2317. mshlflags);
  2318. #else
  2319. olChk(MarshalContext(pstStm,
  2320. _ppc,
  2321. dwDestContext,
  2322. pvDestContext,
  2323. mshlflags,
  2324. P_INDEPENDENT(_pdf->GetDFlags())));
  2325. #endif
  2326. }
  2327. olDebugOut((DEB_TRACE, "Out CExposedDocFile::MarshalInterface\n"));
  2328. EH_Err:
  2329. olLog(("%p::Out CExposedDocFile::MarshalInterface(). ret == %lx\n",
  2330. this, sc));
  2331. return ResultFromScode(sc);
  2332. }
  2333. //+--------------------------------------------------------------
  2334. //
  2335. // Member: CExposedDocFile::UnmarshalInterface, public
  2336. //
  2337. // Synopsis: Non-functional
  2338. //
  2339. // Arguments: [pstStm] -
  2340. // [riid] -
  2341. // [ppvObj] -
  2342. //
  2343. // Returns: Appropriate status code
  2344. //
  2345. // Modifies: [ppvObj]
  2346. //
  2347. // History: 04-May-92 DrewB Created
  2348. //
  2349. //---------------------------------------------------------------
  2350. STDMETHODIMP CExposedDocFile::UnmarshalInterface(IStream *pstStm,
  2351. REFIID riid,
  2352. void **ppvObj)
  2353. {
  2354. olLog(("%p::INVALID CALL TO CExposedDocFile::UnmarshalInterface()\n",
  2355. this));
  2356. return ResultFromScode(STG_E_INVALIDFUNCTION);
  2357. }
  2358. //+--------------------------------------------------------------
  2359. //
  2360. // Member: CExposedDocFile::StaticReleaseMarshalData, public static
  2361. //
  2362. // Synopsis: Releases any references held in marshal data
  2363. //
  2364. // Arguments: [pstStm] - Marshal data stream
  2365. //
  2366. // Returns: Appropriate status code
  2367. //
  2368. // History: 02-Feb-94 DrewB Created
  2369. //
  2370. // Notes: Assumes standard marshal header has already been read
  2371. //
  2372. //---------------------------------------------------------------
  2373. SCODE CExposedDocFile::StaticReleaseMarshalData(IStream *pstStm,
  2374. DWORD mshlflags)
  2375. {
  2376. SCODE sc;
  2377. CPubDocFile *pdf;
  2378. CDFBasis *pdfb;
  2379. ULONG_PTR df;
  2380. #ifdef POINTER_IDENTITY
  2381. CExposedDocFile *pedf;
  2382. #endif
  2383. olDebugOut((DEB_ITRACE, "In CExposedDocFile::StaticReleaseMarshalData:("
  2384. "%p, %lX)\n", pstStm, mshlflags));
  2385. //First unmarshal the standard marshalled version
  2386. olChk(CoReleaseMarshalData(pstStm));
  2387. // The final release of the exposed object may have shut down the
  2388. // shared memory heap, so do not access shared memory after this point
  2389. //Then do the rest of it.
  2390. #ifdef MULTIHEAP
  2391. olChk(SkipSharedMemory(pstStm, mshlflags));
  2392. #endif
  2393. #ifdef POINTER_IDENTITY
  2394. olChk(UnmarshalPointer(pstStm, (void **) &pedf));
  2395. #endif
  2396. olChk(UnmarshalPointer(pstStm, (void **)&pdf));
  2397. olChk(UnmarshalPointer(pstStm, (void **)&pdfb));
  2398. olChk(UnmarshalPointer(pstStm, (void **)&df));
  2399. #ifdef ASYNC
  2400. olChk(ReleaseContext(pstStm, TRUE,
  2401. P_INDEPENDENT(df) != 0,
  2402. mshlflags));
  2403. olChk(ReleaseConnection(pstStm, mshlflags));
  2404. #else
  2405. olChk(ReleaseContext(pstStm, P_INDEPENDENT(df), mshlflags));
  2406. #endif
  2407. #ifdef MULTIHEAP
  2408. g_smAllocator.SetState(NULL, NULL, 0, NULL, NULL);
  2409. #endif
  2410. olDebugOut((DEB_ITRACE,
  2411. "Out CExposedDocFile::StaticReleaseMarshalData\n"));
  2412. EH_Err:
  2413. return sc;
  2414. }
  2415. //+--------------------------------------------------------------
  2416. //
  2417. // Member: CExposedDocFile::ReleaseMarshalData, public
  2418. //
  2419. // Synopsis: Non-functional
  2420. //
  2421. // Arguments: [pstStm] -
  2422. //
  2423. // Returns: Appropriate status code
  2424. //
  2425. // History: 18-Sep-92 DrewB Created
  2426. //
  2427. //---------------------------------------------------------------
  2428. STDMETHODIMP CExposedDocFile::ReleaseMarshalData(IStream *pstStm)
  2429. {
  2430. SCODE sc;
  2431. DWORD mshlflags;
  2432. IID iid;
  2433. #ifdef MULTIHEAP
  2434. CSafeMultiHeap smh(_ppc);
  2435. #endif
  2436. olLog(("%p::In CExposedDocFile::ReleaseMarshalData(%p)\n", this, pstStm));
  2437. olDebugOut((DEB_TRACE, "In CExposedDocFile::ReleaseMarshalData:%p(%p)\n",
  2438. this, pstStm));
  2439. olChk(Validate());
  2440. olChk(_pdf->CheckReverted());
  2441. olChk(SkipStdMarshal(pstStm, &iid, &mshlflags));
  2442. olAssert(IsEqualIID(iid, IID_IStorage));
  2443. sc = StaticReleaseMarshalData(pstStm, mshlflags);
  2444. olDebugOut((DEB_TRACE, "Out CExposedDocFile::ReleaseMarshalData\n"));
  2445. EH_Err:
  2446. olLog(("%p::Out CExposedDocFile::ReleaseMarshalData(). ret == %lx\n",
  2447. this, sc));
  2448. return ResultFromScode(sc);
  2449. }
  2450. //+--------------------------------------------------------------
  2451. //
  2452. // Member: CExposedDocFile::DisconnectObject, public
  2453. //
  2454. // Synopsis: Non-functional
  2455. //
  2456. // Arguments: [dwRevserved] -
  2457. //
  2458. // Returns: Appropriate status code
  2459. //
  2460. // History: 18-Sep-92 DrewB Created
  2461. //
  2462. //---------------------------------------------------------------
  2463. STDMETHODIMP CExposedDocFile::DisconnectObject(DWORD dwReserved)
  2464. {
  2465. olLog(("%p::INVALID CALL TO CExposedDocFile::DisconnectObject()\n",
  2466. this));
  2467. return ResultFromScode(STG_E_INVALIDFUNCTION);
  2468. }
  2469. //+---------------------------------------------------------------------------
  2470. //
  2471. // Member: CExposedDocFile::SwitchToFile, public
  2472. //
  2473. // Synopsis: Switches the underlying file to another file
  2474. //
  2475. // Arguments: [ptcsFile] - New file name
  2476. //
  2477. // Returns: Appropriate status code
  2478. //
  2479. // History: 08-Jan-93 DrewB Created
  2480. //
  2481. //----------------------------------------------------------------------------
  2482. STDMETHODIMP CExposedDocFile::SwitchToFile(OLECHAR *ptcsFile)
  2483. {
  2484. ULONG ulOpenLock;
  2485. SCODE sc;
  2486. SAFE_SEM;
  2487. SAFE_ACCESS;
  2488. olLog(("%p::In CExposedDocFile::SwitchToFile(" OLEFMT ")\n",
  2489. this, ptcsFile));
  2490. olDebugOut((DEB_TRACE, "In CExposedDocFile::SwitchToFile:"
  2491. "%p(" OLEFMT ")\n",
  2492. this, ptcsFile));
  2493. olChk(ValidateNameW(ptcsFile, _MAX_PATH));
  2494. olChk(Validate());
  2495. olChk(TakeSafeSem());
  2496. olChk(_pdf->CheckReverted());
  2497. #ifdef COORD
  2498. olAssert(_pdf->IsRoot() || _pdf->IsCoord());
  2499. #else
  2500. olAssert(_pdf->IsRoot());
  2501. #endif
  2502. SafeReadAccess();
  2503. ulOpenLock = _ppc->GetOpenLock();
  2504. #ifdef COORD
  2505. sc = _pdf->GetRoot()->SwitchToFile(ptcsFile,
  2506. _ppc->GetOriginal(),
  2507. &ulOpenLock);
  2508. #else
  2509. sc = ((CRootPubDocFile *)(CPubDocFile*)_pdf)->SwitchToFile(ptcsFile,
  2510. _ppc->GetOriginal(),
  2511. &ulOpenLock);
  2512. #endif
  2513. _ppc->SetOpenLock(ulOpenLock);
  2514. olDebugOut((DEB_TRACE, "Out CExposedDocFile::SwitchToFile\n"));
  2515. EH_Err:
  2516. olLog(("%p::Out CExposedDocFile::SwitchToFile(). ret == %lx\n",
  2517. this, sc));
  2518. return ResultFromScode(sc);
  2519. }
  2520. #if WIN32 >= 300
  2521. // IAccessControl methods
  2522. STDMETHODIMP CExposedDocFile::GrantAccessRights(ULONG cCount,
  2523. ACCESS_REQUEST pAccessRequestList[])
  2524. {
  2525. olAssert((_pIAC != NULL));
  2526. return _pIAC->GrantAccessRights(cCount, pAccessRequestList);
  2527. }
  2528. STDMETHODIMP CExposedDocFile::SetAccessRights(ULONG cCount,
  2529. ACCESS_REQUEST pAccessRequestList[])
  2530. {
  2531. olAssert((_pIAC != NULL));
  2532. return _pIAC->SetAccessRights(cCount, pAccessRequestList);
  2533. }
  2534. STDMETHODIMP CExposedDocFile::ReplaceAllAccessRights(ULONG cCount,
  2535. ACCESS_REQUEST pAccessRequestList[])
  2536. {
  2537. olAssert((_pIAC != NULL));
  2538. return _pIAC->ReplaceAllAccessRights(cCount, pAccessRequestList);
  2539. }
  2540. STDMETHODIMP CExposedDocFile::DenyAccessRights(ULONG cCount,
  2541. ACCESS_REQUEST pAccessRequestList[])
  2542. {
  2543. olAssert((_pIAC != NULL));
  2544. return _pIAC->DenyAccessRights(cCount, pAccessRequestList);
  2545. }
  2546. STDMETHODIMP CExposedDocFile::RevokeExplicitAccessRights(ULONG cCount,
  2547. TRUSTEE pTrustee[])
  2548. {
  2549. olAssert((_pIAC != NULL));
  2550. return _pIAC->RevokeExplicitAccessRights(cCount, pTrustee);
  2551. }
  2552. STDMETHODIMP CExposedDocFile::IsAccessPermitted(TRUSTEE *pTrustee,
  2553. DWORD grfAccessPermissions)
  2554. {
  2555. olAssert((_pIAC != NULL));
  2556. return _pIAC->IsAccessPermitted(pTrustee, grfAccessPermissions);
  2557. }
  2558. STDMETHODIMP CExposedDocFile::GetEffectiveAccessRights(TRUSTEE *pTrustee,
  2559. DWORD *pgrfAccessPermissions )
  2560. {
  2561. olAssert((_pIAC != NULL));
  2562. return _pIAC->GetEffectiveAccessRights(pTrustee, pgrfAccessPermissions);
  2563. }
  2564. STDMETHODIMP CExposedDocFile::GetExplicitAccessRights(ULONG *pcCount,
  2565. PEXPLICIT_ACCESS *pExplicitAccessList)
  2566. {
  2567. olAssert((_pIAC != NULL));
  2568. return _pIAC->GetExplicitAccessRights(pcCount, pExplicitAccessList);
  2569. }
  2570. STDMETHODIMP CExposedDocFile::CommitAccessRights(DWORD grfCommitFlags)
  2571. {
  2572. olAssert((_pIAC != NULL));
  2573. return _pIAC->CommitAccessRights(grfCommitFlags);
  2574. }
  2575. STDMETHODIMP CExposedDocFile::RevertAccessRights()
  2576. {
  2577. olAssert((_pIAC != NULL));
  2578. return _pIAC->RevertAccessRights();
  2579. }
  2580. #endif // if WIN32 >= 300
  2581. #ifdef COORD
  2582. //+---------------------------------------------------------------------------
  2583. //
  2584. // Member: CExposedDocFile::CommitPhase1, public
  2585. //
  2586. // Synopsis: Do phase 1 of an exposed two phase commit
  2587. //
  2588. // Arguments: [grfCommitFlags] -- Commit flags
  2589. //
  2590. // Returns: Appropriate status code
  2591. //
  2592. // History: 08-Aug-95 PhilipLa Created
  2593. //
  2594. //----------------------------------------------------------------------------
  2595. SCODE CExposedDocFile::CommitPhase1(DWORD grfCommitFlags)
  2596. {
  2597. SCODE sc;
  2598. SAFE_SEM;
  2599. SAFE_ACCESS;
  2600. olChk(VerifyCommitFlags(grfCommitFlags));
  2601. olChk(Validate());
  2602. olChk(TakeSafeSem());
  2603. SafeWriteAccess();
  2604. #ifdef DIRECTWRITERLOCK
  2605. olChk(ValidateWriteAccess());
  2606. #endif
  2607. sc = _pdf->CommitPhase1(grfCommitFlags,
  2608. &_ulLock,
  2609. &_sigMSF,
  2610. &_cbSizeBase,
  2611. &_cbSizeOrig);
  2612. EH_Err:
  2613. return sc;
  2614. }
  2615. //+---------------------------------------------------------------------------
  2616. //
  2617. // Member: CExposedDocFile::CommitPhase2, public
  2618. //
  2619. // Synopsis: Do phase 2 of an exposed two phase commit
  2620. //
  2621. // Arguments: [grfCommitFlags] -- Commit flags
  2622. // [fCommit] -- TRUE if transaction is to commit, FALSE if abort
  2623. //
  2624. // Returns: Appropriate status code
  2625. //
  2626. // History: 08-Aug-95 PhilipLa Created
  2627. //
  2628. //----------------------------------------------------------------------------
  2629. SCODE CExposedDocFile::CommitPhase2(DWORD grfCommitFlags,
  2630. BOOL fCommit)
  2631. {
  2632. SCODE sc;
  2633. SAFE_SEM;
  2634. SAFE_ACCESS;
  2635. olChk(Validate());
  2636. olChk(TakeSafeSem());
  2637. SafeWriteAccess();
  2638. #ifdef DIRECTWRITERLOCK
  2639. olChk(ValidateWriteAccess());
  2640. #endif
  2641. sc = _pdf->CommitPhase2(grfCommitFlags,
  2642. fCommit,
  2643. _ulLock,
  2644. _sigMSF,
  2645. _cbSizeBase,
  2646. _cbSizeOrig);
  2647. _ulLock = _cbSizeBase = _cbSizeOrig = 0;
  2648. _sigMSF = 0;
  2649. EH_Err:
  2650. return sc;
  2651. }
  2652. #endif //COORD
  2653. #ifdef NEWPROPS
  2654. //+---------------------------------------------------------------------------
  2655. //
  2656. // Member: CExposedDocFile::Lock, IBlockingLock
  2657. //
  2658. // Synopsis: Acquires the semaphore associated with the docfile.
  2659. //
  2660. // Notes: This member is called by CPropertyStorage.
  2661. //
  2662. //----------------------------------------------------------------------------
  2663. STDMETHODIMP
  2664. CExposedDocFile::Lock(DWORD dwTimeout)
  2665. {
  2666. #ifdef MULTIHEAP
  2667. CSafeMultiHeap smh(_ppc);
  2668. #endif
  2669. TakeSem();
  2670. SetDifferentBasisAccess(_pdfb, _ppc);
  2671. return S_OK;
  2672. }
  2673. //+---------------------------------------------------------------------------
  2674. //
  2675. // Member: CExposedDocFile::Unlock, public IBlockingLock
  2676. //
  2677. // Synopsis: Releases the semaphore associated with the docfile.
  2678. //
  2679. // Notes: This member is called by CPropertyStorage.
  2680. //
  2681. //----------------------------------------------------------------------------
  2682. STDMETHODIMP
  2683. CExposedDocFile::Unlock(VOID)
  2684. {
  2685. #ifdef MULTIHEAP
  2686. CSafeMultiHeap smh(_ppc);
  2687. #endif
  2688. ClearBasisAccess(_pdfb);
  2689. ReleaseSem(S_OK);
  2690. return( S_OK );
  2691. }
  2692. #endif
  2693. #ifdef DIRECTWRITERLOCK
  2694. //+---------------------------------------------------------------------------
  2695. //
  2696. // Member: CExposedDocFile::WaitForWriteAccess, public IDirectWriterLock
  2697. //
  2698. // Synopsis: tries to obtain exclusive write access in direct mode
  2699. //
  2700. // Notes: Tree mutex must be taken when accessing recursion count
  2701. //
  2702. //----------------------------------------------------------------------------
  2703. STDMETHODIMP CExposedDocFile::WaitForWriteAccess (DWORD dwTimeout)
  2704. {
  2705. SAFE_SEM;
  2706. SAFE_ACCESS;
  2707. HRESULT hr = TakeSafeSem();
  2708. if (SUCCEEDED(hr) && *_ppc->GetRecursionCount() == 0)
  2709. {
  2710. SafeReadAccess();
  2711. hr = _pdfb->WaitForWriteAccess (dwTimeout, _ppc->GetGlobal());
  2712. }
  2713. if (SUCCEEDED(hr)) ++(*_ppc->GetRecursionCount());
  2714. return hr;
  2715. }
  2716. //+---------------------------------------------------------------------------
  2717. //
  2718. // Member: CExposedDocFile::ReleaseWriteAccess, public IDirectWriterLock
  2719. //
  2720. // Synopsis: releases exclusive write access from WaitForWriteAccess
  2721. //
  2722. // Notes: Tree mutex must be taken when accessing recursion count
  2723. //
  2724. //----------------------------------------------------------------------------
  2725. STDMETHODIMP CExposedDocFile::ReleaseWriteAccess ()
  2726. {
  2727. SAFE_SEM;
  2728. SAFE_ACCESS;
  2729. HRESULT hr = TakeSafeSem();
  2730. if (SUCCEEDED(hr) && *_ppc->GetRecursionCount() == 1)
  2731. {
  2732. SafeReadAccess();
  2733. hr = _pdf->Commit(STGC_DEFAULT); // Flush
  2734. if (SUCCEEDED(hr)) hr = _pdfb->ReleaseWriteAccess();
  2735. }
  2736. if (SUCCEEDED(hr)) --(*_ppc->GetRecursionCount());
  2737. return hr;
  2738. }
  2739. //+---------------------------------------------------------------------------
  2740. //
  2741. // Member: CExposedDocFile::HaveWriteAccess, public IDirectWriterLock
  2742. //
  2743. // Synopsis: returns S_OK if write lock is active, S_FALSE if not
  2744. //
  2745. // Notes:
  2746. //
  2747. //----------------------------------------------------------------------------
  2748. STDMETHODIMP CExposedDocFile::HaveWriteAccess ()
  2749. {
  2750. SAFE_SEM;
  2751. HRESULT hr = TakeSafeSem();
  2752. olAssert(_pdfb->DirectWriterMode());
  2753. if (SUCCEEDED(hr))
  2754. {
  2755. hr = (_pdfb->HaveWriteAccess()) ? S_OK : S_FALSE;
  2756. }
  2757. return hr;
  2758. }
  2759. //+--------------------------------------------------------------
  2760. //
  2761. // Member: CExposedDocFile::ValidateWriteAccess, public
  2762. //
  2763. // Synopsis: returns whether writer currently has write access
  2764. //
  2765. // Notes: tree mutex must be taken
  2766. //
  2767. // History: 30-Apr-96 HenryLee Created
  2768. //
  2769. //---------------------------------------------------------------
  2770. HRESULT CExposedDocFile::ValidateWriteAccess()
  2771. {
  2772. if (_pdf->GetTransactedDepth() >= 1)
  2773. return S_OK;
  2774. return (!_pdfb->DirectWriterMode() || (*_ppc->GetRecursionCount()) > 0) ?
  2775. S_OK : STG_E_ACCESSDENIED;
  2776. };
  2777. #endif // DIRECTWRITERLOCK