ReactOS  0.4.14-dev-342-gdc047f9
SHParseDisplayName.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 SHParseDisplayName
5  * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "shelltest.h"
9 
10 /* Version masks */
11 #define T_ALL 0x0
12 #define T_WIN2K 0x1
13 #define T_WINXP 0x2
14 #define T_WIN2K3 0x4
15 #define T_VISTA 0x8
16 #define T_WIN7 0x10
17 #define T_WIN8 0x20
18 #define T_WIN10 0x40
19 
20 #define T_PRE_VISTA T_WIN2K|T_WINXP|T_WIN2K3
21 #define T_VISTA_PLUS T_VISTA|T_WIN7|T_WIN8|T_WIN10
22 
23 struct test_data
24 {
25  int testline;
31 };
32 
33 struct test_data Tests[] =
34 {
35  /* Tests for CDesktopFolder */
36  {__LINE__, NULL, NULL, 0, E_OUTOFMEMORY, T_PRE_VISTA},
37  {__LINE__, NULL, NULL, 0, E_INVALIDARG, T_VISTA_PLUS},
38  {__LINE__, L"", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
40  {__LINE__, L" ", NULL, 0, E_INVALIDARG, T_VISTA_PLUS},
41  {__LINE__, L":", NULL, 0, E_INVALIDARG, 0},
42  {__LINE__, L": ", NULL, 0, E_INVALIDARG, 0},
43  {__LINE__, L" :", NULL, 0, E_INVALIDARG, 0},
44  {__LINE__, L"/", NULL, 0, E_INVALIDARG, 0},
45  {__LINE__, L"//", NULL, 0, E_INVALIDARG, 0},
46  /* This opens C:\ from Win+R and address bar */
47  {__LINE__, L"\\", NULL, 0, E_INVALIDARG, 0},
48  /* These two opens "C:\Program Files" from Win+R and address bar */
49  {__LINE__, L"\\Program Files", NULL, 0, E_INVALIDARG, 0},
50  {__LINE__, L"\\Program Files\\", NULL, 0, E_INVALIDARG, 0},
51  {__LINE__, L"\\\\?", NULL, 0, E_INVALIDARG, 0},
52  {__LINE__, L"\\\\?\\", NULL, 0, E_INVALIDARG, 0},
53  /* Tests for the shell: protocol */
54  {__LINE__, L"shell:", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0},
55  {__LINE__, L"shell::", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0},
56  {__LINE__, L"shell:::", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0},
57  {__LINE__, L"shell:::{", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0},
58  {__LINE__, L"shell:fail", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0},
59  {__LINE__, L"shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
60  {__LINE__, L"shell:desktop", NULL, CSIDL_DESKTOPDIRECTORY, S_OK, T_PRE_VISTA},
61  {__LINE__, L"shell:windows", NULL, CSIDL_WINDOWS, S_OK, T_PRE_VISTA},
62  {__LINE__, L"shell:system", NULL, CSIDL_SYSTEM, S_OK, T_PRE_VISTA},
63  {__LINE__, L"shell:personal", NULL, CSIDL_MYDOCUMENTS, S_OK, T_PRE_VISTA},
64  {__LINE__, L"shell:programs", NULL, CSIDL_PROGRAMS, S_OK, T_PRE_VISTA},
65  {__LINE__, L"shell:programfiles", NULL, CSIDL_PROGRAM_FILES, S_OK, T_PRE_VISTA},
66  /* The following tests are confusing. They don't work for SHParseDisplayName but work on psfDesktop->ParseDisplayName */
67  {__LINE__, L"shell:desktop", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_VISTA_PLUS},
68  {__LINE__, L"shell:windows", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_VISTA_PLUS},
69  {__LINE__, L"shell:system", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_VISTA_PLUS},
70  {__LINE__, L"shell:personal", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_VISTA_PLUS},
71  {__LINE__, L"shell:programs", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_VISTA_PLUS},
72  {__LINE__, L"shell:programfiles", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_VISTA_PLUS},
73  /* Tests for CInternet */
74  {__LINE__, L"aa:", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
75  {__LINE__, L"garbage:", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
76  {__LINE__, L"ftp:", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
77  {__LINE__, L"ftp:/", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
78  {__LINE__, L"ftp://", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
79  {__LINE__, L"ftp://a", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
80  {__LINE__, L"ftp://ftp.gnu.org/gnu/octave/", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
81  {__LINE__, L"aa:", L"aa:", 0, S_OK, T_VISTA_PLUS},
82  {__LINE__, L"garbage:", L"garbage:", 0, S_OK, T_VISTA_PLUS},
83  {__LINE__, L"ftp:", L"ftp:", 0, S_OK, T_VISTA_PLUS},
84  {__LINE__, L"ftp:/", L"ftp:/", 0, S_OK, T_VISTA_PLUS},
85  {__LINE__, L"ftp://", L"ftp:///", 0, S_OK, T_VISTA_PLUS},
86  {__LINE__, L"ftp://a", L"ftp://a/", 0, S_OK, T_VISTA_PLUS},
87  {__LINE__, L"ftp://ftp.gnu.org/gnu/octave/", L"ftp://ftp.gnu.org/gnu/octave/", 0, S_OK, T_VISTA_PLUS},
88  /* Tests for CRegFolder */
89  {__LINE__, L"::", NULL, 0, CO_E_CLASSSTRING, 0},
90  {__LINE__, L"::{", NULL, 0, CO_E_CLASSSTRING, 0},
91  {__LINE__, L"::{ ", NULL, 0, CO_E_CLASSSTRING, 0},
92  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
93  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D} ", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
94  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}a", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
95  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}garbage", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
96  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D ", NULL, 0, CO_E_CLASSSTRING, 0},
97  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\", NULL, 0, E_INVALIDARG, 0},
98  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\ ", NULL, 0, E_INVALIDARG, 0},
99  {__LINE__, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}", 0, S_OK, 0},
100  /* Tests for CDrivesFolder */
101  {__LINE__, L"c:", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
102  {__LINE__, L"c:", L"C:\\", 0, S_OK, T_VISTA_PLUS},
103  {__LINE__, L"c:\\", L"C:\\", 0, S_OK, 0},
104  {__LINE__, L"C:\\", L"C:\\", 0, S_OK, 0},
105  {__LINE__, L"y:\\", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_PRE_VISTA},
106  {__LINE__, L"y:\\", NULL, 0, HRESULT_FROM_WIN32(ERROR_INVALID_DRIVE), T_VISTA_PLUS},
107  {__LINE__, L"C:\\ ", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), T_PRE_VISTA},
108  {__LINE__, L"C:\\ ", NULL, 0, E_INVALIDARG, T_VISTA_PLUS},
109  /* Tests for CFSFolder */
110  {__LINE__, L"$", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0},
111  {__LINE__, L"c:\\Program Files", L"C:\\Program Files", 0, S_OK, 0},
112  {__LINE__, L"c:\\Program Files\\", L"C:\\Program Files", 0, S_OK, 0},
113  /* Paths with . are valid for win+r dialog or address bar but not for ParseDisplayName */
114  {__LINE__, L"c:\\Program Files\\.", NULL, 0, E_INVALIDARG, 0},
115  {__LINE__, L"c:\\Program Files\\..", NULL, 0, E_INVALIDARG, 0}, /* This gives C:\ when entered in address bar */
116  {__LINE__, L".", NULL, 0, E_INVALIDARG, 0},
117  {__LINE__, L"..", NULL, 0, E_INVALIDARG, 0},
118  {__LINE__, L"C:\\.", NULL, 0, E_INVALIDARG, 0},
119  {__LINE__, L"fonts", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}, /* These three work for ShellExecute */
120  {__LINE__, L"winsxs", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0},
121  {__LINE__, L"system32", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}
122 };
123 
125 {
126  switch (LOWORD(GetVersion()))
127  {
128  case 5: return T_WIN2K;
129  case (5 | (1 << 8)): return T_WINXP;
130  case (5 | (2 << 8)): return T_WIN2K3;
131  case 6: return T_VISTA;
132  case (6 | (1 << 8)): return T_WIN7;
133  case (6 | (2 << 8)): return T_WIN8;
134  case 10: return T_WIN10;
135  }
136 
137  return 0;
138 }
139 
141 {
142  HRESULT hr;
143  WCHAR winDir[MAX_PATH];
144  UINT os_flag = get_host_os_flag();
145  ok (os_flag != 0, "Incompatible os version %d!", os_flag);
146  if (os_flag == 0)
147  return;
148 
149  IShellFolder *psfDesktop;
150  hr = SHGetDesktopFolder(&psfDesktop);
151  ok(hr == S_OK, "hr = %lx\n", hr);
152 
153  GetWindowsDirectoryW(winDir, _countof(winDir));
154  SetCurrentDirectoryW(winDir);
155 
156  for (UINT i = 0; i < _countof(Tests); i ++)
157  {
158  if (Tests[i].ValidForVersion && !(Tests[i].ValidForVersion & os_flag))
159  continue;
160 
161  PIDLIST_ABSOLUTE pidl;
163  ok(hr == Tests[i].hResult, "%d: Expected error 0x%lx, got 0x%lx\n", Tests[i].testline, Tests[i].hResult, hr);
164 
166  {
167  ok(pidl == NULL, "%d: Expected no pidl\n", Tests[i].testline);
168  continue;
169  }
170 
171  ok(pidl != NULL, "%d: Expected pidl on success\n", Tests[i].testline);
172  if(!pidl)
173  continue;
174 
175  STRRET strret;
176  hr = psfDesktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
177  ok(hr == S_OK, "%d: hr = %lx\n", Tests[i].testline, hr);
178 
179  ok(strret.uType == STRRET_WSTR, "%d: Expected STRRET_WSTR\n", Tests[i].testline);
180 
182  {
183  ok(!wcscmp(strret.pOleStr, Tests[i].wszExpectedDisplayName), "%d: expected %S got %S\n", Tests[i].testline, Tests[i].wszExpectedDisplayName, strret.pOleStr);
184  }
185  else
186  {
187  PIDLIST_ABSOLUTE pidlSpecial;
189  ok(hr == S_OK, "%d: hr = %lx\n", Tests[i].testline, hr);
190 
191  STRRET strretSpecial;
192  hr = psfDesktop->GetDisplayNameOf(pidlSpecial, SHGDN_FORPARSING, &strretSpecial);
193  ok(hr == S_OK, "%d: hr = %lx\n", Tests[i].testline, hr);
194 
195  ok(strret.uType == STRRET_WSTR, "%d: Expected STRRET_WSTR\n", Tests[i].testline);
196 
197  ok(!wcscmp(strret.pOleStr, strretSpecial.pOleStr), "%d: expected %S got %S\n", Tests[i].testline, strretSpecial.pOleStr, strret.pOleStr);
198  }
199  }
200 
201  CoUninitialize();
202 }
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
HRESULT hr
Definition: shlfolder.c:183
#define T_PRE_VISTA
#define _countof(array)
Definition: fontsub.cpp:30
#define T_VISTA
#define T_WIN8
LPWSTR pOleStr
Definition: shtypes.idl:96
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2040
PCWSTR wszExpectedDisplayName
int32_t INT
Definition: typedefs.h:56
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2015
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 E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define T_VISTA_PLUS
#define CSIDL_WINDOWS
Definition: shlobj.h:2038
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
UINT get_host_os_flag()
#define T_WIN2K
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
__wchar_t WCHAR
Definition: xmlstorage.h:180
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2761
LONG HRESULT
Definition: typedefs.h:77
#define T_WIN10
#define MAX_PATH
Definition: compat.h:26
static const WCHAR L[]
Definition: oid.c:1250
START_TEST(SHParseDisplayName)
#define ERROR_INVALID_DRIVE
Definition: winerror.h:118
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define S_OK
Definition: intsafe.h:59
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2248
#define ok(value,...)
Definition: atltest.h:57
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1367
unsigned int UINT
Definition: ndis.h:50
#define T_WIN7
#define CO_E_CLASSSTRING
Definition: winerror.h:2806
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define CSIDL_SYSTEM
Definition: shlobj.h:2039
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2018
#define T_WIN2K3
UINT uType
Definition: shtypes.idl:93
#define CSIDL_PROGRAMS
Definition: shlobj.h:2005
#define T_WINXP
#define LOWORD(l)
Definition: pedump.c:82
struct test_data Tests[]