Changeset 6711 for trunk/src/ole32/stg_stream.c
- Timestamp:
- Sep 15, 2001, 11:32:00 AM (24 years ago)
- File:
-
- 1 edited
-
trunk/src/ole32/stg_stream.c (modified) (51 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ole32/stg_stream.c
r6648 r6711 1 /* $Id: stg_stream.c,v 1.3 2001-09-05 13:17:12 bird Exp $ */2 1 /* 3 2 * Compound Storage (32 bit version) … … 28 27 29 28 #include "storage32.h" 29 30 #ifdef __WIN32OS2__ 31 #undef FIXME 32 #undef TRACE 33 #ifdef DEBUG 34 #define TRACE WriteLog("OLE32: %s", __FUNCTION__); WriteLog 35 #define FIXME WriteLog("FIXME OLE32: %s", __FUNCTION__); WriteLog 36 #else 37 #define TRACE 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL) 38 #define FIXME 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL) 39 #endif 40 #endif 30 41 31 42 DEFAULT_DEBUG_CHANNEL(storage); … … 66 77 */ 67 78 StgStreamImpl* StgStreamImpl_Construct( 68 StorageBaseImpl* parentStorage,79 StorageBaseImpl* parentStorage, 69 80 DWORD grfMode, 70 81 ULONG ownerProperty) … … 73 84 74 85 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(StgStreamImpl)); 75 86 76 87 if (newStream!=0) 77 88 { … … 81 92 ICOM_VTBL(newStream) = &StgStreamImpl_Vtbl; 82 93 newStream->ref = 0; 83 94 84 95 /* 85 96 * We want to nail-down the reference to the storage in case the … … 89 100 IStorage_AddRef((IStorage*)newStream->parentStorage); 90 101 91 newStream->grfMode = grfMode; 102 newStream->grfMode = grfMode; 92 103 newStream->ownerProperty = ownerProperty; 93 104 94 105 /* 95 106 * Start the stream at the begining. … … 97 108 newStream->currentPosition.s.HighPart = 0; 98 109 newStream->currentPosition.s.LowPart = 0; 99 110 100 111 /* 101 112 * Initialize the rest of the data. … … 105 116 newStream->bigBlockChain = 0; 106 117 newStream->smallBlockChain = 0; 107 118 108 119 /* 109 120 * Read the size from the property and determine if the blocks forming … … 112 123 StgStreamImpl_OpenBlockChain(newStream); 113 124 } 114 125 115 126 return newStream; 116 127 } … … 119 130 * This is the destructor of the StgStreamImpl class. 120 131 * 121 * This method will clean-up all the resources used-up by the given StgStreamImpl 132 * This method will clean-up all the resources used-up by the given StgStreamImpl 122 133 * class. The pointer passed-in to this function will be freed and will not 123 134 * be valid anymore. … … 151 162 * Finally, free the memory used-up by the class. 152 163 */ 153 HeapFree(GetProcessHeap(), 0, This); 164 HeapFree(GetProcessHeap(), 0, This); 154 165 } 155 166 … … 159 170 */ 160 171 HRESULT WINAPI StgStreamImpl_QueryInterface( 161 IStream* iface,162 REFIID riid, /* [in] */ 163 void** ppvObject) /* [iid_is][out] */ 172 IStream* iface, 173 REFIID riid, /* [in] */ 174 void** ppvObject) /* [iid_is][out] */ 164 175 { 165 176 StgStreamImpl* const This=(StgStreamImpl*)iface; … … 170 181 if (ppvObject==0) 171 182 return E_INVALIDARG; 172 183 173 184 /* 174 185 * Initialize the return parameter. 175 186 */ 176 187 *ppvObject = 0; 177 188 178 189 /* 179 190 * Compare the riid with the interface IDs implemented by this object. 180 191 */ 181 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 192 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 182 193 { 183 194 *ppvObject = (IStream*)This; 184 195 } 185 else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0) 196 else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0) 186 197 { 187 198 *ppvObject = (IStream*)This; 188 199 } 189 200 190 201 /* 191 202 * Check that we obtained an interface. … … 193 204 if ((*ppvObject)==0) 194 205 return E_NOINTERFACE; 195 206 196 207 /* 197 208 * Query Interface always increases the reference count by one when it is … … 199 210 */ 200 211 StgStreamImpl_AddRef(iface); 201 212 202 213 return S_OK;; 203 214 } … … 208 219 */ 209 220 ULONG WINAPI StgStreamImpl_AddRef( 210 IStream* iface)221 IStream* iface) 211 222 { 212 223 StgStreamImpl* const This=(StgStreamImpl*)iface; 213 224 214 225 This->ref++; 215 226 216 227 return This->ref; 217 228 } … … 222 233 */ 223 234 ULONG WINAPI StgStreamImpl_Release( 224 IStream* iface)235 IStream* iface) 225 236 { 226 237 StgStreamImpl* const This=(StgStreamImpl*)iface; 227 238 228 239 ULONG newRef; 229 240 230 241 This->ref--; 231 242 232 243 newRef = This->ref; 233 244 234 245 /* 235 246 * If the reference count goes down to 0, perform suicide. … … 239 250 StgStreamImpl_Destroy(This); 240 251 } 241 252 242 253 return newRef; 243 254 } … … 273 284 */ 274 285 readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, 275 This->ownerProperty,276 &curProperty);277 286 This->ownerProperty, 287 &curProperty); 288 278 289 if (readSucessful) 279 290 { 280 291 This->streamSize = curProperty.size; 281 292 282 293 /* 283 294 * This code supports only streams that are <32 bits in size. 284 295 */ 285 296 assert(This->streamSize.s.HighPart == 0); 286 297 287 298 if(curProperty.startingBlock == BLOCK_END_OF_CHAIN) 288 299 { … … 292 303 { 293 304 if ( (This->streamSize.s.HighPart == 0) && 294 (This->streamSize.s.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )305 (This->streamSize.s.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) 295 306 { 296 This->smallBlockChain = SmallBlockChainStream_Construct(297 This->parentStorage->ancestorStorage, 298 This->ownerProperty);307 This->smallBlockChain = SmallBlockChainStream_Construct( 308 This->parentStorage->ancestorStorage, 309 This->ownerProperty); 299 310 } 300 311 else 301 312 { 302 This->bigBlockChain = BlockChainStream_Construct(303 This->parentStorage->ancestorStorage,304 NULL,305 This->ownerProperty);313 This->bigBlockChain = BlockChainStream_Construct( 314 This->parentStorage->ancestorStorage, 315 NULL, 316 This->ownerProperty); 306 317 } 307 318 } … … 318 329 * See the documentation of ISequentialStream for more info. 319 330 */ 320 HRESULT WINAPI StgStreamImpl_Read( 321 IStream* iface,322 void* pv, /* [length_is][size_is][out] */323 ULONG cb, /* [in] */ 324 ULONG* pcbRead) /* [out] */ 331 HRESULT WINAPI StgStreamImpl_Read( 332 IStream* iface, 333 void* pv, /* [length_is][size_is][out] */ 334 ULONG cb, /* [in] */ 335 ULONG* pcbRead) /* [out] */ 325 336 { 326 337 StgStreamImpl* const This=(StgStreamImpl*)iface; … … 330 341 331 342 TRACE("(%p, %p, %ld, %p)\n", 332 iface, pv, cb, pcbRead);333 334 /* 343 iface, pv, cb, pcbRead); 344 345 /* 335 346 * If the caller is not interested in the nubmer of bytes read, 336 347 * we use another buffer to avoid "if" statements in the code. … … 338 349 if (pcbRead==0) 339 350 pcbRead = &bytesReadBuffer; 340 351 341 352 /* 342 353 * Using the known size of the stream, calculate the number of bytes … … 344 355 */ 345 356 bytesToReadFromBuffer = min( This->streamSize.s.LowPart - This->currentPosition.s.LowPart, cb); 346 357 347 358 /* 348 359 * Depending on the type of chain that was opened when the stream was constructed, … … 352 363 { 353 364 SmallBlockChainStream_ReadAt(This->smallBlockChain, 354 This->currentPosition,355 bytesToReadFromBuffer,356 pv,357 pcbRead);358 365 This->currentPosition, 366 bytesToReadFromBuffer, 367 pv, 368 pcbRead); 369 359 370 } 360 371 else if (This->bigBlockChain!=0) 361 372 { 362 373 BlockChainStream_ReadAt(This->bigBlockChain, 363 This->currentPosition,364 bytesToReadFromBuffer,365 pv,366 pcbRead);374 This->currentPosition, 375 bytesToReadFromBuffer, 376 pv, 377 pcbRead); 367 378 } 368 379 else … … 387 398 */ 388 399 This->currentPosition.s.LowPart += *pcbRead; 389 400 390 401 /* 391 402 * The function returns S_OK if the buffer was filled completely … … 395 406 if(*pcbRead == cb) 396 407 return S_OK; 397 408 398 409 return S_FALSE; 399 410 } 400 411 401 412 /*** 402 413 * This method is part of the ISequentialStream interface. … … 410 421 */ 411 422 HRESULT WINAPI StgStreamImpl_Write( 412 IStream* iface,413 const void* pv, /* [size_is][in] */ 414 ULONG cb, /* [in] */ 415 ULONG* pcbWritten) /* [out] */ 423 IStream* iface, 424 const void* pv, /* [size_is][in] */ 425 ULONG cb, /* [in] */ 426 ULONG* pcbWritten) /* [out] */ 416 427 { 417 428 StgStreamImpl* const This=(StgStreamImpl*)iface; … … 421 432 422 433 TRACE("(%p, %p, %ld, %p)\n", 423 iface, pv, cb, pcbWritten);424 434 iface, pv, cb, pcbWritten); 435 425 436 /* 426 437 * Do we have permission to write to this stream? … … 436 447 if (pcbWritten == 0) 437 448 pcbWritten = &bytesWritten; 438 449 439 450 /* 440 451 * Initialize the out parameter … … 451 462 newSize.s.LowPart = This->currentPosition.s.LowPart + cb; 452 463 } 453 464 454 465 /* 455 466 * Verify if we need to grow the stream … … 460 471 IStream_SetSize(iface, newSize); 461 472 } 462 473 463 474 /* 464 475 * Depending on the type of chain that was opened when the stream was constructed, … … 468 479 { 469 480 SmallBlockChainStream_WriteAt(This->smallBlockChain, 470 This->currentPosition,471 cb,472 pv,473 pcbWritten);474 481 This->currentPosition, 482 cb, 483 pv, 484 pcbWritten); 485 475 486 } 476 487 else if (This->bigBlockChain!=0) 477 488 { 478 489 BlockChainStream_WriteAt(This->bigBlockChain, 479 This->currentPosition,480 cb,481 pv,482 pcbWritten);490 This->currentPosition, 491 cb, 492 pv, 493 pcbWritten); 483 494 } 484 495 else 485 496 assert(FALSE); 486 497 487 498 /* 488 499 * Advance the position pointer for the number of positions written. 489 500 */ 490 501 This->currentPosition.s.LowPart += *pcbWritten; 491 502 492 503 return S_OK; 493 504 } … … 500 511 * 501 512 * See the documentation of IStream for more info. 502 */ 503 HRESULT WINAPI StgStreamImpl_Seek( 504 IStream* iface,505 LARGE_INTEGER dlibMove, /* [in] */ 506 DWORD dwOrigin, /* [in] */ 507 ULARGE_INTEGER* plibNewPosition) /* [out] */513 */ 514 HRESULT WINAPI StgStreamImpl_Seek( 515 IStream* iface, 516 LARGE_INTEGER dlibMove, /* [in] */ 517 DWORD dwOrigin, /* [in] */ 518 ULARGE_INTEGER* plibNewPosition) /* [out] */ 508 519 { 509 520 StgStreamImpl* const This=(StgStreamImpl*)iface; … … 512 523 513 524 TRACE("(%p, %ld, %ld, %p)\n", 514 iface, dlibMove.s.LowPart, dwOrigin, plibNewPosition);515 516 /* 525 iface, dlibMove.s.LowPart, dwOrigin, plibNewPosition); 526 527 /* 517 528 * The caller is allowed to pass in NULL as the new position return value. 518 529 * If it happens, we assign it to a dynamic variable to avoid special cases … … 556 567 /* ... and subtract with carry */ 557 568 if (dlibMove.s.LowPart > plibNewPosition->s.LowPart) { 558 /* carry needed, This accounts for any underflows at [1]*/559 plibNewPosition->s.HighPart -= 1; 569 /* carry needed, This accounts for any underflows at [1]*/ 570 plibNewPosition->s.HighPart -= 1; 560 571 } 561 572 plibNewPosition->s.LowPart -= dlibMove.s.LowPart; /* [1] */ 562 plibNewPosition->s.HighPart -= dlibMove.s.HighPart; 573 plibNewPosition->s.HighPart -= dlibMove.s.HighPart; 563 574 } else { 564 575 /* add directly */ … … 566 577 plibNewPosition->s.LowPart += dlibMove.s.LowPart; 567 578 if((plibNewPosition->s.LowPart < initialLowPart) || 568 (plibNewPosition->s.LowPart < dlibMove.s.LowPart)) {569 /* LowPart has rolled over => add the carry digit to HighPart */570 plibNewPosition->s.HighPart++;579 (plibNewPosition->s.LowPart < dlibMove.s.LowPart)) { 580 /* LowPart has rolled over => add the carry digit to HighPart */ 581 plibNewPosition->s.HighPart++; 571 582 } 572 plibNewPosition->s.HighPart += dlibMove.s.HighPart; 573 } 574 /* 575 * Check if we end-up before the beginning of the file. That should 583 plibNewPosition->s.HighPart += dlibMove.s.HighPart; 584 } 585 /* 586 * Check if we end-up before the beginning of the file. That should 576 587 * trigger an error. 577 588 */ … … 581 592 582 593 /* 583 * We currently don't support files with offsets of >32 bits. 594 * We currently don't support files with offsets of >32 bits. 584 595 * Note that we have checked for a negative offset already 585 596 */ … … 594 605 */ 595 606 This->currentPosition = *plibNewPosition; 596 607 597 608 return S_OK; 598 609 } … … 607 618 * See the documentation of IStream for more info. 608 619 */ 609 HRESULT WINAPI StgStreamImpl_SetSize( 610 IStream* iface,611 ULARGE_INTEGER libNewSize) /* [in] */ 620 HRESULT WINAPI StgStreamImpl_SetSize( 621 IStream* iface, 622 ULARGE_INTEGER libNewSize) /* [in] */ 612 623 { 613 624 StgStreamImpl* const This=(StgStreamImpl*)iface; … … 658 669 Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, 659 670 This->ownerProperty, 660 &curProperty); 671 &curProperty); 661 672 /* 662 673 * Determine if we have to switch from small to big blocks or vice versa 663 */ 664 if ( (This->smallBlockChain!=0) && 674 */ 675 if ( (This->smallBlockChain!=0) && 665 676 (curProperty.size.s.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) 666 677 { … … 694 705 curProperty.size.s.HighPart = libNewSize.s.HighPart; 695 706 curProperty.size.s.LowPart = libNewSize.s.LowPart; 696 707 697 708 if (Success) 698 709 { 699 710 StorageImpl_WriteProperty(This->parentStorage->ancestorStorage, 700 This->ownerProperty,701 &curProperty);702 } 703 711 This->ownerProperty, 712 &curProperty); 713 } 714 704 715 This->streamSize = libNewSize; 705 716 706 717 return S_OK; 707 718 } 708 719 709 720 /*** 710 721 * This method is part of the IStream interface. … … 714 725 * See the documentation of IStream for more info. 715 726 */ 716 HRESULT WINAPI StgStreamImpl_CopyTo( 717 IStream* iface,718 IStream* pstm, /* [unique][in] */ 719 ULARGE_INTEGER cb, /* [in] */ 720 ULARGE_INTEGER* pcbRead, /* [out] */ 721 ULARGE_INTEGER* pcbWritten) /* [out] */ 727 HRESULT WINAPI StgStreamImpl_CopyTo( 728 IStream* iface, 729 IStream* pstm, /* [unique][in] */ 730 ULARGE_INTEGER cb, /* [in] */ 731 ULARGE_INTEGER* pcbRead, /* [out] */ 732 ULARGE_INTEGER* pcbWritten) /* [out] */ 722 733 { 723 734 HRESULT hr = S_OK; … … 727 738 ULARGE_INTEGER totalBytesWritten; 728 739 729 TRACE("(%p, %p, %ld, %p, %p)\n", 730 iface, pstm, cb.s.LowPart, pcbRead, pcbWritten);740 TRACE("(%p, %p, %ld, %p, %p)\n", 741 iface, pstm, cb.s.LowPart, pcbRead, pcbWritten); 731 742 732 743 /* … … 750 761 else 751 762 copySize = cb.s.LowPart; 752 763 753 764 IStream_Read(iface, tmpBuffer, copySize, &bytesRead); 754 765 755 766 totalBytesRead.s.LowPart += bytesRead; 756 767 757 768 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten); 758 769 … … 767 778 break; 768 779 } 769 780 770 781 if (bytesRead!=copySize) 771 782 cb.s.LowPart = 0; … … 798 809 * 799 810 * See the documentation of IStream for more info. 800 */ 801 HRESULT WINAPI StgStreamImpl_Commit( 802 IStream* iface,803 DWORD grfCommitFlags) /* [in] */ 811 */ 812 HRESULT WINAPI StgStreamImpl_Commit( 813 IStream* iface, 814 DWORD grfCommitFlags) /* [in] */ 804 815 { 805 816 return S_OK; … … 813 824 * 814 825 * See the documentation of IStream for more info. 815 */ 816 HRESULT WINAPI StgStreamImpl_Revert( 817 IStream* iface)826 */ 827 HRESULT WINAPI StgStreamImpl_Revert( 828 IStream* iface) 818 829 { 819 830 return S_OK; 820 831 } 821 832 822 HRESULT WINAPI StgStreamImpl_LockRegion( 823 IStream* iface,824 ULARGE_INTEGER libOffset, /* [in] */ 825 ULARGE_INTEGER cb, /* [in] */ 826 DWORD dwLockType) /* [in] */ 833 HRESULT WINAPI StgStreamImpl_LockRegion( 834 IStream* iface, 835 ULARGE_INTEGER libOffset, /* [in] */ 836 ULARGE_INTEGER cb, /* [in] */ 837 DWORD dwLockType) /* [in] */ 827 838 { 828 839 FIXME("not implemented!\n"); … … 830 841 } 831 842 832 HRESULT WINAPI StgStreamImpl_UnlockRegion( 833 IStream* iface,834 ULARGE_INTEGER libOffset, /* [in] */ 835 ULARGE_INTEGER cb, /* [in] */ 836 DWORD dwLockType) /* [in] */ 843 HRESULT WINAPI StgStreamImpl_UnlockRegion( 844 IStream* iface, 845 ULARGE_INTEGER libOffset, /* [in] */ 846 ULARGE_INTEGER cb, /* [in] */ 847 DWORD dwLockType) /* [in] */ 837 848 { 838 849 FIXME("not implemented!\n"); … … 847 858 * 848 859 * See the documentation of IStream for more info. 849 */ 850 HRESULT WINAPI StgStreamImpl_Stat( 851 IStream* iface,852 STATSTG* pstatstg, /* [out] */853 DWORD grfStatFlag) /* [in] */ 860 */ 861 HRESULT WINAPI StgStreamImpl_Stat( 862 IStream* iface, 863 STATSTG* pstatstg, /* [out] */ 864 DWORD grfStatFlag) /* [in] */ 854 865 { 855 866 StgStreamImpl* const This=(StgStreamImpl*)iface; … … 857 868 StgProperty curProperty; 858 869 BOOL readSucessful; 859 870 860 871 /* 861 872 * Read the information from the property. 862 873 */ 863 874 readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, 864 This->ownerProperty,865 &curProperty);866 875 This->ownerProperty, 876 &curProperty); 877 867 878 if (readSucessful) 868 879 { 869 StorageUtl_CopyPropertyToSTATSTG(pstatstg, 870 &curProperty, 871 grfStatFlag);880 StorageUtl_CopyPropertyToSTATSTG(pstatstg, 881 &curProperty, 882 grfStatFlag); 872 883 873 884 pstatstg->grfMode = This->grfMode; 874 885 875 886 return S_OK; 876 887 } 877 888 878 889 return E_FAIL; 879 890 } 880 881 HRESULT WINAPI StgStreamImpl_Clone( 882 IStream* iface, 883 IStream** ppstm) /* [out] */ 884 { 885 FIXME("not implemented!\n"); 886 return E_NOTIMPL; 887 } 891 892 /*** 893 * This method is part of the IStream interface. 894 * 895 * This method returns a clone of the interface that allows for 896 * another seek pointer 897 * 898 * See the documentation of IStream for more info. 899 * 900 * I am not totally sure what I am doing here but I presume that this 901 * should be basically as simple as creating a new stream with the same 902 * parent etc and positioning its seek cursor. 903 */ 904 HRESULT WINAPI StgStreamImpl_Clone( 905 IStream* iface, 906 IStream** ppstm) /* [out] */ 907 { 908 StgStreamImpl* const This=(StgStreamImpl*)iface; 909 HRESULT hres; 910 StgStreamImpl* new_stream; 911 LARGE_INTEGER seek_pos; 912 913 /* 914 * Sanity check 915 */ 916 if ( ppstm == 0 ) 917 return STG_E_INVALIDPOINTER; 918 919 new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->ownerProperty); 920 921 if (!new_stream) 922 return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */ 923 924 *ppstm = (IStream*) new_stream; 925 seek_pos.QuadPart = This->currentPosition.QuadPart; 926 927 hres=StgStreamImpl_Seek (*ppstm, seek_pos, STREAM_SEEK_SET, NULL); 928 929 assert (SUCCEEDED(hres)); 930 931 return S_OK; 932 }
Note:
See TracChangeset
for help on using the changeset viewer.
