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