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
d016dc40
Commit
d016dc40
authored
Jul 31, 2014
by
David Hedberg
Committed by
Alexandre Julliard
Aug 05, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Implement IEnumShellItems for IShellItemArray.
parent
e6cb2dba
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
327 additions
and
2 deletions
+327
-2
shellitem.c
dlls/shell32/shellitem.c
+172
-2
shlfolder.c
dlls/shell32/tests/shlfolder.c
+155
-0
No files found.
dlls/shell32/shellitem.c
View file @
d016dc40
...
...
@@ -770,6 +770,173 @@ HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv)
}
/*************************************************************************
* IEnumShellItems implementation
*/
typedef
struct
{
IEnumShellItems
IEnumShellItems_iface
;
LONG
ref
;
IShellItemArray
*
array
;
DWORD
count
;
DWORD
position
;
}
IEnumShellItemsImpl
;
static
inline
IEnumShellItemsImpl
*
impl_from_IEnumShellItems
(
IEnumShellItems
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
IEnumShellItemsImpl
,
IEnumShellItems_iface
);
}
static
HRESULT
WINAPI
IEnumShellItems_fnQueryInterface
(
IEnumShellItems
*
iface
,
REFIID
riid
,
void
**
ppvObject
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
TRACE
(
"%p (%s, %p)
\n
"
,
This
,
shdebugstr_guid
(
riid
),
ppvObject
);
*
ppvObject
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IEnumShellItems
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
ppvObject
=
&
This
->
IEnumShellItems_iface
;
}
if
(
*
ppvObject
)
{
IUnknown_AddRef
((
IUnknown
*
)
*
ppvObject
);
return
S_OK
;
}
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
IEnumShellItems_fnAddRef
(
IEnumShellItems
*
iface
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
LONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"%p - ref %d
\n
"
,
This
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
IEnumShellItems_fnRelease
(
IEnumShellItems
*
iface
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
LONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"%p - ref %d
\n
"
,
This
,
ref
);
if
(
!
ref
)
{
TRACE
(
"Freeing.
\n
"
);
IShellItemArray_Release
(
This
->
array
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
return
0
;
}
return
ref
;
}
static
HRESULT
WINAPI
IEnumShellItems_fnNext
(
IEnumShellItems
*
iface
,
ULONG
celt
,
IShellItem
**
rgelt
,
ULONG
*
pceltFetched
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
HRESULT
hr
=
S_FALSE
;
UINT
i
;
ULONG
fetched
=
0
;
TRACE
(
"%p (%d %p %p)
\n
"
,
This
,
celt
,
rgelt
,
pceltFetched
);
if
(
pceltFetched
==
NULL
&&
celt
!=
1
)
return
E_INVALIDARG
;
for
(
i
=
This
->
position
;
fetched
<
celt
&&
i
<
This
->
count
;
i
++
)
{
hr
=
IShellItemArray_GetItemAt
(
This
->
array
,
i
,
&
rgelt
[
fetched
]);
if
(
FAILED
(
hr
))
break
;
fetched
++
;
This
->
position
++
;
}
if
(
SUCCEEDED
(
hr
))
{
if
(
pceltFetched
!=
NULL
)
*
pceltFetched
=
fetched
;
if
(
fetched
>
0
)
return
S_OK
;
return
S_FALSE
;
}
return
hr
;
}
static
HRESULT
WINAPI
IEnumShellItems_fnSkip
(
IEnumShellItems
*
iface
,
ULONG
celt
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
TRACE
(
"%p (%d)
\n
"
,
This
,
celt
);
This
->
position
=
min
(
This
->
position
+
celt
,
This
->
count
-
1
);
return
S_OK
;
}
static
HRESULT
WINAPI
IEnumShellItems_fnReset
(
IEnumShellItems
*
iface
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
TRACE
(
"%p
\n
"
,
This
);
This
->
position
=
0
;
return
S_OK
;
}
static
HRESULT
WINAPI
IEnumShellItems_fnClone
(
IEnumShellItems
*
iface
,
IEnumShellItems
**
ppenum
)
{
IEnumShellItemsImpl
*
This
=
impl_from_IEnumShellItems
(
iface
);
TRACE
(
"%p (%p)
\n
"
,
This
,
ppenum
);
/* Not implemented anywhere */
*
ppenum
=
NULL
;
return
E_NOTIMPL
;
}
static
const
IEnumShellItemsVtbl
vt_IEnumShellItems
=
{
IEnumShellItems_fnQueryInterface
,
IEnumShellItems_fnAddRef
,
IEnumShellItems_fnRelease
,
IEnumShellItems_fnNext
,
IEnumShellItems_fnSkip
,
IEnumShellItems_fnReset
,
IEnumShellItems_fnClone
};
static
HRESULT
IEnumShellItems_Constructor
(
IShellItemArray
*
array
,
IEnumShellItems
**
ppesi
)
{
IEnumShellItemsImpl
*
This
;
HRESULT
ret
;
This
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
IEnumShellItemsImpl
));
if
(
!
This
)
return
E_OUTOFMEMORY
;
This
->
ref
=
1
;
This
->
IEnumShellItems_iface
.
lpVtbl
=
&
vt_IEnumShellItems
;
This
->
array
=
array
;
This
->
position
=
0
;
IShellItemArray_AddRef
(
This
->
array
);
IShellItemArray_GetCount
(
This
->
array
,
&
This
->
count
);
ret
=
IEnumShellItems_QueryInterface
(
&
This
->
IEnumShellItems_iface
,
&
IID_IEnumShellItems
,
(
void
**
)
ppesi
);
IEnumShellItems_Release
(
&
This
->
IEnumShellItems_iface
);
return
ret
;
}
/*************************************************************************
* IShellItemArray implementation
*/
typedef
struct
{
...
...
@@ -955,9 +1122,12 @@ static HRESULT WINAPI IShellItemArray_fnEnumItems(IShellItemArray *iface,
IEnumShellItems
**
ppenumShellItems
)
{
IShellItemArrayImpl
*
This
=
impl_from_IShellItemArray
(
iface
);
FIXME
(
"Stub: %p (%p)
\n
"
,
This
,
ppenumShellItems
);
HRESULT
hr
;
TRACE
(
"%p (%p)
\n
"
,
This
,
ppenumShellItems
);
return
E_NOTIMPL
;
hr
=
IEnumShellItems_Constructor
(
iface
,
ppenumShellItems
);
return
hr
;
}
static
const
IShellItemArrayVtbl
vt_IShellItemArray
=
{
...
...
dlls/shell32/tests/shlfolder.c
View file @
d016dc40
...
...
@@ -3728,6 +3728,160 @@ static void test_SHCreateShellItemArray(void)
Cleanup
();
}
static
void
test_ShellItemArrayEnumItems
(
void
)
{
IShellFolder
*
pdesktopsf
,
*
psf
;
IEnumIDList
*
peidl
;
WCHAR
cTestDirW
[
MAX_PATH
];
HRESULT
hr
;
LPITEMIDLIST
pidl_testdir
;
static
const
WCHAR
testdirW
[]
=
{
't'
,
'e'
,
's'
,
't'
,
'd'
,
'i'
,
'r'
,
0
};
if
(
!
pSHCreateShellItemArray
)
{
win_skip
(
"No SHCreateShellItemArray, skipping test.."
);
return
;
}
CreateFilesFolders
();
SHGetDesktopFolder
(
&
pdesktopsf
);
GetCurrentDirectoryW
(
MAX_PATH
,
cTestDirW
);
myPathAddBackslashW
(
cTestDirW
);
lstrcatW
(
cTestDirW
,
testdirW
);
hr
=
IShellFolder_ParseDisplayName
(
pdesktopsf
,
NULL
,
NULL
,
cTestDirW
,
NULL
,
&
pidl_testdir
,
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IShellFolder_BindToObject
(
pdesktopsf
,
pidl_testdir
,
NULL
,
(
REFIID
)
&
IID_IShellFolder
,
(
void
**
)
&
psf
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
pILFree
(
pidl_testdir
);
}
IShellFolder_Release
(
pdesktopsf
);
hr
=
IShellFolder_EnumObjects
(
psf
,
NULL
,
SHCONTF_FOLDERS
|
SHCONTF_NONFOLDERS
,
&
peidl
);
ok
(
hr
==
S_OK
,
"Got %08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
IShellItemArray
*
psia
;
LPITEMIDLIST
apidl
[
5
];
UINT
done
,
numitems
,
i
;
for
(
done
=
0
;
done
<
5
;
done
++
)
if
(
IEnumIDList_Next
(
peidl
,
1
,
&
apidl
[
done
],
NULL
)
!=
S_OK
)
break
;
ok
(
done
==
5
,
"Got %d pidls
\n
"
,
done
);
IEnumIDList_Release
(
peidl
);
/* Create a ShellItemArray */
hr
=
pSHCreateShellItemArray
(
NULL
,
psf
,
done
,
(
LPCITEMIDLIST
*
)
apidl
,
&
psia
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
IEnumShellItems
*
iesi
;
IShellItem
*
my_array
[
10
];
ULONG
fetched
;
IShellItemArray_GetCount
(
psia
,
&
numitems
);
ok
(
numitems
==
done
,
"Got %d, expected %d
\n
"
,
numitems
,
done
);
iesi
=
NULL
;
hr
=
IShellItemArray_EnumItems
(
psia
,
&
iesi
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
iesi
!=
NULL
,
"Got NULL
\n
"
);
if
(
SUCCEEDED
(
hr
))
{
IEnumShellItems
*
iesi2
;
/* This should fail according to the documentation and Win7+ */
for
(
i
=
0
;
i
<
10
;
i
++
)
my_array
[
i
]
=
(
void
*
)
0xdeadbeef
;
hr
=
IEnumShellItems_Next
(
iesi
,
2
,
my_array
,
NULL
);
ok
(
hr
==
E_INVALIDARG
||
broken
(
hr
==
S_OK
)
/* Vista */
,
"Got 0x%08x
\n
"
,
hr
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
ok
(
my_array
[
i
]
==
(
void
*
)
0xdeadbeef
||
broken
(
my_array
[
i
]
!=
(
void
*
)
0xdeadbeef
&&
my_array
[
i
]
!=
NULL
),
/* Vista */
"Got %p (%d)
\n
"
,
my_array
[
i
],
i
);
if
(
my_array
[
i
]
!=
(
void
*
)
0xdeadbeef
)
IShellItem_Release
(
my_array
[
i
]);
}
ok
(
my_array
[
2
]
==
(
void
*
)
0xdeadbeef
,
"Got %p
\n
"
,
my_array
[
2
]);
IEnumShellItems_Reset
(
iesi
);
for
(
i
=
0
;
i
<
10
;
i
++
)
my_array
[
i
]
=
(
void
*
)
0xdeadbeef
;
hr
=
IEnumShellItems_Next
(
iesi
,
1
,
my_array
,
NULL
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
my_array
[
0
]
!=
NULL
&&
my_array
[
0
]
!=
(
void
*
)
0xdeadbeef
,
"Got %p
\n
"
,
my_array
[
0
]);
if
(
my_array
[
0
]
!=
NULL
&&
my_array
[
0
]
!=
(
void
*
)
0xdeadbeef
)
IShellItem_Release
(
my_array
[
0
]);
ok
(
my_array
[
1
]
==
(
void
*
)
0xdeadbeef
,
"Got %p
\n
"
,
my_array
[
1
]);
IEnumShellItems_Reset
(
iesi
);
fetched
=
0
;
for
(
i
=
0
;
i
<
10
;
i
++
)
my_array
[
i
]
=
(
void
*
)
0xdeadbeef
;
hr
=
IEnumShellItems_Next
(
iesi
,
numitems
,
my_array
,
&
fetched
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
fetched
==
numitems
,
"Got %d
\n
"
,
fetched
);
for
(
i
=
0
;
i
<
numitems
;
i
++
)
{
ok
(
my_array
[
i
]
!=
NULL
&&
my_array
[
i
]
!=
(
void
*
)
0xdeadbeef
,
"Got %p at %d
\n
"
,
my_array
[
i
],
i
);
if
(
my_array
[
i
]
!=
NULL
&&
my_array
[
i
]
!=
(
void
*
)
0xdeadbeef
)
IShellItem_Release
(
my_array
[
i
]);
}
ok
(
my_array
[
i
]
==
(
void
*
)
0xdeadbeef
,
"Got %p
\n
"
,
my_array
[
i
]);
/* Compare all the items */
IEnumShellItems_Reset
(
iesi
);
for
(
i
=
0
;
i
<
numitems
;
i
++
)
{
IShellItem
*
psi
;
int
order
;
hr
=
IShellItemArray_GetItemAt
(
psia
,
i
,
&
psi
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
hr
=
IEnumShellItems_Next
(
iesi
,
1
,
my_array
,
&
fetched
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
fetched
==
1
,
"Got %d
\n
"
,
fetched
);
hr
=
IShellItem_Compare
(
psi
,
my_array
[
0
],
0
,
&
order
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
order
==
0
,
"Got %d
\n
"
,
order
);
IShellItem_Release
(
psi
);
IShellItem_Release
(
my_array
[
0
]);
}
my_array
[
0
]
=
(
void
*
)
0xdeadbeef
;
hr
=
IEnumShellItems_Next
(
iesi
,
1
,
my_array
,
&
fetched
);
ok
(
hr
==
S_FALSE
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
fetched
==
0
,
"Got %d
\n
"
,
fetched
);
ok
(
my_array
[
0
]
==
(
void
*
)
0xdeadbeef
,
"Got %p
\n
"
,
my_array
[
0
]);
/* Cloning not implemented anywhere */
iesi2
=
(
void
*
)
0xdeadbeef
;
hr
=
IEnumShellItems_Clone
(
iesi
,
&
iesi2
);
ok
(
hr
==
E_NOTIMPL
,
"Got 0x%08x
\n
"
,
hr
);
ok
(
iesi2
==
NULL
||
broken
(
iesi2
==
(
void
*
)
0xdeadbeef
)
/* Vista */
,
"Got %p
\n
"
,
iesi2
);
IEnumShellItems_Release
(
iesi
);
}
IShellItemArray_Release
(
psia
);
}
for
(
i
=
0
;
i
<
done
;
i
++
)
pILFree
(
apidl
[
i
]);
}
}
static
void
test_ShellItemBindToHandler
(
void
)
{
IShellItem
*
psi
;
...
...
@@ -5090,6 +5244,7 @@ START_TEST(shlfolder)
test_LocalizedNames
();
test_SHCreateShellItem
();
test_SHCreateShellItemArray
();
test_ShellItemArrayEnumItems
();
test_desktop_IPersist
();
test_GetUIObject
();
test_SHSimpleIDListFromPath
();
...
...
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