ReactOS 0.4.16-dev-1946-g52006dd
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 if (!g_bVista) // Only Vista fails on a default install
112 {
113 compare(psf, dir3, programs, S_GREATERTHAN);
114 compare(psf, programs, dir3, S_LESSTHAN);
115 }
116 compare(psf, dir3, dir3, S_EQUAL);
117
118 compare(psf, dir4, desktop, S_LESSTHAN);
119 compare(psf, desktop, dir4, S_GREATERTHAN);
120 if (!g_bVista) // Only Vista fails on a default install
121 {
122 compare(psf, dir4, programs, S_GREATERTHAN);
123 compare(psf, programs, dir4, S_LESSTHAN);
124 }
125 compare(psf, dir4, dir4, S_EQUAL);
126
127 // Now compare the paths against eachother.
128 compare(psf, dir1, dir2, S_LESSTHAN);
129 compare(psf, dir2, dir1, S_GREATERTHAN);
130 if (!g_bVista) // Only Vista fails on a default install
131 {
132 compare(psf, dir2, dir3, S_LESSTHAN);
133 compare(psf, dir3, dir2, S_GREATERTHAN);
134 }
135 compare(psf, dir3, dir4, S_LESSTHAN);
136 compare(psf, dir4, dir3, S_GREATERTHAN);
137
138 // Check that comparing desktop pidl with another one with another IShellFolder fails
139 CComPtr<IShellFolder> psf2;
140 hr = psf->BindToObject(programs, NULL, IID_IShellFolder, reinterpret_cast<void**>(&psf2));
141 ok(hr == S_OK, "Impossible to bind to Programs pidl");
142 if (hr == S_OK)
143 {
144 // Compare desktop pidl in programs scope should fail since it's relative pidl
145 compare(psf2, desktop, programs, E_INVALIDARG);
146 compare(psf2, programs, desktop, E_INVALIDARG);
147 // For the same reasons, filesystem paths can't be compared with special shell
148 // folders that don't have CFSFolder in children
149 compare(psf2, dir1, dir2, E_INVALIDARG);
150 compare(psf2, dir2, dir1, E_INVALIDARG);
151 }
152}
153
154static
155VOID
157 _In_ IShellFolder2 *psf2)
158{
159 HRESULT hr;
160 CComPtr<IDropTarget> pdt;
161 CComPtr<IDropTarget> pdt_2;
162 CComPtr<IContextMenu> pcm;
163 CComPtr<IContextMenu> pcm_2;
164 CComPtr<IShellView> psv;
165 CComPtr<IShellView> psv_2;
166
167 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt));
168 ok(hr == S_OK, "hr = %lx\n", hr);
169
170 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt_2));
171 ok(hr == S_OK, "hr = %lx\n", hr);
172 ok(pdt != pdt_2, "Expected %p != %p\n", static_cast<PVOID>(pdt), static_cast<PVOID>(pdt_2));
173
174 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm));
175 ok(hr == S_OK, "hr = %lx\n", hr);
176
177 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm_2));
178 ok(hr == S_OK, "hr = %lx\n", hr);
179 ok(pcm != pcm_2, "Expected %p != %p\n", static_cast<PVOID>(pcm), static_cast<PVOID>(pcm_2));
180
181 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv));
182 ok(hr == S_OK, "hr = %lx\n", hr);
183
184 hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv_2));
185 ok(hr == S_OK, "hr = %lx\n", hr);
186 ok(psv != psv_2, "Expected %p != %p\n", static_cast<PVOID>(psv), static_cast<PVOID>(psv_2));
187
188 STRRET strret;
189 hr = psf2->GetDisplayNameOf(NULL, 0, &strret);
190 ok(hr == S_OK, "hr = %lx\n", hr);
191}
192
194{
195 CComPtr<IPersistFolder2> ppf2;
197 ok(hr == S_OK, "hr = %lx\n", hr);
198
199 /* Create a tiny pidl with no contents */
200 LPITEMIDLIST testpidl = (LPITEMIDLIST)SHAlloc(3 * sizeof(WORD));
201 testpidl->mkid.cb = 2 * sizeof(WORD);
202 *(WORD*)((char*)testpidl + (int)(2 * sizeof(WORD))) = 0;
203
204 hr = ppf2->Initialize(testpidl);
205 ok(hr == E_INVALIDARG, "hr = %lx\n", hr);
206
207 //crashes in xp, works on win10
208 //hr = ppf2->Initialize(NULL);
209 //ok(hr == S_OK, "hr = %lx\n", hr);
210 //hr = ppf2->Initialize((LPCITEMIDLIST)0xdeaddead);
211 //ok(hr == S_OK, "hr = %lx\n", hr);
212 //hr = ppf2->GetCurFolder(NULL);
213 //ok(hr == E_INVALIDARG, "hr = %lx\n", hr);
214
215 CComHeapPtr<ITEMIDLIST> pidl;
216 hr = ppf2->GetCurFolder(&pidl);
217 ok(hr == S_OK, "hr = %lx\n", hr);
218 ok(pidl->mkid.cb == 0, "expected empty pidl got cb = %x\n", pidl->mkid.cb);
219}
220
221START_TEST(CShellDesktop)
222{
223 HRESULT hr;
224 CComPtr<IShellFolder2> psf2;
225 CComPtr<IShellFolder2> psf2_2;
226 CComPtr<IShellFolder> psf;
227
229
230 hr = CoCreateInstance(CLSID_ShellDesktop,
231 NULL,
232 CLSCTX_INPROC_SERVER,
233 IID_PPV_ARG(IShellFolder2, &psf2));
234 ok(hr == S_OK, "hr = %lx\n", hr);
235 if (FAILED(hr))
236 {
237 skip("Could not instantiate CShellDesktop\n");
238 return;
239 }
240
241 /* second create should give us a pointer to the same object */
242 hr = CoCreateInstance(CLSID_ShellDesktop,
243 NULL,
244 CLSCTX_INPROC_SERVER,
245 IID_PPV_ARG(IShellFolder2, &psf2_2));
246 ok(hr == S_OK, "hr = %lx\n", hr);
247 ok(psf2 == psf2_2, "Expected %p == %p\n", static_cast<PVOID>(psf2), static_cast<PVOID>(psf2_2));
248
249 /* SHGetDesktopFolder should also give us the same pointer */
250 hr = SHGetDesktopFolder(&psf);
251 ok(hr == S_OK, "hr = %lx\n", hr);
252 ok(psf == static_cast<IShellFolder *>(psf2), "Expected %p == %p\n", static_cast<PVOID>(psf), static_cast<PVOID>(psf2));
253
254 TestDesktopFolder(psf2);
256 TestInitialize(psf);
257}
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:348
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3277
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
FxCollectionEntry * cur
const GLuint * programs
Definition: glext.h:6724
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
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 __cdecl winetest_ok(int condition, const char *msg,...) __WINE_PRINTF_ATTR(2
VOID TestInitialize()
Definition: CFSFolder.cpp:105
BOOL expected
Definition: store.c:2000
#define _In_
Definition: no_sal2.h:158
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
VOID PathToIDList(LPCWSTR pszPath, ITEMIDLIST **ppidl)
Definition: shelltest.cpp:83
static const BOOL g_bVista
Definition: shelltest.h:18
#define S_LESSTHAN
Definition: shellutils.h:675
#define S_GREATERTHAN
Definition: shellutils.h:677
#define S_EQUAL
Definition: shellutils.h:676
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_DESKTOP
Definition: shlobj.h:2179
#define CSIDL_PROGRAMS
Definition: shlobj.h:2181
#define CSIDL_INTERNET
Definition: shlobj.h:2180
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define IID_PPV_ARG(Itype, ppType)