From e4f309eda9346fcdc574f24655f037c32c62556b Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 19 Apr 2010 16:07:09 -0500 Subject: [PATCH 1/4] ole32: Cache all extended big block depot locations. --- dlls/ole32/storage32.c | 78 ++++++++++++++++++++++++++++++++++++----------- dlls/ole32/storage32.h | 2 + 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 5c58201..311f2ae 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2768,6 +2768,40 @@ static HRESULT StorageImpl_Construct( This->firstFreeSmallBlock = 0; + /* Read the extended big block depot locations. */ + if (This->extBigBlockDepotCount != 0) + { + ULONG current_block = This->extBigBlockDepotStart; + ULONG cache_size = This->extBigBlockDepotCount * 2; + int i; + + This->extBigBlockDepotLocations = HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * cache_size); + if (!This->extBigBlockDepotLocations) + { + hr = E_OUTOFMEMORY; + goto end; + } + + This->extBigBlockDepotLocationsSize = cache_size; + + for (i=0; iextBigBlockDepotCount; i++) + { + if (current_block == BLOCK_END_OF_CHAIN) + { + WARN("File has too few extended big block depot blocks.\n"); + hr = STG_E_DOCFILECORRUPT; + goto end; + } + This->extBigBlockDepotLocations[i] = current_block; + current_block = Storage32Impl_GetNextExtendedBlock(This, current_block); + } + } + else + { + This->extBigBlockDepotLocations = NULL; + This->extBigBlockDepotLocationsSize = 0; + } + /* * Create the block chain abstractions. */ @@ -2884,6 +2918,8 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface) StorageImpl_Invalidate(iface); + HeapFree(GetProcessHeap(), 0, This->extBigBlockDepotLocations); + BlockChainStream_Destroy(This->smallBlockRootChain); BlockChainStream_Destroy(This->rootBlockChain); BlockChainStream_Destroy(This->smallBlockDepotChain); @@ -3097,18 +3133,14 @@ static ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This, ULONG depotIndex) ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock; ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock; ULONG blockIndex = BLOCK_UNUSED; - ULONG extBlockIndex = This->extBigBlockDepotStart; + ULONG extBlockIndex; assert(depotIndex >= COUNT_BBDEPOTINHEADER); - if (This->extBigBlockDepotStart == BLOCK_END_OF_CHAIN) + if (extBlockCount >= This->extBigBlockDepotCount) return BLOCK_UNUSED; - while (extBlockCount > 0) - { - extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex); - extBlockCount--; - } + extBlockIndex = This->extBigBlockDepotLocations[extBlockCount]; if (extBlockIndex != BLOCK_UNUSED) StorageImpl_ReadDWordFromBigBlock(This, extBlockIndex, @@ -3130,15 +3162,13 @@ static void Storage32Impl_SetExtDepotBlock(StorageImpl* This, ULONG depotIndex, ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER; ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock; ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock; - ULONG extBlockIndex = This->extBigBlockDepotStart; + ULONG extBlockIndex; assert(depotIndex >= COUNT_BBDEPOTINHEADER); - while (extBlockCount > 0) - { - extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex); - extBlockCount--; - } + assert(extBlockCount < This->extBigBlockDepotCount); + + extBlockIndex = This->extBigBlockDepotLocations[extBlockCount]; if (extBlockIndex != BLOCK_UNUSED) { @@ -3175,14 +3205,10 @@ static ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This) } else { - unsigned int i; /* - * Follow the chain to the last one. + * Find the last existing extended block. */ - for (i = 0; i < (numExtBlocks - 1); i++) - { - nextExtBlock = Storage32Impl_GetNextExtendedBlock(This, nextExtBlock); - } + nextExtBlock = This->extBigBlockDepotLocations[This->extBigBlockDepotCount-1]; /* * Add the new extended block to the chain. @@ -3197,6 +3223,20 @@ static ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This) memset(depotBuffer, BLOCK_UNUSED, This->bigBlockSize); StorageImpl_WriteBigBlock(This, index, depotBuffer); + /* Add the block to our cache. */ + if (This->extBigBlockDepotLocationsSize == numExtBlocks) + { + ULONG new_cache_size = (This->extBigBlockDepotLocationsSize+1)*2; + ULONG *new_cache = HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * new_cache_size); + + memcpy(new_cache, This->extBigBlockDepotLocations, sizeof(ULONG) * This->extBigBlockDepotLocationsSize); + HeapFree(GetProcessHeap(), 0, This->extBigBlockDepotLocations); + + This->extBigBlockDepotLocations = new_cache; + This->extBigBlockDepotLocationsSize = new_cache_size; + } + This->extBigBlockDepotLocations[numExtBlocks] = index; + return index; } diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 36d0e2f..72a5fe7 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -353,6 +353,8 @@ struct StorageImpl ULONG smallBlockLimit; ULONG smallBlockDepotStart; ULONG extBigBlockDepotStart; + ULONG *extBigBlockDepotLocations; + ULONG extBigBlockDepotLocationsSize; ULONG extBigBlockDepotCount; ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER]; -- 1.7.1