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