ReactOS 0.4.16-dev-1260-g901af6a
ItemIDList.cpp File Reference
#include "shelltest.h"
#include <shellutils.h>
Include dependency graph for ItemIDList.cpp:

Go to the source code of this file.

Classes

struct  FS95
 

Macros

#define TEST_CLSID(pidl, type, offset, clsid)
 

Enumerations

enum  {
  DIRBIT = 1 , FILEBIT = 2 , PT_COMPUTER_REGITEM = 0x2E , PT_INTERNET_URL = 0x61 ,
  PT_CONTROLS_OLDREGITEM = 0x70 , PT_CONTROLS_NEWREGITEM = 0x71
}
 

Functions

static BYTE GetPIDLType (LPCITEMIDLIST pidl)
 
static int FileStruct_Att (LPCITEMIDLIST pidl)
 
static HRESULT ParseDisplayName (PWSTR pszPath, LPITEMIDLIST *ppidl, IBindCtx *pBC=NULL)
 
static HRESULT GetDisplayNameOf (IShellFolder *pSF, LPCITEMIDLIST pidl, UINT Flags, PWSTR Buf, UINT Cap)
 
static HRESULT GetDisplayNameOf (PCIDLIST_ABSOLUTE pidl, UINT Flags, PWSTR Buf, UINT Cap)
 
 START_TEST (SHSimpleIDListFromPath)
 
 START_TEST (ILCreateFromPath)
 
 START_TEST (PIDL)
 
 START_TEST (ILIsEqual)
 

Macro Definition Documentation

◆ TEST_CLSID

#define TEST_CLSID (   pidl,
  type,
  offset,
  clsid 
)
Value:
do { \
ok_long(GetPIDLType(pidl), (type)); \
ok_int(*(CLSID*)((&pidl->mkid.abID[(offset) - sizeof(WORD)])) == clsid, TRUE); \
} while (0)
static BYTE GetPIDLType(LPCITEMIDLIST pidl)
Definition: ItemIDList.cpp:20
#define TRUE
Definition: types.h:120
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLintptr offset
Definition: glext.h:5920
REFCLSID clsid
Definition: msctf.c:82

Definition at line 78 of file ItemIDList.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
DIRBIT 
FILEBIT 
PT_COMPUTER_REGITEM 
PT_INTERNET_URL 
PT_CONTROLS_OLDREGITEM 
PT_CONTROLS_NEWREGITEM 

Definition at line 12 of file ItemIDList.cpp.

12 {
13 DIRBIT = 1, FILEBIT = 2,
15 PT_INTERNET_URL = 0x61,
18};
@ PT_CONTROLS_OLDREGITEM
Definition: ItemIDList.cpp:16
@ PT_CONTROLS_NEWREGITEM
Definition: ItemIDList.cpp:17
@ PT_INTERNET_URL
Definition: ItemIDList.cpp:15
@ FILEBIT
Definition: ItemIDList.cpp:13
@ PT_COMPUTER_REGITEM
Definition: ItemIDList.cpp:14
@ DIRBIT
Definition: ItemIDList.cpp:13

Function Documentation

◆ FileStruct_Att()

static int FileStruct_Att ( LPCITEMIDLIST  pidl)
static

Definition at line 47 of file ItemIDList.cpp.

48{
49 C_ASSERT(FIELD_OFFSET(FS95, att) == 12);
50 FS95 *p = FS95::Validate(pidl);
51 return p ? p->att : (UINT(1) << 31);
52}
GLfloat GLfloat p
Definition: glext.h:8902
#define C_ASSERT(e)
Definition: intsafe.h:73
unsigned int UINT
Definition: ndis.h:50
static FS95 * Validate(LPCITEMIDLIST p)
Definition: ItemIDList.cpp:40
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by START_TEST().

◆ GetDisplayNameOf() [1/2]

static HRESULT GetDisplayNameOf ( IShellFolder pSF,
LPCITEMIDLIST  pidl,
UINT  Flags,
PWSTR  Buf,
UINT  Cap 
)
static

Definition at line 61 of file ItemIDList.cpp.

62{
63 STRRET sr;
64 HRESULT hr = pSF->GetDisplayNameOf(pidl, Flags, &sr);
65 if (SUCCEEDED(hr))
66 hr = StrRetToBufW(&sr, pidl, Buf, Cap);
67 return hr;
68}
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1530
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
HRESULT hr
Definition: shlfolder.c:183
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by GetDisplayNameOf(), and START_TEST().

◆ GetDisplayNameOf() [2/2]

static HRESULT GetDisplayNameOf ( PCIDLIST_ABSOLUTE  pidl,
UINT  Flags,
PWSTR  Buf,
UINT  Cap 
)
static

Definition at line 70 of file ItemIDList.cpp.

71{
72 CComPtr<IShellFolder> pSF;
73 PCUITEMID_CHILD pidlChild;
74 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &pSF), &pidlChild);
75 return FAILED(hr) ? hr : GetDisplayNameOf(pSF, pidlChild, Flags, Buf, Cap);
76}
static HRESULT GetDisplayNameOf(IShellFolder *pSF, LPCITEMIDLIST pidl, UINT Flags, PWSTR Buf, UINT Cap)
Definition: ItemIDList.cpp:61
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1497
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
#define IID_PPV_ARG(Itype, ppType)

◆ GetPIDLType()

static BYTE GetPIDLType ( LPCITEMIDLIST  pidl)
static

Definition at line 20 of file ItemIDList.cpp.

21{
22 // Return the type without the 0x80 flag
23 return pidl && pidl->mkid.cb >= 3 ? (pidl->mkid.abID[0] & 0x7F) : 0;
24}

◆ ParseDisplayName()

static HRESULT ParseDisplayName ( PWSTR  pszPath,
LPITEMIDLIST ppidl,
IBindCtx pBC = NULL 
)
static

Definition at line 54 of file ItemIDList.cpp.

55{
56 CComPtr<IShellFolder> pSF;
58 return FAILED(hr) ? hr : pSF->ParseDisplayName(NULL, pBC, pszPath, NULL, ppidl, NULL);
59}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define NULL
Definition: types.h:112

◆ START_TEST() [1/4]

START_TEST ( ILCreateFromPath  )

Definition at line 186 of file ItemIDList.cpp.

187{
190
191 ok_ptr(ILCreateFromPathW(L"c:\\IDontExist"), NULL);
192
194 CComHeapPtr<ITEMIDLIST> pidlDir(ILCreateFromPathW(szPath));
195 if (szPath[1] != ':' || PathFindFileNameW(szPath) <= szPath)
196 {
197 skip("Not a local directory %ls\n", szPath);
198 }
199 else if (!(LPITEMIDLIST)pidlDir)
200 {
201 skip("?\n");
202 }
203 else
204 {
205 item = ILFindLastID(pidlDir);
206 ok_long(item->mkid.abID[0] & 0x73, 0x30 | DIRBIT);
207 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
208 }
209 PathAppendW(szPath, L"kernel32.dll");
210 CComHeapPtr<ITEMIDLIST> pidlFile(ILCreateFromPathW(szPath));
211 if (!(LPITEMIDLIST)pidlFile)
212 {
213 skip("?\n");
214 }
215 else
216 {
217 item = ILFindLastID(pidlFile);
218 ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT);
219 ok_int(*(UINT*)(&item->mkid.abID[2]) > 1024 * 42, TRUE); // At least this large
220 }
221}
#define ok_long(expression, result)
Definition: atltest.h:133
#define skip(...)
Definition: atltest.h:64
#define ok_int(expression, result)
Definition: atltest.h:134
#define ok_ptr(expression, result)
Definition: atltest.h:108
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1644
LPCWSTR szPath
Definition: env.c:37
static ATOM item
Definition: dde.c:856
#define L(x)
Definition: ntvdm.h:50
#define PathAppendW
Definition: pathcch.h:309
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1101
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
#define _countof(array)
Definition: sndvol32.h:70
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ START_TEST() [2/4]

