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: CExposedStream code
9 //
10 // Notes: See the header file expst.hxx for details
11 //
12 //--------------------------------------------------------------------------
13
14 #include "exphead.cxx"
15
16 #include "expst.hxx"
17 #include "logfile.hxx"
18
19 #ifndef min
20 #define min(a, b) ((a)<(b) ? (a) : (b))
21 #endif
22 #ifndef max
23 #define max(a, b) ((a)>(b) ? (a) : (b))
24 #endif
25
26 // Maximum stream size supported by exposed streams
27 // This is MAX_ULONG with one subtracted so that
28 // the seek pointer has a spot to sit even at the
29 // end of the stream
30 #define CBMAXSTREAM 0xfffffffeUL
31 // Maximum seek pointer value
32 #define CBMAXSEEK (CBMAXSTREAM+1)
33
34 //+--------------------------------------------------------------
35 //
36 // Member: CExposedStream::CExposedStream, public
37 //
38 // Synopsis: Empty object constructor
39 //
40 //---------------------------------------------------------------
41
42
CExposedStream()43 CExposedStream::CExposedStream()
44 {
45 olDebugOut((DEB_ITRACE, "In CExposedStream::CExposedStream()\n"));
46 _cReferences = 0;
47 _ulAccessLockBase = 0;
48 _ulPos = 0;
49 _pst = NULL;
50 _pdfParent = NULL;
51 _fDirty = FALSE;
52 #ifdef NEWPROPS
53 _pb = NULL;
54 _cbUsed = 0;
55 _cbOriginalStreamSize = 0;
56 _fChangePending = FALSE;
57 #endif
58
59 olDebugOut((DEB_ITRACE, "Out CExposedStream::CExposedStream\n"));
60 }
61
62 //+--------------------------------------------------------------
63 //
64 // Member: CExposedStream::Init, public
65 //
66 // Synopsis: Base constructor
67 //
68 // Arguments: [pst] - Direct stream
69 // [pdfParent] - the storage parent
70 // [df] - Permission flags
71 // [pdfn] - name of stream
72 // [ulPos] - offset
73 //
74 // Returns: Appropriate status code
75 //
76 // Note: We add "this" as a child to the parent to
77 // 1) Check for multiple instantiation of a child
78 // 2) Uses the RevertFromAbove() function to check
79 // for reverted state.
80 //
81 //---------------------------------------------------------------
82
Init(CDirectStream * pst,CExposedDocFile * pdfParent,const DFLAGS df,const CDfName * pdfn,const ULONG ulPos)83 SCODE CExposedStream::Init(CDirectStream *pst,
84 CExposedDocFile* pdfParent,
85 const DFLAGS df,
86 const CDfName *pdfn,
87 const ULONG ulPos)
88 {
89 olDebugOut((DEB_ITRACE, "In CExposedStream::Init("
90 "%p, %lu)\n", pst, ulPos));
91 _ulPos = ulPos;
92 _pst = pst;
93 _pdfParent = pdfParent;
94 _df = df;
95 _dfn.Set(pdfn->GetLength(), pdfn->GetBuffer());
96 olAssert(pdfParent);
97 _pdfParent->AddChild(this);
98 _cReferences = 1;
99 _sig = CEXPOSEDSTREAM_SIG;
100 olDebugOut((DEB_ITRACE, "Out CExposedStream::Init\n"));
101 return S_OK;
102 }
103
104
105 //+--------------------------------------------------------------
106 //
107 // Member: CExposedStream::Read, public
108 //
109 // Synopsis: Read from a stream
110 //
111 // Arguments: [pb] - Buffer
112 // [cb] - Count of bytes to read
113 // [pcbRead] - Return number of bytes read
114 //
115 // Returns: Appropriate status code
116 //
117 // Modifies: [pcbRead]
118 //
119 //---------------------------------------------------------------
120
121
Read(VOID HUGEP * pb,ULONG cb,ULONG * pcbRead)122 STDMETHODIMP CExposedStream::Read(VOID HUGEP *pb, ULONG cb, ULONG *pcbRead)
123 {
124 SCODE sc;
125 ULONG cbRead = 0;
126
127 olLog(("%p::In CExposedStream::Read(%p, %lu, %p)\n",
128 this, pb, cb, pcbRead));
129 olDebugOut((DEB_ITRACE, "In CExposedStream::Read(%p,%lu,%p)\n",
130 pb, cb, pcbRead));
131 if (pcbRead)
132 olChkTo(EH_BadPtr, ValidateOutBuffer(pcbRead, sizeof(ULONG)));
133 olChk(ValidateHugeOutBuffer(pb, cb));
134 olChk(Validate());
135 olChk(CheckReverted());
136
137 if (!P_READ(_df))
138 sc = STG_E_ACCESSDENIED;
139 else
140 sc = _pst->ReadAt(_ulPos, pb, cb,
141 (ULONG STACKBASED *)&cbRead);
142 olAssert( CBMAXSEEK - _ulPos >= cbRead);
143 _ulPos+=cbRead;
144
145 olDebugOut((DEB_ITRACE, "Out CExposedStream::Read => %lu\n", cbRead));
146
147 EH_Err:
148 if (pcbRead)
149 {
150 *pcbRead = cbRead;
151 olLog(("%p::Out CExposedStream::Read() *pcbRead==%lu, ret=%lx\n",
152 this, SAFE_DREF(pcbRead), sc));
153 }
154 else
155 {
156 olLog(("%p::Out CExposedStream::Read(). ret == %lx\n", this, sc));
157 }
158
159 EH_BadPtr:
160 return ResultFromScode(sc);
161 }
162
163 //+--------------------------------------------------------------
164 //
165 // Member: CExposedStream::Write, public
166 //
167 // Synopsis: Write to a stream
168 //
169 // Arguments: [pb] - Buffer
170 // [cb] - Count of bytes to write
171 // [pcbWritten] - Return of bytes written
172 //
173 // Returns: Appropriate status code
174 //
175 // Modifies: [pcbWritten]
176 //
177 //---------------------------------------------------------------
178
179
Write(VOID const HUGEP * pb,ULONG cb,ULONG * pcbWritten)180 STDMETHODIMP CExposedStream::Write(
181 VOID const HUGEP *pb,
182 ULONG cb,
183 ULONG *pcbWritten)
184 {
185 SCODE sc;
186 ULONG cbWritten = 0;
187
188 olLog(("%p::In CExposedStream::Write(%p, %lu, %p)\n",
189 this, pb, cb, pcbWritten));
190 olDebugOut((DEB_ITRACE,
191 "In CExposedStream::Write(%p, %lu, %p)\n",
192 pb, cb, pcbWritten));
193
194 if (pcbWritten)
195 {
196 olChkTo(EH_BadPtr,
197 ValidateOutBuffer(pcbWritten, sizeof(ULONG)));
198 }
199 olChk(ValidateHugeBuffer(pb, cb));
200 olChk(Validate());
201 olChk(CheckReverted());
202 if (!P_WRITE(_df))
203 sc = STG_E_ACCESSDENIED;
204 else
205 {
206 sc = _pst->WriteAt(_ulPos, pb, cb,
207 (ULONG STACKBASED *)&cbWritten);
208 if (SUCCEEDED(sc))
209 SetDirty();
210 }
211 olAssert( CBMAXSEEK - _ulPos >= cbWritten);
212 _ulPos += cbWritten;
213
214 olDebugOut((DEB_ITRACE, "Out CExposedStream::Write => %lu\n",
215 cbWritten));
216 EH_Err:
217 if (pcbWritten)
218 {
219 *pcbWritten = cbWritten;
220 olLog(("%p::Out CExposedStream::Write(). *pcbWritten == %lu, ret = %lx\n",
221 this, *pcbWritten, sc));
222 }
223 else
224 {
225 olLog(("%p::Out CExposedStream::Write(). ret == %lx\n",this, sc));
226 }
227
228 EH_BadPtr:
229 return ResultFromScode(sc);
230 }
231
232 //+--------------------------------------------------------------
233 //
234 // Member: CExposedStream::Seek, public
235 //
236 // Synopsis: Seek to a point in a stream
237 //
238 // Arguments: [dlibMove] - Offset to move by
239 // [dwOrigin] - SEEK_SET, SEEK_CUR, SEEK_END
240 // [plibNewPosition] - Return of new offset
241 //
242 // Returns: Appropriate status code
243 //
244 // Modifies: [plibNewPosition]
245 //
246 //---------------------------------------------------------------
247
248
Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER * plibNewPosition)249 STDMETHODIMP CExposedStream::Seek(LARGE_INTEGER dlibMove,
250 DWORD dwOrigin,
251 ULARGE_INTEGER *plibNewPosition)
252 {
253 SCODE sc;
254 LONG lMove;
255 ULARGE_INTEGER ulPos;
256 ULONG cbSize;
257
258 olLog(("%p::In CExposedStream::Seek(%ld, %lu, %p)\n",
259 this, LIGetLow(dlibMove), dwOrigin, plibNewPosition));
260 olDebugOut((DEB_ITRACE, "In CExposedStream::Seek(%ld, %lu, %p)\n",
261 LIGetLow(dlibMove), dwOrigin, plibNewPosition));
262
263 if (plibNewPosition)
264 {
265 olChk(ValidateOutBuffer(plibNewPosition, sizeof(ULARGE_INTEGER)));
266 ULISet32(*plibNewPosition, 0);
267 }
268 if (dwOrigin != STREAM_SEEK_SET && dwOrigin != STREAM_SEEK_CUR &&
269 dwOrigin != STREAM_SEEK_END)
270 olErr(EH_Err, STG_E_INVALIDFUNCTION);
271
272 // Truncate dlibMove to 32 bits
273 if (dwOrigin == STREAM_SEEK_SET)
274 {
275 // Make sure we don't seek too far
276 if (LIGetHigh(dlibMove) != 0)
277 LISet32(dlibMove, /*(LONG)*/0xffffffff);
278 }
279 else
280 {
281 // High dword must be zero for positive values or -1 for
282 // negative values
283 // Additionally, for negative values, the low dword can't
284 // exceed -0x80000000 because the 32nd bit is the sign
285 // bit
286 if (LIGetHigh(dlibMove) > 0 ||
287 (LIGetHigh(dlibMove) == 0 &&
288 LIGetLow(dlibMove) >= 0x80000000))
289 LISet32(dlibMove, 0x7fffffff);
290 else if (LIGetHigh(dlibMove) < -1 ||
291 (LIGetHigh(dlibMove) == -1 &&
292 LIGetLow(dlibMove) <= 0x7fffffff))
293 LISet32(dlibMove, /*(LONG)*/0x80000000);
294 }
295
296 lMove = (LONG)LIGetLow(dlibMove);
297 olChk(Validate());
298 olChk(CheckReverted());
299 ULISet32(ulPos, _ulPos);
300 switch(dwOrigin)
301 {
302 case STREAM_SEEK_SET:
303 ULISetLow(ulPos, (ULONG)lMove);
304 break;
305 case STREAM_SEEK_END:
306 olChk(GetSize(&cbSize));
307 if (lMove < 0)
308 {
309 if ((ULONG)(-lMove) > cbSize)
310 olErr(EH_Err, STG_E_INVALIDFUNCTION);
311 }
312 else if ((ULONG)lMove > CBMAXSEEK-cbSize)
313 lMove = (LONG)(CBMAXSEEK-cbSize);
314 ULISetLow(ulPos, cbSize+lMove);
315 break;
316 case STREAM_SEEK_CUR:
317 if (lMove < 0)
318 {
319 if ((ULONG)(-lMove) > _ulPos)
320 olErr(EH_Err, STG_E_INVALIDFUNCTION);
321 }
322 else if ((ULONG)lMove > CBMAXSEEK - _ulPos)
323 lMove = (LONG)(CBMAXSEEK- _ulPos);
324 ULISetLow(ulPos, _ulPos+lMove);
325 break;
326 }
327 _ulPos = ULIGetLow(ulPos);
328 if (plibNewPosition)
329 *plibNewPosition = ulPos;
330
331 olDebugOut((DEB_ITRACE, "Out CExposedStream::Seek => %lu\n",
332 ULIGetLow(ulPos)));
333 EH_Err:
334 olLog(("%p::Out CExposedStream::Seek(). ulPos == %lu, ret == %lx\n",
335 this, ULIGetLow(ulPos), sc));
336 return ResultFromScode(sc);
337 }
338
339 //+--------------------------------------------------------------
340 //
341 // Member: CExposedStream::SetSize, public
342 //
343 // Synopsis: Sets the size of a stream
344 //
345 // Arguments: [ulNewSize] - New size
346 //
347 // Returns: Appropriate status code
348 //
349 //---------------------------------------------------------------
SetSize(ULONG cb)350 SCODE CExposedStream::SetSize(ULONG cb)
351 {
352 olDebugOut((DEB_ITRACE,
353 "In CExposedStream::SetSize(ULONG %lu)\n", cb));
354 SCODE sc;
355
356 olChk(Validate());
357 olChk(CheckReverted());
358 if (!P_WRITE(_df))
359 sc = STG_E_ACCESSDENIED;
360 else
361 {
362 olChk(_pst->SetSize(cb));
363 SetDirty();
364 }
365
366 EH_Err:
367 olDebugOut((DEB_ITRACE, "Out CExposedStream::SetSize()\n"));
368 return sc;
369 }
370
371 //+--------------------------------------------------------------
372 //
373 // Member: CExposedStream::SetSize, public
374 //
375 // Synopsis: Sets the size of a stream
376 //
377 // Arguments: [ulNewSize] - New size
378 //
379 // Returns: Appropriate status code
380 //
381 //---------------------------------------------------------------
382
SetSize(ULARGE_INTEGER ulNewSize)383 STDMETHODIMP CExposedStream::SetSize(ULARGE_INTEGER ulNewSize)
384 {
385 SCODE sc;
386
387 olLog(("%p::In CExposedStream::SetSize(%lu)\n",
388 this, ULIGetLow(ulNewSize)));
389 olDebugOut((DEB_ITRACE, "In CExposedStream::SetSize(%lu)\n",
390 ULIGetLow(ulNewSize)));
391
392 if (ULIGetHigh(ulNewSize) != 0)
393 olErr(EH_Err, STG_E_INVALIDFUNCTION);
394 olChk(SetSize(ULIGetLow(ulNewSize)));
395
396 olDebugOut((DEB_ITRACE, "Out CExposedStream::SetSize\n"));
397 EH_Err:
398 olLog(("%p::Out CExposedStream::SetSize(). ret == %lx\n", this, sc));
399 return ResultFromScode(sc);
400 }
401
402 //+--------------------------------------------------------------
403 //
404 // Member: CExposedStream::CopyTo, public
405 //
406 // Synopsis: Copies information from one stream to another
407 //
408 // Arguments: [pstm] - Destination
409 // [cb] - Number of bytes to copy
410 // [pcbRead] - Return number of bytes read
411 // [pcbWritten] - Return number of bytes written
412 //
413 // Returns: Appropriate status code
414 //
415 // Modifies: [pcbRead]
416 // [pcbWritten]
417 //
418 // Notes: We do our best to handle overlap correctly. This allows
419 // CopyTo to be used to insert and remove space within a
420 // stream.
421 //
422 // In the error case, we make no gurantees as to the
423 // validity of pcbRead, pcbWritten, or either stream's
424 // seek position.
425 //
426 //---------------------------------------------------------------
427
428
CopyTo(IStream * pstm,ULARGE_INTEGER cb,ULARGE_INTEGER * pcbRead,ULARGE_INTEGER * pcbWritten)429 STDMETHODIMP CExposedStream::CopyTo(IStream *pstm,
430 ULARGE_INTEGER cb,
431 ULARGE_INTEGER *pcbRead,
432 ULARGE_INTEGER *pcbWritten)
433 {
434 SCODE sc;
435 ULONG ulCopySize;
436 ULONG ulSrcSize;
437 ULONG ulSrcOrig;
438 ULARGE_INTEGER uliDestOrig;
439 LARGE_INTEGER liDestPos;
440 BYTE *pb = NULL;
441 BOOL fOverlap;
442 ULONG ulBytesCopied = 0;
443
444 olLog(("%p::In CExposedStream::CopyTo(%p, %lu, %p, %p)\n",
445 this, pstm, ULIGetLow(cb), pcbRead, pcbWritten));
446 olDebugOut((DEB_TRACE, "In CExposedStream::CopyTo("
447 "%p, %lu, %p, %p)\n", pstm, ULIGetLow(cb),
448 pcbRead, pcbWritten));
449
450 if (pcbRead) // okay to set to NULL => not interested
451 {
452 olChk(ValidateOutBuffer(pcbRead, sizeof(ULARGE_INTEGER)));
453 ULISet32(*pcbRead, 0);
454 }
455 if (pcbWritten) // okay to set to NULL => not interested
456 {
457 olChk(ValidateOutBuffer(pcbWritten, sizeof(ULARGE_INTEGER)));
458 ULISet32(*pcbWritten, 0);
459 }
460
461 olChk(ValidateInterface(pstm, IID_IStream));
462 olChk(Validate());
463 olChk(CheckReverted());
464
465 // Bound the size of the copy
466 // 1. The maximum we can copy is 0xffffffff
467
468 if (ULIGetHigh(cb) == 0)
469 ulCopySize = ULIGetLow(cb);
470 else
471 ulCopySize = 0xffffffff;
472
473 // 2. We can only copy what's available in the source stream
474
475 olChk(GetSize(&ulSrcSize));
476
477 ulSrcOrig = _ulPos;
478 if (ulSrcSize < ulSrcOrig)
479 {
480 // Nothing in source to copy
481 ulCopySize = 0;
482 }
483 else if ((ulSrcSize - ulSrcOrig) < ulCopySize)
484 {
485 // Shrink ulCopySize to fit bytes in source
486 ulCopySize = ulSrcSize - ulSrcOrig;
487 }
488
489 // 3. We can only copy what will fit in the destination
490
491 LISet32(liDestPos, 0);
492 olHChk(pstm->Seek(liDestPos, STREAM_SEEK_CUR, &uliDestOrig));
493 olAssert(ULIGetHigh(uliDestOrig) == 0);
494
495 if (ulCopySize > CBMAXSEEK - ULIGetLow(uliDestOrig))
496 ulCopySize = CBMAXSEEK - ULIGetLow(uliDestOrig);
497
498 // We are allowed to fail here with out-of-memory
499 olMem(pb = new BYTE[STREAMBUFFERSIZE]);
500
501 // Since we have no reliable way to determine if the source and
502 // destination represent the same stream, we assume they
503 // do and always handle overlap.
504
505 fOverlap = (ULIGetLow(uliDestOrig) > ulSrcOrig &&
506 ULIGetLow(uliDestOrig) < ulSrcOrig + ulCopySize);
507
508 ULONG ulSrcCopyOffset;
509 ULONG ulDstCopyOffset;
510 if (fOverlap)
511 {
512 // We're going to copy back to front, so determine the
513 // stream end positions
514 ulSrcCopyOffset = ulSrcOrig + ulCopySize;
515
516 // uliDestOrig is the destination starting offset
517 ulDstCopyOffset = ULIGetLow(uliDestOrig) + ulCopySize;
518 }
519
520 while (ulCopySize > 0)
521 {
522 // We can only copy up to STREAMBUFFERSIZE bytes at a time
523 ULONG cbPart = min(ulCopySize, STREAMBUFFERSIZE);
524
525 if (fOverlap)
526 {
527 // We're copying back to front so we need to seek to
528 // set up the streams correctly
529
530 ulSrcCopyOffset -= cbPart;
531 ulDstCopyOffset -= cbPart;
532
533 // Set source stream position
534 _ulPos = ulSrcCopyOffset;
535
536 // Set destination stream position
537 LISet32(liDestPos, ulDstCopyOffset);
538 olHChk(pstm->Seek(liDestPos, STREAM_SEEK_SET, NULL));
539 }
540
541 {
542 ULONG ulRead;
543 olHChk(Read(pb, cbPart, &ulRead));
544 if (cbPart != ulRead)
545 {
546 // There was no error, but we were unable to read cbPart
547 // bytes. Something's wrong (the underlying ILockBytes?)
548 // but we can't control it; just return an error.
549 olErr(EH_Err, STG_E_READFAULT);
550 }
551 }
552
553
554 {
555 ULONG ulWritten;
556 olHChk(pstm->Write(pb, cbPart, &ulWritten));
557 if (cbPart != ulWritten)
558 {
559 // There was no error, but we were unable to write
560 // ulWritten bytes. We can't trust the pstm
561 // implementation, so all we can do here is return
562 // an error.
563 olErr(EH_Err, STG_E_WRITEFAULT);
564 }
565 }
566
567 olAssert(ulCopySize >= cbPart);
568 ulCopySize -= cbPart;
569 ulBytesCopied += cbPart;
570 }
571
572 if (fOverlap)
573 {
574 // Set the seek pointers to the correct location
575 _ulPos = ulSrcOrig + ulBytesCopied;
576
577 LISet32(liDestPos, ULIGetLow(uliDestOrig) + ulBytesCopied);
578 olHChk(pstm->Seek(liDestPos, STREAM_SEEK_SET, NULL));
579 }
580
581 if (pcbRead)
582 ULISet32(*pcbRead, ulBytesCopied);
583 if (pcbWritten)
584 ULISet32(*pcbWritten, ulBytesCopied);
585
586 olDebugOut((DEB_ITRACE, "Out CExposedStream::CopyTo => %lu, %lu\n",
587 pcbRead ? ULIGetLow(*pcbRead) : 0,
588 pcbWritten ? ULIGetLow(*pcbWritten) : 0));
589 // Fall through
590 EH_Err:
591 delete [] pb;
592 olLog(("%p::Out CExposedStream::CopyTo(). "
593 "cbRead == %lu, cbWritten == %lu, ret == %lx\n",
594 this, pcbRead ? ULIGetLow(*pcbRead) : 0,
595 pcbWritten ? ULIGetLow(*pcbWritten) : 0, sc));
596 return ResultFromScode(sc);
597 }
598
599 //+--------------------------------------------------------------
600 //
601 // Member: CExposedStream::Release, public
602 //
603 // Synopsis: Releases a stream
604 //
605 // Returns: Appropriate status code
606 //
607 //---------------------------------------------------------------
608
609
STDMETHODIMP_(ULONG)610 STDMETHODIMP_(ULONG) CExposedStream::Release(void)
611 {
612 LONG lRet;
613
614 olLog(("%p::In CExposedStream::Release()\n", this));
615 olDebugOut((DEB_ITRACE, "In CExposedStream::Release()\n"));
616
617 if (FAILED(Validate()))
618 return 0;
619 olAssert(_cReferences > 0);
620 lRet = AtomicDec(&_cReferences);
621 if (lRet == 0)
622 {
623 Commit(0); // flush data
624 delete this;
625 }
626 else if (lRet < 0)
627 lRet = 0;
628
629 olDebugOut((DEB_ITRACE, "Out CExposedStream::Release\n"));
630 olLog(("%p::Out CExposedStream::Release(). ret == %lu\n", this, lRet));
631 FreeLogFile();
632 return lRet;
633 }
634
635 //+--------------------------------------------------------------
636 //
637 // Member: CExposedStream::Stat, public
638 //
639 // Synopsis: Fills in a buffer of information about this object
640 //
641 // Arguments: [pstatstg] - Buffer
642 //
643 // Returns: Appropriate status code
644 //
645 // Modifies: [pstatstg]
646 //
647 //---------------------------------------------------------------
648
649
STDMETHODIMP_(SCODE)650 STDMETHODIMP_(SCODE) CExposedStream::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
651 {
652 SCODE sc;
653
654 olLog(("%p::In CExposedStream::Stat(%p)\n", this, pstatstg));
655 olDebugOut((DEB_ITRACE, "In CExposedStream::Stat(%p)\n",
656 pstatstg));
657
658 olChkTo(EH_RetSc, ValidateOutBuffer(pstatstg, sizeof(STATSTGW)));
659 olChk(VerifyStatFlag(grfStatFlag));
660 olChk(Validate());
661 olChk(CheckReverted());
662 pstatstg->grfMode = DFlagsToMode(_df);
663
664 pstatstg->clsid = CLSID_NULL; // irrelevant for streams
665 pstatstg->grfStateBits = 0; // irrelevant for streams
666 pstatstg->type = STGTY_STREAM;
667 pstatstg->grfLocksSupported = 0;
668 pstatstg->reserved = 0;
669
670 // we null these values 'cos they are not interesting for
671 // direct streams ...
672 pstatstg->ctime.dwLowDateTime = pstatstg->ctime.dwHighDateTime = 0;
673 pstatstg->mtime.dwLowDateTime = pstatstg->mtime.dwHighDateTime = 0;
674 pstatstg->atime.dwLowDateTime = pstatstg->atime.dwHighDateTime = 0;
675 pstatstg->pwcsName = NULL;
676 if ((grfStatFlag & STATFLAG_NONAME) == 0)
677 { // fill in name
678 olChk(DfAllocWCS((WCHAR *)_dfn.GetBuffer(),
679 &pstatstg->pwcsName));
680 wcscpy(pstatstg->pwcsName, (WCHAR *)_dfn.GetBuffer());
681 }
682 ULONG cbSize;
683 GetSize(&cbSize);
684 ULISet32(pstatstg->cbSize, cbSize);
685
686 olDebugOut((DEB_ITRACE, "Out CExposedStream::Stat\n"));
687 EH_Err:
688 if (FAILED(sc))
689 memset(pstatstg, 0, sizeof(STATSTGW));
690 EH_RetSc:
691 olLog(("%p::Out CExposedStream::Stat(). ret == %lx\n",
692 this, sc));
693 return sc;
694 }
695
696 //+--------------------------------------------------------------
697 //
698 // Member: CExposedStream::Clone, public
699 //
700 // Synopsis: Clones a stream
701 //
702 // Returns: Appropriate status code
703 //
704 //---------------------------------------------------------------
705
706
Clone(IStream ** ppstm)707 STDMETHODIMP CExposedStream::Clone(IStream **ppstm)
708 {
709 CExposedStream *pst;
710 SCODE sc;
711
712 olLog(("%p::In CExposedStream::Clone(%p)\n", this, ppstm));
713 olDebugOut((DEB_ITRACE, "In CExposedStream::Clone(%p)\n", ppstm));
714
715 olChk(ValidateOutPtrBuffer(ppstm));
716 *ppstm = NULL;
717 olChk(Validate());
718 olChk(CheckReverted());
719 olMemTo(EH_pst, pst = new CExposedStream);
720 olChkTo(EH_pst, pst->Init(_pst, _pdfParent, _df, &_dfn, _ulPos));
721 _pst->AddRef();
722 *ppstm = pst;
723
724 olDebugOut((DEB_ITRACE, "Out CExposedStream::Clone => %p\n", *ppstm));
725 return ResultFromScode(sc);
726
727 EH_pst:
728 delete pst;
729 EH_Err:
730 olLog(("%p::Out CExposedStream::Clone(). *ppstm == %p, ret == %lx\n",
731 this, SAFE_DREFppstm, sc));
732 return ResultFromScode(sc);
733 }
734
735 //+--------------------------------------------------------------
736 //
737 // Member: CExposedStream::AddRef, public
738 //
739 // Synopsis: Increments the ref count
740 //
741 // Returns: Appropriate status code
742 //
743 //---------------------------------------------------------------
744
STDMETHODIMP_(ULONG)745 STDMETHODIMP_(ULONG) CExposedStream::AddRef(void)
746 {
747 ULONG ulRet;
748
749 olLog(("%p::In CExposedStream::AddRef()\n", this));
750 olDebugOut((DEB_ITRACE, "In CExposedStream::AddRef()\n"));
751
752 if (FAILED(Validate()))
753 return 0;
754 AtomicInc(&_cReferences);
755 ulRet = _cReferences;
756
757 olDebugOut((DEB_ITRACE, "Out CExposedStream::AddRef\n"));
758 olLog(("%p::Out CExposedStream::AddRef(). ret == %lu\n", this, ulRet));
759 return ulRet;
760 }
761
762 //+--------------------------------------------------------------
763 //
764 // Member: CExposedStream::LockRegion, public
765 //
766 // Synopsis: Nonfunctional
767 //
768 // Returns: Appropriate status code
769 //
770 //---------------------------------------------------------------
771
LockRegion(ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)772 STDMETHODIMP CExposedStream::LockRegion(ULARGE_INTEGER libOffset,
773 ULARGE_INTEGER cb,
774 DWORD dwLockType)
775 {
776 olDebugOut((DEB_ITRACE, "In CExposedStream::LockRegion("
777 "%lu, %lu\n", ULIGetLow(cb), dwLockType));
778 olDebugOut((DEB_ITRACE, "Out CExposedStream::LockRegion\n"));
779 olLog(("%p::INVALID CALL TO CExposedStream::LockRegion()\n"));
780 UNREFERENCED_PARM(libOffset);
781 UNREFERENCED_PARM(cb);
782 UNREFERENCED_PARM(dwLockType);
783 olAssert(FALSE && aMsg("function not implemented!"));
784 return ResultFromScode(STG_E_INVALIDFUNCTION);
785 }
786
787 //+--------------------------------------------------------------
788 //
789 // Member: CExposedStream::UnlockRegion, public
790 //
791 // Synopsis: Nonfunctional
792 //
793 // Returns: Appropriate status code
794 //
795 //---------------------------------------------------------------
796
UnlockRegion(ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)797 STDMETHODIMP CExposedStream::UnlockRegion(ULARGE_INTEGER libOffset,
798 ULARGE_INTEGER cb,
799 DWORD dwLockType)
800 {
801 olDebugOut((DEB_ITRACE, "In CExposedStream::UnlockRegion(%lu, %lu)\n",
802 ULIGetLow(cb), dwLockType));
803 olDebugOut((DEB_ITRACE, "Out CExposedStream::UnlockRegion\n"));
804 olLog(("%p::INVALID CALL TO CExposedStream::UnlockRegion()\n"));
805 UNREFERENCED_PARM(libOffset);
806 UNREFERENCED_PARM(cb);
807 UNREFERENCED_PARM(dwLockType);
808 olAssert(FALSE && aMsg("function not implemented!"));
809 return ResultFromScode(STG_E_INVALIDFUNCTION);
810 }
811
812 //+--------------------------------------------------------------
813 //
814 // Member: CExposedStream::Commit, public
815 //
816 // Returns: Appropriate status code
817 //
818 //---------------------------------------------------------------
819
820
Commit(DWORD grfCommitFlags)821 STDMETHODIMP CExposedStream::Commit(DWORD grfCommitFlags)
822 {
823 SCODE sc;
824 olDebugOut((DEB_ITRACE, "In CExposedStream::Commit(%lu)\n",
825 grfCommitFlags));
826 olLog(("%p::In CExposedStream::Commit(%lx)\n", this, grfCommitFlags));
827
828 olChk(Validate());
829 olChk(CheckReverted());
830
831 if (_fDirty)
832 { // We're a stream so we must have a parent
833 // We dirty all parents up to the next
834 // transacted storage
835 _pdfParent->SetDirty();
836 sc = _pdfParent->GetBaseMS()
837 ->Flush(FLUSH_CACHE(grfCommitFlags));
838 }
839
840 olDebugOut((DEB_ITRACE, "Out CExposedStream::Commit\n"));
841 EH_Err:
842 olLog(("%p::Out CExposedStream::Commit(). ret == %lx", this, sc));
843 return ResultFromScode(sc);
844 }
845
846 //+--------------------------------------------------------------
847 //
848 // Member: CExposedStream::Revert, public
849 //
850 // Synopsis: No-op in current implementation
851 //
852 // Returns: Appropriate status code
853 //
854 //---------------------------------------------------------------
855
856
Revert(void)857 STDMETHODIMP CExposedStream::Revert(void)
858 {
859 olDebugOut((DEB_ITRACE, "In CExposedStream::Revert()\n"));
860 olDebugOut((DEB_ITRACE, "Out CExposedStream::Revert\n"));
861
862 olLog(("%p::In CExposedStream::Revert()\n", this));
863 olLog(("%p::Out CExposedStream::Revert(). ret == %lx", this, S_OK));
864
865 return ResultFromScode(STG_E_UNIMPLEMENTEDFUNCTION);
866 }
867
868 //+--------------------------------------------------------------
869 //
870 // Member: CExposedStream::QueryInterface, public
871 //
872 // Synopsis: Returns an object for the requested interface
873 //
874 // Arguments: [iid] - Interface ID
875 // [ppvObj] - Object return
876 //
877 // Returns: Appropriate status code
878 //
879 // Modifies: [ppvObj]
880 //
881 //---------------------------------------------------------------
882
883
QueryInterface(REFIID iid,void ** ppvObj)884 STDMETHODIMP CExposedStream::QueryInterface(REFIID iid, void **ppvObj)
885 {
886 SCODE sc;
887
888 olLog(("%p::In CExposedStream::QueryInterface(?, %p)\n",
889 this, ppvObj));
890 olDebugOut((DEB_ITRACE, "In CExposedStream::QueryInterface(?, %p)\n",
891 ppvObj));
892 olChk(ValidateOutPtrBuffer(ppvObj));
893 *ppvObj = NULL;
894 olChk(ValidateIid(iid));
895 olChk(Validate());
896 olChk(CheckReverted());
897 if (IsEqualIID(iid, IID_IStream) || IsEqualIID(iid, IID_IUnknown))
898 {
899 olChk(AddRef());
900 *ppvObj = this;
901 }
902 else
903 olErr(EH_Err, E_NOINTERFACE);
904 sc = S_OK;
905
906 olDebugOut((DEB_ITRACE, "Out CExposedStream::QueryInterface => %p\n",
907 ppvObj));
908 EH_Err:
909 olLog(("%p::Out CExposedStream::QueryInterface(). *ppvObj == %p, ret == %lx\n",
910 this, *ppvObj, sc));
911 return ResultFromScode(sc);
912 }
913
914 //+--------------------------------------------------------------
915 //
916 // Member: CExposedStream::RevertFromAbove, public (virtual)
917 //
918 // Synopsis: Parent has asked for reversion
919 //
920 //---------------------------------------------------------------
921
RevertFromAbove(void)922 void CExposedStream::RevertFromAbove(void)
923 {
924 msfDebugOut((DEB_ITRACE,
925 "In CExposedStream::RevertFromAbove:%p()\n", this));
926 _df |= DF_REVERTED;
927 _pst->Release();
928 #if DBG == 1
929 _pst = NULL;
930 #endif
931 msfDebugOut((DEB_ITRACE, "Out CExposedStream::RevertFromAbove\n"));
932 }
933
934 #ifdef NEWPROPS
935 //+-------------------------------------------------------------------
936 //
937 // Member: CExposedStream::Open
938 //
939 // Synopsis: Opens mapped view of exposed stream. Called by
940 // NtCreatePropertySet et al.
941 //
942 // Notes: Gets the size of the underlying stream and reads it
943 // into memory so that it can be "mapped."
944 //
945 //--------------------------------------------------------------------
946
Open(IN VOID * powner,OUT LONG * phr)947 VOID CExposedStream::Open(IN VOID *powner, OUT LONG *phr)
948 {
949 LONG& sc = *phr;
950 sc = S_OK;
951
952 // If given a pointer to the owner of this mapped stream,
953 // save it. This could be NULL. (i.e. when called from ReOpen)
954 if( NULL != powner )
955 _powner = (BYTE*) powner;
956
957 if (_pb == NULL)
958 {
959 VOID *pv;
960 _cbUsed = 0;
961 olChk(CheckReverted());
962 _pst->GetSize(&_cbOriginalStreamSize);
963
964 if (_cbOriginalStreamSize > CBMAXPROPSETSTREAM)
965 olErr(EH_Err, STG_E_INVALIDHEADER);
966
967 _cbUsed = _cbOriginalStreamSize;
968 olMemTo(EH_Err, pv = new BYTE[_cbOriginalStreamSize]);
969 _pb = (BYTE*) pv;
970 olChkTo(EH_Read,
971 _pst->ReadAt(0, pv, _cbOriginalStreamSize, &_cbUsed));
972 olAssert(_cbOriginalStreamSize == _cbUsed &&
973 "CExposedStream did not read in all the info!");
974
975 // Notify our owner that we have new data
976 if (*phr == S_OK && _powner != NULL && 0 != _cbUsed)
977 {
978 *phr = RtlOnMappedStreamEvent((VOID*)_powner, pv, _cbUsed );
979 }
980
981 }
982 olDebugOut((DEB_PROP_MAP, "CExposedStream(%X):Open returns normally\n", this));
983 return;
984
985 // Error handling
986 EH_Read:
987 delete[] _pb;
988 _pb = NULL;
989 _cbUsed = 0;
990
991 EH_Err:
992 olDebugOut((DEB_PROP_MAP,
993 "CExposedStream(%X):Open exception returns %08X\n",
994 this, *phr));
995 return;
996 }
997
998 //+-------------------------------------------------------------------
999 //
1000 // Member: CExposedStream::Close
1001 //
1002 // Synopsis: Operates on mapped view of exposed stream. Called by
1003 // NtCreatePropertySet et al.
1004 //
1005 // Notes: Does nothing because the object may be mapped in
1006 // another process.
1007 //
1008 //--------------------------------------------------------------------
1009
Close(OUT LONG * phr)1010 VOID CExposedStream::Close(OUT LONG *phr)
1011 {
1012 // Write the changes. We don't need to Commit them,
1013 // they will be implicitely committed when the
1014 // Stream is Released.
1015
1016 *phr = Write();
1017
1018 if( FAILED(*phr) )
1019 {
1020 olDebugOut( (DEB_PROP_MAP,
1021 "CPubStream(%08X)::Close exception returns %08X\n",
1022 this, *phr));
1023 }
1024
1025 return;
1026 }
1027
1028 //+-------------------------------------------------------------------
1029 //
1030 // Member: CExposedStream::ReOpen
1031 //
1032 // Synopsis: Operates on mapped view of exposed stream. Called by
1033 // NtCreatePropertySet et al.
1034 //
1035 // Notes: Combined open and map.
1036 //
1037 //--------------------------------------------------------------------
1038
ReOpen(IN OUT VOID ** ppv,OUT LONG * phr)1039 VOID CExposedStream::ReOpen(IN OUT VOID **ppv, OUT LONG *phr)
1040 {
1041 *ppv = NULL;
1042 Open( (void*)NULL, // unspecified owner
1043 phr);
1044 if ( SUCCEEDED(*phr) )
1045 *ppv = _pb;
1046 }
1047
1048 //+-------------------------------------------------------------------
1049 //
1050 // Member: CExposedStream::Quiesce
1051 //
1052 // Synopsis: Operates on mapped view of exposed stream. Called by
1053 // NtCreatePropertySet et al.
1054 //
1055 // Notes: Meaningless for docfile mapped stream.
1056 //
1057 //--------------------------------------------------------------------
1058
Quiesce(VOID)1059 VOID CExposedStream::Quiesce(VOID)
1060 {
1061 olAssert(_pb != NULL);
1062 DfpdbgCheckUnusedMemory();
1063 }
1064
1065 //+-------------------------------------------------------------------
1066 //
1067 // Member: CExposedStream::Map
1068 //
1069 // Synopsis: Operates on mapped view of exposed stream. Called by
1070 // NtCreatePropertySet et al.
1071 //
1072 // Notes: Return the address of the "mapping" buffer.
1073 //
1074 //--------------------------------------------------------------------
1075
Map(BOOLEAN fCreate,VOID ** ppv)1076 VOID CExposedStream::Map(BOOLEAN fCreate, VOID **ppv)
1077 {
1078 UNREFERENCED_PARM(fCreate);
1079 olAssert(_pb != NULL);
1080 DfpdbgCheckUnusedMemory();
1081 *ppv = _pb;
1082 }
1083
1084 //+-------------------------------------------------------------------
1085 //
1086 // Member: CExposedStream::Unmap
1087 //
1088 // Synopsis: Operates on mapped view of exposed stream. Called by
1089 // NtCreatePropertySet et al.
1090 //
1091 // Notes: Unmapping is merely zeroing the pointer. We don't
1092 // flush because that's done explicitly by the
1093 // CPropertyStorage class.
1094 //
1095 //
1096 //--------------------------------------------------------------------
1097
Unmap(BOOLEAN fFlush,VOID ** pv)1098 VOID CExposedStream::Unmap(BOOLEAN fFlush, VOID **pv)
1099 {
1100 UNREFERENCED_PARM(fFlush);
1101 DfpdbgCheckUnusedMemory();
1102 *pv = NULL;
1103 }
1104
1105 //+-------------------------------------------------------------------
1106 //
1107 // Member: CExposedStream::Flush
1108 //
1109 // Synopsis: Operates on mapped view of exposed stream. Called by
1110 // NtCreatePropertySet et al.
1111 // Flush the memory property set to disk and commit it.
1112 //
1113 //--------------------------------------------------------------------
1114
Flush(OUT LONG * phr)1115 VOID CExposedStream::Flush(OUT LONG *phr)
1116 {
1117 *phr = S_OK;
1118 // write out any data we have cached to the stream
1119 if (S_OK == (*phr = Write()))
1120 {
1121 // commit the stream
1122 (*phr) = Commit(STGC_DEFAULT);
1123 }
1124
1125 return;
1126 }
1127
1128 //+-------------------------------------------------------------------
1129 //
1130 // Member: CExposedStream::GetSize
1131 //
1132 // Synopsis: Returns size of exposed stream. Called by
1133 // NtCreatePropertySet et al.
1134 //
1135 // Notes:
1136 //--------------------------------------------------------------------
1137
GetSize(OUT LONG * phr)1138 ULONG CExposedStream::GetSize(OUT LONG *phr)
1139 {
1140 *phr = S_OK;
1141 if (_pb == NULL)
1142 Open((void*)NULL, // unspecified owner
1143 phr);
1144
1145 if( SUCCEEDED(*phr) )
1146 {
1147 olAssert(_pb != NULL);
1148 DfpdbgCheckUnusedMemory();
1149 }
1150
1151 return _cbUsed;
1152 }
1153
1154 //+-------------------------------------------------------------------
1155 //
1156 // Member: CExposedStream::SetSize
1157 //
1158 // Synopsis: Sets size of "map." Called by
1159 // NtCreatePropertySet et al.
1160 //
1161 // Arguments: [cb] -- requested size.
1162 // [fPersistent] -- FALSE if expanding in-memory read-only image
1163 // [ppv] -- new mapped address.
1164 //
1165 // Signals: Not enough disk space.
1166 //
1167 //
1168 //--------------------------------------------------------------------
1169
SetSize(ULONG cb,IN BOOLEAN fPersistent,VOID ** ppv,OUT LONG * phr)1170 VOID CExposedStream::SetSize(ULONG cb, IN BOOLEAN fPersistent,
1171 VOID **ppv, OUT LONG *phr)
1172 {
1173 *phr = S_OK;
1174 LONG& sc=*phr;
1175 BYTE *pbNew;
1176
1177 olAssert(cb != 0);
1178 DfpdbgCheckUnusedMemory();
1179 olChk(CheckReverted());
1180
1181 //
1182 // if we are growing the data, we should grow the stream
1183 //
1184 if (fPersistent && cb > _cbUsed)
1185 {
1186 olChk(_pst->SetSize(cb));
1187 }
1188
1189 olMem(pbNew = new BYTE[cb]);
1190
1191 memcpy(pbNew, _pb, (cb < _cbUsed) ? cb : _cbUsed); // smaller of the 2
1192 delete[] _pb;
1193
1194 _pb = pbNew;
1195 _cbUsed = cb;
1196 *ppv = _pb;
1197
1198 DfpdbgFillUnusedMemory();
1199
1200 EH_Err:
1201 olDebugOut((DEB_PROP_MAP, "CPubStream(%08X):SetSize %s returns hr=%08X\n",
1202 this, *phr != S_OK ? "exception" : "", *phr));
1203 return;
1204 }
1205
1206
1207 //+-------------------------------------------------------------------
1208 //
1209 // Member: CExposedStream::QueryTimeStamps
1210 //
1211 // Synopsis: Operates on mapped view of exposed stream. Called by
1212 // NtCreatePropertySet et al.
1213 //
1214 // Notes:
1215 //
1216 //--------------------------------------------------------------------
1217
QueryTimeStamps(STATPROPSETSTG * pspss,BOOLEAN fNonSimple) const1218 VOID CExposedStream::QueryTimeStamps(STATPROPSETSTG *pspss,
1219 BOOLEAN fNonSimple) const
1220 {
1221 UNREFERENCED_PARM(fNonSimple);
1222 UNREFERENCED_PARM(pspss);
1223 }
1224
1225 //+-------------------------------------------------------------------
1226 //
1227 // Member: CExposedStream::QueryModifyTime
1228 //
1229 // Synopsis: Operates on mapped view of exposed stream. Called by
1230 // NtCreatePropertySet et al.
1231 //
1232 // Notes:
1233 //
1234 //--------------------------------------------------------------------
1235
QueryModifyTime(OUT LONGLONG * pll) const1236 BOOLEAN CExposedStream::QueryModifyTime(OUT LONGLONG *pll) const
1237 {
1238 UNREFERENCED_PARM(pll);
1239 return (FALSE);
1240 }
1241
1242 //+-------------------------------------------------------------------
1243 //
1244 // Member: CExposedStream::QuerySecurity
1245 //
1246 // Synopsis: Operates on mapped view of exposed stream. Called by
1247 // NtCreatePropertySet et al.
1248 //
1249 // Notes:
1250 //
1251 //--------------------------------------------------------------------
1252
QuerySecurity(OUT ULONG * pul) const1253 BOOLEAN CExposedStream::QuerySecurity(OUT ULONG *pul) const
1254 {
1255 UNREFERENCED_PARM(pul);
1256 return FALSE;
1257 }
1258
1259 //+-------------------------------------------------------------------
1260 //
1261 // Member: CExposedStream::IsWriteable
1262 //
1263 // Synopsis: Operates on mapped view of exposed stream. Called by
1264 // NtCreatePropertySet et al.
1265 //
1266 // Notes:
1267 //
1268 //--------------------------------------------------------------------
1269
IsWriteable() const1270 BOOLEAN CExposedStream::IsWriteable() const
1271 {
1272 return TRUE;
1273 }
1274
1275 //+-------------------------------------------------------------------
1276 //
1277 // Member: CExposedStream::SetChangePending
1278 //
1279 // Synopsis: Operates on mapped view of exposed stream. Called by
1280 // NtCreatePropertySet et al.
1281 //
1282 // Notes:
1283 //
1284 //--------------------------------------------------------------------
1285
1286 #if DBGPROP
SetChangePending(BOOLEAN f)1287 BOOLEAN CExposedStream::SetChangePending(BOOLEAN f)
1288 {
1289 BOOL fOld = _fChangePending;
1290 _fChangePending = f;
1291 return(_fChangePending);
1292 }
1293 #endif
1294
1295 //+-------------------------------------------------------------------
1296 //
1297 // Member: CExposedStream::IsNtMappedStream
1298 //
1299 // Synopsis: Operates on mapped view of exposed stream. Called by
1300 // NtCreatePropertySet et al.
1301 //
1302 // Notes:
1303 //
1304 //--------------------------------------------------------------------
1305
1306 #if DBGPROP
IsNtMappedStream(VOID) const1307 BOOLEAN CExposedStream::IsNtMappedStream(VOID) const
1308 {
1309 return FALSE;
1310 }
1311 #endif
1312
1313 //+-------------------------------------------------------------------
1314 //
1315 // Member: CExposedStream::GetHandle
1316 //
1317 // Synopsis: Operates on mapped view of exposed stream. Called by
1318 // NtCreatePropertySet et al.
1319 //
1320 // Notes:
1321 //
1322 //--------------------------------------------------------------------
1323
GetHandle(VOID) const1324 HANDLE CExposedStream::GetHandle(VOID) const
1325 {
1326 return INVALID_HANDLE_VALUE;
1327 }
1328
1329 //+-------------------------------------------------------------------
1330 //
1331 // Member: CExposedStream::SetModified
1332 //
1333 // Synopsis: Operates on mapped view of exposed stream. Called by
1334 // NtCreatePropertySet et al.
1335 //
1336 // Notes:
1337 //
1338 //--------------------------------------------------------------------
1339
SetModified(VOID)1340 VOID CExposedStream::SetModified(VOID)
1341 {
1342 _fDirty = TRUE;
1343 }
1344
1345 //+-------------------------------------------------------------------
1346 //
1347 // Member: CExposedStream::IsModified
1348 //
1349 // Synopsis: Operates on mapped view of exposed stream. Called by
1350 // NtCreatePropertySet et al.
1351 //
1352 // Notes:
1353 //
1354 //--------------------------------------------------------------------
1355
IsModified(VOID) const1356 BOOLEAN CExposedStream::IsModified(VOID) const
1357 {
1358 return _fDirty;
1359 }
1360
1361 #if DBG
1362 //+-------------------------------------------------------------------
1363 //
1364 // Member: CExposedStream::DfpdbgFillUnusedMemory
1365 //
1366 //--------------------------------------------------------------------
1367
DfpdbgFillUnusedMemory(VOID)1368 VOID CExposedStream::DfpdbgFillUnusedMemory(VOID)
1369 {
1370 if (_pb == NULL)
1371 return;
1372
1373 BYTE * pbEndPlusOne = _pb + BytesCommitted();
1374
1375 for (BYTE *pbUnused = _pb + _cbUsed;
1376 pbUnused < pbEndPlusOne;
1377 pbUnused++)
1378 {
1379 *pbUnused = (BYTE)(DWORD)pbUnused;
1380 }
1381 }
1382
1383
1384 //+-------------------------------------------------------------------
1385 //
1386 // Member: CExposedStream::DfpdbgCheckUnusedMemory
1387 //
1388 //--------------------------------------------------------------------
1389
DfpdbgCheckUnusedMemory(VOID)1390 VOID CExposedStream::DfpdbgCheckUnusedMemory(VOID)
1391 {
1392
1393 if (_pb == NULL)
1394 return;
1395
1396 if (_cbUsed == 0)
1397 return;
1398
1399 BYTE * pbEndPlusOne = _pb + BytesCommitted();
1400
1401 for (BYTE *pbUnused = _pb + _cbUsed;
1402 pbUnused < pbEndPlusOne;
1403 pbUnused ++)
1404 {
1405 olAssert(*pbUnused == (BYTE)(DWORD)pbUnused);
1406 }
1407 }
1408
1409 #endif // DBG
1410
1411
1412 //+-------------------------------------------------------------------
1413 //
1414 // Member: CExposedStream::Write, private
1415 //
1416 // Synopsis: Writes a mapped view of an exposed Stream to the
1417 // underlying Stream. Used by RtlCreatePropertySet et al.
1418 //
1419 // Notes: The Stream is not commited. To commit the Stream, in
1420 // addition to writing it, the Flush method should be used.
1421 // The Commit is omitted so that it can be skipped in
1422 // the Property Set Close path, thus eliminating a
1423 // performance penalty.
1424 //
1425 //--------------------------------------------------------------------
1426
Write(VOID)1427 HRESULT CExposedStream::Write(VOID)
1428 {
1429 HRESULT hr;
1430 ULONG cbWritten;
1431
1432 if (!_fDirty ||!_pb)
1433 {
1434 olDebugOut((DEB_PROP_MAP,
1435 "CExposedStream(%08X):Flush returns with not-dirty\n", this));
1436
1437 // flushing a stream which isn't a property stream
1438 // this could be optimized by propagating a 'no property streams'
1439 // flag up the storage hierachy such that FlushBufferedData is
1440 // not even called for non-property streams.
1441 return S_OK;
1442 }
1443
1444 hr=CheckReverted();
1445 if (S_OK!=hr) goto Exit;
1446 olAssert( _pst != NULL );
1447 olAssert( _pb != NULL );
1448 olAssert( _powner != NULL );
1449
1450 // notify our owner that we are about to perform a write
1451 hr = RtlOnMappedStreamEvent( (void*)_powner, (void*) _pb, _cbUsed );
1452 if ( S_OK != hr ) goto Exit;
1453
1454 hr = _pst->WriteAt(0, _pb, _cbUsed, &cbWritten);
1455
1456 if( S_OK != hr ) goto Exit;
1457 // notify our owner that we are done with the write
1458 hr = RtlOnMappedStreamEvent( (VOID*)_powner, (VOID *) _pb, _cbUsed );
1459 if( S_OK != hr ) goto Exit;
1460
1461 if (_cbUsed < _cbOriginalStreamSize)
1462 {
1463 // if the stream is shrinking, this is a good time to do it.
1464 hr = _pst->SetSize(_cbUsed);
1465 if (S_OK!=hr) goto Exit;
1466 }
1467
1468 Exit:
1469 if (hr == S_OK || hr == STG_E_REVERTED)
1470 {
1471 _fDirty = FALSE;
1472 }
1473
1474 olDebugOut((DEB_PROP_MAP, "CPubStream(%08X):Flush %s returns hr=%08X\n",
1475 this, hr != S_OK ? "exception" : "", hr));
1476
1477 return hr;
1478 }
1479
1480 //+--------------------------------------------------------------
1481 //
1482 // Member: CExposedStream::FlushBufferedData, public
1483 //
1484 // Synopsis: Flush out the property buffers.
1485 //
1486 //---------------------------------------------------------------
1487
FlushBufferedData()1488 SCODE CExposedStream::FlushBufferedData()
1489 {
1490 SCODE sc = S_OK;
1491
1492 olDebugOut((DEB_ITRACE, "In CExposedStream::FlushBufferedData:%p()\n",
1493 this));
1494
1495 Flush(&sc);
1496
1497 olDebugOut((DEB_PROP_MAP,
1498 "CExposedStream(%08X):FlushBufferedData returns %08X\n",
1499 this, sc));
1500
1501 return sc;
1502 }
1503
1504 #endif // ifdef NEWPROPS
1505
1506
1507
1508
1509
1510