Robert Shearman : ole32: Ensure that a returned free block is valid in storage.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 3 15:58:32 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: f0dc9deff0dd6d0e366257b26ecdfb373f004749
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=f0dc9deff0dd6d0e366257b26ecdfb373f004749

Author: Robert Shearman <rob at codeweavers.com>
Date:   Thu Aug  3 20:25:14 2006 +0100

ole32: Ensure that a returned free block is valid in storage.

Otherwise, an IStream_SetSize call followed by an IStream_Read call 
could fail with STG_E_DOCFILECORRUPT.

---

 dlls/ole32/stg_bigblockfile.c |   28 ++++++++++++++++++++++++----
 dlls/ole32/storage32.c        |    5 +++++
 dlls/ole32/storage32.h        |    1 +
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/dlls/ole32/stg_bigblockfile.c b/dlls/ole32/stg_bigblockfile.c
index 0d28586..b946ab0 100644
--- a/dlls/ole32/stg_bigblockfile.c
+++ b/dlls/ole32/stg_bigblockfile.c
@@ -351,12 +351,11 @@ void* BIGBLOCKFILE_GetROBigBlock(
 }
 
 /******************************************************************************
- *      BIGBLOCKFILE_GetBigBlock
+ *      BIGBLOCKFILE_EnsureExists
  *
- * Returns the specified block.
- * Will grow the file if necessary.
+ * Grows the file if necessary to make sure the block is valid.
  */
-void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
+void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index)
 {
   /*
    * block index starts at -1
@@ -379,6 +378,27 @@ void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOC
 
     BIGBLOCKFILE_SetSize(This, newSize);
   }
+}
+
+/******************************************************************************
+ *      BIGBLOCKFILE_GetBigBlock
+ *
+ * Returns the specified block.
+ * Will grow the file if necessary.
+ */
+void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
+{
+  /* FIXME: is this necessary? */
+  BIGBLOCKFILE_EnsureExists(This, index);
+
+  /*
+   * block index starts at -1
+   * translate to zero based index
+   */
+  if (index == 0xffffffff)
+    index = 0;
+  else
+    index++;
 
   return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_WRITE);
 }
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index a8a8f0b..abf944a 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -2717,6 +2717,11 @@ static ULONG StorageImpl_GetNextFreeBigB
     depotBlockOffset = 0;
   }
 
+  /*
+   * make sure that the block physically exists before using it
+   */
+  BIGBLOCKFILE_EnsureExists(This->bigBlockFile, freeBlock);
+
   This->prevFreeBlock = freeBlock;
 
   return freeBlock;
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 884dc0e..4562772 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -190,6 +190,7 @@ BigBlockFile*  BIGBLOCKFILE_Construct(HA
                                       ULONG blocksize,
                                       BOOL fileBased);
 void           BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
+void           BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
 void*          BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
 void*          BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
 void           BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock);




More information about the wine-cvs mailing list