mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 12:17:30 +00:00
[OLE32]
- Sync to Wine-20100918. See issue #5592 for more details. svn path=/trunk/; revision=48795
This commit is contained in:
parent
2cc0f42e45
commit
2c10fb5d07
4 changed files with 224 additions and 50 deletions
|
@ -450,7 +450,9 @@ HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
|
||||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||||
if(FAILED(hr)) return hr;
|
if(FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
unk = NULL;
|
||||||
hr = IDropTarget_QueryInterface(pDropTarget, &IID_IUnknown, (void**)&unk);
|
hr = IDropTarget_QueryInterface(pDropTarget, &IID_IUnknown, (void**)&unk);
|
||||||
|
if (SUCCEEDED(hr) && !unk) hr = E_NOINTERFACE;
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
{
|
{
|
||||||
IStream_Release(stream);
|
IStream_Release(stream);
|
||||||
|
|
|
@ -295,6 +295,9 @@ static HRESULT WINAPI StgStreamImpl_Write(
|
||||||
*/
|
*/
|
||||||
This->currentPosition.u.LowPart += *pcbWritten;
|
This->currentPosition.u.LowPart += *pcbWritten;
|
||||||
|
|
||||||
|
if (SUCCEEDED(res))
|
||||||
|
res = StorageBaseImpl_Flush(This->parentStorage);
|
||||||
|
|
||||||
TRACE("<-- S_OK, written %u\n", *pcbWritten);
|
TRACE("<-- S_OK, written %u\n", *pcbWritten);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -417,6 +420,10 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
|
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = StorageBaseImpl_Flush(This->parentStorage);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -856,7 +856,7 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement(
|
||||||
return STG_E_FILENOTFOUND;
|
return STG_E_FILENOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return StorageBaseImpl_Flush(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -1011,7 +1011,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream(
|
||||||
return STG_E_INSUFFICIENTMEMORY;
|
return STG_E_INSUFFICIENTMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return StorageBaseImpl_Flush(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -1047,6 +1047,9 @@ static HRESULT WINAPI StorageBaseImpl_SetClass(
|
||||||
¤tEntry);
|
¤tEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hRes))
|
||||||
|
hRes = StorageBaseImpl_Flush(This);
|
||||||
|
|
||||||
return hRes;
|
return hRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1203,6 +1206,8 @@ static HRESULT WINAPI StorageBaseImpl_CreateStorage(
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = StorageBaseImpl_Flush(This);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1916,6 +1921,9 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement(
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
StorageBaseImpl_DestroyDirEntry(This, entryToDeleteRef);
|
StorageBaseImpl_DestroyDirEntry(This, entryToDeleteRef);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = StorageBaseImpl_Flush(This);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2849,7 +2857,10 @@ end:
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
StorageImpl_Flush((StorageBaseImpl*)This);
|
||||||
*result = This;
|
*result = This;
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -2888,8 +2899,26 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface)
|
||||||
static HRESULT StorageImpl_Flush(StorageBaseImpl* iface)
|
static HRESULT StorageImpl_Flush(StorageBaseImpl* iface)
|
||||||
{
|
{
|
||||||
StorageImpl *This = (StorageImpl*) iface;
|
StorageImpl *This = (StorageImpl*) iface;
|
||||||
|
int i;
|
||||||
|
HRESULT hr;
|
||||||
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
return ILockBytes_Flush(This->lockBytes);
|
hr = BlockChainStream_Flush(This->smallBlockRootChain);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = BlockChainStream_Flush(This->rootBlockChain);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = BlockChainStream_Flush(This->smallBlockDepotChain);
|
||||||
|
|
||||||
|
for (i=0; SUCCEEDED(hr) && i<BLOCKCHAIN_CACHE_SIZE; i++)
|
||||||
|
if (This->blockChainCache[i])
|
||||||
|
hr = BlockChainStream_Flush(This->blockChainCache[i]);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = ILockBytes_Flush(This->lockBytes);
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -3846,13 +3875,20 @@ static BOOL StorageImpl_ReadBigBlock(
|
||||||
void* buffer)
|
void* buffer)
|
||||||
{
|
{
|
||||||
ULARGE_INTEGER ulOffset;
|
ULARGE_INTEGER ulOffset;
|
||||||
DWORD read;
|
DWORD read=0;
|
||||||
|
|
||||||
ulOffset.u.HighPart = 0;
|
ulOffset.u.HighPart = 0;
|
||||||
ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
|
ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
|
||||||
|
|
||||||
StorageImpl_ReadAt(This, ulOffset, buffer, This->bigBlockSize, &read);
|
StorageImpl_ReadAt(This, ulOffset, buffer, This->bigBlockSize, &read);
|
||||||
return (read == This->bigBlockSize);
|
|
||||||
|
if (read && read < This->bigBlockSize)
|
||||||
|
{
|
||||||
|
/* File ends during this block; fill the rest with 0's. */
|
||||||
|
memset((LPBYTE)buffer+read, 0, This->bigBlockSize-read);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (read != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL StorageImpl_ReadDWordFromBigBlock(
|
static BOOL StorageImpl_ReadDWordFromBigBlock(
|
||||||
|
@ -5812,6 +5848,53 @@ ULONG BlockChainStream_GetSectorOfOffset(BlockChainStream *This, ULONG offset)
|
||||||
return This->indexCache[min_run].firstSector + offset - This->indexCache[min_run].firstOffset;
|
return This->indexCache[min_run].firstSector + offset - This->indexCache[min_run].firstOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT BlockChainStream_GetBlockAtOffset(BlockChainStream *This,
|
||||||
|
ULONG index, BlockChainBlock **block, ULONG *sector, BOOL create)
|
||||||
|
{
|
||||||
|
BlockChainBlock *result=NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
if (This->cachedBlocks[i].index == index)
|
||||||
|
{
|
||||||
|
*sector = This->cachedBlocks[i].sector;
|
||||||
|
*block = &This->cachedBlocks[i];
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sector = BlockChainStream_GetSectorOfOffset(This, index);
|
||||||
|
if (*sector == BLOCK_END_OF_CHAIN)
|
||||||
|
return STG_E_DOCFILECORRUPT;
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
if (This->cachedBlocks[0].index == 0xffffffff)
|
||||||
|
result = &This->cachedBlocks[0];
|
||||||
|
else if (This->cachedBlocks[1].index == 0xffffffff)
|
||||||
|
result = &This->cachedBlocks[1];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = &This->cachedBlocks[This->blockToEvict++];
|
||||||
|
if (This->blockToEvict == 2)
|
||||||
|
This->blockToEvict = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result->dirty)
|
||||||
|
{
|
||||||
|
if (!StorageImpl_WriteBigBlock(This->parentStorage, result->sector, result->data))
|
||||||
|
return STG_E_WRITEFAULT;
|
||||||
|
result->dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->read = 0;
|
||||||
|
result->index = index;
|
||||||
|
result->sector = *sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
*block = result;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
BlockChainStream* BlockChainStream_Construct(
|
BlockChainStream* BlockChainStream_Construct(
|
||||||
StorageImpl* parentStorage,
|
StorageImpl* parentStorage,
|
||||||
ULONG* headOfStreamPlaceHolder,
|
ULONG* headOfStreamPlaceHolder,
|
||||||
|
@ -5827,6 +5910,11 @@ BlockChainStream* BlockChainStream_Construct(
|
||||||
newStream->indexCache = NULL;
|
newStream->indexCache = NULL;
|
||||||
newStream->indexCacheLen = 0;
|
newStream->indexCacheLen = 0;
|
||||||
newStream->indexCacheSize = 0;
|
newStream->indexCacheSize = 0;
|
||||||
|
newStream->cachedBlocks[0].index = 0xffffffff;
|
||||||
|
newStream->cachedBlocks[0].dirty = 0;
|
||||||
|
newStream->cachedBlocks[1].index = 0xffffffff;
|
||||||
|
newStream->cachedBlocks[1].dirty = 0;
|
||||||
|
newStream->blockToEvict = 0;
|
||||||
|
|
||||||
if (FAILED(BlockChainStream_UpdateIndexCache(newStream)))
|
if (FAILED(BlockChainStream_UpdateIndexCache(newStream)))
|
||||||
{
|
{
|
||||||
|
@ -5838,10 +5926,30 @@ BlockChainStream* BlockChainStream_Construct(
|
||||||
return newStream;
|
return newStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT BlockChainStream_Flush(BlockChainStream* This)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (!This) return S_OK;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
if (This->cachedBlocks[i].dirty)
|
||||||
|
{
|
||||||
|
if (StorageImpl_WriteBigBlock(This->parentStorage, This->cachedBlocks[i].sector, This->cachedBlocks[i].data))
|
||||||
|
This->cachedBlocks[i].dirty = 0;
|
||||||
|
else
|
||||||
|
return STG_E_WRITEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void BlockChainStream_Destroy(BlockChainStream* This)
|
void BlockChainStream_Destroy(BlockChainStream* This)
|
||||||
{
|
{
|
||||||
if (This)
|
if (This)
|
||||||
|
{
|
||||||
|
BlockChainStream_Flush(This);
|
||||||
HeapFree(GetProcessHeap(), 0, This->indexCache);
|
HeapFree(GetProcessHeap(), 0, This->indexCache);
|
||||||
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5907,6 +6015,8 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This,
|
||||||
ULONG blockIndex;
|
ULONG blockIndex;
|
||||||
BYTE* bufferWalker;
|
BYTE* bufferWalker;
|
||||||
ULARGE_INTEGER stream_size;
|
ULARGE_INTEGER stream_size;
|
||||||
|
HRESULT hr;
|
||||||
|
BlockChainBlock *cachedBlock;
|
||||||
|
|
||||||
TRACE("(%p)-> %i %p %i %p\n",This, offset.u.LowPart, buffer, size, bytesRead);
|
TRACE("(%p)-> %i %p %i %p\n",This, offset.u.LowPart, buffer, size, bytesRead);
|
||||||
|
|
||||||
|
@ -5928,32 +6038,50 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This,
|
||||||
*/
|
*/
|
||||||
bufferWalker = buffer;
|
bufferWalker = buffer;
|
||||||
|
|
||||||
while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) )
|
while (size > 0)
|
||||||
{
|
{
|
||||||
ULARGE_INTEGER ulOffset;
|
ULARGE_INTEGER ulOffset;
|
||||||
DWORD bytesReadAt;
|
DWORD bytesReadAt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate how many bytes we can copy from this big block.
|
* Calculate how many bytes we can copy from this big block.
|
||||||
*/
|
*/
|
||||||
bytesToReadInBuffer =
|
bytesToReadInBuffer =
|
||||||
min(This->parentStorage->bigBlockSize - offsetInBlock, size);
|
min(This->parentStorage->bigBlockSize - offsetInBlock, size);
|
||||||
|
|
||||||
TRACE("block %i\n",blockIndex);
|
hr = BlockChainStream_GetBlockAtOffset(This, blockNoInSequence, &cachedBlock, &blockIndex, size == bytesToReadInBuffer);
|
||||||
ulOffset.u.HighPart = 0;
|
|
||||||
ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
|
|
||||||
offsetInBlock;
|
|
||||||
|
|
||||||
StorageImpl_ReadAt(This->parentStorage,
|
if (FAILED(hr))
|
||||||
ulOffset,
|
return hr;
|
||||||
bufferWalker,
|
|
||||||
bytesToReadInBuffer,
|
|
||||||
&bytesReadAt);
|
|
||||||
/*
|
|
||||||
* Step to the next big block.
|
|
||||||
*/
|
|
||||||
if( size > bytesReadAt && FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
|
|
||||||
return STG_E_DOCFILECORRUPT;
|
|
||||||
|
|
||||||
|
if (!cachedBlock)
|
||||||
|
{
|
||||||
|
/* Not in cache, and we're going to read past the end of the block. */
|
||||||
|
ulOffset.u.HighPart = 0;
|
||||||
|
ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
|
||||||
|
offsetInBlock;
|
||||||
|
|
||||||
|
StorageImpl_ReadAt(This->parentStorage,
|
||||||
|
ulOffset,
|
||||||
|
bufferWalker,
|
||||||
|
bytesToReadInBuffer,
|
||||||
|
&bytesReadAt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!cachedBlock->read)
|
||||||
|
{
|
||||||
|
if (!StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data))
|
||||||
|
return STG_E_READFAULT;
|
||||||
|
|
||||||
|
cachedBlock->read = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(bufferWalker, cachedBlock->data+offsetInBlock, bytesToReadInBuffer);
|
||||||
|
bytesReadAt = bytesToReadInBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNoInSequence++;
|
||||||
bufferWalker += bytesReadAt;
|
bufferWalker += bytesReadAt;
|
||||||
size -= bytesReadAt;
|
size -= bytesReadAt;
|
||||||
*bytesRead += bytesReadAt;
|
*bytesRead += bytesReadAt;
|
||||||
|
@ -5983,51 +6111,61 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
|
||||||
ULONG bytesToWrite;
|
ULONG bytesToWrite;
|
||||||
ULONG blockIndex;
|
ULONG blockIndex;
|
||||||
const BYTE* bufferWalker;
|
const BYTE* bufferWalker;
|
||||||
|
HRESULT hr;
|
||||||
/*
|
BlockChainBlock *cachedBlock;
|
||||||
* Find the first block in the stream that contains part of the buffer.
|
|
||||||
*/
|
|
||||||
blockIndex = BlockChainStream_GetSectorOfOffset(This, blockNoInSequence);
|
|
||||||
|
|
||||||
/* BlockChainStream_SetSize should have already been called to ensure we have
|
|
||||||
* enough blocks in the chain to write into */
|
|
||||||
if (blockIndex == BLOCK_END_OF_CHAIN)
|
|
||||||
{
|
|
||||||
ERR("not enough blocks in chain to write data\n");
|
|
||||||
return STG_E_DOCFILECORRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
*bytesWritten = 0;
|
*bytesWritten = 0;
|
||||||
bufferWalker = buffer;
|
bufferWalker = buffer;
|
||||||
|
|
||||||
while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) )
|
while (size > 0)
|
||||||
{
|
{
|
||||||
ULARGE_INTEGER ulOffset;
|
ULARGE_INTEGER ulOffset;
|
||||||
DWORD bytesWrittenAt;
|
DWORD bytesWrittenAt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate how many bytes we can copy from this big block.
|
* Calculate how many bytes we can copy to this big block.
|
||||||
*/
|
*/
|
||||||
bytesToWrite =
|
bytesToWrite =
|
||||||
min(This->parentStorage->bigBlockSize - offsetInBlock, size);
|
min(This->parentStorage->bigBlockSize - offsetInBlock, size);
|
||||||
|
|
||||||
TRACE("block %i\n",blockIndex);
|
hr = BlockChainStream_GetBlockAtOffset(This, blockNoInSequence, &cachedBlock, &blockIndex, size == bytesToWrite);
|
||||||
ulOffset.u.HighPart = 0;
|
|
||||||
ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
|
|
||||||
offsetInBlock;
|
|
||||||
|
|
||||||
StorageImpl_WriteAt(This->parentStorage,
|
/* BlockChainStream_SetSize should have already been called to ensure we have
|
||||||
ulOffset,
|
* enough blocks in the chain to write into */
|
||||||
bufferWalker,
|
if (FAILED(hr))
|
||||||
bytesToWrite,
|
{
|
||||||
&bytesWrittenAt);
|
ERR("not enough blocks in chain to write data\n");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
if (!cachedBlock)
|
||||||
* Step to the next big block.
|
{
|
||||||
*/
|
/* Not in cache, and we're going to write past the end of the block. */
|
||||||
if(size > bytesWrittenAt && FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
|
ulOffset.u.HighPart = 0;
|
||||||
&blockIndex)))
|
ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This->parentStorage, blockIndex) +
|
||||||
return STG_E_DOCFILECORRUPT;
|
offsetInBlock;
|
||||||
|
|
||||||
|
StorageImpl_WriteAt(This->parentStorage,
|
||||||
|
ulOffset,
|
||||||
|
bufferWalker,
|
||||||
|
bytesToWrite,
|
||||||
|
&bytesWrittenAt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!cachedBlock->read && bytesToWrite != This->parentStorage->bigBlockSize)
|
||||||
|
{
|
||||||
|
if (!StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data))
|
||||||
|
return STG_E_READFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(cachedBlock->data+offsetInBlock, bufferWalker, bytesToWrite);
|
||||||
|
bytesWrittenAt = bytesToWrite;
|
||||||
|
cachedBlock->read = 1;
|
||||||
|
cachedBlock->dirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNoInSequence++;
|
||||||
bufferWalker += bytesWrittenAt;
|
bufferWalker += bytesWrittenAt;
|
||||||
size -= bytesWrittenAt;
|
size -= bytesWrittenAt;
|
||||||
*bytesWritten += bytesWrittenAt;
|
*bytesWritten += bytesWrittenAt;
|
||||||
|
@ -6050,6 +6188,7 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This,
|
||||||
{
|
{
|
||||||
ULONG blockIndex;
|
ULONG blockIndex;
|
||||||
ULONG numBlocks;
|
ULONG numBlocks;
|
||||||
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out how many blocks are needed to contain the new size
|
* Figure out how many blocks are needed to contain the new size
|
||||||
|
@ -6117,6 +6256,18 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This,
|
||||||
last_run->lastOffset--;
|
last_run->lastOffset--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the last accessed block cache.
|
||||||
|
*/
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
if (This->cachedBlocks[i].index >= numBlocks)
|
||||||
|
{
|
||||||
|
This->cachedBlocks[i].index = 0xffffffff;
|
||||||
|
This->cachedBlocks[i].dirty = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -512,6 +512,15 @@ struct BlockChainRun
|
||||||
ULONG lastOffset;
|
ULONG lastOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct BlockChainBlock
|
||||||
|
{
|
||||||
|
ULONG index;
|
||||||
|
ULONG sector;
|
||||||
|
int read;
|
||||||
|
int dirty;
|
||||||
|
BYTE data[MAX_BIG_BLOCK_SIZE];
|
||||||
|
} BlockChainBlock;
|
||||||
|
|
||||||
struct BlockChainStream
|
struct BlockChainStream
|
||||||
{
|
{
|
||||||
StorageImpl* parentStorage;
|
StorageImpl* parentStorage;
|
||||||
|
@ -520,6 +529,8 @@ struct BlockChainStream
|
||||||
struct BlockChainRun* indexCache;
|
struct BlockChainRun* indexCache;
|
||||||
ULONG indexCacheLen;
|
ULONG indexCacheLen;
|
||||||
ULONG indexCacheSize;
|
ULONG indexCacheSize;
|
||||||
|
BlockChainBlock cachedBlocks[2];
|
||||||
|
ULONG blockToEvict;
|
||||||
ULONG tailIndex;
|
ULONG tailIndex;
|
||||||
ULONG numBlocks;
|
ULONG numBlocks;
|
||||||
};
|
};
|
||||||
|
@ -553,6 +564,9 @@ BOOL BlockChainStream_SetSize(
|
||||||
BlockChainStream* This,
|
BlockChainStream* This,
|
||||||
ULARGE_INTEGER newSize);
|
ULARGE_INTEGER newSize);
|
||||||
|
|
||||||
|
HRESULT BlockChainStream_Flush(
|
||||||
|
BlockChainStream* This);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* SmallBlockChainStream definitions.
|
* SmallBlockChainStream definitions.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue