ReactOS 0.4.15-dev-7846-g8ba6c66
shfldr_special.c
Go to the documentation of this file.
1/*
2 * Tests for special shell folders
3 *
4 * Copyright 2008 Robert Shearman for CodeWeavers
5 * Copyright 2008 Owen Rudge
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <stdio.h>
24
25#define COBJMACROS
26#ifndef __REACTOS__
27#define NONAMELESSUNION
28#define NONAMELESSSTRUCT
29#endif
30
31#define WIN32_LEAN_AND_MEAN
32#include <windows.h>
33#include "shellapi.h"
34#include "shlwapi.h"
35#include "shlobj.h"
36
37#include "wine/test.h"
38
39static inline BOOL SHELL_OsIsUnicode(void)
40{
41 return !(GetVersion() & 0x80000000);
42}
43
44/* Tests for My Network Places */
46{
47 static WCHAR my_network_places_path[] = {
48 ':',':','{','2','0','8','D','2','C','6','0','-','3','A','E','A','-',
49 '1','0','6','9','-','A','2','D','7','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 };
50 static WCHAR entire_network_path[] = {
51 ':',':','{','2','0','8','D','2','C','6','0','-','3','A','E','A','-',
52 '1','0','6','9','-','A','2','D','7','-','0','8','0','0','2','B','3','0','3','0','9','D',
53 '}','\\','E','n','t','i','r','e','N','e','t','w','o','r','k',0 };
54 IShellFolder *psfDesktop;
55 HRESULT hr;
56 DWORD eaten = 0xdeadbeef;
57 LPITEMIDLIST pidl;
58 DWORD attr = ~0;
59 DWORD expected_attr;
60
61 hr = SHGetDesktopFolder(&psfDesktop);
62 ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%x\n", hr);
63
64 hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, my_network_places_path, &eaten, &pidl, &attr);
65 ok(hr == S_OK, "IShellFolder_ParseDisplayName failed with error 0x%x\n", hr);
67 ok(eaten == 0xdeadbeef, "eaten should not have been set to %u\n", eaten);
68 expected_attr = SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
70 ok((attr == expected_attr) || /* Win9x, NT4 */
71 (attr == (expected_attr | SFGAO_STREAM)) || /* W2K */
72 (attr == (expected_attr | SFGAO_CANDELETE)) || /* XP, W2K3 */
73 (attr == (expected_attr | SFGAO_CANDELETE | SFGAO_NONENUMERATED)), /* Vista */
74 "Unexpected attributes : %08x\n", attr);
75
76 ILFree(pidl);
77
78 /* Start clean again */
79 eaten = 0xdeadbeef;
80 attr = ~0;
81
82 hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, entire_network_path, &eaten, &pidl, &attr);
83 IShellFolder_Release(psfDesktop);
87 {
88 win_skip("'EntireNetwork' is not available on Win9x, NT4 and Vista\n");
89 return;
90 }
91 ok(hr == S_OK, "IShellFolder_ParseDisplayName failed with error 0x%x\n", hr);
93 ok(eaten == 0xdeadbeef, "eaten should not have been set to %u\n", eaten);
94 expected_attr = SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_HASPROPSHEET|SFGAO_CANLINK;
96 ok(attr == expected_attr || /* winme, nt4 */
97 attr == (expected_attr | SFGAO_STREAM) || /* win2k */
98 attr == (expected_attr | SFGAO_STORAGEANCESTOR), /* others */
99 "attr should be 0x%x, not 0x%x\n", expected_attr, attr);
100
101 ILFree(pidl);
102}
103
104/* Tests for Control Panel */
106{
107 /* path of My Computer\Control Panel */
108 static WCHAR control_panel_path[] = {
109 ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}','\\',
110 ':',':','{','2','1','E','C','2','0','2','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','D','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 };
111 IShellFolder *psfDesktop;
112 HRESULT hr;
113 DWORD eaten = 0xdeadbeef;
114 LPITEMIDLIST pidl;
115 DWORD attr = ~0;
116
117 hr = SHGetDesktopFolder(&psfDesktop);
118 ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%x\n", hr);
119
120 hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, control_panel_path, &eaten, &pidl, &attr);
121 ok(hr == S_OK, "IShellFolder_ParseDisplayName failed with error 0x%x\n", hr);
122 todo_wine ok(eaten == 0xdeadbeef, "eaten should not have been set to %u\n", eaten);
124 ok((attr == (SFGAO_CANLINK | SFGAO_FOLDER)) || /* Win9x, NT4 */
125 (attr == (SFGAO_CANLINK | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_STREAM)) || /* W2K */
126 (attr == (SFGAO_CANLINK | SFGAO_FOLDER | SFGAO_HASSUBFOLDER)) || /* W2K, XP, W2K3 */
127 (attr == (SFGAO_CANLINK | SFGAO_NONENUMERATED)) || /* Vista */
128 (attr == SFGAO_CANLINK), /* Vista, W2K8 */
129 "Unexpected attributes : %08x\n", attr);
130
131 ILFree(pidl);
132 IShellFolder_Release(psfDesktop);
133}
134
135static void test_printers_folder(void)
136{
138 IPersistFolder2 *pf;
141 LPITEMIDLIST pidl1, pidl2;
142 HRESULT hr;
143 INT i;
144
146
147 hr = CoCreateInstance(&CLSID_Printers, NULL, CLSCTX_INPROC_SERVER, &IID_IShellFolder2, (void**)&folder);
148 if (hr != S_OK)
149 {
150 win_skip("Failed to created IShellFolder2 for Printers folder\n");
152 return;
153 }
154
155if (0)
156{
157 /* crashes on XP */
158 IShellFolder2_GetDetailsOf(folder, NULL, 0, NULL);
159 IShellFolder2_GetDefaultColumnState(folder, 0, NULL);
160 IPersistFolder2_GetCurFolder(pf, NULL);
161}
162
163 /* 5 columns defined */
164 hr = IShellFolder2_GetDetailsOf(folder, NULL, 6, &details);
165 ok(hr == E_NOTIMPL, "got 0x%08x\n", hr);
166
167 hr = IShellFolder2_GetDefaultColumnState(folder, 6, &state);
168 ok(broken(hr == E_NOTIMPL) || hr == E_INVALIDARG /* Win7 */, "got 0x%08x\n", hr);
169
170 details.str.pOleStr = NULL;
171 hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, &details);
172 ok(hr == S_OK || broken(hr == E_NOTIMPL) /* W2K */, "got 0x%08x\n", hr);
173 if (SHELL_OsIsUnicode()) SHFree(details.str.pOleStr);
174
175 /* test every column if method is implemented */
176 if (hr == S_OK)
177 {
178 ok(details.str.uType == STRRET_WSTR, "got %d\n", details.str.uType);
179
180 for(i = 0; i < 6; i++)
181 {
182 hr = IShellFolder2_GetDetailsOf(folder, NULL, i, &details);
183 ok(hr == S_OK, "got 0x%08x\n", hr);
184
185 /* all columns are left-aligned */
186 ok(details.fmt == LVCFMT_LEFT, "got 0x%x\n", details.fmt);
187 /* can't be on w9x at this point, IShellFolder2 unsupported there,
188 check present for running Wine with w9x setup */
189 if (SHELL_OsIsUnicode()) SHFree(details.str.pOleStr);
190
191 hr = IShellFolder2_GetDefaultColumnState(folder, i, &state);
192 ok(hr == S_OK, "got 0x%08x\n", hr);
193 /* all columns are string except document count */
194 if (i == 1)
196 else
198 }
199 }
200
201 /* default pidl */
202 hr = IShellFolder2_QueryInterface(folder, &IID_IPersistFolder2, (void**)&pf);
203 ok(hr == S_OK, "got 0x%08x\n", hr);
204
205 /* not initialized */
206 pidl1 = (void*)0xdeadbeef;
207 hr = IPersistFolder2_GetCurFolder(pf, &pidl1);
208 ok(hr == S_FALSE, "got 0x%08x\n", hr);
209 ok(pidl1 == NULL, "got %p\n", pidl1);
210
212 ok(hr == S_OK, "got 0x%08x\n", hr);
213
214 hr = IPersistFolder2_Initialize(pf, pidl2);
215 ok(hr == S_OK, "got 0x%08x\n", hr);
216
217 hr = IPersistFolder2_GetCurFolder(pf, &pidl1);
218 ok(hr == S_OK, "got 0x%08x\n", hr);
219
220 ok(ILIsEqual(pidl1, pidl2), "expected same PIDL\n");
221 IPersistFolder2_Release(pf);
222
223 ILFree(pidl1);
224 ILFree(pidl2);
225 IShellFolder2_Release(folder);
226
228}
229
230static void test_desktop_folder(void)
231{
232 IShellFolder *psf;
233 HRESULT hr;
234
235 hr = SHGetDesktopFolder(&psf);
236 ok(hr == S_OK, "Got %x\n", hr);
237
238 hr = IShellFolder_QueryInterface(psf, &IID_IShellFolder, NULL);
239 ok(hr == E_POINTER, "Got %x\n", hr);
240
241 IShellFolder_Release(psf);
242}
243
245{
246 static WCHAR MyComputer[] = { ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 };
247 static WCHAR MyDocuments[] = { ':',':','{','4','5','0','D','8','F','B','A','-','A','D','2','5','-','1','1','D','0','-','9','8','A','8','-','0','8','0','0','3','6','1','B','1','1','0','3','}', 0 };
248 static WCHAR RecycleBin[] = { ':',':','{','6','4','5','F','F','0','4','0','-','5','0','8','1','-','1','0','1','B','-','9','F','0','8','-','0','0','A','A','0','0','2','F','9','5','4','E','}', 0 };
249 static WCHAR ControlPanel[]= { ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}','\\',
250 ':',':','{','2','1','E','C','2','0','2','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','D','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 };
251 static WCHAR *folders[] = { MyComputer, MyDocuments, RecycleBin, ControlPanel };
252 IShellFolder *desktop;
253 ITEMIDLIST *pidl;
254 STRRET strret;
255 DWORD eaten;
256 HRESULT hr;
257 UINT i;
258
259 hr = SHGetDesktopFolder(&desktop);
260 ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%08x\n", hr);
261 if (FAILED(hr)) return;
262
263 for (i = 0; i < ARRAY_SIZE(folders); i++)
264 {
266
267 hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, folders[i], &eaten, &pidl, NULL);
268 ok(hr == S_OK, "IShellFolder::ParseDisplayName failed with error 0x%08x\n", hr);
269 if (FAILED(hr)) continue;
270
271 hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER, &strret);
272 ok(hr == S_OK, "IShellFolder::GetDisplayNameOf failed with error 0x%08x\n", hr);
273 hr = StrRetToBufW(&strret, pidl, name1, ARRAY_SIZE(name1));
274 ok(hr == S_OK, "StrRetToBuf failed with error 0x%08x\n", hr);
275
276 hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, &strret);
277 ok(hr == S_OK, "IShellFolder::GetDisplayNameOf failed with error 0x%08x\n", hr);
278 hr = StrRetToBufW(&strret, pidl, name2, ARRAY_SIZE(name2));
279 ok(hr == S_OK, "StrRetToBuf failed with error 0x%08x\n", hr);
280
281 ok(!lstrcmpW(name1, name2), "the display names are not equal: %s vs %s\n", wine_dbgstr_w(name1), wine_dbgstr_w(name2));
282 ok(name1[0] != ':' || name1[1] != ':', "display name is a GUID: %s\n", wine_dbgstr_w(name1));
283
284 hr = IShellFolder_GetDisplayNameOf(desktop, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &strret);
285 ok(hr == S_OK, "IShellFolder::GetDisplayNameOf failed with error 0x%08x\n", hr);
286 hr = StrRetToBufW(&strret, pidl, name1, ARRAY_SIZE(name1));
287 ok(hr == S_OK, "StrRetToBuf failed with error 0x%08x\n", hr);
288
289 ok(lstrcmpW(name1, name2), "the display names are equal: %s\n", wine_dbgstr_w(name1));
290 ok(name1[0] == ':' && name1[1] == ':', "display name is not a GUID: %s\n", wine_dbgstr_w(name1));
291
292 ILFree(pidl);
293 }
294 IShellFolder_Release(desktop);
295}
296
297START_TEST(shfldr_special)
298{
304}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define broken(x)
Definition: _sntprintf.h:21
static int state
Definition: maze.c:121
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define MAX_PATH
Definition: compat.h:34
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3188
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1522
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static WCHAR name1[]
Definition: record.c:34
static WCHAR name2[]
Definition: record.c:35
#define todo_wine
Definition: custom.c:79
int details
Definition: msacm.c:1366
unsigned int UINT
Definition: ndis.h:50
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:929
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:539
#define LVCFMT_LEFT
Definition: commctrl.h:2598
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
#define win_skip
Definition: test.h:160
static void test_parse_for_control_panel(void)
static void test_printers_folder(void)
static void test_desktop_folder(void)
static void test_desktop_displaynameof(void)
static void test_parse_for_entire_network(void)
static BOOL SHELL_OsIsUnicode(void)
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_PRINTERS
Definition: shlobj.h:2162
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
@ STRRET_WSTR
Definition: shtypes.idl:85
@ SHCOLSTATE_TYPE_INT
Definition: shtypes.idl:122
@ SHCOLSTATE_TYPE_STR
Definition: shtypes.idl:121
@ SHCOLSTATE_ONBYDEFAULT
Definition: shtypes.idl:125
DWORD SHCOLSTATEF
Definition: shtypes.idl:142
Definition: cookie.c:202
Definition: fci.c:116
int32_t INT
Definition: typedefs.h:58
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_NO_NET_OR_BAD_PATH
Definition: winerror.h:706
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define ERROR_BAD_NET_NAME
Definition: winerror.h:159
__wchar_t WCHAR
Definition: xmlstorage.h:180