START_TEST ( ILIsEqual  )

Definition at line 289 of file ItemIDList.cpp.

290{
291 LPITEMIDLIST p1, p2, pidl;
292
293 p1 = p2 = NULL;
294 ok_int(ILIsEqual(p1, p2), TRUE);
295
296 ITEMIDLIST emptyitem = {}, emptyitem2 = {};
297 ok_int(ILIsEqual(&emptyitem, &emptyitem2), TRUE);
298
299 ok_int(ILIsEqual(NULL, &emptyitem), FALSE); // These two are not equal for some reason
300
303 if (p1 && p2)
304 {
305 ok_int(ILIsEqual(p1, p2), TRUE);
306 p1->mkid.abID[0] = PT_COMPUTER_REGITEM; // RegItem in wrong parent
307 ok_int(ILIsEqual(p1, p2), FALSE);
308 }
309 else
310 {
311 skip("Unable to initialize test\n");
312 }
313 ILFree(p1);
314 ILFree(p2);
315
316 // ILIsParent must compare like ILIsEqual
317 p1 = SHSimpleIDListFromPath(L"c:\\");
318 p2 = SHSimpleIDListFromPath(L"c:\\dir\\file");
319 if (p1 && p2)
320 {
321 ok_int(ILIsParent(NULL, p1, FALSE), FALSE); // NULL is always false
322 ok_int(ILIsParent(p1, NULL, FALSE), FALSE); // NULL is always false
323 ok_int(ILIsParent(NULL, NULL, FALSE), FALSE); // NULL is always false
324 ok_int(ILIsParent(p1, p1, FALSE), TRUE); // I'm my own parent
325 ok_int(ILIsParent(p1, p1, TRUE), FALSE); // Self is not immediate
326 ok_int(ILIsParent(p1, p2, FALSE), TRUE); // Grandchild
327 ok_int(ILIsParent(p1, p2, TRUE), FALSE); // Grandchild is not immediate
328 ok_ptr(ILFindChild(p1, p2), ILGetNext(ILGetNext(p2))); // Child is "dir\\file", skip MyComputer and C:
329 ok_int(ILIsEmpty(pidl = ILFindChild(p1, p1)) && pidl, TRUE); // Self
330 ILRemoveLastID(p2);
331 ok_int(ILIsParent(p1, p2, TRUE), TRUE); // Immediate child
332
333 p1->mkid.abID[0] = PT_COMPUTER_REGITEM; // RegItem in wrong parent
334 ok_int(ILIsParent(p1, p2, FALSE), FALSE);
335 }
336 else
337 {
338 skip("Unable to initialize test\n");
339 }
340 ILFree(p1);
341 ILFree(p2);
342}
#define FALSE
Definition: types.h:117
LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner, int nFolder, BOOL fCreate)
Definition: pidl.c:445
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1044
BOOL WINAPI ILIsParent(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild, BOOL bImmediate)
Definition: pidl.c:697
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:221
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:970
PUIDLIST_RELATIVE WINAPI ILFindChild(PIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
Definition: pidl.c:750
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:582
static BOOL ILIsEmpty(_In_opt_ PCUIDLIST_RELATIVE pidl)
Definition: shlobj.h:2527
PIDLIST_ABSOLUTE WINAPI SHSimpleIDListFromPath(PCWSTR)
#define CSIDL_DRIVES
Definition: shlobj.h:2197

◆ START_TEST() [3/4]

START_TEST ( PIDL  )

Definition at line 223 of file ItemIDList.cpp.

224{
225 CCoInit ComInit;
226 LPITEMIDLIST pidl;
227
229 if (pidl)
230 TEST_CLSID(ILFindLastID(pidl), 0x1f, 4, CLSID_MyComputer);
231 else
232 skip("?\n");
233 ILFree(pidl);
234
236 if (pidl)
237 {
238 // Accept both the old and new format from the special folder API (NT5 vs NT6)
239 LPITEMIDLIST pidlLeaf = ILFindLastID(pidl);
240 if (LOBYTE(GetVersion()) < 6)
241 TEST_CLSID(pidlLeaf, PT_CONTROLS_OLDREGITEM, 4, CLSID_Printers);
242 else
243 TEST_CLSID(pidlLeaf, PT_CONTROLS_NEWREGITEM, 14, CLSID_Printers);
244
245 // The Control Panel should always return the new format when parsing
246 LPITEMIDLIST pidl2;
247 WCHAR szParse[MAX_PATH];
248 if (SUCCEEDED(GetDisplayNameOf(pidl, SHGDN_FORPARSING, szParse, _countof(szParse))) &&
249 SUCCEEDED(ParseDisplayName(szParse, &pidl2)))
250 {
251 TEST_CLSID(ILFindLastID(pidl2), PT_CONTROLS_NEWREGITEM, 14, CLSID_Printers);
252 ILFree(pidl2);
253 }
254 else
255 {
256 skip("Failed to parse in Control Panel\n");
257 }
258 }
259 else
260 {
261 skip("?\n");
262 }
263 ILFree(pidl);
264
265
266 CComPtr<IShellFolder> pInternet;
267 HRESULT hr = SHCoCreateInstance(NULL, &CLSID_Internet, NULL, IID_PPV_ARG(IShellFolder, &pInternet));
268 if (SUCCEEDED(hr))
269 {
270 PCWSTR pszUrl = L"http://example.com/page?query&foo=bar";
271 PIDLIST_RELATIVE pidlUrl;
272 hr = pInternet->ParseDisplayName(NULL, NULL, const_cast<PWSTR>(pszUrl), NULL, &pidlUrl, NULL);
273 ok_long(hr, S_OK);
274 if (hr == S_OK)
275 {
276 ok_int(pidlUrl->mkid.abID[0], PT_INTERNET_URL);
278 hr = GetDisplayNameOf(pInternet, pidlUrl, SHGDN_FORPARSING, buf, _countof(buf));
279 ok_long(hr, S_OK);
280 if (SUCCEEDED(hr))
281 {
282 ok(!lstrcmpiW(buf, pszUrl), "FORPARSING must match URL\n");
283 }
284 ILFree(pidlUrl);
285 }
286 }
287}
#define TEST_CLSID(pidl, type, offset, clsid)
Definition: ItemIDList.cpp:78
#define ok(value,...)
Definition: atltest.h:57
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv)
Definition: shellole.c:105
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define S_OK
Definition: intsafe.h:52
#define LOBYTE(W)
Definition: jmemdos.c:487
static IParseDisplayName ParseDisplayName
Definition: moniker.c:816
#define CSIDL_PRINTERS
Definition: shlobj.h:2185
COM Initialisation.
Definition: shellclasses.h:179
BYTE abID[1]
Definition: shtypes.idl:28
SHITEMID mkid
Definition: shtypes.idl:34
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57

