mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-09 01:04:07 +00:00
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.
|
||||
*
|
||||
* TODO: Switch from small blocks to big blocks and vice versa.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||
|
@ -626,6 +624,19 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
|
|||
&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)
|
||||
{
|
||||
|
|
|
@ -104,6 +104,7 @@ static ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This);
|
|||
static ULONG BlockChainStream_GetCount(BlockChainStream* This);
|
||||
|
||||
static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This);
|
||||
static ULONG SmallBlockChainStream_GetHeadOfChain(SmallBlockChainStream* This);
|
||||
static BOOL StorageImpl_WriteDWordToBigBlock( StorageImpl* This,
|
||||
ULONG blockIndex, ULONG offset, DWORD value);
|
||||
static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This,
|
||||
|
@ -3627,6 +3628,86 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
|||
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)
|
||||
{
|
||||
StorageInternalImpl* This = (StorageInternalImpl*) iface;
|
||||
|
|
|
@ -306,6 +306,10 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
|||
StorageImpl* This,
|
||||
SmallBlockChainStream** ppsbChain);
|
||||
|
||||
SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks(
|
||||
StorageImpl* This,
|
||||
BlockChainStream** ppbbChain);
|
||||
|
||||
/****************************************************************************
|
||||
* StgStreamImpl definitions.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue