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;
|
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.
|
* Finally, free the memory used-up by the class.
|
||||||
*/
|
*/
|
||||||
|
@ -179,73 +164,6 @@ static ULONG WINAPI StgStreamImpl_Release(
|
||||||
return ref;
|
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.
|
* This method is part of the ISequentialStream interface.
|
||||||
*
|
*
|
||||||
|
@ -319,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
|
||||||
{
|
{
|
||||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||||
|
|
||||||
ULARGE_INTEGER newSize;
|
|
||||||
ULONG bytesWritten = 0;
|
ULONG bytesWritten = 0;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
|
||||||
|
@ -365,22 +282,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
|
||||||
TRACE("<-- S_OK, written 0\n");
|
TRACE("<-- S_OK, written 0\n");
|
||||||
return S_OK;
|
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,
|
res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
|
||||||
This->dirEntry,
|
This->dirEntry,
|
||||||
|
@ -415,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek(
|
||||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||||
|
|
||||||
ULARGE_INTEGER newPosition;
|
ULARGE_INTEGER newPosition;
|
||||||
|
DirEntry currentEntry;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p, %d, %d, %p)\n",
|
TRACE("(%p, %d, %d, %p)\n",
|
||||||
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||||
|
@ -453,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek(
|
||||||
*plibNewPosition = This->currentPosition;
|
*plibNewPosition = This->currentPosition;
|
||||||
break;
|
break;
|
||||||
case STREAM_SEEK_END:
|
case STREAM_SEEK_END:
|
||||||
*plibNewPosition = This->streamSize;
|
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, ¤tEntry);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
*plibNewPosition = currentEntry.size;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN("invalid dwOrigin %d\n", dwOrigin);
|
WARN("invalid dwOrigin %d\n", dwOrigin);
|
||||||
|
@ -511,16 +416,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||||
return STG_E_ACCESSDENIED;
|
return STG_E_ACCESSDENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
|
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
This->streamSize = libNewSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct(
|
||||||
newStream->currentPosition.u.HighPart = 0;
|
newStream->currentPosition.u.HighPart = 0;
|
||||||
newStream->currentPosition.u.LowPart = 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 */
|
/* add us to the storage's list of active streams */
|
||||||
StorageBaseImpl_AddStream(parentStorage, newStream);
|
StorageBaseImpl_AddStream(parentStorage, newStream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2339,16 +2339,22 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
|
||||||
StorageImpl *This = (StorageImpl*)base;
|
StorageImpl *This = (StorageImpl*)base;
|
||||||
DirEntry data;
|
DirEntry data;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
ULARGE_INTEGER newSize;
|
||||||
|
|
||||||
hr = StorageImpl_ReadDirEntry(This, index, &data);
|
hr = StorageImpl_ReadDirEntry(This, index, &data);
|
||||||
if (FAILED(hr)) return hr;
|
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. */
|
hr = StorageImpl_StreamSetSize(base, index, newSize);
|
||||||
assert(FALSE);
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
data.size = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
|
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);
|
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,
|
static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
|
||||||
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
||||||
{
|
{
|
||||||
|
@ -430,23 +431,10 @@ struct StgStreamImpl
|
||||||
*/
|
*/
|
||||||
DirRef dirEntry;
|
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
|
* This is the current position of the cursor in the stream
|
||||||
*/
|
*/
|
||||||
ULARGE_INTEGER currentPosition;
|
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