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
fc50ff07
Commit
fc50ff07
authored
Dec 18, 2009
by
Vincent Povirk
Committed by
Alexandre Julliard
Dec 21, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Store the most recent item name in IEnumSTATSTG instead of a stack.
parent
44928502
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
187 deletions
+71
-187
storage32.c
dlls/ole32/storage32.c
+66
-180
storage32.c
dlls/ole32/tests/storage32.c
+5
-7
No files found.
dlls/ole32/storage32.c
View file @
fc50ff07
...
...
@@ -258,23 +258,12 @@ struct IEnumSTATSTGImpl
StorageBaseImpl
*
parentStorage
;
/* Reference to the parent storage */
DirRef
storageDirEntry
;
/* Directory entry of the storage to enumerate */
/*
* The current implementation of the IEnumSTATSTGImpl class uses a stack
* to walk the directory entries to get the content of a storage. This stack
* is implemented by the following 3 data members
*/
ULONG
stackSize
;
ULONG
stackMaxSize
;
DirRef
*
stackToVisit
;
#define ENUMSTATSGT_SIZE_INCREMENT 10
WCHAR
name
[
DIRENTRY_NAME_MAX_LEN
];
/* The most recent name visited */
};
static
IEnumSTATSTGImpl
*
IEnumSTATSTGImpl_Construct
(
StorageBaseImpl
*
This
,
DirRef
storageDirEntry
);
static
void
IEnumSTATSTGImpl_Destroy
(
IEnumSTATSTGImpl
*
This
);
static
void
IEnumSTATSTGImpl_PushSearchNode
(
IEnumSTATSTGImpl
*
This
,
DirRef
nodeToPush
);
static
DirRef
IEnumSTATSTGImpl_PopSearchNode
(
IEnumSTATSTGImpl
*
This
,
BOOL
remove
);
/************************************************************************
** Block Functions
...
...
@@ -4446,7 +4435,6 @@ static HRESULT WINAPI StorageInternalImpl_Revert(
static
void
IEnumSTATSTGImpl_Destroy
(
IEnumSTATSTGImpl
*
This
)
{
IStorage_Release
((
IStorage
*
)
This
->
parentStorage
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
stackToVisit
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
...
...
@@ -4497,6 +4485,51 @@ static ULONG WINAPI IEnumSTATSTGImpl_Release(
return
newRef
;
}
static
HRESULT
IEnumSTATSTGImpl_GetNextRef
(
IEnumSTATSTGImpl
*
This
,
DirRef
*
ref
)
{
DirRef
result
=
DIRENTRY_NULL
;
DirRef
searchNode
;
DirEntry
entry
;
HRESULT
hr
;
WCHAR
result_name
[
DIRENTRY_NAME_MAX_LEN
];
hr
=
StorageBaseImpl_ReadDirEntry
(
This
->
parentStorage
,
This
->
parentStorage
->
storageDirEntry
,
&
entry
);
searchNode
=
entry
.
dirRootEntry
;
while
(
SUCCEEDED
(
hr
)
&&
searchNode
!=
DIRENTRY_NULL
)
{
hr
=
StorageBaseImpl_ReadDirEntry
(
This
->
parentStorage
,
searchNode
,
&
entry
);
if
(
SUCCEEDED
(
hr
))
{
LONG
diff
=
entryNameCmp
(
entry
.
name
,
This
->
name
);
if
(
diff
<=
0
)
{
searchNode
=
entry
.
rightChild
;
}
else
{
result
=
searchNode
;
memcpy
(
result_name
,
entry
.
name
,
sizeof
(
result_name
));
searchNode
=
entry
.
leftChild
;
}
}
}
if
(
SUCCEEDED
(
hr
))
{
*
ref
=
result
;
if
(
result
!=
DIRENTRY_NULL
)
memcpy
(
This
->
name
,
result_name
,
sizeof
(
result_name
));
}
return
hr
;
}
static
HRESULT
WINAPI
IEnumSTATSTGImpl_Next
(
IEnumSTATSTG
*
iface
,
ULONG
celt
,
...
...
@@ -4509,6 +4542,7 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next(
STATSTG
*
currentReturnStruct
=
rgelt
;
ULONG
objectFetched
=
0
;
DirRef
currentSearchNode
;
HRESULT
hr
=
S_OK
;
if
(
(
rgelt
==
0
)
||
(
(
celt
!=
1
)
&&
(
pceltFetched
==
0
)
)
)
return
E_INVALIDARG
;
...
...
@@ -4529,18 +4563,12 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next(
*/
*
pceltFetched
=
0
;
/*
* Start with the node at the top of the stack.
*/
currentSearchNode
=
IEnumSTATSTGImpl_PopSearchNode
(
This
,
FALSE
);
while
(
(
*
pceltFetched
<
celt
)
&&
(
currentSearchNode
!=
DIRENTRY_NULL
)
)
while
(
*
pceltFetched
<
celt
)
{
/*
* Remove the top node from the stack
*/
IEnumSTATSTGImpl_PopSearchNode
(
This
,
TRUE
)
;
hr
=
IEnumSTATSTGImpl_GetNextRef
(
This
,
&
currentSearchNode
);
if
(
FAILED
(
hr
)
||
currentSearchNode
==
DIRENTRY_NULL
)
break
;
/*
* Read the entry from the storage.
...
...
@@ -4562,22 +4590,12 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next(
*/
(
*
pceltFetched
)
++
;
currentReturnStruct
++
;
/*
* Push the next search node in the search stack.
*/
IEnumSTATSTGImpl_PushSearchNode
(
This
,
currentEntry
.
rightChild
);
/*
* continue the iteration.
*/
currentSearchNode
=
IEnumSTATSTGImpl_PopSearchNode
(
This
,
FALSE
);
}
if
(
*
pceltFetched
=
=
celt
)
return
S_OK
;
if
(
SUCCEEDED
(
hr
)
&&
*
pceltFetched
!
=
celt
)
hr
=
S_FALSE
;
return
S_FALSE
;
return
hr
;
}
...
...
@@ -4587,53 +4605,27 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Skip(
{
IEnumSTATSTGImpl
*
const
This
=
(
IEnumSTATSTGImpl
*
)
iface
;
DirEntry
currentEntry
;
ULONG
objectFetched
=
0
;
DirRef
currentSearchNode
;
HRESULT
hr
=
S_OK
;
if
(
This
->
parentStorage
->
reverted
)
return
STG_E_REVERTED
;
/*
* Start with the node at the top of the stack.
*/
currentSearchNode
=
IEnumSTATSTGImpl_PopSearchNode
(
This
,
FALSE
);
while
(
(
objectFetched
<
celt
)
&&
(
currentSearchNode
!=
DIRENTRY_NULL
)
)
while
(
(
objectFetched
<
celt
)
)
{
/*
* Remove the top node from the stack
*/
IEnumSTATSTGImpl_PopSearchNode
(
This
,
TRUE
);
hr
=
IEnumSTATSTGImpl_GetNextRef
(
This
,
&
currentSearchNode
);
/*
* Read the entry from the storage.
*/
StorageBaseImpl_ReadDirEntry
(
This
->
parentStorage
,
currentSearchNode
,
&
currentEntry
);
if
(
FAILED
(
hr
)
||
currentSearchNode
==
DIRENTRY_NULL
)
break
;
/*
* Step to the next item in the iteration
*/
objectFetched
++
;
/*
* Push the next search node in the search stack.
*/
IEnumSTATSTGImpl_PushSearchNode
(
This
,
currentEntry
.
rightChild
);
/*
* continue the iteration.
*/
currentSearchNode
=
IEnumSTATSTGImpl_PopSearchNode
(
This
,
FALSE
);
}
if
(
objectFetched
=
=
celt
)
return
S_
OK
;
if
(
SUCCEEDED
(
hr
)
&&
objectFetched
!
=
celt
)
return
S_
FALSE
;
return
S_FALSE
;
return
hr
;
}
static
HRESULT
WINAPI
IEnumSTATSTGImpl_Reset
(
...
...
@@ -4641,36 +4633,12 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Reset(
{
IEnumSTATSTGImpl
*
const
This
=
(
IEnumSTATSTGImpl
*
)
iface
;
DirEntry
storageEntry
;
HRESULT
hr
;
if
(
This
->
parentStorage
->
reverted
)
return
STG_E_REVERTED
;
/*
* Re-initialize the search stack to an empty stack
*/
This
->
stackSize
=
0
;
/*
* Read the storage entry from the top-level storage.
*/
hr
=
StorageBaseImpl_ReadDirEntry
(
This
->
parentStorage
,
This
->
storageDirEntry
,
&
storageEntry
);
This
->
name
[
0
]
=
0
;
if
(
SUCCEEDED
(
hr
))
{
assert
(
storageEntry
.
sizeOfNameString
!=
0
);
/*
* Push the search node in the search stack.
*/
IEnumSTATSTGImpl_PushSearchNode
(
This
,
storageEntry
.
dirRootEntry
);
}
return
hr
;
return
S_OK
;
}
static
HRESULT
WINAPI
IEnumSTATSTGImpl_Clone
(
...
...
@@ -4698,15 +4666,7 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Clone(
* The new clone enumeration must point to the same current node as
* the ole one.
*/
newClone
->
stackSize
=
This
->
stackSize
;
newClone
->
stackMaxSize
=
This
->
stackMaxSize
;
newClone
->
stackToVisit
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
ULONG
)
*
newClone
->
stackMaxSize
);
memcpy
(
newClone
->
stackToVisit
,
This
->
stackToVisit
,
sizeof
(
DirRef
)
*
newClone
->
stackSize
);
memcpy
(
newClone
->
name
,
This
->
name
,
sizeof
(
newClone
->
name
));
*
ppenum
=
(
IEnumSTATSTG
*
)
newClone
;
...
...
@@ -4719,72 +4679,6 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Clone(
return
S_OK
;
}
static
void
IEnumSTATSTGImpl_PushSearchNode
(
IEnumSTATSTGImpl
*
This
,
DirRef
nodeToPush
)
{
DirEntry
storageEntry
;
HRESULT
hr
;
/*
* First, make sure we're not trying to push an unexisting node.
*/
if
(
nodeToPush
==
DIRENTRY_NULL
)
return
;
/*
* First push the node to the stack
*/
if
(
This
->
stackSize
==
This
->
stackMaxSize
)
{
This
->
stackMaxSize
+=
ENUMSTATSGT_SIZE_INCREMENT
;
This
->
stackToVisit
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
This
->
stackToVisit
,
sizeof
(
DirRef
)
*
This
->
stackMaxSize
);
}
This
->
stackToVisit
[
This
->
stackSize
]
=
nodeToPush
;
This
->
stackSize
++
;
/*
* Read the storage entry from the top-level storage.
*/
hr
=
StorageBaseImpl_ReadDirEntry
(
This
->
parentStorage
,
nodeToPush
,
&
storageEntry
);
if
(
SUCCEEDED
(
hr
))
{
assert
(
storageEntry
.
sizeOfNameString
!=
0
);
/*
* Push the previous search node in the search stack.
*/
IEnumSTATSTGImpl_PushSearchNode
(
This
,
storageEntry
.
leftChild
);
}
}
static
DirRef
IEnumSTATSTGImpl_PopSearchNode
(
IEnumSTATSTGImpl
*
This
,
BOOL
remove
)
{
DirRef
topNode
;
if
(
This
->
stackSize
==
0
)
return
DIRENTRY_NULL
;
topNode
=
This
->
stackToVisit
[
This
->
stackSize
-
1
];
if
(
remove
)
This
->
stackSize
--
;
return
topNode
;
}
/*
* Virtual function table for the IEnumSTATSTGImpl class.
*/
...
...
@@ -4829,14 +4723,6 @@ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
newEnumeration
->
storageDirEntry
=
storageDirEntry
;
/*
* Initialize the search stack
*/
newEnumeration
->
stackSize
=
0
;
newEnumeration
->
stackMaxSize
=
ENUMSTATSGT_SIZE_INCREMENT
;
newEnumeration
->
stackToVisit
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DirRef
)
*
ENUMSTATSGT_SIZE_INCREMENT
);
/*
* Make sure the current node of the iterator is the first one.
*/
IEnumSTATSTGImpl_Reset
((
IEnumSTATSTG
*
)
newEnumeration
);
...
...
dlls/ole32/tests/storage32.c
View file @
fc50ff07
...
...
@@ -891,12 +891,10 @@ static void test_streamenum(void)
r
=
IStorage_DestroyElement
(
stg
,
stmname
);
ok
(
r
==
S_OK
,
"IStorage->DestroyElement failed
\n
"
);
todo_wine
{
count
=
0xf00
;
r
=
IEnumSTATSTG_Next
(
ee
,
1
,
&
stat
,
&
count
);
ok
(
r
==
S_FALSE
,
"IEnumSTATSTG->Next failed
\n
"
);
ok
(
count
==
0
,
"count wrong
\n
"
);
}
/* reset and try again */
r
=
IEnumSTATSTG_Reset
(
ee
);
...
...
@@ -918,8 +916,8 @@ static void test_streamenum(void)
count
=
0xf00
;
r
=
IEnumSTATSTG_Next
(
ee
,
1
,
&
stat
,
&
count
);
todo_wine
ok
(
r
==
S_OK
,
"IEnumSTATSTG->Next failed
\n
"
);
todo_wine
ok
(
count
==
1
,
"count wrong
\n
"
);
ok
(
r
==
S_OK
,
"IEnumSTATSTG->Next failed
\n
"
);
ok
(
count
==
1
,
"count wrong
\n
"
);
if
(
r
==
S_OK
)
{
...
...
@@ -934,8 +932,8 @@ static void test_streamenum(void)
count
=
0xf00
;
r
=
IEnumSTATSTG_Next
(
ee
,
1
,
&
stat
,
&
count
);
todo_wine
ok
(
r
==
S_OK
,
"IEnumSTATSTG->Next failed
\n
"
);
todo_wine
ok
(
count
==
1
,
"count wrong
\n
"
);
ok
(
r
==
S_OK
,
"IEnumSTATSTG->Next failed
\n
"
);
ok
(
count
==
1
,
"count wrong
\n
"
);
if
(
r
==
S_OK
)
{
...
...
@@ -976,7 +974,7 @@ static void test_streamenum(void)
if
(
r
==
S_OK
)
{
todo_wine
ok
(
lstrcmpiW
(
stat
.
pwcsName
,
stmname3
)
==
0
,
"expected ABCDEFGHIJ, got %s
\n
"
,
wine_dbgstr_w
(
stat
.
pwcsName
));
ok
(
lstrcmpiW
(
stat
.
pwcsName
,
stmname3
)
==
0
,
"expected ABCDEFGHIJ, got %s
\n
"
,
wine_dbgstr_w
(
stat
.
pwcsName
));
CoTaskMemFree
(
stat
.
pwcsName
);
}
...
...
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