ole32: Use the storage vtable to resize streams.
This commit is contained in:
parent
1d4c698ef3
commit
6d06c43e53
|
@ -483,7 +483,6 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||||
{
|
{
|
||||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||||
|
|
||||||
DirEntry currentEntry;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
|
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
|
||||||
|
@ -512,99 +511,17 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||||
return STG_E_ACCESSDENIED;
|
return STG_E_ACCESSDENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In simple mode keep the stream size above the small block limit */
|
|
||||||
if (This->parentStorage->openFlags & STGM_SIMPLE)
|
|
||||||
libNewSize.u.LowPart = max(libNewSize.u.LowPart, LIMIT_TO_USE_SMALL_BLOCK);
|
|
||||||
|
|
||||||
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
|
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
/*
|
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
|
||||||
* This will happen if we're creating a stream
|
|
||||||
*/
|
|
||||||
if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0))
|
|
||||||
{
|
|
||||||
if (libNewSize.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read this stream's size to see if it's small blocks or big blocks
|
|
||||||
*/
|
|
||||||
StorageBaseImpl_ReadDirEntry(This->parentStorage,
|
|
||||||
This->dirEntry,
|
|
||||||
¤tEntry);
|
|
||||||
/*
|
|
||||||
* Determine if we have to switch from small to big blocks or vice versa
|
|
||||||
*/
|
|
||||||
if ( (This->smallBlockChain!=0) &&
|
|
||||||
(currentEntry.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
|
|
||||||
{
|
|
||||||
if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Transform the small block chain into a big block chain
|
|
||||||
*/
|
|
||||||
This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks(
|
|
||||||
This->parentStorage->ancestorStorage,
|
|
||||||
&This->smallBlockChain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( (This->bigBlockChain!=0) &&
|
|
||||||
(currentEntry.size.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) )
|
|
||||||
{
|
|
||||||
if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Transform the big block chain into a small block chain
|
|
||||||
*/
|
|
||||||
This->smallBlockChain = Storage32Impl_BigBlocksToSmallBlocks(
|
|
||||||
This->parentStorage->ancestorStorage,
|
|
||||||
&This->bigBlockChain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (This->smallBlockChain!=0)
|
|
||||||
{
|
|
||||||
SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BlockChainStream_SetSize(This->bigBlockChain, libNewSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write the new information about this stream to the directory entry
|
|
||||||
*/
|
|
||||||
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
|
|
||||||
This->dirEntry,
|
|
||||||
¤tEntry);
|
|
||||||
|
|
||||||
currentEntry.size.u.HighPart = libNewSize.u.HighPart;
|
|
||||||
currentEntry.size.u.LowPart = libNewSize.u.LowPart;
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
StorageBaseImpl_WriteDirEntry(This->parentStorage,
|
This->streamSize = libNewSize;
|
||||||
This->dirEntry,
|
|
||||||
¤tEntry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
This->streamSize = libNewSize;
|
return hr;
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
|
@ -2246,6 +2246,93 @@ static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT StorageImpl_StreamSetSize(StorageBaseImpl *base, DirRef index,
|
||||||
|
ULARGE_INTEGER newsize)
|
||||||
|
{
|
||||||
|
StorageImpl *This = (StorageImpl*)base;
|
||||||
|
DirEntry data;
|
||||||
|
HRESULT hr;
|
||||||
|
SmallBlockChainStream *smallblock=NULL;
|
||||||
|
BlockChainStream *bigblock=NULL;
|
||||||
|
|
||||||
|
hr = StorageImpl_ReadDirEntry(This, index, &data);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
/* In simple mode keep the stream size above the small block limit */
|
||||||
|
if (This->base.openFlags & STGM_SIMPLE)
|
||||||
|
newsize.QuadPart = max(newsize.QuadPart, LIMIT_TO_USE_SMALL_BLOCK);
|
||||||
|
|
||||||
|
if (data.size.QuadPart == newsize.QuadPart)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
/* Create a block chain object of the appropriate type */
|
||||||
|
if (data.size.QuadPart == 0)
|
||||||
|
{
|
||||||
|
if (newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
|
||||||
|
{
|
||||||
|
smallblock = SmallBlockChainStream_Construct(This, NULL, index);
|
||||||
|
if (!smallblock) return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bigblock = BlockChainStream_Construct(This, NULL, index);
|
||||||
|
if (!bigblock) return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
|
||||||
|
{
|
||||||
|
smallblock = SmallBlockChainStream_Construct(This, NULL, index);
|
||||||
|
if (!smallblock) return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bigblock = BlockChainStream_Construct(This, NULL, index);
|
||||||
|
if (!bigblock) return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the block chain type if necessary. */
|
||||||
|
if (smallblock && newsize.QuadPart >= LIMIT_TO_USE_SMALL_BLOCK)
|
||||||
|
{
|
||||||
|
bigblock = Storage32Impl_SmallBlocksToBigBlocks(This, &smallblock);
|
||||||
|
if (!bigblock)
|
||||||
|
{
|
||||||
|
SmallBlockChainStream_Destroy(smallblock);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bigblock && newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
|
||||||
|
{
|
||||||
|
smallblock = Storage32Impl_BigBlocksToSmallBlocks(This, &bigblock);
|
||||||
|
if (!smallblock)
|
||||||
|
{
|
||||||
|
BlockChainStream_Destroy(bigblock);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the size of the block chain. */
|
||||||
|
if (smallblock)
|
||||||
|
{
|
||||||
|
SmallBlockChainStream_SetSize(smallblock, newsize);
|
||||||
|
SmallBlockChainStream_Destroy(smallblock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BlockChainStream_SetSize(bigblock, newsize);
|
||||||
|
BlockChainStream_Destroy(bigblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the size in the directory entry. */
|
||||||
|
hr = StorageImpl_ReadDirEntry(This, index, &data);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
data.size = newsize;
|
||||||
|
|
||||||
|
hr = StorageImpl_WriteDirEntry(This, index, &data);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
|
static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index,
|
||||||
ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
|
||||||
{
|
{
|
||||||
|
@ -2325,7 +2412,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl =
|
||||||
StorageImpl_BaseReadDirEntry,
|
StorageImpl_BaseReadDirEntry,
|
||||||
StorageImpl_DestroyDirEntry,
|
StorageImpl_DestroyDirEntry,
|
||||||
StorageImpl_StreamReadAt,
|
StorageImpl_StreamReadAt,
|
||||||
StorageImpl_StreamWriteAt
|
StorageImpl_StreamWriteAt,
|
||||||
|
StorageImpl_StreamSetSize
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT StorageImpl_Construct(
|
static HRESULT StorageImpl_Construct(
|
||||||
|
@ -3787,6 +3875,13 @@ static HRESULT StorageInternalImpl_StreamWriteAt(StorageBaseImpl *base,
|
||||||
index, offset, size, buffer, bytesWritten);
|
index, offset, size, buffer, bytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base,
|
||||||
|
DirRef index, ULARGE_INTEGER newsize)
|
||||||
|
{
|
||||||
|
return StorageBaseImpl_StreamSetSize(&base->ancestorStorage->base,
|
||||||
|
index, newsize);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
**
|
**
|
||||||
** Storage32InternalImpl_Commit
|
** Storage32InternalImpl_Commit
|
||||||
|
@ -4235,7 +4330,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl =
|
||||||
StorageInternalImpl_ReadDirEntry,
|
StorageInternalImpl_ReadDirEntry,
|
||||||
StorageInternalImpl_DestroyDirEntry,
|
StorageInternalImpl_DestroyDirEntry,
|
||||||
StorageInternalImpl_StreamReadAt,
|
StorageInternalImpl_StreamReadAt,
|
||||||
StorageInternalImpl_StreamWriteAt
|
StorageInternalImpl_StreamWriteAt,
|
||||||
|
StorageInternalImpl_StreamSetSize
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -254,6 +254,7 @@ struct StorageBaseImplVtbl {
|
||||||
HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
|
HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
|
||||||
HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
|
HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
|
||||||
HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
|
HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
|
||||||
|
HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
|
static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
|
||||||
|
@ -299,6 +300,12 @@ static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
|
||||||
return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
|
return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This,
|
||||||
|
DirRef index, ULARGE_INTEGER newsize)
|
||||||
|
{
|
||||||
|
return This->baseVtbl->StreamSetSize(This, index, newsize);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* StorageBaseImpl stream list handlers
|
* StorageBaseImpl stream list handlers
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue