Ulrich Czekalla : ole32: Return error instead of asserting if storage file is corrupt.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Dec 22 11:11:24 CST 2005


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

Author: Ulrich Czekalla <ulrich at codeweavers.com>
Date:   Thu Dec 22 17:15:05 2005 +0100

ole32: Return error instead of asserting if storage file is corrupt.

---

 dlls/ole32/stg_stream.c |   37 +++++++++++++------------------------
 dlls/ole32/storage32.c  |   32 +++++++++++++++++++++-----------
 dlls/ole32/storage32.h  |    2 +-
 include/winerror.h      |    1 +
 4 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c
index 928028b..40f0e81 100644
--- a/dlls/ole32/stg_stream.c
+++ b/dlls/ole32/stg_stream.c
@@ -273,7 +273,7 @@ static HRESULT WINAPI StgStreamImpl_Read
    */
   if (This->smallBlockChain!=0)
   {
-    SmallBlockChainStream_ReadAt(This->smallBlockChain,
+    res = SmallBlockChainStream_ReadAt(This->smallBlockChain,
 				 This->currentPosition,
 				 bytesToReadFromBuffer,
 				 pv,
@@ -282,7 +282,7 @@ static HRESULT WINAPI StgStreamImpl_Read
   }
   else if (This->bigBlockChain!=0)
   {
-    BlockChainStream_ReadAt(This->bigBlockChain,
+    res = BlockChainStream_ReadAt(This->bigBlockChain,
 			    This->currentPosition,
 			    bytesToReadFromBuffer,
 			    pv,
@@ -300,30 +300,19 @@ static HRESULT WINAPI StgStreamImpl_Read
     goto end;
   }
 
-  /*
-   * We should always be able to read the proper amount of data from the
-   * chain.
-   */
-  assert(bytesToReadFromBuffer == *pcbRead);
-
-  /*
-   * Advance the pointer for the number of positions read.
-   */
-  This->currentPosition.u.LowPart += *pcbRead;
-
-  if(*pcbRead != cb)
+  if (SUCCEEDED(res))
   {
-    WARN("read %ld instead of the required %ld bytes !\n", *pcbRead, cb);
-    /*
-     * this used to return S_FALSE, however MSDN docu says that an app should
-     * be prepared to handle error in case of stream end reached, as *some*
-     * implementations *might* return an error (IOW: most do *not*).
-     * As some program fails on returning S_FALSE, I better use S_OK here.
-     */
-    res = S_OK;
+      /*
+       * We should always be able to read the proper amount of data from the
+       * chain.
+       */
+      assert(bytesToReadFromBuffer == *pcbRead);
+
+      /*
+       * Advance the pointer for the number of positions read.
+       */
+      This->currentPosition.u.LowPart += *pcbRead;
   }
-  else
-    res = S_OK;
 
 end:
   TRACE("<-- %08lx\n", res);
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 708d994..c9d696e 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -3414,7 +3414,8 @@ BlockChainStream* Storage32Impl_SmallBlo
   ULARGE_INTEGER size, offset;
   ULONG cbRead, cbWritten, cbTotalRead, cbTotalWritten;
   ULONG propertyIndex;
-  BOOL successRead, successWrite;
+  BOOL successWrite;
+  HRESULT successRead;
   StgProperty chainProperty;
   BYTE *buffer;
   BlockChainStream *bbTempChain = NULL;
@@ -3463,7 +3464,7 @@ BlockChainStream* Storage32Impl_SmallBlo
 
     offset.u.LowPart += This->smallBlockSize;
 
-  } while (successRead && successWrite);
+  } while (SUCCEEDED(successRead) && successWrite);
   HeapFree(GetProcessHeap(),0,buffer);
 
   assert(cbTotalRead == cbTotalWritten);
@@ -4397,6 +4398,9 @@ BOOL BlockChainStream_ReadAt(BlockChainS
     blockNoInSequence--;
   }
 
+  if ((blockNoInSequence > 0) && (blockIndex == BLOCK_END_OF_CHAIN))
+      return FALSE; /* We failed to find the starting block */
+
   This->lastBlockNoInSequenceIndex = blockIndex;
 
   /*
@@ -5098,13 +5102,14 @@ ULONG SmallBlockChainStream_GetNextFreeB
  * bytesRead may be NULL.
  * Failure will be returned if the specified number of bytes has not been read.
  */
-BOOL SmallBlockChainStream_ReadAt(
+HRESULT SmallBlockChainStream_ReadAt(
   SmallBlockChainStream* This,
   ULARGE_INTEGER         offset,
   ULONG                  size,
   void*                  buffer,
   ULONG*                 bytesRead)
 {
+  HRESULT rc = S_OK;
   ULARGE_INTEGER offsetInBigBlockFile;
   ULONG blockNoInSequence =
     offset.u.LowPart / This->parentStorage->smallBlockSize;
@@ -5127,9 +5132,9 @@ BOOL SmallBlockChainStream_ReadAt(
 
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
-							&blockIndex)))
-      return FALSE;
+    rc = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex);
+    if(FAILED(rc))
+      return rc;
     blockNoInSequence--;
   }
 
