Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
89646084
Commit
89646084
authored
Apr 16, 2010
by
Vincent Povirk
Committed by
Alexandre Julliard
Aug 26, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Cache data and block locations in BigBlockStream objects.
parent
101de22a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
196 additions
and
46 deletions
+196
-46
storage32.c
dlls/ole32/storage32.c
+182
-46
storage32.h
dlls/ole32/storage32.h
+14
-0
No files found.
dlls/ole32/storage32.c
View file @
89646084
...
@@ -2857,7 +2857,10 @@ end:
...
@@ -2857,7 +2857,10 @@ end:
*
result
=
NULL
;
*
result
=
NULL
;
}
}
else
else
{
StorageImpl_Flush
((
StorageBaseImpl
*
)
This
);
*
result
=
This
;
*
result
=
This
;
}
return
hr
;
return
hr
;
}
}
...
@@ -2896,8 +2899,26 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface)
...
@@ -2896,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
);
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
]);
return
ILockBytes_Flush
(
This
->
lockBytes
);
if
(
SUCCEEDED
(
hr
))
hr
=
ILockBytes_Flush
(
This
->
lockBytes
);
return
hr
;
}
}
/******************************************************************************
/******************************************************************************
...
@@ -5820,6 +5841,53 @@ ULONG BlockChainStream_GetSectorOfOffset(BlockChainStream *This, ULONG offset)
...
@@ -5820,6 +5841,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
,
...
@@ -5835,6 +5903,11 @@ BlockChainStream* BlockChainStream_Construct(
...
@@ -5835,6 +5903,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
)))
{
{
...
@@ -5846,10 +5919,30 @@ BlockChainStream* BlockChainStream_Construct(
...
@@ -5846,10 +5919,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
);
}
}
...
@@ -5915,6 +6008,8 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This,
...
@@ -5915,6 +6008,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
);
...
@@ -5936,32 +6031,50 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This,
...
@@ -5936,32 +6031,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
,
if
(
!
cachedBlock
)
&
bytesReadAt
);
{
/*
/* Not in cache, and we're going to read past the end of the block. */
* Step to the next big block.
ulOffset
.
u
.
HighPart
=
0
;
*/
ulOffset
.
u
.
LowPart
=
StorageImpl_GetBigBlockOffset
(
This
->
parentStorage
,
blockIndex
)
+
if
(
size
>
bytesReadAt
&&
FAILED
(
StorageImpl_GetNextBlockInChain
(
This
->
parentStorage
,
blockIndex
,
&
blockIndex
)))
offsetInBlock
;
return
STG_E_DOCFILECORRUPT
;
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
;
...
@@ -5991,51 +6104,61 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
...
@@ -5991,51 +6104,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
;
...
@@ -6058,6 +6181,7 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This,
...
@@ -6058,6 +6181,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
...
@@ -6125,6 +6249,18 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This,
...
@@ -6125,6 +6249,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
;
}
}
...
...
dlls/ole32/storage32.h
View file @
89646084
...
@@ -512,6 +512,15 @@ struct BlockChainRun
...
@@ -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
...
@@ -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(
...
@@ -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.
*
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment