ole32: Support storage files larger than 4 GB.
Vincent Povirk
madewokherd at gmail.com
Wed Jun 11 14:38:19 CDT 2014
-------------- next part --------------
From be82cfd61c0219d8eb82bcf0bf8fa549dd138124 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Tue, 20 May 2014 16:08:09 -0500
Subject: [PATCH 1/3] ole32: Support storage files larger than 4 GB.
---
dlls/ole32/stg_stream.c | 4 +-
dlls/ole32/storage32.c | 100 ++++++++++++++++++++++--------------------------
dlls/ole32/storage32.h | 1 +
3 files changed, 49 insertions(+), 56 deletions(-)
diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c
index d7abd0e..b60b17b 100644
--- a/dlls/ole32/stg_stream.c
+++ b/dlls/ole32/stg_stream.c
@@ -166,7 +166,7 @@ static HRESULT WINAPI StgStreamImpl_Read(
/*
* Advance the pointer for the number of positions read.
*/
- This->currentPosition.u.LowPart += *pcbRead;
+ This->currentPosition.QuadPart += *pcbRead;
}
TRACE("<-- %08x\n", res);
@@ -247,7 +247,7 @@ static HRESULT WINAPI StgStreamImpl_Write(
/*
* Advance the position pointer for the number of positions written.
*/
- This->currentPosition.u.LowPart += *pcbWritten;
+ This->currentPosition.QuadPart += *pcbWritten;
if (SUCCEEDED(res))
res = StorageBaseImpl_Flush(This->parentStorage);
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index a880e2a..69a2198 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -353,9 +353,9 @@ static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This);
** Block Functions
*/
-static ULONG StorageImpl_GetBigBlockOffset(StorageImpl* This, ULONG index)
+static ULONGLONG StorageImpl_GetBigBlockOffset(StorageImpl* This, ULONG index)
{
- return (index+1) * This->bigBlockSize;
+ return (ULONGLONG)(index+1) * This->bigBlockSize;
}
/************************************************************************
@@ -1322,8 +1322,7 @@ static HRESULT StorageImpl_CreateDirEntry(
/*
* initialize the size used by the directory stream
*/
- newSize.u.HighPart = 0;
- newSize.u.LowPart = storage->bigBlockSize * blockCount;
+ newSize.QuadPart = (ULONGLONG)storage->bigBlockSize * blockCount;
/*
* add a block to the directory stream
@@ -2602,7 +2601,6 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
if (FAILED(hr)) return hr;
/* Grow the stream if necessary */
- newSize.QuadPart = 0;
newSize.QuadPart = offset.QuadPart + size;
if (newSize.QuadPart > data.size.QuadPart)
@@ -4156,8 +4154,7 @@ HRESULT StorageImpl_ReadRawDirEntry(StorageImpl *This, ULONG index, BYTE *buffer
HRESULT hr;
ULONG bytesRead;
- offset.u.HighPart = 0;
- offset.u.LowPart = index * RAW_DIRENTRY_SIZE;
+ offset.QuadPart = (ULONGLONG)index * RAW_DIRENTRY_SIZE;
hr = BlockChainStream_ReadAt(
This->rootBlockChain,
@@ -4184,8 +4181,7 @@ HRESULT StorageImpl_WriteRawDirEntry(StorageImpl *This, ULONG index, const BYTE
ULARGE_INTEGER offset;
ULONG bytesRead;
- offset.u.HighPart = 0;
- offset.u.LowPart = index * RAW_DIRENTRY_SIZE;
+ offset.QuadPart = (ULONGLONG)index * RAW_DIRENTRY_SIZE;
return BlockChainStream_WriteAt(
This->rootBlockChain,
@@ -4267,6 +4263,11 @@ void UpdateRawDirEntry(BYTE *buffer, const DirEntry *newData)
buffer,
OFFSET_PS_SIZE,
newData->size.u.LowPart);
+
+ StorageUtl_WriteDWord(
+ buffer,
+ OFFSET_PS_SIZE_HIGH,
+ newData->size.u.HighPart);
}
/******************************************************************************
@@ -4350,7 +4351,10 @@ HRESULT StorageImpl_ReadDirEntry(
OFFSET_PS_SIZE,
&buffer->size.u.LowPart);
- buffer->size.u.HighPart = 0;
+ StorageUtl_ReadDWord(
+ currentEntry,
+ OFFSET_PS_SIZE_HIGH,
+ &buffer->size.u.HighPart);
}
return readRes;
@@ -4381,8 +4385,7 @@ static HRESULT StorageImpl_ReadBigBlock(
DWORD read=0;
HRESULT hr;
- ulOffset.u.HighPart = 0;
- ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
+ ulOffset.QuadPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
hr = StorageImpl_ReadAt(This, ulOffset, buffer, This->bigBlockSize, &read);
@@ -4407,9 +4410,8 @@ static BOOL StorageImpl_ReadDWordFromBigBlock(
DWORD read;
DWORD tmp;
- ulOffset.u.HighPart = 0;
- ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
- ulOffset.u.LowPart += offset;
+ ulOffset.QuadPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
+ ulOffset.QuadPart += offset;
StorageImpl_ReadAt(This, ulOffset, &tmp, sizeof(DWORD), &read);
*value = lendian32toh(tmp);
@@ -4424,8 +4426,7 @@ static BOOL StorageImpl_WriteBigBlock(
ULARGE_INTEGER ulOffset;
DWORD wrote;
- ulOffset.u.HighPart = 0;
- ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
+ ulOffset.QuadPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
StorageImpl_WriteAt(This, ulOffset, buffer, This->bigBlockSize, &wrote);
return (wrote == This->bigBlockSize);
@@ -4440,9 +4441,8 @@ static BOOL StorageImpl_WriteDWordToBigBlock(
ULARGE_INTEGER ulOffset;
DWORD wrote;
- ulOffset.u.HighPart = 0;
- ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
- ulOffset.u.LowPart += offset;
+ ulOffset.QuadPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
+ ulOffset.QuadPart += offset;
value = htole32(value);
StorageImpl_WriteAt(This, ulOffset, &value, sizeof(DWORD), &wrote);
@@ -7029,8 +7029,8 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This,
void* buffer,
ULONG* bytesRead)
{
- ULONG blockNoInSequence = offset.u.LowPart / This->parentStorage->bigBlockSize;
- ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->bigBlockSize;
+ ULONG blockNoInSequence = offset.QuadPart / This->parentStorage->bigBlockSize;
+ ULONG offsetInBlock = offset.QuadPart % This->parentStorage->bigBlockSize;
ULONG bytesToReadInBuffer;
ULONG blockIndex;
BYTE* bufferWalker;
@@ -7077,8 +7077,7 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This,
if (!cachedBlock)
{
/* Not in cache, and we're going to read past the end of the block. */
- ulOffset.u.HighPart = 0;
- ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
+ ulOffset.QuadPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
offsetInBlock;
StorageImpl_ReadAt(This->parentStorage,
@@ -7127,8 +7126,8 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
const void* buffer,
ULONG* bytesWritten)
{
- ULONG blockNoInSequence = offset.u.LowPart / This->parentStorage->bigBlockSize;
- ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->bigBlockSize;
+ ULONG blockNoInSequence = offset.QuadPart / This->parentStorage->bigBlockSize;
+ ULONG offsetInBlock = offset.QuadPart % This->parentStorage->bigBlockSize;
ULONG bytesToWrite;
ULONG blockIndex;
const BYTE* bufferWalker;
@@ -7162,8 +7161,7 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
if (!cachedBlock)
{
/* Not in cache, and we're going to write past the end of the block. */
- ulOffset.u.HighPart = 0;
- ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
+ ulOffset.QuadPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
offsetInBlock;
StorageImpl_WriteAt(This->parentStorage,
@@ -7215,9 +7213,9 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This,
/*
* Figure out how many blocks are needed to contain the new size
*/
- numBlocks = newSize.u.LowPart / This->parentStorage->bigBlockSize;
+ numBlocks = newSize.QuadPart / This->parentStorage->bigBlockSize;
- if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0)
+ if ((newSize.QuadPart % This->parentStorage->bigBlockSize) != 0)
numBlocks++;
if (numBlocks)
@@ -7346,9 +7344,9 @@ static BOOL BlockChainStream_Enlarge(BlockChainStream* This,
/*
* Figure out how many blocks are needed to contain this stream
*/
- newNumBlocks = newSize.u.LowPart / This->parentStorage->bigBlockSize;
+ newNumBlocks = newSize.QuadPart / This->parentStorage->bigBlockSize;
- if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0)
+ if ((newSize.QuadPart % This->parentStorage->bigBlockSize) != 0)
newNumBlocks++;
/*
@@ -7423,10 +7421,10 @@ BOOL BlockChainStream_SetSize(
{
ULARGE_INTEGER size = BlockChainStream_GetSize(This);
- if (newSize.u.LowPart == size.u.LowPart)
+ if (newSize.QuadPart == size.QuadPart)
return TRUE;
- if (newSize.u.LowPart < size.u.LowPart)
+ if (newSize.QuadPart < size.QuadPart)
{
BlockChainStream_Shrink(This, newSize);
}
@@ -7468,10 +7466,8 @@ static ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This)
* size of them
*/
ULARGE_INTEGER result;
- result.u.HighPart = 0;
-
- result.u.LowPart =
- BlockChainStream_GetCount(This) *
+ result.QuadPart =
+ (ULONGLONG)BlockChainStream_GetCount(This) *
This->parentStorage->bigBlockSize;
return result;
@@ -7556,8 +7552,7 @@ static HRESULT SmallBlockChainStream_GetNextBlockInChain(
*nextBlockInChain = BLOCK_END_OF_CHAIN;
- offsetOfBlockInDepot.u.HighPart = 0;
- offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG);
+ offsetOfBlockInDepot.QuadPart = (ULONGLONG)blockIndex * sizeof(ULONG);
/*
* Read those bytes in the buffer from the small block file.
@@ -7598,8 +7593,7 @@ static void SmallBlockChainStream_SetNextBlockInChain(
DWORD buffer;
ULONG bytesWritten;
- offsetOfBlockInDepot.u.HighPart = 0;
- offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG);
+ offsetOfBlockInDepot.QuadPart = (ULONGLONG)blockIndex * sizeof(ULONG);
StorageUtl_WriteDWord((BYTE *)&buffer, 0, nextBlock);
@@ -7654,7 +7648,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
*/
while (nextBlockIndex != BLOCK_UNUSED)
{
- offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG);
+ offsetOfBlockInDepot.QuadPart = (ULONGLONG)blockIndex * sizeof(ULONG);
res = BlockChainStream_ReadAt(
This->parentStorage->smallBlockDepotChain,
@@ -7682,14 +7676,14 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
ULARGE_INTEGER newSize, offset;
ULONG bytesWritten;
- newSize.QuadPart = (count + 1) * This->parentStorage->bigBlockSize;
+ newSize.QuadPart = (ULONGLONG)(count + 1) * This->parentStorage->bigBlockSize;
BlockChainStream_Enlarge(This->parentStorage->smallBlockDepotChain, newSize);
/*
* Initialize all the small blocks to free
*/
memset(smallBlockDepot, BLOCK_UNUSED, This->parentStorage->bigBlockSize);
- offset.QuadPart = count * This->parentStorage->bigBlockSize;
+ offset.QuadPart = (ULONGLONG)count * This->parentStorage->bigBlockSize;
BlockChainStream_WriteAt(This->parentStorage->smallBlockDepotChain,
offset, This->parentStorage->bigBlockSize, smallBlockDepot, &bytesWritten);
@@ -7707,7 +7701,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
*/
blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1;
- size_required.QuadPart = blocksRequired * This->parentStorage->bigBlockSize;
+ size_required.QuadPart = (ULONGLONG)blocksRequired * This->parentStorage->bigBlockSize;
old_size = BlockChainStream_GetSize(This->parentStorage->smallBlockRootChain);
@@ -7801,11 +7795,10 @@ HRESULT SmallBlockChainStream_ReadAt(
/*
* Calculate the offset of the small block in the small block file.
*/
- offsetInBigBlockFile.u.HighPart = 0;
- offsetInBigBlockFile.u.LowPart =
- blockIndex * This->parentStorage->smallBlockSize;
+ offsetInBigBlockFile.QuadPart =
+ (ULONGLONG)blockIndex * This->parentStorage->smallBlockSize;
- offsetInBigBlockFile.u.LowPart += offsetInBlock;
+ offsetInBigBlockFile.QuadPart += offsetInBlock;
/*
* Read those bytes in the buffer from the small block file.
@@ -7897,11 +7890,10 @@ HRESULT SmallBlockChainStream_WriteAt(
/*
* Calculate the offset of the small block in the small block file.
*/
- offsetInBigBlockFile.u.HighPart = 0;
- offsetInBigBlockFile.u.LowPart =
- blockIndex * This->parentStorage->smallBlockSize;
+ offsetInBigBlockFile.QuadPart =
+ (ULONGLONG)blockIndex * This->parentStorage->smallBlockSize;
- offsetInBigBlockFile.u.LowPart += offsetInBlock;
+ offsetInBigBlockFile.QuadPart += offsetInBlock;
/*
* Write those bytes in the buffer to the small block file.
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index cc5b970..108aad7 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -71,6 +71,7 @@ static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C;
static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070;
static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074;
static const ULONG OFFSET_PS_SIZE = 0x00000078;
+static const ULONG OFFSET_PS_SIZE_HIGH = 0x0000007C;
static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
static const WORD MIN_BIG_BLOCK_SIZE_BITS = 0x0009;
static const WORD MAX_BIG_BLOCK_SIZE_BITS = 0x000c;
--
1.8.3.2
More information about the wine-patches
mailing list