@@ -5158,27 +5163,32 @@ BOOL SmallBlockChainStream_ReadAt(
 
     /*
      * Read those bytes in the buffer from the small block file.
+     * The small block has already been identified so it shouldn't fail
+     * unless the file is corrupt.
      */
-    BlockChainStream_ReadAt(This->parentStorage->smallBlockRootChain,
+    if (!BlockChainStream_ReadAt(This->parentStorage->smallBlockRootChain,
       offsetInBigBlockFile,
       bytesToReadInBuffer,
       bufferWalker,
-      &bytesReadFromBigBlockFile);
+      &bytesReadFromBigBlockFile))
+      return STG_E_DOCFILECORRUPT;
 
     assert(bytesReadFromBigBlockFile == bytesToReadInBuffer);
 
     /*
      * Step to the next big block.
      */
-    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
-      return FALSE;
+    rc = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex);
+    if(FAILED(rc))
+      return rc;
+
     bufferWalker += bytesToReadInBuffer;
     size         -= bytesToReadInBuffer;
     *bytesRead   += bytesToReadInBuffer;
     offsetInBlock = 0;  /* There is no offset on the next block */
   }
 
-  return (size == 0);
+  return rc;
 }
 
 /******************************************************************************
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 4061a06..0472524 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -667,7 +667,7 @@ void SmallBlockChainStream_FreeBlock(
 ULONG SmallBlockChainStream_GetNextFreeBlock(
          SmallBlockChainStream* This);
 
-BOOL SmallBlockChainStream_ReadAt(
+HRESULT SmallBlockChainStream_ReadAt(
 	       SmallBlockChainStream* This,
 	       ULARGE_INTEGER offset,
 	       ULONG          size,
diff --git a/include/winerror.h b/include/winerror.h
index bf866da..b824c79 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -1691,6 +1691,7 @@
 #define STG_E_SHAREREQUIRED                                _HRESULT_TYPEDEF_(0x80030106L)
 #define STG_E_NOTFILEBASEDSTORAGE                          _HRESULT_TYPEDEF_(0x80030107L)
 #define STG_E_EXTANTMARSHALLINGS                           _HRESULT_TYPEDEF_(0x80030108L)
+#define STG_E_DOCFILECORRUPT                               _HRESULT_TYPEDEF_(0x80030109L)
 
 #define STG_E_STATUS_COPY_PROTECTION_FAILURE               _HRESULT_TYPEDEF_(0x80030305L)
 #define STG_E_CSS_AUTHENTICATION_FAILURE                   _HRESULT_TYPEDEF_(0x80030306L)




More information about the wine-cvs mailing list