ole32: Add big block chain to small block chain conversion routine.
This commit is contained in:
parent
972e4a22f8
commit
85a5867308
|
@ -537,8 +537,6 @@ static HRESULT WINAPI StgStreamImpl_Seek(
|
||||||
*
|
*
|
||||||
* It will change the size of a stream.
|
* It will change the size of a stream.
|
||||||
*
|
*
|
||||||
* TODO: Switch from small blocks to big blocks and vice versa.
|
|
||||||
*
|
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
static HRESULT WINAPI StgStreamImpl_SetSize(
|
static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||||
|
@ -626,6 +624,19 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||||
&This->smallBlockChain);
|
&This->smallBlockChain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( (This->bigBlockChain!=0) &&
|
||||||
|
(curProperty.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)
|
if (This->smallBlockChain!=0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,6 +104,7 @@ static ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This);
|
||||||
static ULONG BlockChainStream_GetCount(BlockChainStream* This);
|
static ULONG BlockChainStream_GetCount(BlockChainStream* This);
|
||||||
|
|
||||||
static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This);
|
static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This);
|
||||||
|
static ULONG SmallBlockChainStream_GetHeadOfChain(SmallBlockChainStream* This);
|
||||||
static BOOL StorageImpl_WriteDWordToBigBlock( StorageImpl* This,
|
static BOOL StorageImpl_WriteDWordToBigBlock( StorageImpl* This,
|
||||||
ULONG blockIndex, ULONG offset, DWORD value);
|
ULONG blockIndex, ULONG offset, DWORD value);
|
||||||
static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This,
|
static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This,
|
||||||
|
@ -3627,6 +3628,86 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||||
return bigBlockChain;
|
return bigBlockChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Storage32Impl_BigBlocksToSmallBlocks
|
||||||
|
*
|
||||||
|
* This method will convert a big block chain to a small block chain.
|
||||||
|
* The big block chain will be destroyed on success.
|
||||||
|
*/
|
||||||
|
SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks(
|
||||||
|
StorageImpl* This,
|
||||||
|
BlockChainStream** ppbbChain)
|
||||||
|
{
|
||||||
|
ULARGE_INTEGER size, offset, cbTotalRead;
|
||||||
|
ULONG cbRead, cbWritten, propertyIndex, sbHeadOfChain = BLOCK_END_OF_CHAIN;
|
||||||
|
HRESULT resWrite = S_OK, resRead;
|
||||||
|
StgProperty chainProperty;
|
||||||
|
BYTE* buffer;
|
||||||
|
SmallBlockChainStream* sbTempChain;
|
||||||
|
|
||||||
|
TRACE("%p %p\n", This, ppbbChain);
|
||||||
|
|
||||||
|
sbTempChain = SmallBlockChainStream_Construct(This, &sbHeadOfChain,
|
||||||
|
PROPERTY_NULL);
|
||||||
|
|
||||||
|
if(!sbTempChain)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
size = BlockChainStream_GetSize(*ppbbChain);
|
||||||
|
SmallBlockChainStream_SetSize(sbTempChain, size);
|
||||||
|
|
||||||
|
offset.u.HighPart = 0;
|
||||||
|
offset.u.LowPart = 0;
|
||||||
|
cbTotalRead.QuadPart = 0;
|
||||||
|
buffer = HeapAlloc(GetProcessHeap(), 0, This->bigBlockSize);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
resRead = BlockChainStream_ReadAt(*ppbbChain, offset,
|
||||||
|
This->bigBlockSize, buffer, &cbRead);
|
||||||
|
|
||||||
|
if(FAILED(resRead))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(cbRead > 0)
|
||||||
|
{
|
||||||
|
cbTotalRead.QuadPart += cbRead;
|
||||||
|
|
||||||
|
resWrite = SmallBlockChainStream_WriteAt(sbTempChain, offset,
|
||||||
|
cbRead, buffer, &cbWritten);
|
||||||
|
|
||||||
|
if(FAILED(resWrite))
|
||||||
|
break;
|
||||||
|
|
||||||
|
offset.u.LowPart += This->bigBlockSize;
|
||||||
|
}
|
||||||
|
}while(cbTotalRead.QuadPart < size.QuadPart);
|
||||||
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
|
|
||||||
|
size.u.HighPart = 0;
|
||||||
|
size.u.LowPart = 0;
|
||||||
|
|
||||||
|
if(FAILED(resRead) || FAILED(resWrite))
|
||||||
|
{
|
||||||
|
ERR("conversion failed: resRead = 0x%08x, resWrite = 0x%08x\n", resRead, resWrite);
|
||||||
|
SmallBlockChainStream_SetSize(sbTempChain, size);
|
||||||
|
SmallBlockChainStream_Destroy(sbTempChain);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destroy the original big block chain */
|
||||||
|
propertyIndex = (*ppbbChain)->ownerPropertyIndex;
|
||||||
|
BlockChainStream_SetSize(*ppbbChain, size);
|
||||||
|
BlockChainStream_Destroy(*ppbbChain);
|
||||||
|
*ppbbChain = NULL;
|
||||||
|
|
||||||
|
StorageImpl_ReadProperty(This, propertyIndex, &chainProperty);
|
||||||
|
chainProperty.startingBlock = sbHeadOfChain;
|
||||||
|
StorageImpl_WriteProperty(This, propertyIndex, &chainProperty);
|
||||||
|
|
||||||
|
SmallBlockChainStream_Destroy(sbTempChain);
|
||||||
|
return SmallBlockChainStream_Construct(This, NULL, propertyIndex);
|
||||||
|
}
|
||||||
|
|
||||||
static void StorageInternalImpl_Destroy( StorageBaseImpl *iface)
|
static void StorageInternalImpl_Destroy( StorageBaseImpl *iface)
|
||||||
{
|
{
|
||||||
StorageInternalImpl* This = (StorageInternalImpl*) iface;
|
StorageInternalImpl* This = (StorageInternalImpl*) iface;
|
||||||
|
|
|
@ -306,6 +306,10 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||||
StorageImpl* This,
|
StorageImpl* This,
|
||||||
SmallBlockChainStream** ppsbChain);
|
SmallBlockChainStream** ppsbChain);
|
||||||
|
|
||||||
|
SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks(
|
||||||
|
StorageImpl* This,
|
||||||
|
BlockChainStream** ppbbChain);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* StgStreamImpl definitions.
|
* StgStreamImpl definitions.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue