ole32: Don't track the stream size in storage stream objects.

We can't do this safely when there are multiple objects for a single stream.
This commit is contained in:
Vincent Povirk 2009-11-30 15:40:53 -06:00 committed by Alexandre Julliard
parent 6d06c43e53
commit 8518323e07
3 changed files with 17 additions and 141 deletions

View File

@ -74,21 +74,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This)
This->parentStorage = 0;
/*
* Make sure we clean-up the block chain stream objects that we were using.
*/
if (This->bigBlockChain != 0)
{
BlockChainStream_Destroy(This->bigBlockChain);
This->bigBlockChain = 0;
}
if (This->smallBlockChain != 0)
{
SmallBlockChainStream_Destroy(This->smallBlockChain);
This->smallBlockChain = 0;
}
/*
* Finally, free the memory used-up by the class.
*/
@ -179,73 +164,6 @@ static ULONG WINAPI StgStreamImpl_Release(
return ref;
}
/***
* This method will open the block chain pointed by the directory entry
* that describes the stream.
* If the stream's size is null, no chain is opened.
*/
static void StgStreamImpl_OpenBlockChain(
StgStreamImpl* This)
{
DirEntry currentEntry;
HRESULT hr;
/*
* Make sure no old object is left over.
*/
if (This->smallBlockChain != 0)
{
SmallBlockChainStream_Destroy(This->smallBlockChain);
This->smallBlockChain = 0;
}
if (This->bigBlockChain != 0)
{
BlockChainStream_Destroy(This->bigBlockChain);
This->bigBlockChain = 0;
}
/*
* Read the information from the directory entry.
*/
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
This->dirEntry,
&currentEntry);
if (SUCCEEDED(hr))
{
This->streamSize = currentEntry.size;
/*
* This code supports only streams that are <32 bits in size.
*/
assert(This->streamSize.u.HighPart == 0);
if(currentEntry.startingBlock == BLOCK_END_OF_CHAIN)
{
assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) );
}
else
{
if ( (This->streamSize.u.HighPart == 0) &&
(This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
{
This->smallBlockChain = SmallBlockChainStream_Construct(
This->parentStorage->ancestorStorage,
NULL,
This->dirEntry);
}
else
{
This->bigBlockChain = BlockChainStream_Construct(
This->parentStorage->ancestorStorage,
NULL,
This->dirEntry);
}
}
}
}
/***
* This method is part of the ISequentialStream interface.
*
@ -319,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
HRESULT res;
@ -365,22 +282,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
TRACE("<-- S_OK, written 0\n");
return S_OK;
}
else
{
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
}
/*
* Verify if we need to grow the stream
*/
if (newSize.u.LowPart > This->streamSize.u.LowPart)
{
/* grow stream */
res = IStream_SetSize(iface, newSize);
if (FAILED(res))
return res;
}
res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
This->dirEntry,
@ -415,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek(
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newPosition;
DirEntry currentEntry;
HRESULT hr;
TRACE("(%p, %d, %d, %p)\n",
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
@ -453,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek(
*plibNewPosition = This->currentPosition;
break;
case STREAM_SEEK_END:
*plibNewPosition = This->streamSize;
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, &currentEntry);
if (FAILED(hr)) return hr;
*plibNewPosition = currentEntry.size;
break;
default:
WARN("invalid dwOrigin %d\n", dwOrigin);
@ -511,16 +416,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
return STG_E_ACCESSDENIED;
}
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
if (SUCCEEDED(hr))
{
This->streamSize = libNewSize;
}
return hr;
}
@ -853,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct(
newStream->currentPosition.u.HighPart = 0;
newStream->currentPosition.u.LowPart = 0;
/*
* Initialize the rest of the data.
*/
newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = 0;
newStream->bigBlockChain = 0;
newStream->smallBlockChain = 0;
/*
* Read the size from the directory entry and determine if the blocks forming
* this stream are large or small.
*/
StgStreamImpl_OpenBlockChain(newStream);
/* add us to the storage's list of active streams */
StorageBaseImpl_AddStream(parentStorage, newStream);
}

View File

@ -2339,16 +2339,22 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
StorageImpl *This = (StorageImpl*)base;
DirEntry data;
HRESULT hr;
ULARGE_INTEGER newSize;
hr = StorageImpl_ReadDirEntry(This, index, &data);
if (FAILED(hr)) return hr;
/* FIXME: Enlarge the stream first if necessary. */
/* Grow the stream if necessary */
newSize.QuadPart = 0;
newSize.QuadPart = offset.QuadPart + size;
if (data.size.QuadPart == 0)
if (newSize.QuadPart > data.size.QuadPart)
{
/* This shouldn't happen for now, because the stream object will set the size. */
assert(FALSE);
hr = StorageImpl_StreamSetSize(base, index, newSize);
if (FAILED(hr))
return hr;
data.size = newSize;
}
if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)

View File

@ -293,7 +293,8 @@ static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This,
return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead);
}
/* Write size bytes to this directory entry's stream at the given offset. */
/* Write size bytes to this directory entry's stream at the given offset,
* growing the stream if necessary. */
static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
{
@ -430,23 +431,10 @@ struct StgStreamImpl
*/
DirRef dirEntry;
/*
* Helper variable that contains the size of the stream
*/
ULARGE_INTEGER streamSize;
/*
* This is the current position of the cursor in the stream
*/
ULARGE_INTEGER currentPosition;
/*
* The information in the stream is represented by a chain of small blocks
* or a chain of large blocks. Depending on the case, one of the two
* following variables points to that information.
*/
BlockChainStream* bigBlockChain;
SmallBlockChainStream* smallBlockChain;
};
/*