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
090824fe
Commit
090824fe
authored
Jul 26, 2010
by
David Hedberg
Committed by
Alexandre Julliard
Jul 26, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Initial implementation of IShellItemArray with SHCreateShellItemArray.
parent
dcb2ebee
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
370 additions
and
1 deletion
+370
-1
shell32.spec
dlls/shell32/shell32.spec
+1
-0
shellitem.c
dlls/shell32/shellitem.c
+236
-1
shlfolder.c
dlls/shell32/tests/shlfolder.c
+132
-0
shobjidl.idl
include/shobjidl.idl
+1
-0
No files found.
dlls/shell32/shell32.spec
View file @
090824fe
...
...
@@ -334,6 +334,7 @@
@ stdcall SHCreateItemFromParsingName(wstr ptr ptr ptr)
@ stub SHCreateProcessAsUserW
@ stdcall SHCreateShellItem(ptr ptr ptr ptr)
@ stdcall SHCreateShellItemArray(ptr ptr long ptr ptr)
@ stdcall SHEmptyRecycleBinA(long str long)
@ stdcall SHEmptyRecycleBinW(long wstr long)
@ stub SHExtractIconsW
...
...
dlls/shell32/shellitem.c
View file @
090824fe
/*
* IShellItem
implementation
* IShellItem
and IShellItemArray implementations
*
* Copyright 2008 Vincent Povirk for CodeWeavers
*
...
...
@@ -592,3 +592,238 @@ HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv)
return
ret
;
}
/*************************************************************************
* IShellItemArray implementation
*/
typedef
struct
{
const
IShellItemArrayVtbl
*
lpVtbl
;
LONG
ref
;
IShellItem
**
array
;
DWORD
item_count
;
}
IShellItemArrayImpl
;
static
HRESULT
WINAPI
IShellItemArray_fnQueryInterface
(
IShellItemArray
*
iface
,
REFIID
riid
,
void
**
ppvObject
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
TRACE
(
"%p (%s, %p)
\n
"
,
This
,
shdebugstr_guid
(
riid
),
ppvObject
);
*
ppvObject
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IShellItemArray
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
ppvObject
=
This
;
}
if
(
*
ppvObject
)
{
IUnknown_AddRef
((
IUnknown
*
)
*
ppvObject
);
return
S_OK
;
}
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
IShellItemArray_fnAddRef
(
IShellItemArray
*
iface
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
LONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"%p - ref %d
\n
"
,
This
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
IShellItemArray_fnRelease
(
IShellItemArray
*
iface
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
LONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"%p - ref %d
\n
"
,
This
,
ref
);
if
(
!
ref
)
{
UINT
i
;
TRACE
(
"Freeing.
\n
"
);
for
(
i
=
0
;
i
<
This
->
item_count
;
i
++
)
IShellItem_Release
(
This
->
array
[
i
]);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
array
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
return
0
;
}
return
ref
;
}
static
HRESULT
WINAPI
IShellItemArray_fnBindToHandler
(
IShellItemArray
*
iface
,
IBindCtx
*
pbc
,
REFGUID
bhid
,
REFIID
riid
,
void
**
ppvOut
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
FIXME
(
"Stub: %p (%p, %s, %s, %p)
\n
"
,
This
,
pbc
,
shdebugstr_guid
(
bhid
),
shdebugstr_guid
(
riid
),
ppvOut
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
IShellItemArray_fnGetPropertyStore
(
IShellItemArray
*
iface
,
GETPROPERTYSTOREFLAGS
flags
,
REFIID
riid
,
void
**
ppv
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
FIXME
(
"Stub: %p (%x, %s, %p)
\n
"
,
This
,
flags
,
shdebugstr_guid
(
riid
),
ppv
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
IShellItemArray_fnGetPropertyDescriptionList
(
IShellItemArray
*
iface
,
REFPROPERTYKEY
keyType
,
REFIID
riid
,
void
**
ppv
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
FIXME
(
"Stub: %p (%p, %s, %p)
\n
"
,
This
,
keyType
,
shdebugstr_guid
(
riid
),
ppv
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
IShellItemArray_fnGetAttributes
(
IShellItemArray
*
iface
,
SIATTRIBFLAGS
AttribFlags
,
SFGAOF
sfgaoMask
,
SFGAOF
*
psfgaoAttribs
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
FIXME
(
"Stub: %p (%x, %x, %p)
\n
"
,
This
,
AttribFlags
,
sfgaoMask
,
psfgaoAttribs
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
IShellItemArray_fnGetCount
(
IShellItemArray
*
iface
,
DWORD
*
pdwNumItems
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
TRACE
(
"%p (%p)
\n
"
,
This
,
pdwNumItems
);
*
pdwNumItems
=
This
->
item_count
;
return
S_OK
;
}
static
HRESULT
WINAPI
IShellItemArray_fnGetItemAt
(
IShellItemArray
*
iface
,
DWORD
dwIndex
,
IShellItem
**
ppsi
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
TRACE
(
"%p (%x, %p)
\n
"
,
This
,
dwIndex
,
ppsi
);
/* zero indexed */
if
(
dwIndex
+
1
>
This
->
item_count
)
return
E_FAIL
;
*
ppsi
=
This
->
array
[
dwIndex
];
IShellItem_AddRef
(
*
ppsi
);
return
S_OK
;
}
static
HRESULT
WINAPI
IShellItemArray_fnEnumItems
(
IShellItemArray
*
iface
,
IEnumShellItems
**
ppenumShellItems
)
{
IShellItemArrayImpl
*
This
=
(
IShellItemArrayImpl
*
)
iface
;
FIXME
(
"Stub: %p (%p)
\n
"
,
This
,
ppenumShellItems
);
return
E_NOTIMPL
;
}
static
const
IShellItemArrayVtbl
vt_IShellItemArray
=
{
IShellItemArray_fnQueryInterface
,
IShellItemArray_fnAddRef
,
IShellItemArray_fnRelease
,
IShellItemArray_fnBindToHandler
,
IShellItemArray_fnGetPropertyStore
,
IShellItemArray_fnGetPropertyDescriptionList
,
IShellItemArray_fnGetAttributes
,
IShellItemArray_fnGetCount
,
IShellItemArray_fnGetItemAt
,
IShellItemArray_fnEnumItems
};
static
HRESULT
WINAPI
IShellItemArray_Constructor
(
IUnknown
*
pUnkOuter
,
REFIID
riid
,
void
**
ppv
)
{
IShellItemArrayImpl
*
This
;
HRESULT
ret
;
TRACE
(
"(%p, %s, %p)
\n
"
,
pUnkOuter
,
debugstr_guid
(
riid
),
ppv
);
if
(
pUnkOuter
)
return
CLASS_E_NOAGGREGATION
;
This
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
IShellItemArrayImpl
));
if
(
!
This
)
return
E_OUTOFMEMORY
;
This
->
ref
=
1
;
This
->
lpVtbl
=
&
vt_IShellItemArray
;
ret
=
IShellItemArray_QueryInterface
((
IShellItemArray
*
)
This
,
riid
,
ppv
);
IShellItemArray_Release
((
IShellItemArray
*
)
This
);
return
ret
;
}
HRESULT
WINAPI
SHCreateShellItemArray
(
PCIDLIST_ABSOLUTE
pidlParent
,
IShellFolder
*
psf
,
UINT
cidl
,
PCUITEMID_CHILD_ARRAY
ppidl
,
IShellItemArray
**
ppsiItemArray
)
{
IShellItemArrayImpl
*
This
;
IShellItem
**
array
;
HRESULT
ret
=
E_FAIL
;
UINT
i
;
TRACE
(
"%p, %p, %d, %p, %p
\n
"
,
pidlParent
,
psf
,
cidl
,
ppidl
,
ppsiItemArray
);
if
(
!
pidlParent
&&
!
psf
)
return
E_POINTER
;
if
(
!
ppidl
)
return
E_INVALIDARG
;
array
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
cidl
*
sizeof
(
IShellItem
*
));
if
(
!
array
)
return
E_OUTOFMEMORY
;
for
(
i
=
0
;
i
<
cidl
;
i
++
)
{
ret
=
SHCreateShellItem
(
pidlParent
,
psf
,
ppidl
[
i
],
&
array
[
i
]);
if
(
FAILED
(
ret
))
break
;
}
if
(
SUCCEEDED
(
ret
))
{
ret
=
IShellItemArray_Constructor
(
NULL
,
&
IID_IShellItemArray
,
(
void
**
)
&
This
);
if
(
SUCCEEDED
(
ret
))
{
This
->
array
=
array
;
This
->
item_count
=
cidl
;
*
ppsiItemArray
=
(
IShellItemArray
*
)
This
;
return
ret
;
}
}
/* Something failed, clean up. */
for
(
i
=
0
;
i
<
cidl
;
i
++
)
if
(
array
[
i
])
IShellItem_Release
(
array
[
i
]);
HeapFree
(
GetProcessHeap
(),
0
,
array
);
*
ppsiItemArray
=
NULL
;
return
ret
;
}
dlls/shell32/tests/shlfolder.c
View file @
090824fe
...
...
@@ -58,6 +58,7 @@ static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
static
HRESULT
(
WINAPI
*
pSHCreateItemFromIDList
)(
PCIDLIST_ABSOLUTE
pidl
,
REFIID
riid
,
void
**
ppv
);
static
HRESULT
(
WINAPI
*
pSHCreateItemFromParsingName
)(
PCWSTR
,
IBindCtx
*
,
REFIID
,
void
**
);
static
HRESULT
(
WINAPI
*
pSHCreateShellItem
)(
LPCITEMIDLIST
,
IShellFolder
*
,
LPCITEMIDLIST
,
IShellItem
**
);
static
HRESULT
(
WINAPI
*
pSHCreateShellItemArray
)(
LPCITEMIDLIST
,
IShellFolder
*
,
UINT
,
LPCITEMIDLIST
*
,
IShellItemArray
**
);
static
LPITEMIDLIST
(
WINAPI
*
pILCombine
)(
LPCITEMIDLIST
,
LPCITEMIDLIST
);
static
HRESULT
(
WINAPI
*
pSHParseDisplayName
)(
LPCWSTR
,
IBindCtx
*
,
LPITEMIDLIST
*
,
SFGAOF
,
SFGAOF
*
);
static
LPITEMIDLIST
(
WINAPI
*
pSHSimpleIDListFromPathAW
)(
LPCVOID
);
...
...
@@ -79,6 +80,7 @@ static void init_function_pointers(void)
MAKEFUNC
(
SHCreateItemFromIDList
);
MAKEFUNC
(
SHCreateItemFromParsingName
);
MAKEFUNC
(
SHCreateShellItem
);
MAKEFUNC
(
SHCreateShellItemArray
);
MAKEFUNC
(
SHGetFolderPathA
);
MAKEFUNC
(
SHGetFolderPathAndSubDirA
);
MAKEFUNC
(
SHGetPathFromIDListW
);
...
...
@@ -2930,6 +2932,135 @@ static void test_SHGetItemFromObject(void)
IShellFolder_Release
(
psfdesktop
);
}
static
void
test_SHCreateShellItemArray
(
void
)
{
IShellFolder
*
pdesktopsf
,
*
psf
;
IShellItemArray
*
psia
;
IEnumIDList
*
peidl
;
HRESULT
hr
;
WCHAR
cTestDirW
[
MAX_PATH
];
LPITEMIDLIST
pidl_testdir
,
pidl
;
static
const
WCHAR
testdirW
[]
=
{
't'
,
'e'
,
's'
,
't'
,
'd'
,
'i'
,
'r'
,
0
};
if
(
!
pSHCreateShellItemArray
)
{
skip
(
"No pSHCreateShellItemArray!
\n
"
);
return
;
}
ok
(
pSHGetSpecialFolderLocation
!=
NULL
,
"SHGetSpecialFolderLocation missing.
\n
"
);
if
(
0
)
{
/* Crashes under native */
pSHCreateShellItemArray
(
NULL
,
NULL
,
0
,
NULL
,
NULL
);
pSHCreateShellItemArray
(
NULL
,
NULL
,
1
,
NULL
,
NULL
);
pSHCreateShellItemArray
(
NULL
,
pdesktopsf
,
0
,
NULL
,
NULL
);
pSHCreateShellItemArray
(
pidl
,
NULL
,
0
,
NULL
,
NULL
);
}
hr
=
pSHCreateShellItemArray
(
NULL
,
NULL
,
0
,
NULL
,
&
psia
);
ok
(
hr
==
E_POINTER
,
"got 0x%08x
\n
"
,
hr
);
SHGetDesktopFolder
(
&
pdesktopsf
);
hr
=
pSHCreateShellItemArray
(
NULL
,
pdesktopsf
,
0
,
NULL
,
&
psia
);
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
hr
=
pSHCreateShellItemArray
(
NULL
,
pdesktopsf
,
1
,
NULL
,
&
psia
);
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
pSHGetSpecialFolderLocation
(
NULL
,
CSIDL_DESKTOP
,
&
pidl
);
hr
=
pSHCreateShellItemArray
(
pidl
,
NULL
,
0
,
NULL
,
&
psia
);
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
pILFree
(
pidl
);
GetCurrentDirectoryW
(
MAX_PATH
,
cTestDirW
);
myPathAddBackslashW
(
cTestDirW
);
lstrcatW
(
cTestDirW
,
testdirW
);
CreateFilesFolders
();
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
);
}
IShellFolder_Release
(
pdesktopsf
);
if
(
FAILED
(
hr
))
{
skip
(
"Failed to set up environment for SHCreateShellItemArray tests.
\n
"
);
pILFree
(
pidl_testdir
);
Cleanup
();
return
;
}
hr
=
IShellFolder_EnumObjects
(
psf
,
NULL
,
SHCONTF_FOLDERS
|
SHCONTF_NONFOLDERS
,
&
peidl
);
ok
(
hr
==
S_OK
,
"Got %08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
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
))
{
IShellItem
*
psi
;
if
(
0
)
{
/* Crashes in Windows 7 */
hr
=
IShellItemArray_GetCount
(
psia
,
NULL
);
}
IShellItemArray_GetCount
(
psia
,
&
numitems
);
ok
(
numitems
==
done
,
"Got %d, expected %d
\n
"
,
numitems
,
done
);
hr
=
IShellItemArray_GetItemAt
(
psia
,
numitems
,
&
psi
);
ok
(
hr
==
E_FAIL
,
"Got 0x%08x
\n
"
,
hr
);
/* Compare all the items */
for
(
i
=
0
;
i
<
numitems
;
i
++
)
{
LPITEMIDLIST
pidl_abs
;
pidl_abs
=
ILCombine
(
pidl_testdir
,
apidl
[
i
]);
hr
=
IShellItemArray_GetItemAt
(
psia
,
i
,
&
psi
);
ok
(
hr
==
S_OK
,
"(%d) Failed with 0x%08x
\n
"
,
i
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
pSHGetIDListFromObject
((
IUnknown
*
)
psi
,
&
pidl
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
ILIsEqual
(
pidl_abs
,
pidl
),
"Pidl not equal.
\n
"
);
pILFree
(
pidl
);
}
IShellItem_Release
(
psi
);
}
pILFree
(
pidl_abs
);
}
for
(
i
=
0
;
i
<
done
;
i
++
)
pILFree
(
apidl
[
i
]);
IShellItemArray_Release
(
psia
);
}
}
IShellFolder_Release
(
psf
);
pILFree
(
pidl_testdir
);
Cleanup
();
}
static
void
test_SHParseDisplayName
(
void
)
{
LPITEMIDLIST
pidl1
,
pidl2
;
...
...
@@ -3431,6 +3562,7 @@ START_TEST(shlfolder)
test_SHGetFolderPathAndSubDirA
();
test_LocalizedNames
();
test_SHCreateShellItem
();
test_SHCreateShellItemArray
();
test_desktop_IPersist
();
test_GetUIObject
();
test_SHSimpleIDListFromPath
();
...
...
include/shobjidl.idl
View file @
090824fe
...
...
@@ -517,6 +517,7 @@ cpp_quote("HRESULT WINAPI SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl, REFIID
cpp_quote
(
"HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv);"
)
cpp_quote
(
"HRESULT WINAPI SHGetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl);"
)
cpp_quote
(
"HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv);"
)
cpp_quote
(
"HRESULT WINAPI SHCreateShellItemArray(PCIDLIST_ABSOLUTE pidlParent, IShellFolder* psf, UINT cidl, PCUITEMID_CHILD_ARRAY ppidl, IShellItemArray **ppsiItemArray);"
)
/*****************************************************************************
*
IShellItemFilter
interface
...
...
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