ReactOS 0.4.16-dev-338-g34e76ad
CShellDesktop.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for CShellDesktop
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 * Mark Jansen
7 */
8
9#include "shelltest.h"
10
11#include <ndk/rtlfuncs.h>
12#include <stdio.h>
13#include <shellutils.h>
14
15// We would normally use S_LESSTHAN and S_GREATERTHAN, but w2k3 returns numbers like 3 and -3...
16// So instead we check on the sign bit (compare result is the low word of the hresult).
17#define SHORT_SIGN_BIT 0x8000
18
19static
20VOID
22{
23 HRESULT hr;
25 {
26 hr = psf->CompareIDs(0, pidl1, pidl2);
27 }
29 {
30 winetest_ok(0, "Exception %lx!\n", _SEH2_GetExceptionCode());
32 }
34 if (expected == S_LESSTHAN)
35 winetest_ok(SUCCEEDED(hr) && (hr & SHORT_SIGN_BIT), "hr = %lx\n", hr);
36 else if (expected == S_EQUAL)
37 winetest_ok(hr == S_EQUAL, "hr = %lx\n", hr);
38 else if (expected == S_GREATERTHAN)
39 winetest_ok(SUCCEEDED(hr) && !(hr & SHORT_SIGN_BIT), "hr = %lx\n", hr);
40 else
41 winetest_ok(hr == expected, "hr = %lx\n", hr);
42}
43
44// make the winetest_ok look like it came from the line where the compare function was called, and not from inside the compare_imp function :)
45#define compare (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : compare_imp
46
47static
48VOID
50{
52
53 CComHeapPtr<ITEMIDLIST> desktop;
55 ok(hr == S_OK, "hr = %lx\n", hr);
56 compare(psf, desktop, NULL, E_INVALIDARG);
57 compare(psf, NULL, desktop, E_INVALIDARG);
58 compare(psf, desktop, desktop, S_EQUAL);
59
60 // First check the ordering of some special folders against eachother
61 CComHeapPtr<ITEMIDLIST> internet;
63 ok(hr == S_OK, "hr = %lx\n", hr);
64 compare(psf, internet, desktop, S_LESSTHAN);
65 compare(psf, desktop, internet, S_GREATERTHAN);
66
67 CComHeapPtr<ITEMIDLIST> programs;
69 ok(hr == S_OK, "hr = %lx\n", hr);
70 compare(psf, programs, desktop, S_LESSTHAN);
71 compare(psf, desktop, programs, S_GREATERTHAN);
72 compare(psf, internet, programs, S_GREATERTHAN);
73 compare(psf, programs, internet, S_LESSTHAN);
74
75 // Verify that an idlist retrieved from GetCurFolder is equal to the original one.
76 CComPtr<IPersistFolder2> persist;
78 ok(hr == S_OK, "hr = %lx\n", hr);
79 if (hr == S_OK)
80 {
81 CComHeapPtr<ITEMIDLIST> cur;
82 hr = persist->GetCurFolder(&cur);
83 ok(hr == S_OK, "hr = %lx\n", hr);
84 compare(psf, cur, desktop, S_EQUAL);
85 compare(psf, desktop, cur, S_EQUAL);
86 }
87
88 // Compare special folders against full paths
89 CComHeapPtr<ITEMIDLIST> dir1, dir2;
90 PathToIDList(L"A:\\AAA.AAA", &dir1);
91 PathToIDList(L"A:\\ZZZ.ZZZ", &dir2);
92
93 compare(psf, dir1, desktop, S_LESSTHAN);
94 compare(psf, desktop, dir1, S_GREATERTHAN);
95 compare(psf, dir1, programs, S_LESSTHAN);
96 compare(psf, programs, dir1, S_GREATERTHAN);
97 compare(psf, dir1, dir1, S_EQUAL);
98
99 compare(psf, dir2, desktop, S_LESSTHAN);
100 compare(psf, desktop, dir2, S_GREATERTHAN);
101 compare(psf, dir2, programs, S_LESSTHAN);
102 compare(psf, programs, dir2, S_GREATERTHAN);
103 compare(psf, dir2, dir2, S_EQUAL);
104
105 CComHeapPtr<ITEMIDLIST> dir3, dir4;
106 PathToIDList(L"Z:\\AAA.AAA", &dir3);
107 PathToIDList(L"Z:\\ZZZ.ZZZ", &dir4);
108
109 compare(psf, dir3, desktop, S_LESSTHAN);
110 compare(psf, desktop, dir3, S_GREATERTHAN);
111 compare(psf, dir3, programs, S_GREATERTHAN);
112 compare(psf, programs, dir3, S_LESSTHAN);
113 compare(psf, dir3, dir3, S_EQUAL);
114
115 compare(psf, dir4, desktop, S_LESSTHAN);
116 compare(psf, desktop, dir4, S_GREATERTHAN);
117 compare(psf, dir4, programs, S_GREATERTHAN);
118 compare(psf, programs, dir4, S_LESSTHAN);
119 compare(psf, dir4, dir4, S_EQUAL);
120
121 // Now compare the paths against eachother.
122 compare(psf, dir1, dir2, S_LESSTHAN);
123 compare(psf, dir2, dir1, S_GREATERTHAN);
124
125 compare(psf, dir2, dir3, S_LESSTHAN);
126 compare(psf, dir3, dir2, S_GREATERTHAN);
127
128 compare(psf, dir3, dir4, S_LESSTHAN);
129 compare(psf, dir4, dir3, S_GREATERTHAN);
130
131 // Check that comparing desktop pidl with another one with another IShellFolder fails
132 CComPtr<IShellFolder> psf2;
133 hr = psf->BindToObject(programs, NULL, IID_IShellFolder, reinterpret_cast<void**>(&psf2));
134 ok(hr == S_OK, "Impossible to bind to Programs pidl");
135 if (hr == S_OK)
136 {
137 // Compare desktop pidl in programs scope should fail since it's relative pidl
138 compare(psf2, desktop, programs, E_INVALIDARG);
139 compare(psf2, programs, desktop, E_INVALIDARG);
140 // For the same reasons, filesystem paths can't be compared with special shell
141 // folders that don't have CFSFolder in children
142 compare(psf2, dir1, dir2, E_INVALIDARG);
143 compare(psf2, dir2, dir1, E_INVALIDARG);
144 }
145}
146
147static
148VOID
150 _In_ IShellFolder2 *psf2)
151{
152 HRESULT hr;
153 CComPtr<IDropTarget> pdt;
154 CComPtr<IDropTarget> pdt_2;
155 CComPtr<IContextMenu> pcm;
156 CComPtr<IContextMenu> pcm_2;
157 CComPtr<IShellView> psv;
158 CComPtr<IShellView> psv_2;
159
160 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt));
161 ok(hr == S_OK, "hr = %lx\n", hr);
162
163 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt_2));
164 ok(hr == S_OK, "hr = %lx\n", hr);
165 ok(pdt != pdt_2, "Expected %p != %p\n", static_cast<PVOID>(pdt), static_cast<PVOID>(pdt_2));
166
167 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm));
168 ok(hr == S_OK, "hr = %lx\n", hr);
169
170 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm_2));
171 ok(hr == S_OK, "hr = %lx\n", hr);
172 ok(pcm != pcm_2, "Expected %p != %p\n", static_cast<PVOID>(pcm), static_cast<PVOID>(pcm_2));
173
174 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv));
175 ok(hr == S_OK, "hr = %lx\n", hr);
176
177 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv_2));
178 ok(hr == S_OK, "hr = %lx\n", hr);
179 ok(psv != psv_2, "Expected %p != %p\n", static_cast<PVOID>(psv), static_cast<PVOID>(psv_2));
180
181 STRRET strret;
182 hr = psf2->GetDisplayNameOf(NULL, 0, &strret);
183 ok(hr == S_OK, "hr = %lx\n", hr);
184}
185
187{
188 CComPtr<IPersistFolder2> ppf2;
190 ok(hr == S_OK, "hr = %lx\n", hr);
191
192 /* Create a tiny pidl with no contents */
193 LPITEMIDLIST testpidl = (LPITEMIDLIST)SHAlloc(3 * sizeof(WORD));
194 testpidl->mkid.cb = 2 * sizeof(WORD);
195 *(WORD*)((char*)testpidl + (int)(2 * sizeof(WORD))) = 0;
196
197 hr = ppf2->Initialize(testpidl);
198 ok(hr == E_INVALIDARG, "hr = %lx\n", hr);
199
200 //crashes in xp, works on win10
201 //hr = ppf2->Initialize(NULL);
202 //ok(hr == S_OK, "hr = %lx\n", hr);
203 //hr = ppf2->Initialize((LPCITEMIDLIST)0xdeaddead);
204 //ok(hr == S_OK, "hr = %lx\n", hr);
205 //hr = ppf2->GetCurFolder(NULL);
206 //ok(hr == E_INVALIDARG, "hr = %lx\n", hr);
207
208 CComHeapPtr<ITEMIDLIST> pidl;
209 hr = ppf2->GetCurFolder(&pidl);
210 ok(hr == S_OK, "hr = %lx\n", hr);
211 ok(pidl->mkid.cb == 0, "expected empty pidl got cb = %x\n", pidl->mkid.cb);
212}
213
214START_TEST(CShellDesktop)
215{
216 HRESULT hr;
217 CComPtr<IShellFolder2> psf2;
218 CComPtr<IShellFolder2> psf2_2;
219 CComPtr<IShellFolder> psf;
220
222
223 hr = CoCreateInstance(CLSID_ShellDesktop,
224 NULL,
225 CLSCTX_INPROC_SERVER,
226 IID_PPV_ARG(IShellFolder2, &psf2));
227 ok(hr == S_OK, "hr = %lx\n", hr);
228 if (FAILED(hr))
229 {
230 skip("Could not instantiate CShellDesktop\n");
231 return;
232 }
233
234 /* second create should give us a pointer to the same object */
235 hr = CoCreateInstance(CLSID_ShellDesktop,
236 NULL,
237 CLSCTX_INPROC_SERVER,
238 IID_PPV_ARG(IShellFolder2, &psf2_2));
239 ok(hr == S_OK, "hr = %lx\n", hr);
240 ok(psf2 == psf2_2, "Expected %p == %p\n", static_cast<PVOID>(psf2), static_cast<PVOID>(psf2_2));
241
242 /* SHGetDesktopFolder should also give us the same pointer */
243 hr = SHGetDesktopFolder(&psf);
244 ok(hr == S_OK, "hr = %lx\n", hr);
245 ok(psf == static_cast<IShellFolder *>(psf2), "Expected %p == %p\n", static_cast<PVOID>(psf), static_cast<PVOID>(psf2));
246
247 TestDesktopFolder(psf2);
249 TestInitialize(psf);
250}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define compare
static VOID TestCompareIDList(IShellFolder *psf)
static VOID compare_imp(IShellFolder *psf, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, HRESULT expected)
#define SHORT_SIGN_BIT
static VOID TestDesktopFolder(_In_ IShellFolder2 *psf2)
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3150
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned short WORD
Definition: ntddk_ex.h:93
FxCollectionEntry * cur
const GLuint * programs
Definition: glext.h:6724
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
HRESULT BindToObject([in] PCUIDLIST_RELATIVE pidl, [in] LPBC pbcReserved, [in] REFIID riid, [out, iid_is(riid)] void **ppvOut)
HRESULT CompareIDs([in] LPARAM lParam, [in] PCUIDLIST_RELATIVE pidl1, [in] PCUIDLIST_RELATIVE pidl2)
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
VOID TestInitialize()
Definition: CFSFolder.cpp:105
BOOL expected
Definition: store.c:2063
#define _In_
Definition: no_sal2.h:158
#define L(x)
Definition: ntvdm.h:50
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
VOID PathToIDList(LPCWSTR pszPath, ITEMIDLIST **ppidl)
Definition: shelltest.cpp:83
#define S_LESSTHAN
Definition: shellutils.h:616
#define S_GREATERTHAN
Definition: shellutils.h:618
#define S_EQUAL
Definition: shellutils.h:617
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_DESKTOP
Definition: shlobj.h:2173
#define CSIDL_PROGRAMS
Definition: shlobj.h:2175
#define CSIDL_INTERNET
Definition: shlobj.h:2174
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define IID_PPV_ARG(Itype, ppType)