◆ START_TEST() [4/4]

START_TEST ( SHSimpleIDListFromPath  )

Definition at line 84 of file ItemIDList.cpp.

85{
86 HRESULT hr;
89
90 // We compare pidl1 and pidl2
91 CComHeapPtr<ITEMIDLIST> pidl1(SHSimpleIDListFromPath(szPath));
92 CComHeapPtr<ITEMIDLIST> pidl2(ILCreateFromPathW(szPath));
93
94 // Yes, they are equal logically
95 LPITEMIDLIST pidl1Last = ILFindLastID(pidl1), pidl2Last = ILFindLastID(pidl2);
96 ok_int(ILIsEqual(pidl1, pidl2), TRUE);
97 ok_int(ILIsEqual(pidl1Last, pidl2Last), TRUE);
98
99 // Bind to parent
100 CComPtr<IShellFolder> psf1, psf2;
101 hr = SHBindToParent(pidl1, IID_PPV_ARG(IShellFolder, &psf1), NULL);
102 ok_long(hr, S_OK);
103 hr = SHBindToParent(pidl2, IID_PPV_ARG(IShellFolder, &psf2), NULL);
104 ok_long(hr, S_OK);
105
106 // Get attributes
107 DWORD attrs1 = SFGAO_FOLDER, attrs2 = SFGAO_FOLDER;
108 hr = (psf1 ? psf1->GetAttributesOf(1, &pidl1Last, &attrs1) : E_UNEXPECTED);
109 ok_long(hr, S_OK);
110 hr = (psf2 ? psf2->GetAttributesOf(1, &pidl2Last, &attrs2) : E_UNEXPECTED);
111 ok_long(hr, S_OK);
112
113 // There is the difference in attributes because SHSimpleIDListFromPath
114 // cannot create PIDLs to folders, only files and drives:
115 ok_long((attrs1 & SFGAO_FOLDER), 0);
116 ok_long((attrs2 & SFGAO_FOLDER), SFGAO_FOLDER);
117
118
119 // Make sure the internal details match Windows NT5+
122 CComHeapPtr<ITEMIDLIST> pidlSys32(SHSimpleIDListFromPath(szPath));
123 if (szPath[1] != ':' || PathFindFileNameW(szPath) <= szPath)
124 {
125 skip("Not a local directory %ls\n", szPath);
126 }
127 else if (!(LPITEMIDLIST)pidlSys32)
128 {
129 skip("?\n");
130 }
131 else
132 {
133 item = ILFindLastID(pidlSys32);
134 ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT); // This is actually a file PIDL
135 ok_long(FileStruct_Att(item), 0); // Simple PIDL without attributes
136 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
137
138 ILRemoveLastID(pidlSys32); // Now we should have "c:\Windows"
139 item = ILFindLastID(pidlSys32);
140 ok_long(item->mkid.abID[0] & 0x73, 0x30 | DIRBIT);
141 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
142 }
143
144 WCHAR drive[4] = { szPath[0], szPath[1], L'\\', L'\0' };
145 CComHeapPtr<ITEMIDLIST> pidlDrive(SHSimpleIDListFromPath(drive));
146 if (drive[1] != ':')
147 {
148 skip("Not a local drive %ls\n", drive);
149 }
150 else if (!(LPITEMIDLIST)pidlDrive)
151 {
152 skip("?\n");
153 }
154 else
155 {
156 item = ILFindLastID(pidlDrive);
157 ok_long(item->mkid.abID[0] & 0x70, 0x20); // Something in My Computer
158 ok_char(item->mkid.abID[1] | 32, drive[0] | 32);
159 }
160
161 CComHeapPtr<ITEMIDLIST> pidlVirt(SHSimpleIDListFromPath(L"x:\\IDontExist"));
162 if (!(LPITEMIDLIST)pidlVirt)
163 {
164 skip("?\n");
165 }
166 else
167 {
168 item = ILFindLastID(pidlVirt);
169 ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT); // Yes, a file
170 ok_long(FileStruct_Att(item), 0); // Simple PIDL, no attributes
171 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
172
173 ILRemoveLastID(pidlVirt); // "x:\"
174 item = ILFindLastID(pidlVirt);
175 ok_long(item->mkid.abID[0] & 0x70, 0x20); // Something in My Computer
176 ok_char(item->mkid.abID[1] | 32, 'x' | 32); // x:
177 }
178
179 LPITEMIDLIST pidl;
180 ok_int((pidl = SHSimpleIDListFromPath(L"c:")) != NULL, LOBYTE(GetVersion()) >= 6);
181 ILFree(pidl);
182 ok_int((pidl = SHSimpleIDListFromPath(L"c:\\")) != NULL, TRUE);
183 ILFree(pidl);
184}
static int FileStruct_Att(LPCITEMIDLIST pidl)
Definition: ItemIDList.cpp:47
#define ok_char(expression, result)
Definition: atltest.h:122
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
unsigned long DWORD
Definition: ntddk_ex.h:95
#define E_UNEXPECTED
Definition: winerror.h:2456