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:
parent
6d06c43e53
commit
8518323e07
|
@ -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,
|
||||
¤tEntry);
|
||||
|
||||
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, ¤tEntry);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue