Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1992 lines
61 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: expdf.cxx
  7. //
  8. // Contents: Exposed DocFile implementation
  9. //
  10. // Notes:
  11. // The CExposedDocFile class is the implementation
  12. // of IStorage. It implements IPropertySetStorage
  13. // by inheriting from CPropertySetStorage. CPropertySetStorage
  14. // implements all the functionality of IPropertySetStorage.
  15. //
  16. // Note that this interface is solely UNICODE, the ASCII layer
  17. // support which is present if _UNICODE is not defined, provides
  18. // the overloaded functions that handles the ASCII to Unicode
  19. // conversion.
  20. //
  21. //---------------------------------------------------------------------------
  22. // Initialize all the GUID's in ref.hxx
  23. #ifdef INITGUID
  24. #error "Something is Wrong: INIT_GUID should not be defined yet"
  25. #else
  26. #define INITGUID
  27. #include "h/ref.hxx"
  28. #endif
  29. // enable memory leak detection if neccessary
  30. #include "h/dbg.hxx"
  31. #include "exphead.cxx"
  32. #include "expdf.hxx"
  33. #include "expst.hxx"
  34. #include "expiter.hxx"
  35. #include "logfile.hxx"
  36. #include "h/rexpdf.hxx"
  37. #include "h/docfilep.hxx"
  38. // Check for proper single-instance flags
  39. #define NOT_SINGLE(md) (((md) & STGM_DENY) != STGM_SHARE_EXCLUSIVE)
  40. #define EnforceSingle(mode) (NOT_SINGLE(mode) ? STG_E_INVALIDFUNCTION : S_OK)
  41. //+--------------------------------------------------------------
  42. //
  43. // Member: CExposedDocFile::CExposedDocFile, public
  44. //
  45. // Synopsis: Constructor
  46. //
  47. // Arguments: [pdf] - Public DocFile
  48. // [pdfb] - DocFile basis
  49. // [ppc] - Context
  50. // [fOwnContext] - Whether this object owns the context
  51. //
  52. //---------------------------------------------------------------
  53. CExposedDocFile::CExposedDocFile(CExposedDocFile *pdfParent,
  54. CDocFile *pdf,
  55. DFLAGS const df,
  56. DFLUID luid,
  57. ILockBytes *pilbBase,
  58. CDfName const *pdfn,
  59. CMStream* pmsBase,
  60. CDFBasis *pdfb)
  61. #ifdef NEWPROPS
  62. #ifdef _MSC_VER
  63. #pragma warning(disable: 4355)
  64. #endif // _MSC_VER
  65. : CPropertySetStorage(this)
  66. #ifdef _MSC_VER
  67. #pragma warning(default: 4355)
  68. #endif // _MSC_VER
  69. #endif // NEWPROPS
  70. {
  71. olDebugOut((DEB_ITRACE, "In CExposedDocFile::CExposedDocFile(%p)\n",
  72. pdf));
  73. _pdfb = pdfb;
  74. _pdfb->AddRef();
  75. _pdf = pdf;
  76. _df = df;
  77. _luid = luid;
  78. _pdfParent = pdfParent;
  79. // note: we don't addref here 'cos it is only done in the root
  80. _pilbBase = pilbBase;
  81. _pmsBase = pmsBase;
  82. if (pdfn) _dfn.Set(pdfn->GetLength(), pdfn->GetBuffer());
  83. else _dfn.Set((WORD)0, (BYTE*)NULL);
  84. if (!IsRoot())
  85. _pdfParent->AddChild(this);
  86. _fDirty = FALSE;
  87. _cReferences = 1;
  88. _ulAccessLockBase = 0;
  89. _sig = CEXPOSEDDOCFILE_SIG;
  90. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::CExposedDocFile\n"));
  91. }
  92. //+--------------------------------------------------------------
  93. //
  94. // Member: CExposedDocFile::~CExposedDocFile, public
  95. //
  96. // Synopsis: Destructor
  97. //
  98. //---------------------------------------------------------------
  99. CExposedDocFile::~CExposedDocFile(void)
  100. {
  101. olDebugOut((DEB_TRACE, "In CExposedDocFile::~CExposedDocFile\n"));
  102. olAssert(_cReferences == 0);
  103. if (_pdfb) _pdfb->Release();
  104. _sig = CEXPOSEDDOCFILE_SIGDEL;
  105. if (SUCCEEDED(CheckReverted()))
  106. {
  107. if (IsRoot()) {
  108. olDebugOut((DEB_TRACE, "Destr called for root\n"));
  109. olAssert(_pilbBase==NULL);
  110. }
  111. else {
  112. _pdfParent->ReleaseChild(this);
  113. }
  114. _cilChildren.DeleteByName(NULL);
  115. if (_pdf) _pdf->Release();
  116. }
  117. olDebugOut((DEB_TRACE, "Out CExposedDocFile::~CExposedDocFile\n"));
  118. }
  119. //+--------------------------------------------------------------
  120. //
  121. // Member: CExposedDocFile::Release, public
  122. //
  123. // Synopsis: Releases resources for a CExposedDocFile
  124. //
  125. // Returns: Appropriate status code
  126. //
  127. //---------------------------------------------------------------
  128. STDMETHODIMP_(ULONG) CExposedDocFile::Release(void)
  129. {
  130. LONG lRet;
  131. olLog(("%p::In CExposedDocFile::Release()\n", this));
  132. olDebugOut((DEB_ITRACE, "In CExposedDocFile::Release()\n"));
  133. TRY
  134. {
  135. if (FAILED(Validate())) return 0;
  136. olAssert(_cReferences > 0);
  137. lRet = AtomicDec(&_cReferences);
  138. if (_pdf && !P_TRANSACTED(_df) && SUCCEEDED(CheckReverted()))
  139. {
  140. TIME_T tm;
  141. olVerSucc(DfGetTOD(&tm));
  142. olVerSucc(_pdf->SetTime(WT_ACCESS, tm));
  143. #ifdef NEWPROPS
  144. olVerSucc(FlushBufferedData());
  145. #endif
  146. if (IsDirty())
  147. {
  148. olVerSucc(DfGetTOD(&tm));
  149. olVerSucc(_pdf->SetTime(WT_MODIFICATION, tm));
  150. if (!IsRoot())
  151. _pdfParent->SetDirty();
  152. olAssert(P_WRITE(_df) &&
  153. aMsg("Dirty & Direct but no write access"));
  154. SetClean();
  155. }
  156. if (IsRoot() && P_WRITE(_df))
  157. {
  158. SCODE sc;
  159. sc = _pmsBase->Flush(0);
  160. #if DBG == 1
  161. if (FAILED(sc))
  162. {
  163. olDebugOut((DEB_ERROR,
  164. "ILockBytes::Flush() failed in release path "
  165. "with error %lx\n", sc));
  166. }
  167. #endif
  168. }
  169. }
  170. if (lRet == 0)
  171. {
  172. delete this;
  173. }
  174. else if (lRet < 0)
  175. lRet = 0;
  176. }
  177. CATCH(CException, e)
  178. {
  179. UNREFERENCED_PARM(e);
  180. lRet = 0;
  181. }
  182. END_CATCH
  183. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::Release()\n"));
  184. olLog(("%p::Out CExposedDocFile::Release(). ret == %lu\n", this, lRet));
  185. FreeLogFile();
  186. return (ULONG)lRet;
  187. }
  188. //+--------------------------------------------------------------
  189. //
  190. // Member: CExposedDocFile::CheckCopyTo, private
  191. //
  192. // Synopsis: Checks for CopyTo legality
  193. //
  194. // Returns: Appropriate status code
  195. //
  196. //---------------------------------------------------------------
  197. inline SCODE CExposedDocFile::CheckCopyTo(void)
  198. {
  199. // it is an error to copy a parent to child
  200. return _pdfb->GetCopyBase() != NULL &&
  201. IsAtOrAbove(_pdfb->GetCopyBase()) ? STG_E_ACCESSDENIED : S_OK;
  202. }
  203. //+--------------------------------------------------------------
  204. //
  205. // Member: CExposedDocFile::ConvertInternalStream, private
  206. //
  207. // Synopsis: Converts an internal stream to a storage
  208. //
  209. // Arguments: [pwcsName] - Name
  210. // [pdfExp] - Destination docfile
  211. //
  212. // Returns: Appropriate status code
  213. //
  214. //---------------------------------------------------------------
  215. static WCHAR const wcsIllegalName[] = {'\\','\0'};
  216. SCODE CExposedDocFile::ConvertInternalStream(CExposedDocFile *pdfExp)
  217. {
  218. CExposedStream *pstFrom=NULL, *pstTo=NULL;
  219. SCODE sc=S_OK;
  220. CDfName const dfnIllegal(wcsIllegalName);
  221. CDfName const dfnContents(wcsContents);
  222. olDebugOut((DEB_ITRACE, "In CExposedDocFile::ConvertInternalStream(%p)\n",
  223. pdfExp));
  224. olChk(GetExposedStream(&dfnIllegal, DF_READWRITE | DF_DENYALL,
  225. &pstFrom));
  226. olChkTo(EH_pstFrom,
  227. pdfExp->CreateExposedStream(&dfnContents, DF_WRITE | DF_DENYALL,
  228. &pstTo));
  229. olChkTo(EH_pstTo, CopyStreamToStream(pstFrom->GetDirectStream(),
  230. pstTo->GetDirectStream()));
  231. olChkTo(EH_pstTo, DestroyEntry(&dfnIllegal, FALSE));
  232. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::ConvertInternalStream\n"));
  233. // Fall through
  234. EH_pstTo:
  235. pstTo->Release();
  236. EH_pstFrom:
  237. pstFrom->Release();
  238. EH_Err:
  239. return sc;
  240. }
  241. //+---------------------------------------------------------------------------
  242. //
  243. // Member: CExposedDocFile::CreateEntry, private
  244. //
  245. // Synopsis: Creates elements, used in CreateStream, CreateStorage and
  246. // for properties
  247. //
  248. // Arguments: [pwcsName] - Name
  249. // [dwType] - Entry type
  250. // [grfMode] - Access mode
  251. // [ppv] - Object return
  252. //
  253. // Returns: Appropriate status code
  254. //
  255. // Modifies: [ppv]
  256. //
  257. //----------------------------------------------------------------------------
  258. SCODE CExposedDocFile::CreateEntry(WCHAR const *pwcsName,
  259. DWORD dwType,
  260. DWORD grfMode,
  261. void **ppv)
  262. {
  263. SCODE sc;
  264. SEntryBuffer eb;
  265. CDfName dfn;
  266. BOOL fRenamed = FALSE;
  267. CExposedStream *pstExp;
  268. CExposedDocFile *pdfExp;
  269. olDebugOut((DEB_ITRACE, "In CExposedDocFile::CreateEntry:%p("
  270. "%ws, %lX, %lX, %p)\n",
  271. this, pwcsName, dwType, grfMode, ppv));
  272. olChk(EnforceSingle(grfMode));
  273. olChk(CheckReverted());
  274. dfn.Set(pwcsName);
  275. if (grfMode & (STGM_CREATE | STGM_CONVERT))
  276. {
  277. if (FAILED(sc = _pdf->IsEntry(&dfn, &eb)))
  278. {
  279. if (sc != STG_E_FILENOTFOUND)
  280. olErr(EH_Err, sc);
  281. }
  282. else if (eb.dwType == dwType && (grfMode & STGM_CREATE))
  283. olChk(DestroyEntry(&dfn, FALSE));
  284. else if (eb.dwType == STGTY_STREAM && (grfMode & STGM_CONVERT) &&
  285. dwType == STGTY_STORAGE)
  286. {
  287. CDfName const dfnIllegal(wcsIllegalName);
  288. olChk(RenameEntry(&dfn, &dfnIllegal));
  289. fRenamed = TRUE;
  290. }
  291. else
  292. olErr(EH_Err, STG_E_FILEALREADYEXISTS);
  293. }
  294. if (REAL_STGTY(dwType) == STGTY_STREAM)
  295. {
  296. olChk(CreateExposedStream(&dfn, ModeToDFlags(grfMode), &pstExp));
  297. *ppv = pstExp;
  298. }
  299. else
  300. {
  301. olAssert(REAL_STGTY(dwType) == STGTY_STORAGE);
  302. olChk(CreateExposedDocFile(&dfn, ModeToDFlags(grfMode), &pdfExp));
  303. // If we've renamed the original stream for conversion, convert
  304. if (fRenamed)
  305. {
  306. olChkTo(EH_pdfExpInit, ConvertInternalStream(pdfExp));
  307. sc = STG_S_CONVERTED;
  308. }
  309. *ppv = pdfExp;
  310. }
  311. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::CreateEntry\n"));
  312. return sc;
  313. EH_pdfExpInit:
  314. pdfExp->Release();
  315. olVerSucc(DestroyEntry(&dfn, TRUE));
  316. EH_Err:
  317. return sc;
  318. }
  319. //+---------------------------------------------------------------------------
  320. //
  321. // Member: CExposedDocFile::OpenEntry, private
  322. //
  323. // Synopsis: Opens elements, used in OpenStream, OpenStorage and
  324. // for properties
  325. //
  326. // Arguments: [pwcsName] - Name
  327. // [dwType] - Entry type
  328. // [grfMode] - Access mode
  329. // [ppv] - Object return
  330. //
  331. // Returns: Appropriate status code
  332. //
  333. // Modifies: [ppv]
  334. //
  335. //----------------------------------------------------------------------------
  336. SCODE CExposedDocFile::OpenEntry(WCHAR const *pwcsName,
  337. DWORD dwType,
  338. DWORD grfMode,
  339. void **ppv)
  340. {
  341. CDfName dfn;
  342. SCODE sc;
  343. CExposedDocFile *pdfExp;
  344. CExposedStream *pstExp;
  345. olDebugOut((DEB_ITRACE, "In CExposedDocFile::OpenEntry:%p("
  346. "%ws, %lX, %lX, %p)\n", this, pwcsName, dwType, grfMode, ppv));
  347. olChk(EnforceSingle(grfMode));
  348. dfn.Set(pwcsName);
  349. if (REAL_STGTY(dwType) == STGTY_STREAM)
  350. {
  351. olChk(GetExposedStream(&dfn, ModeToDFlags(grfMode), &pstExp));
  352. *ppv = pstExp;
  353. }
  354. else
  355. {
  356. olAssert(REAL_STGTY(dwType) == STGTY_STORAGE);
  357. olChk(GetExposedDocFile(&dfn, ModeToDFlags(grfMode), &pdfExp));
  358. *ppv = pdfExp;
  359. }
  360. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::OpenEntry\n"));
  361. return S_OK;
  362. EH_Err:
  363. return sc;
  364. }
  365. //+--------------------------------------------------------------
  366. //
  367. // Member: CExposedDocFile::CreateStream, public
  368. //
  369. // Synopsis: Creates a stream
  370. //
  371. // Arguments: [pwcsName] - Name
  372. // [grfMode] - Permissions
  373. // [reserved1]
  374. // [reserved2]
  375. // [ppstm] - Stream return
  376. //
  377. // Returns: Appropriate status code
  378. //
  379. // Modifies: [ppstm]
  380. //
  381. //---------------------------------------------------------------
  382. TSTDMETHODIMP CExposedDocFile::CreateStream(WCHAR const *pwcsName,
  383. DWORD grfMode,
  384. DWORD reserved1,
  385. DWORD reserved2,
  386. IStream **ppstm)
  387. {
  388. SCODE sc;
  389. olDebugOut((DEB_ITRACE, "In CExposedDocFile::CreateStream("
  390. "%ws, %lX, %lu, %lu, %p)\n", pwcsName, grfMode, reserved1,
  391. reserved2, ppstm));
  392. olLog(("%p::In CExposedDocFile::CreateStream(%ws, %lX, %lu, %lu, %p)\n",
  393. this, pwcsName, grfMode, reserved1, reserved2, ppstm));
  394. TRY
  395. {
  396. olChk(ValidateOutPtrBuffer(ppstm));
  397. *ppstm = NULL;
  398. olChk(CheckWName(pwcsName));
  399. if (reserved1 != 0 || reserved2 != 0)
  400. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  401. olChk(VerifyPerms(grfMode));
  402. if (grfMode & (STGM_CONVERT | STGM_TRANSACTED | STGM_PRIORITY |
  403. STGM_DELETEONRELEASE))
  404. olErr(EH_Err, STG_E_INVALIDFUNCTION);
  405. olChk(Validate());
  406. olChk(CheckCopyTo());
  407. sc = CreateEntry(pwcsName, STGTY_STREAM, grfMode, (void **)ppstm);
  408. }
  409. CATCH(CException, e)
  410. {
  411. sc = e.GetErrorCode();
  412. }
  413. END_CATCH
  414. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::CreateStream => %p\n",
  415. *ppstm));
  416. EH_Err:
  417. olLog(("%p::Out CExposedDocFile::CreateStream(). "
  418. "*ppstm == %p, ret == %lx\n", this, SAFE_DREF(ppstm), sc));
  419. return sc;
  420. }
  421. //+--------------------------------------------------------------
  422. //
  423. // Member: CExposedDocFile::OpenStream, public
  424. //
  425. // Synopsis: Opens an existing stream
  426. //
  427. // Arguments: [pwcsName] - Name
  428. // [reserved1]
  429. // [grfMode] - Permissions
  430. // [reserved2]
  431. // [ppstm] - Stream return
  432. //
  433. // Returns: Appropriate status code
  434. //
  435. // Modifies: [ppstm]
  436. //
  437. //---------------------------------------------------------------
  438. TSTDMETHODIMP CExposedDocFile::OpenStream(WCHAR const *pwcsName,
  439. void *reserved1,
  440. DWORD grfMode,
  441. DWORD reserved2,
  442. IStream **ppstm)
  443. {
  444. SCODE sc;
  445. olDebugOut((DEB_ITRACE, "In CExposedDocFile::OpenStream("
  446. "%ws, %p, %lX, %lu, %p)\n", pwcsName, reserved1,
  447. grfMode, reserved2, ppstm));
  448. olLog(("%p::In CExposedDocFile::OpenStream(%ws, %lu %lX, %lu, %p)\n",
  449. this, pwcsName, reserved1, grfMode, reserved2, ppstm));
  450. TRY
  451. {
  452. olChk(ValidateOutPtrBuffer(ppstm));
  453. *ppstm = NULL;
  454. olChk(CheckWName(pwcsName));
  455. if (reserved1 != NULL || reserved2 != 0)
  456. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  457. olChk(VerifyPerms(grfMode));
  458. if (grfMode & (STGM_TRANSACTED | STGM_PRIORITY |
  459. STGM_DELETEONRELEASE))
  460. olErr(EH_Err, STG_E_INVALIDFUNCTION);
  461. olChk(Validate());
  462. sc = OpenEntry(pwcsName, STGTY_STREAM, grfMode, (void **)ppstm);
  463. }
  464. CATCH(CException, e)
  465. {
  466. sc = e.GetErrorCode();
  467. }
  468. END_CATCH
  469. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::OpenStream => %p\n",
  470. SAFE_DREF(ppstm)));
  471. EH_Err:
  472. olLog(("%p::Out CExposedDocFile::OpenStream(). "
  473. "*ppstm == %p, ret == %lx\n", this, SAVE_DREF(ppstm), sc));
  474. return sc;
  475. }
  476. //+--------------------------------------------------------------
  477. //
  478. // Member: CExposedDocFile::CreateStorage, public
  479. //
  480. // Synopsis: Creates an embedded DocFile
  481. //
  482. // Arguments: [pwcsName] - Name
  483. // [grfMode] - Permissions
  484. // [reserved1]
  485. // [reserved2]
  486. // [ppstg] - New DocFile return
  487. //
  488. // Returns: Appropriate status code
  489. //
  490. // Modifies: [ppstg]
  491. //
  492. //---------------------------------------------------------------
  493. TSTDMETHODIMP CExposedDocFile::CreateStorage(WCHAR const *pwcsName,
  494. DWORD grfMode,
  495. DWORD reserved1,
  496. DWORD reserved2,
  497. IStorage **ppstg)
  498. {
  499. SCODE sc;
  500. olLog(("%p::In CExposedDocFile::CreateStorage(%ws, %lX, %lu, %lu, %p)\n",
  501. this, pwcsName, grfMode, reserved1, reserved2, ppstg));
  502. olDebugOut((DEB_ITRACE, "In CExposedDocFile::CreateStorage:%p("
  503. "%ws, %lX, %lu, %lu, %p)\n", this, pwcsName, grfMode,
  504. reserved1, reserved2, ppstg));
  505. TRY
  506. {
  507. olChk(ValidateOutPtrBuffer(ppstg));
  508. *ppstg = NULL;
  509. olChk(CheckWName(pwcsName));
  510. if (reserved1 != 0 || reserved2 != 0)
  511. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  512. olChk(VerifyPerms(grfMode));
  513. if (grfMode & (STGM_PRIORITY | STGM_DELETEONRELEASE))
  514. olErr(EH_Err, STG_E_INVALIDFUNCTION);
  515. olChk(Validate());
  516. olChk(CheckCopyTo());
  517. sc = CreateEntry(pwcsName, STGTY_STORAGE, grfMode, (void **)ppstg);
  518. }
  519. CATCH(CException, e)
  520. {
  521. sc = e.GetErrorCode();
  522. }
  523. END_CATCH
  524. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::CreateStorage => %p\n",
  525. *ppstg));
  526. EH_Err:
  527. olLog(("%p::Out CExposedDocFile::CreateStorage(). "
  528. "*ppstg == %p, ret == %lX\n", this, *ppstg, sc));
  529. return sc;
  530. }
  531. //+--------------------------------------------------------------
  532. //
  533. // Member: CExposedDocFile::OpenStorage, public
  534. //
  535. // Synopsis: Gets an existing embedded DocFile
  536. //
  537. // Arguments: [pwcsName] - Name
  538. // [pstgPriority] - Priority reopens
  539. // [grfMode] - Permissions
  540. // [snbExclude] - Priority reopens
  541. // [reserved]
  542. // [ppstg] - DocFile return
  543. //
  544. // Returns: Appropriate status code
  545. //
  546. // Modifies: [ppstg]
  547. //
  548. //---------------------------------------------------------------
  549. TSTDMETHODIMP CExposedDocFile::OpenStorage(WCHAR const *pwcsName,
  550. IStorage *pstgPriority,
  551. DWORD grfMode,
  552. SNBW snbExclude,
  553. DWORD reserved,
  554. IStorage **ppstg)
  555. {
  556. SCODE sc;
  557. CExposedDocFile *pdfExp;
  558. olLog(("%p::In CExposedDocFile::OpenStorage(%ws, %p, %lX, %p, %lu, %p)\n",
  559. this, pwcsName, pstgPriority, grfMode, snbExclude, reserved,
  560. ppstg));
  561. olDebugOut((DEB_ITRACE, "In CExposedDocFile::OpenStorage:%p("
  562. "%ws, %p, %lX, %p, %lu, %p)\n", this, pwcsName, pstgPriority,
  563. grfMode, snbExclude, reserved, ppstg));
  564. TRY
  565. {
  566. #ifdef _UNICODE // for UNICODE API's we have to do validation,
  567. // else it had been done in the ascii layer
  568. olChk(CheckWName(pwcsName));
  569. #endif
  570. olChk(ValidateOutPtrBuffer(ppstg));
  571. *ppstg = NULL;
  572. if (reserved != 0)
  573. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  574. olChk(VerifyPerms(grfMode));
  575. if (pstgPriority != NULL ||
  576. (grfMode & (STGM_PRIORITY | STGM_DELETEONRELEASE)))
  577. olErr(EH_Err, STG_E_INVALIDFUNCTION);
  578. olChk(Validate());
  579. if (snbExclude != NULL)
  580. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  581. olChk(OpenEntry(pwcsName, STGTY_STORAGE, grfMode, (void **)&pdfExp));
  582. *ppstg = pdfExp;
  583. }
  584. CATCH(CException, e)
  585. {
  586. sc = e.GetErrorCode();
  587. }
  588. END_CATCH
  589. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::OpenStorage => %p\n",
  590. *ppstg));
  591. EH_Err:
  592. olLog(("%p::Out CExposedDocFile::OpenStorage(). "
  593. "*ppstg == %p, ret == %lX\n", this, SAFE_DREF(ppstg), sc));
  594. return sc;
  595. }
  596. //+---------------------------------------------------------------------------
  597. //
  598. // Member: CExposedDocFile::MakeCopyFlags, public
  599. //
  600. // Synopsis: Translates IID array into bit fields
  601. //
  602. // Arguments: [ciidExclude] - Count of IIDs
  603. // [rgiidExclude] - IIDs not to copy
  604. //
  605. // Returns: Appropriate status code
  606. //
  607. //----------------------------------------------------------------------------
  608. DWORD CExposedDocFile::MakeCopyFlags(DWORD ciidExclude,
  609. IID const *rgiidExclude)
  610. {
  611. DWORD dwCopyFlags;
  612. olDebugOut((DEB_ITRACE, "In CExposedDocFile::MakeCopyFlags(%lu, %p)\n",
  613. ciidExclude, rgiidExclude));
  614. // Copy everything by default
  615. dwCopyFlags = COPY_ALL;
  616. for (; ciidExclude > 0; ciidExclude--, rgiidExclude++)
  617. if (IsEqualIID(*rgiidExclude, IID_IStorage))
  618. dwCopyFlags &= ~COPY_STORAGES;
  619. else if (IsEqualIID(*rgiidExclude, IID_IStream))
  620. dwCopyFlags &= ~COPY_STREAMS;
  621. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::MakeCopyFlags\n"));
  622. return dwCopyFlags;
  623. }
  624. //+--------------------------------------------------------------
  625. //
  626. // Member: CExposedDocFile::CopyTo, public
  627. //
  628. // Synopsis: Makes a copy of a DocFile
  629. //
  630. // Arguments: [ciidExclude] - Length of rgiid array
  631. // [rgiidExclude] - Array of IIDs to exclude
  632. // [snbExclude] - Names to exclude
  633. // [pstgDest] - Parent of copy
  634. //
  635. // Returns: Appropriate status code
  636. //
  637. //---------------------------------------------------------------
  638. TSTDMETHODIMP CExposedDocFile::CopyTo(DWORD ciidExclude,
  639. IID const *rgiidExclude,
  640. SNBW snbExclude,
  641. IStorage *pstgDest)
  642. {
  643. SCODE sc;
  644. DWORD i;
  645. olLog(("%p::In CExposedDocFile::CopyTo(%lu, %p, %p, %p)\n",
  646. this, ciidExclude, rgiidExclude, snbExclude, pstgDest));
  647. olDebugOut((DEB_ITRACE, "In CExposedDocFile::Copy(%lu, %p, %p, %p)\n",
  648. ciidExclude, rgiidExclude, snbExclude, pstgDest));
  649. TRY
  650. {
  651. if (snbExclude)
  652. olChk(ValidateSNBW(snbExclude));
  653. olChk(ValidateInterface(pstgDest, IID_IStorage));
  654. if (rgiidExclude)
  655. {
  656. olAssert(sizeof(IID)*ciidExclude <= 0xffffUL);
  657. olChk(ValidateBuffer(rgiidExclude,
  658. (size_t)(sizeof(IID)*ciidExclude)));
  659. for (i = 0; i<ciidExclude; i++)
  660. olChk(ValidateIid(rgiidExclude[i]));
  661. }
  662. olChk(Validate());
  663. olChk(CheckReverted());
  664. olAssert(_pdfb->GetCopyBase() == NULL);
  665. _pdfb->SetCopyBase(this);
  666. #ifdef NEWPROPS
  667. // Flush all descendant property set buffers so that their
  668. // underlying Streams (which are about to be copied) are
  669. // up to date.
  670. olChk(FlushBufferedData());
  671. #endif
  672. olChk(CopyDocFileToIStorage(GetDF(), pstgDest, snbExclude,
  673. MakeCopyFlags(ciidExclude, rgiidExclude)));
  674. }
  675. CATCH(CException, e)
  676. {
  677. sc = e.GetErrorCode();
  678. }
  679. END_CATCH
  680. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::Copy\n"));
  681. EH_Err:
  682. _pdfb->SetCopyBase(NULL);
  683. olLog(("%p::Out ExposedDocFile::CopyTo(). ret == %lX\n",this, sc));
  684. return sc;
  685. }
  686. //+--------------------------------------------------------------
  687. //
  688. // Member: CExposedDocFile::Commit, public
  689. //
  690. // Synopsis: Commits transacted changes
  691. //
  692. // Arguments: [dwFlags] - DFC_*
  693. //
  694. // Returns: Appropriate status code
  695. //
  696. //---------------------------------------------------------------
  697. STDMETHODIMP CExposedDocFile::Commit(DWORD dwFlags)
  698. {
  699. SCODE sc=S_OK;
  700. TIME_T tm;
  701. olLog(("%p::In CExposedDocFile::Commit(%lX)\n",this, dwFlags));
  702. olDebugOut((DEB_ITRACE, "In CExposedDocFile::Commit(%lX)\n", dwFlags));
  703. TRY
  704. {
  705. if (!VALID_COMMIT(dwFlags))
  706. olErr(EH_Err, STG_E_INVALIDFLAG);
  707. olChk(Validate());
  708. olChk(CheckReverted());
  709. if (!P_WRITE(_df)) olErr(EH_Err, STG_E_ACCESSDENIED);
  710. if (IsDirty())
  711. {
  712. olChk(DfGetTOD(&tm));
  713. olChk(_pdf->SetTime(WT_MODIFICATION, tm));
  714. olChk(_pmsBase->Flush(FLUSH_CACHE(dwFlags)));
  715. if (!IsRoot()) _pdfParent->SetDirty();
  716. }
  717. olChk(DfGetTOD(&tm));
  718. olChk(_pdf->SetTime(WT_ACCESS, tm));
  719. #ifdef NEWPROPS
  720. olChk(FlushBufferedData());
  721. #endif
  722. }
  723. CATCH(CException, e)
  724. {
  725. sc = e.GetErrorCode();
  726. }
  727. END_CATCH
  728. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::Commit\n"));
  729. EH_Err:
  730. olLog(("%p::Out CExposedDocFile::Commit(). ret == %lx\n",this, sc));
  731. return ResultFromScode(sc);
  732. }
  733. //+--------------------------------------------------------------
  734. //
  735. // Member: CExposedDocFile::Revert, public
  736. //
  737. // Synopsis: Reverts transacted changes
  738. //
  739. // Returns: S_OK - for direct mode files, this function
  740. // has not effect
  741. //
  742. //---------------------------------------------------------------
  743. STDMETHODIMP CExposedDocFile::Revert(void)
  744. {
  745. // we don't supported transacted files
  746. // it is stated in the OLE documentation that for direct
  747. // files, this method has no effect
  748. return ResultFromScode(S_OK);
  749. }
  750. //+--------------------------------------------------------------
  751. //
  752. // Member: CExposedDocFile::EnumElements, public
  753. //
  754. // Synopsis: Starts an iterator
  755. //
  756. // Arguments: [reserved1]
  757. // [reserved2]
  758. // [reserved3]
  759. // [ppenm] - Enumerator return
  760. //
  761. // Returns: Appropriate status code
  762. //
  763. // Modifies: [ppenm]
  764. //
  765. //---------------------------------------------------------------
  766. STDMETHODIMP CExposedDocFile::EnumElements(DWORD reserved1,
  767. void *reserved2,
  768. DWORD reserved3,
  769. IEnumSTATSTG **ppenm)
  770. {
  771. SCODE sc;
  772. CExposedIterator *pdiExp;
  773. CDfName dfnTemp;
  774. olLog(("%p::In CExposedDocFile::EnumElements(%lu, %p, %lu, %p)\n",
  775. this, reserved1, reserved2, reserved3, ppenm));
  776. olDebugOut((DEB_ITRACE, "In CExposedDocFile::EnumElements(%p)\n",
  777. ppenm));
  778. TRY
  779. {
  780. olChk(ValidateOutPtrBuffer(ppenm));
  781. *ppenm = NULL;
  782. if (reserved1 != 0 || reserved2 != NULL || reserved3 != 0)
  783. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  784. olChk(Validate());
  785. olChk(CheckReverted());
  786. if (!P_READ(_df))
  787. olErr(EH_Err, STG_E_ACCESSDENIED);
  788. olMem(pdiExp = new CExposedIterator(this, &dfnTemp));
  789. *ppenm = pdiExp;
  790. }
  791. CATCH(CException, e)
  792. {
  793. sc = e.GetErrorCode();
  794. }
  795. END_CATCH
  796. EH_Err:
  797. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::EnumElements => %p\n",
  798. SAFE_DREF(ppenm)));
  799. olLog(("%p::Out CExposedDocFile::EnumElements(). ret == %lx\n",this, sc));
  800. return ResultFromScode(sc);
  801. }
  802. //+--------------------------------------------------------------
  803. //
  804. // Member: CExposedDocFile::DestroyElement, public
  805. //
  806. // Synopsis: Permanently deletes an element of a DocFile
  807. //
  808. // Arguments: [pwcsName] - Name of element
  809. //
  810. // Returns: Appropriate status code
  811. //
  812. //---------------------------------------------------------------
  813. TSTDMETHODIMP CExposedDocFile::DestroyElement(WCHAR const *pwcsName)
  814. {
  815. SCODE sc;
  816. CDfName dfn;
  817. olLog(("%p::In CExposedDocFile::DestroyElement(%ws)\n", this, pwcsName));
  818. olDebugOut((DEB_ITRACE, "In CExposedDocFile::DestroyElement(%ws)\n",
  819. pwcsName));
  820. TRY
  821. {
  822. olChk(CheckWName(pwcsName));
  823. olChk(Validate());
  824. dfn.Set(pwcsName);
  825. olChk(DestroyEntry(&dfn, FALSE));
  826. }
  827. CATCH(CException, e)
  828. {
  829. sc = e.GetErrorCode();
  830. }
  831. END_CATCH
  832. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::DestroyElement\n"));
  833. EH_Err:
  834. olLog(("%p::Out CExposedDocFile::DestroyElement(). ret == %lx\n",
  835. this, sc));
  836. return sc;
  837. }
  838. //+--------------------------------------------------------------
  839. //
  840. // Member: CExposedDocFile::MoveElementTo, public
  841. //
  842. // Synopsis: Move an element of a DocFile to an IStorage
  843. //
  844. // Arguments: [pwcsName] - Current name
  845. // [ptcsNewName] - New name
  846. //
  847. // Returns: Appropriate status code
  848. //
  849. // Algorithm: Open source as storage or stream (whatever works)
  850. // Create appropriate destination
  851. // Copy source to destination
  852. // Set create time of destination equal to create time of source
  853. // If appropriate, delete source
  854. //
  855. //---------------------------------------------------------------
  856. TSTDMETHODIMP CExposedDocFile::MoveElementTo(WCHAR const *pwcsName,
  857. IStorage *pstgParent,
  858. TCHAR const *ptcsNewName,
  859. DWORD grfFlags)
  860. {
  861. IUnknown *punksrc = NULL;
  862. SCODE sc;
  863. olLog(("%p::In CExposedDocFile::MoveElementTo(%ws, %p, %s, %lu)\n",
  864. this, pwcsName, pstgParent, ptcsNewName, grfFlags));
  865. olDebugOut((DEB_ITRACE, "In CExposedDocFile::MoveElementTo("
  866. "%ws, %p, %s, %lu)\n",
  867. pwcsName, pstgParent, ptcsNewName, grfFlags));
  868. TRY
  869. {
  870. IUnknown *punkdst = NULL;
  871. IStorage *pstgsrc;
  872. STATSTG statstg;
  873. olChk(CheckWName(pwcsName));
  874. olChk(Validate());
  875. olChk(VerifyMoveFlags(grfFlags));
  876. // determine source type (determine its type)
  877. sc = OpenStorage(pwcsName, (IStorage*)NULL,
  878. STGM_DIRECT| STGM_READ| STGM_SHARE_EXCLUSIVE,
  879. (SNBW)NULL, (DWORD)NULL, &pstgsrc);
  880. if (SUCCEEDED(sc))
  881. {
  882. HRESULT hr;
  883. // It's a storage
  884. punksrc = pstgsrc;
  885. IStorage *pstgdst;
  886. olHChkTo(EH_UnkSrc, pstgsrc->Stat(&statstg, STATFLAG_NONAME));
  887. hr = pstgParent->CreateStorage(ptcsNewName,
  888. STGM_DIRECT |
  889. STGM_WRITE |
  890. STGM_SHARE_EXCLUSIVE
  891. | STGM_FAILIFTHERE,
  892. 0, 0, &pstgdst);
  893. if (DfGetScode(hr) == STG_E_FILEALREADYEXISTS &&
  894. grfFlags == STGMOVE_COPY)
  895. {
  896. hr = pstgParent->OpenStorage(ptcsNewName,
  897. NULL,
  898. STGM_DIRECT |
  899. STGM_WRITE |
  900. STGM_SHARE_EXCLUSIVE,
  901. NULL,
  902. 0, &pstgdst);
  903. }
  904. olHChkTo(EH_UnkSrc, hr);
  905. punkdst = pstgdst;
  906. sc = DfGetScode(pstgsrc->CopyTo(0, NULL, NULL, pstgdst));
  907. }
  908. else if (sc == STG_E_FILENOTFOUND)
  909. {
  910. // Try opening it as a stream
  911. IStream *pstmsrc, *pstmdst;
  912. olChk(OpenStream(pwcsName, (void *)NULL,
  913. STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE,
  914. (DWORD)NULL, &pstmsrc));
  915. // It's a stream
  916. punksrc = pstmsrc;
  917. olHChkTo(EH_UnkSrc, pstmsrc->Stat(&statstg, STATFLAG_NONAME));
  918. olHChkTo(EH_UnkSrc,
  919. pstgParent->CreateStream(ptcsNewName,
  920. STGM_DIRECT |
  921. STGM_WRITE |
  922. STGM_SHARE_EXCLUSIVE |
  923. (grfFlags == STGMOVE_MOVE ?
  924. STGM_FAILIFTHERE :
  925. STGM_CREATE),
  926. 0, 0, &pstmdst));
  927. punkdst = pstmdst;
  928. ULARGE_INTEGER cb;
  929. cb.QuadPart = 0xFFFFFFFFFFFFFFFF;
  930. sc = DfGetScode(pstmsrc->CopyTo(pstmdst, cb, NULL, NULL));
  931. }
  932. else
  933. olChk(sc);
  934. punkdst->Release();
  935. if (SUCCEEDED(sc))
  936. {
  937. // Make destination create time match source create time
  938. // Note that we don't really care if this call succeeded.
  939. pstgParent->SetElementTimes(ptcsNewName, &statstg.ctime,
  940. NULL, NULL);
  941. if ((grfFlags & STGMOVE_COPY) == STGMOVE_MOVE)
  942. sc = DestroyElement(pwcsName);
  943. }
  944. if (FAILED(sc))
  945. {
  946. // The copy/move failed, so get rid of the partial result.
  947. pstgParent->DestroyElement(ptcsNewName);
  948. }
  949. }
  950. CATCH(CException, e)
  951. {
  952. sc = e.GetErrorCode();
  953. }
  954. END_CATCH
  955. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::MoveElementTo\n"));
  956. // Fall through
  957. EH_UnkSrc:
  958. if (punksrc)
  959. punksrc->Release();
  960. EH_Err:
  961. olLog(("%p::Out CExposedDocFile::MoveElementTo(). ret == %lx\n",
  962. this, sc));
  963. return sc;
  964. }
  965. //+--------------------------------------------------------------
  966. //
  967. // Member: CExposedDocFile::RenameElement, public
  968. //
  969. // Synopsis: Renames an element of a DocFile
  970. //
  971. // Arguments: [pwcsName] - Current name
  972. // [pwcsNewName] - New name
  973. //
  974. // Returns: Appropriate status code
  975. //
  976. //---------------------------------------------------------------
  977. TSTDMETHODIMP CExposedDocFile::RenameElement(WCHAR const *pwcsName,
  978. WCHAR const *pwcsNewName)
  979. {
  980. SCODE sc;
  981. CDfName dfnOld, dfnNew;
  982. olLog(("%p::In CExposedDocFile::RenameElement(%ws, %ws)\n",
  983. this, pwcsName, pwcsNewName));
  984. olDebugOut((DEB_ITRACE, "In CExposedDocFile::RenameElement(%ws, %ws)\n",
  985. pwcsName, pwcsNewName));
  986. TRY
  987. {
  988. olChk(Validate());
  989. olChk(CheckWName(pwcsName));
  990. olChk(CheckWName(pwcsNewName));
  991. dfnOld.Set(pwcsName);
  992. dfnNew.Set(pwcsNewName);
  993. olChk(RenameEntry(&dfnOld, &dfnNew));
  994. }
  995. CATCH(CException, e)
  996. {
  997. sc = e.GetErrorCode();
  998. }
  999. END_CATCH
  1000. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::RenameElement\n"));
  1001. EH_Err:
  1002. olLog(("%p::Out CExposedDocFile::RenameElement(). ret == %lx\n",
  1003. this, sc));
  1004. return sc;
  1005. }
  1006. //+--------------------------------------------------------------
  1007. //
  1008. // Member: CExposedDocFile::SetElementTimes, public
  1009. //
  1010. // Synopsis: Sets element time stamps
  1011. //
  1012. // Arguments: [pwcsName] - Name
  1013. // [pctime] - create time
  1014. // [patime] - access time
  1015. // [pmtime] - modify time
  1016. //
  1017. // Returns: Appropriate status code
  1018. //
  1019. //---------------------------------------------------------------
  1020. TSTDMETHODIMP CExposedDocFile::SetElementTimes(WCHAR const *pwcsName,
  1021. FILETIME const *pctime,
  1022. FILETIME const *patime,
  1023. FILETIME const *pmtime)
  1024. {
  1025. SCODE sc;
  1026. CDfName dfn;
  1027. CDocFile *pdf;
  1028. olLog(("%p::In CExposedDocFile::SetElementTimes(%ws, %p, %p, %p)\n",
  1029. this, pwcsName, pctime, patime, pmtime));
  1030. olDebugOut((DEB_ITRACE, "In CExposedDocFile::SetElementTimes:%p("
  1031. "%ws, %p, %p, %p)\n", this, pwcsName, pctime, patime, pmtime));
  1032. TRY
  1033. {
  1034. if (pwcsName)
  1035. olChk(CheckWName(pwcsName));
  1036. else // function is meant to work on root storage
  1037. {
  1038. olAssert(FALSE &&
  1039. aMsg("SetTimes on root storage is not supported!\n"));
  1040. // SetElementTimes on root storage is not portable
  1041. // since it calls set filetimes.
  1042. return ResultFromScode(STG_E_UNIMPLEMENTEDFUNCTION);
  1043. }
  1044. olChk(Validate());
  1045. if (pctime)
  1046. olChk(ValidateBuffer(pctime, sizeof(FILETIME)));
  1047. if (patime)
  1048. olChk(ValidateBuffer(patime, sizeof(FILETIME)));
  1049. if (pmtime)
  1050. olChk(ValidateBuffer(pmtime, sizeof(FILETIME)));
  1051. dfn.Set(pwcsName);
  1052. olChk(CheckReverted());
  1053. if (!P_WRITE(_df) || _cilChildren.FindByName(&dfn) != NULL)
  1054. olErr(EH_Err, STG_E_ACCESSDENIED);
  1055. olChk(_pdf->GetDocFile(&dfn, DF_WRITE, &pdf));
  1056. if (pctime)
  1057. olChkTo(EH_pdf, pdf->SetTime(WT_CREATION, *pctime));
  1058. if (pmtime)
  1059. olChkTo(EH_pdf, pdf->SetTime(WT_MODIFICATION, *pmtime));
  1060. if (patime)
  1061. olChkTo(EH_pdf, pdf->SetTime(WT_ACCESS, *patime));
  1062. SetDirty();
  1063. }
  1064. CATCH(CException, e)
  1065. {
  1066. sc = e.GetErrorCode();
  1067. }
  1068. END_CATCH
  1069. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::SetElementTimes\n"));
  1070. // Fall thru
  1071. EH_pdf:
  1072. pdf->Release();
  1073. EH_Err:
  1074. olLog(("%p::Out CExposedDocFile::SetElementTimes(). ret == %lx\n",
  1075. this, sc));
  1076. return sc;
  1077. }
  1078. //+--------------------------------------------------------------
  1079. //
  1080. // Member: CExposedDocFile::SetClass, public
  1081. //
  1082. // Synopsis: Sets storage class
  1083. //
  1084. // Arguments: [clsid] - class id
  1085. //
  1086. // Returns: Appropriate status code
  1087. //
  1088. //---------------------------------------------------------------
  1089. STDMETHODIMP CExposedDocFile::SetClass(REFCLSID clsid)
  1090. {
  1091. SCODE sc;
  1092. olLog(("%p::In CExposedDocFile::SetClass(?)\n", this));
  1093. olDebugOut((DEB_ITRACE, "In CExposedDocFile::SetClass:%p(?)\n", this));
  1094. TRY
  1095. {
  1096. olChk(Validate());
  1097. olChk(ValidateBuffer(&clsid, sizeof(CLSID)));
  1098. olChk(CheckReverted());
  1099. if (!P_WRITE(_df))
  1100. olErr(EH_Err, STG_E_ACCESSDENIED);
  1101. olChk(_pdf->SetClass(clsid));
  1102. }
  1103. CATCH(CException, e)
  1104. {
  1105. sc = e.GetErrorCode();
  1106. }
  1107. END_CATCH
  1108. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::SetClass\n"));
  1109. EH_Err:
  1110. olLog(("%p::Out CExposedDocFile::SetClass(). ret == %lx\n",
  1111. this, sc));
  1112. return ResultFromScode(sc);
  1113. }
  1114. //+--------------------------------------------------------------
  1115. //
  1116. // Member: CExposedDocFile::SetStateBits, public
  1117. //
  1118. // Synopsis: Sets state bits
  1119. //
  1120. // Arguments: [grfStateBits] - state bits
  1121. // [grfMask] - state bits mask
  1122. //
  1123. // Returns: Appropriate status code
  1124. //
  1125. //---------------------------------------------------------------
  1126. STDMETHODIMP CExposedDocFile::SetStateBits(DWORD grfStateBits, DWORD grfMask)
  1127. {
  1128. SCODE sc;
  1129. olLog(("%p::In CExposedDocFile::SetStateBits(%lu, %lu)\n", this,
  1130. grfStateBits, grfMask));
  1131. olDebugOut((DEB_ITRACE, "In CExposedDocFile::SetStateBits:%p("
  1132. "%lu, %lu)\n", this, grfStateBits, grfMask));
  1133. TRY
  1134. {
  1135. olChk(Validate());
  1136. olChk(CheckReverted());
  1137. if (!P_WRITE(_df))
  1138. olErr(EH_Err, STG_E_ACCESSDENIED);
  1139. olChk(_pdf->SetStateBits(grfStateBits, grfMask));
  1140. SetDirty();
  1141. }
  1142. CATCH(CException, e)
  1143. {
  1144. sc = e.GetErrorCode();
  1145. }
  1146. END_CATCH
  1147. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::SetStateBits\n"));
  1148. // fall thru
  1149. EH_Err:
  1150. olLog(("%p::Out CExposedDocFile::SetStateBits(). ret == %lx\n",
  1151. this, sc));
  1152. return ResultFromScode(sc);
  1153. }
  1154. //+--------------------------------------------------------------
  1155. //
  1156. // Member: CExposedDocFile::Stat, public virtual
  1157. //
  1158. // Synopsis: Fills in a buffer of information about this object
  1159. //
  1160. // Arguments: [pstatstg] - Buffer
  1161. //
  1162. // Returns: Appropriate status code
  1163. //
  1164. // Modifies: [pstatstg]
  1165. //
  1166. //---------------------------------------------------------------
  1167. TSTDMETHODIMP CExposedDocFile::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
  1168. {
  1169. SCODE sc;
  1170. // root storage should be handled by virtual funcs in CRootExposedDocFile
  1171. olAssert(!IsRoot());
  1172. olLog(("%p::In CExposedDocFile::Stat(%p)\n", this, pstatstg));
  1173. olDebugOut((DEB_ITRACE, "In CExposedDocFile::Stat(%p)\n", pstatstg));
  1174. TRY
  1175. {
  1176. olChkTo(EH_RetSc, ValidateOutBuffer(pstatstg, sizeof(STATSTGW)));
  1177. olChk(VerifyStatFlag(grfStatFlag));
  1178. olChk(CheckReverted());
  1179. olChk(_pdf->GetTime(WT_CREATION, &pstatstg->ctime));
  1180. olChk(_pdf->GetTime(WT_MODIFICATION, &pstatstg->mtime));
  1181. pstatstg->atime.dwLowDateTime = pstatstg->atime.dwHighDateTime = 0;
  1182. olChk(_pdf->GetClass(&pstatstg->clsid));
  1183. olChk(_pdf->GetStateBits(&pstatstg->grfStateBits));
  1184. pstatstg->pwcsName = NULL;
  1185. if ((grfStatFlag & STATFLAG_NONAME) == 0)
  1186. {
  1187. olChk(DfAllocWCS((WCHAR *)_dfn.GetBuffer(), &pstatstg->pwcsName));
  1188. wcscpy(pstatstg->pwcsName, (WCHAR *)_dfn.GetBuffer());
  1189. }
  1190. pstatstg->grfMode = DFlagsToMode(_df);
  1191. pstatstg->type = STGTY_STORAGE;
  1192. ULISet32(pstatstg->cbSize, 0); // irelevant for storage obj
  1193. pstatstg->grfLocksSupported = 0;
  1194. pstatstg->reserved = 0;
  1195. }
  1196. CATCH(CException, e)
  1197. {
  1198. sc = e.GetErrorCode();
  1199. }
  1200. END_CATCH
  1201. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::Stat\n"));
  1202. EH_Err:
  1203. if (FAILED(sc))
  1204. memset(pstatstg, 0, sizeof(STATSTGW));
  1205. EH_RetSc:
  1206. olLog(("%p::Out CExposedDocFile::Stat(). *pstatstg == %p ret == %lx\n",
  1207. this, *pstatstg, sc));
  1208. return sc;
  1209. }
  1210. //+--------------------------------------------------------------
  1211. //
  1212. // Member: CExposedDocFile::AddRef, public
  1213. //
  1214. // Synopsis: Increments the ref count
  1215. //
  1216. // Returns: Appropriate status code
  1217. //
  1218. //---------------------------------------------------------------
  1219. STDMETHODIMP_(ULONG) CExposedDocFile::AddRef(void)
  1220. {
  1221. ULONG ulRet;
  1222. olLog(("%p::In CExposedDocFile::AddRef()\n", this));
  1223. olDebugOut((DEB_ITRACE, "In CExposedDocFile::AddRef()\n"));
  1224. TRY
  1225. {
  1226. if (FAILED(Validate()))
  1227. return 0;
  1228. AtomicInc(&_cReferences);
  1229. ulRet = _cReferences;
  1230. }
  1231. CATCH(CException, e)
  1232. {
  1233. UNREFERENCED_PARM(e);
  1234. ulRet = 0;
  1235. }
  1236. END_CATCH
  1237. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::AddRef\n"));
  1238. olLog(("%p::Out CExposedDocFile::AddRef(). ret == %lu\n", this, ulRet));
  1239. return ulRet;
  1240. }
  1241. //+--------------------------------------------------------------
  1242. //
  1243. // Member: CExposedDocFile::QueryInterface, public
  1244. //
  1245. // Synopsis: Returns an object for the requested interface
  1246. //
  1247. // Arguments: [iid] - Interface ID
  1248. // [ppvObj] - Object return
  1249. //
  1250. // Returns: Appropriate status code
  1251. //
  1252. // Modifies: [ppvObj]
  1253. //
  1254. //---------------------------------------------------------------
  1255. STDMETHODIMP CExposedDocFile::QueryInterface(REFIID iid, void **ppvObj)
  1256. {
  1257. SCODE sc;
  1258. olLog(("%p::In CExposedDocFile::QueryInterface(?, %p)\n",
  1259. this, ppvObj));
  1260. olDebugOut((DEB_ITRACE, "In CExposedDocFile::QueryInterface(?, %p)\n",
  1261. ppvObj));
  1262. TRY
  1263. {
  1264. olChk(ValidateOutPtrBuffer(ppvObj));
  1265. *ppvObj = NULL;
  1266. olChk(ValidateIid(iid));
  1267. olChk(Validate());
  1268. olChk(CheckReverted());
  1269. if ( IsEqualIID(iid, IID_IStorage) || IsEqualIID(iid, IID_IUnknown) )
  1270. {
  1271. olChk(CExposedDocFile::AddRef());
  1272. *ppvObj = (IStorage*) this;
  1273. }
  1274. #ifdef NEWPROPS
  1275. else if (IsEqualIID(iid, IID_IPropertySetStorage))
  1276. {
  1277. olChk(CExposedDocFile::AddRef());
  1278. *ppvObj = (IPropertySetStorage *) this;
  1279. }
  1280. #endif
  1281. else
  1282. olErr(EH_Err, E_NOINTERFACE);
  1283. sc = S_OK;
  1284. }
  1285. CATCH(CException, e)
  1286. {
  1287. sc = e.GetErrorCode();
  1288. }
  1289. END_CATCH
  1290. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::QueryInterface => %p\n",
  1291. ppvObj));
  1292. EH_Err:
  1293. olLog(("%p::Out CExposedDocFile::QueryInterface(). *ppvObj == %p ret == %lx\n",
  1294. this, SAFE_DREF(ppvObj), sc));
  1295. return ResultFromScode(sc);
  1296. }
  1297. //+--------------------------------------------------------------
  1298. //
  1299. // Method: CExposedDocFile::CopyDStreamToIStream, private
  1300. //
  1301. // Synopsis: Copies a CDirectStream to an IStream
  1302. //
  1303. // Arguments: [pstFrom] - CDirectStream
  1304. // [pstTo] - IStream
  1305. //
  1306. // Returns: Appropriate status code
  1307. //
  1308. //---------------------------------------------------------------
  1309. SCODE CExposedDocFile::CopyDStreamToIStream(CDirectStream *pstFrom,
  1310. IStream *pstTo)
  1311. {
  1312. BYTE *pbBuffer;
  1313. SCODE sc;
  1314. ULONG cbRead, cbWritten;
  1315. ULONGLONG cbPos;
  1316. ULARGE_INTEGER cbSize;
  1317. // This is part of CopyTo and therefore we are allowed to
  1318. // fail with out-of-memory
  1319. olMem(pbBuffer = new BYTE[STREAMBUFFERSIZE]);
  1320. // Set destination size for contiguity
  1321. pstFrom->GetSize(&cbSize.QuadPart);
  1322. // Don't need to SetAccess0 here because pstTo is an IStream
  1323. olHChk(pstTo->SetSize(cbSize));
  1324. // Copy between streams
  1325. cbPos = 0;
  1326. for (;;)
  1327. {
  1328. olChk(pstFrom->ReadAt(cbPos, pbBuffer, STREAMBUFFERSIZE,
  1329. (ULONG STACKBASED *)&cbRead));
  1330. if (cbRead == 0) // EOF
  1331. break;
  1332. // Don't need to SetAccess0 here because pstTo is an IStream
  1333. olHChk(pstTo->Write(pbBuffer, cbRead, &cbWritten));
  1334. if (cbRead != cbWritten)
  1335. olErr(EH_Err, STG_E_WRITEFAULT);
  1336. cbPos += cbWritten;
  1337. }
  1338. sc = S_OK;
  1339. EH_Err:
  1340. delete [] pbBuffer;
  1341. return sc;
  1342. }
  1343. //+--------------------------------------------------------------
  1344. //
  1345. // Method: CExposedDocFile::CopyDocFileToIStorage, private
  1346. //
  1347. // Synopsis: Copies a docfile's contents to an IStorage
  1348. //
  1349. // Arguments: [pdfFrom] - From
  1350. // [pstgTo] - To
  1351. // [snbExclude] - Names to not copy
  1352. // [dwCopyFlags] - Bitwise flags for types of objects to copy
  1353. //
  1354. // Returns: Appropriate status code
  1355. //
  1356. //---------------------------------------------------------------
  1357. SCODE CExposedDocFile::CopyDocFileToIStorage(CDocFile *pdfFrom,
  1358. IStorage *pstgTo,
  1359. SNBW snbExclude,
  1360. DWORD dwCopyFlags)
  1361. {
  1362. PDocFileIterator *pdfi;
  1363. SIterBuffer ib;
  1364. CDirectStream *pstFrom = NULL;
  1365. IStream *pstTo = NULL;
  1366. CDocFile *pdfFromChild = NULL;
  1367. IStorage *pstgToChild = NULL;
  1368. SCODE sc;
  1369. TCHAR atcName[CWCSTORAGENAME];
  1370. CLSID clsid;
  1371. DWORD grfStateBits;
  1372. olDebugOut((DEB_ITRACE, "In CopyDocFileToIStorage:%p(%p, %p, %p, %lX)\n",
  1373. this, pdfFrom, pstgTo, snbExclude, dwCopyFlags));
  1374. olChk(pdfFrom->GetClass(&clsid));
  1375. olHChk(pstgTo->SetClass(clsid));
  1376. olChk(pdfFrom->GetStateBits(&grfStateBits));
  1377. olHChk(pstgTo->SetStateBits(grfStateBits, 0xffffffff));
  1378. olChk(pdfFrom->GetIterator(&pdfi));
  1379. for (;;)
  1380. {
  1381. sc = pdfi->BufferGetNext(&ib);
  1382. if (sc == STG_E_NOMOREFILES)
  1383. break;
  1384. else if (FAILED(sc))
  1385. olErr(EH_pdfi, sc);
  1386. if (snbExclude && NameInSNB(&ib.dfnName, snbExclude) == S_OK)
  1387. continue;
  1388. if ((ib.type == STGTY_STORAGE && (dwCopyFlags & COPY_STORAGES) == 0) ||
  1389. (ib.type == STGTY_STREAM && (dwCopyFlags & COPY_STREAMS) == 0)
  1390. )
  1391. continue;
  1392. switch(ib.type)
  1393. {
  1394. case STGTY_STORAGE:
  1395. // Embedded DocFile, create destination and recurse
  1396. sc = pdfFrom->GetDocFile(&ib.dfnName, DF_READ,
  1397. ib.type, &pdfFromChild);
  1398. olChkTo(EH_pdfi, sc);
  1399. WTOT(atcName, (WCHAR *)ib.dfnName.GetBuffer(), CWCSTORAGENAME);
  1400. // Don't need to SetAccess0 here because pstgTo is an IStorage.
  1401. sc = DfGetScode(pstgTo->CreateStorage(atcName, STGM_WRITE |
  1402. STGM_SHARE_EXCLUSIVE |
  1403. STGM_FAILIFTHERE,
  1404. 0, 0, &pstgToChild));
  1405. if (sc == STG_E_FILEALREADYEXISTS)
  1406. olHChkTo(EH_Get, pstgTo->OpenStorage(atcName, NULL,
  1407. STGM_WRITE |
  1408. STGM_SHARE_EXCLUSIVE,
  1409. NULL, 0, &pstgToChild));
  1410. else if (FAILED(sc))
  1411. olErr(EH_Get, sc);
  1412. olChkTo(EH_Create,
  1413. CopyDocFileToIStorage(pdfFromChild, pstgToChild, NULL,
  1414. dwCopyFlags));
  1415. pdfFromChild->Release();
  1416. pstgToChild->Release();
  1417. break;
  1418. case STGTY_STREAM:
  1419. sc = pdfFrom->GetStream(&ib.dfnName, DF_READ, ib.type, &pstFrom);
  1420. olChkTo(EH_pdfi, sc);
  1421. WTOT(atcName, (WCHAR *)ib.dfnName.GetBuffer(), CWCSTORAGENAME);
  1422. // Don't need to SetAccess0 here because pstgTo is an IStorage.
  1423. olHChkTo(EH_Get,
  1424. pstgTo->CreateStream(atcName, STGM_WRITE |
  1425. STGM_SHARE_EXCLUSIVE |
  1426. STGM_CREATE,
  1427. 0, 0, &pstTo));
  1428. olChkTo(EH_Create, CopyDStreamToIStream(pstFrom, pstTo));
  1429. pstFrom->Release();
  1430. pstTo->Release();
  1431. break;
  1432. default:
  1433. olAssert(!aMsg("Unknown type in CopyDocFileToIStorage"));
  1434. break;
  1435. }
  1436. }
  1437. pdfi->Release();
  1438. olDebugOut((DEB_ITRACE, "Out CopyDocFileToIStorage\n"));
  1439. return S_OK;
  1440. EH_Create:
  1441. if (ib.type == STGTY_STORAGE)
  1442. pstgToChild->Release();
  1443. else
  1444. pstTo->Release();
  1445. olVerSucc(pstgTo->DestroyElement(atcName));
  1446. EH_Get:
  1447. if (ib.type == STGTY_STORAGE)
  1448. pdfFromChild->Release();
  1449. else
  1450. pstFrom->Release();
  1451. EH_pdfi:
  1452. pdfi->Release();
  1453. EH_Err:
  1454. return sc;
  1455. }
  1456. //+---------------------------------------------------------------------------
  1457. //
  1458. // Member: CExposedDocFile::SwitchToFile, public
  1459. //
  1460. // Synopsis: Switches the underlying file to another file
  1461. //
  1462. // Arguments: [ptcsFile] - New file name
  1463. //
  1464. // Returns: Appropriate status code
  1465. //
  1466. //----------------------------------------------------------------------------
  1467. STDMETHODIMP CExposedDocFile::SwitchToFile(TCHAR *ptcsFile)
  1468. {
  1469. UNREFERENCED_PARM(ptcsFile);
  1470. olAssert(FALSE && aMsg("Unimplemented Function called!\n"));
  1471. return ResultFromScode(STG_E_UNIMPLEMENTEDFUNCTION);
  1472. }
  1473. //+---------------------------------------------------------------------------
  1474. //
  1475. // Member: CExposedDocFile::CreateExposedStream, private
  1476. //
  1477. // Synopsis: Creates an Exposed Stream
  1478. // This is a private function that creates the exposed stream.
  1479. // It is splitted out as a function so that the code can be
  1480. // reused.
  1481. //
  1482. // Arguments: [pdfnName] name of entry
  1483. // [df] doc file flags
  1484. // [ppStream] returned ExposedStream
  1485. //
  1486. // Returns: Appropriate status code
  1487. //
  1488. //----------------------------------------------------------------------------
  1489. SCODE CExposedDocFile::CreateExposedStream( CDfName const *pdfnName,
  1490. DFLAGS const df,
  1491. CExposedStream **ppStream)
  1492. {
  1493. CExposedStream *pstExp = NULL;
  1494. CDirectStream *pstDirect = NULL;
  1495. SCODE sc = S_OK;
  1496. olChk(CheckReverted());
  1497. if (!P_WRITE(_df)) olErr(EH_Err, STG_E_ACCESSDENIED);
  1498. olChk(_cilChildren.IsDenied(pdfnName, df, _df));
  1499. olChk(_pdf->CreateStream(pdfnName, df, DF_NOLUID, &pstDirect));
  1500. // As soon as we have a base we dirty ourself (in case
  1501. // we get an error later) so that we'll flush properly.
  1502. SetDirty();
  1503. olMemTo(EH_pst, pstExp = new CExposedStream());
  1504. olChkTo(EH_pstExp, pstExp->Init(pstDirect, this,
  1505. df, pdfnName, (ULONG)NULL));
  1506. *ppStream = pstExp;
  1507. return S_OK;
  1508. EH_pstExp:
  1509. delete pstExp;
  1510. EH_pst:
  1511. pstDirect->Release();
  1512. olVerSucc(DestroyEntry(pdfnName, TRUE));
  1513. EH_Err:
  1514. return sc;
  1515. }
  1516. //+---------------------------------------------------------------------------
  1517. //
  1518. // Member: CExposedDocFile::GetExposedStream, private
  1519. //
  1520. // Synopsis: Gets an existing exposed stream
  1521. // This is a private function that gets the exposed stream.
  1522. // It is splitted out as a function so that the code can be
  1523. // reused.
  1524. //
  1525. // Arguments: [pdfnName] name of entry
  1526. // [df] doc file flags
  1527. // [ppStream] returned ExposedStream
  1528. //
  1529. // Returns: Appropriate status code
  1530. //
  1531. //----------------------------------------------------------------------------
  1532. SCODE CExposedDocFile::GetExposedStream( CDfName const *pdfnName,
  1533. DFLAGS const df,
  1534. CExposedStream **ppStream)
  1535. {
  1536. CExposedStream *pstExp = NULL;
  1537. CDirectStream *pstDirect = NULL;
  1538. SCODE sc = S_OK;
  1539. olChk(CheckReverted());
  1540. if (!P_READ(_df)) olErr(EH_Err, STG_E_ACCESSDENIED);
  1541. // Check permissions
  1542. olChk(_cilChildren.IsDenied(pdfnName, df, _df));
  1543. olChk(_pdf->GetStream(pdfnName, df, DF_NOLUID, &pstDirect));
  1544. olMemTo(EH_pst, pstExp = new CExposedStream());
  1545. olChkTo(EH_pstExp, pstExp->Init(pstDirect, this,
  1546. df, pdfnName, (ULONG)NULL));
  1547. *ppStream = pstExp;
  1548. return S_OK;
  1549. EH_pstExp:
  1550. delete pstExp;
  1551. EH_pst:
  1552. pstDirect->Release();
  1553. EH_Err:
  1554. return sc;
  1555. }
  1556. //+--------------------------------------------------------------
  1557. //
  1558. // Member: CExposedDocFile::DestroyEntry, private
  1559. //
  1560. // Synopsis: Destroys an entry and removes it from the children
  1561. // list.
  1562. //
  1563. //---------------------------------------------------------------
  1564. SCODE CExposedDocFile::DestroyEntry( CDfName const *pdfnName,
  1565. BOOL fClean)
  1566. {
  1567. SCODE sc=S_OK;
  1568. olChk(CheckReverted());
  1569. if (!P_WRITE(_df)) olErr(EH_Err, STG_E_ACCESSDENIED);
  1570. olChk(_pdf->DestroyEntry(pdfnName, fClean));
  1571. _cilChildren.DeleteByName(pdfnName);
  1572. SetDirty();
  1573. // Fall through
  1574. EH_Err:
  1575. return sc;
  1576. }
  1577. //+--------------------------------------------------------------
  1578. //
  1579. // Member: CExposedDocFile::CreateExposedDocFile, private
  1580. //
  1581. // Synopsis: Creates an embedded DocFile
  1582. //
  1583. // Arguments: [pdfnName] - Name
  1584. // [df] - Permissions
  1585. // [ppdfDocFile] - New DocFile return
  1586. //
  1587. // Returns: Appropriate status code
  1588. //
  1589. // Modifies: [ppdfDocFile]
  1590. //
  1591. //---------------------------------------------------------------
  1592. SCODE CExposedDocFile::CreateExposedDocFile(CDfName const *pdfnName,
  1593. DFLAGS const df,
  1594. CExposedDocFile **ppdfDocFile)
  1595. {
  1596. SCODE sc;
  1597. CDocFile *pdf=NULL;
  1598. SEntryBuffer eb;
  1599. olChk(CheckReverted());
  1600. if (!P_WRITE(_df)) olErr(EH_Err, STG_E_ACCESSDENIED);
  1601. olChk(_cilChildren.IsDenied(pdfnName, df, _df));
  1602. olChkTo(EH_Reserve, _pdf->CreateDocFile(pdfnName, df, DF_NOLUID,
  1603. &pdf));
  1604. // As soon as we have a base we dirty ourself (in case
  1605. // we get an error later) so that we'll flush properly.
  1606. SetDirty();
  1607. eb.luid = pdf->GetLuid();
  1608. olAssert(eb.luid != DF_NOLUID && aMsg("DocFile id is DF_NOLUID!"));
  1609. olMemTo(EH_pdf,
  1610. *ppdfDocFile = new CExposedDocFile(this, pdf, df, eb.luid,
  1611. _pilbBase, pdfnName, _pmsBase, _pdfb));
  1612. return S_OK;
  1613. EH_pdf:
  1614. pdf->Release();
  1615. olVerSucc(_pdf->DestroyEntry(pdfnName, TRUE));
  1616. return sc;
  1617. EH_Reserve:
  1618. EH_Err:
  1619. return sc;
  1620. }
  1621. //+--------------------------------------------------------------
  1622. //
  1623. // Member: CExposedDocFile::GetExposedDocFile, private
  1624. //
  1625. // Synopsis: Retrieves an embedded DocFile
  1626. //
  1627. // Arguments: [pdfnName] - Name
  1628. // [df] - Permissions
  1629. // [ppdfDocFile] - New DocFile return
  1630. //
  1631. // Returns: Appropriate status code
  1632. //
  1633. // Modifies: [ppdfDocFile]
  1634. //
  1635. //---------------------------------------------------------------
  1636. SCODE CExposedDocFile::GetExposedDocFile( CDfName const *pdfnName,
  1637. DFLAGS const df,
  1638. CExposedDocFile **ppdfDocFile)
  1639. {
  1640. CDocFile *pdf;
  1641. SCODE sc;
  1642. SEntryBuffer eb;
  1643. olChk(CheckReverted());
  1644. if (!P_READ(_df)) olErr(EH_Err, STG_E_ACCESSDENIED);
  1645. // Check to see if an instance with DENY_* exists
  1646. olChk(_cilChildren.IsDenied(pdfnName, df, _df));
  1647. olChk(_pdf->GetDocFile(pdfnName, df, &pdf));
  1648. eb.luid = pdf->GetLuid();
  1649. olAssert(eb.luid != DF_NOLUID && aMsg("DocFile id is DF_NOLUID!"));
  1650. olMemTo(EH_pdf,
  1651. *ppdfDocFile = new CExposedDocFile(this, pdf, df, eb.luid,
  1652. _pilbBase, pdfnName, _pmsBase, _pdfb));
  1653. return S_OK;
  1654. EH_pdf:
  1655. pdf->Release();
  1656. EH_Err:
  1657. return sc;
  1658. }
  1659. //+--------------------------------------------------------------
  1660. //
  1661. // Member: CExposedDocFile::RenameEntry, public
  1662. //
  1663. // Synopsis: Renames an element of a DocFile
  1664. //
  1665. // Arguments: [pdfnName] - Current name
  1666. // [pdfnNewName] - New name
  1667. //
  1668. // Returns: Appropriate status code
  1669. //
  1670. //---------------------------------------------------------------
  1671. SCODE CExposedDocFile::RenameEntry(CDfName const *pdfnName,
  1672. CDfName const *pdfnNewName)
  1673. {
  1674. SCODE sc;
  1675. olChk(CheckReverted());
  1676. if (!P_WRITE(_df))
  1677. sc = STG_E_ACCESSDENIED;
  1678. else
  1679. {
  1680. sc = _pdf->RenameEntry(pdfnName, pdfnNewName);
  1681. if (SUCCEEDED(sc))
  1682. {
  1683. _cilChildren.RenameChild(pdfnName, pdfnNewName);
  1684. SetDirty();
  1685. }
  1686. }
  1687. // Fall through
  1688. EH_Err:
  1689. return sc;
  1690. }
  1691. //+--------------------------------------------------------------
  1692. //
  1693. // Member: CExposedDocFile::RevertFromAbove, public virtual from
  1694. // PRevertable
  1695. //
  1696. // Synopsis: Parent has asked for reversion
  1697. //
  1698. //---------------------------------------------------------------
  1699. void CExposedDocFile::RevertFromAbove(void)
  1700. {
  1701. olDebugOut((DEB_ITRACE, "In CExposedDocFile::RevertFromAbove:%p()\n", this));
  1702. _df |= DF_REVERTED;
  1703. _cilChildren.DeleteByName(NULL);
  1704. _pdf->Release();
  1705. #if DBG == 1
  1706. _pdf = NULL;
  1707. #endif
  1708. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::RevertFromAbove\n"));
  1709. }
  1710. //+--------------------------------------------------------------
  1711. //
  1712. // Member: CExposedDocFile::IsAtOrAbove, public
  1713. //
  1714. // Synopsis: Determines whether the given docfile is an ancestor
  1715. // of this docfile
  1716. //
  1717. // Arguments: [pdf] - Docfile to check
  1718. //
  1719. // Returns: TRUE or FALSE
  1720. //
  1721. //---------------------------------------------------------------
  1722. BOOL CExposedDocFile::IsAtOrAbove(CExposedDocFile *pdf)
  1723. {
  1724. CExposedDocFile *pdfPar = this;
  1725. olAssert(SUCCEEDED(CheckReverted()));
  1726. do
  1727. {
  1728. if (pdfPar == pdf)
  1729. break;
  1730. }
  1731. while (pdfPar = pdfPar->_pdfParent);
  1732. return pdfPar == pdf;
  1733. }
  1734. #ifdef NEWPROPS
  1735. //+---------------------------------------------------------------------------
  1736. //
  1737. // Member: CExposedDocFile::GetStorage, public IPrivateStorage
  1738. //
  1739. // Synopsis: Returns the IStorage for this object.
  1740. //
  1741. // Notes: This member is called by CPropertyStorage.
  1742. //
  1743. //----------------------------------------------------------------------------
  1744. STDMETHODIMP_(IStorage *)
  1745. CExposedDocFile::GetStorage(VOID)
  1746. {
  1747. return this;
  1748. }
  1749. //+--------------------------------------------------------------
  1750. //
  1751. // Member: CExposedDocFile::FlushBufferedData
  1752. // : public, virtual : PRevertable
  1753. //
  1754. // Synopsis: Flush buffered data in any child streams.
  1755. //
  1756. //---------------------------------------------------------------
  1757. SCODE CExposedDocFile::FlushBufferedData(void)
  1758. {
  1759. SCODE sc;
  1760. olDebugOut((DEB_ITRACE,
  1761. "In CExposedDocFile::FlushBufferedData:%p()\n", this));
  1762. sc = _cilChildren.FlushBufferedData();
  1763. olDebugOut((DEB_ITRACE, "Out CExposedDocFile::FlushBufferedData\n"));
  1764. return sc;
  1765. }
  1766. #endif // #ifdef NEWPROPS