ReactOS 0.4.15-dev-8614-gbc76250
ItemIDList.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Test for SHSimpleIDListFromPath
5 * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 * Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
7 */
8
9#include "shelltest.h"
10#include <shellutils.h>
11
12enum { DIRBIT = 1, FILEBIT = 2 };
13
15{
16 // Return the type without the 0x80 flag
17 return pidl && pidl->mkid.cb >= 3 ? (pidl->mkid.abID[0] & 0x7F) : 0;
18}
19
20struct FS95 // FileSystem item header
21{
29
31 {
32 return (p && p->mkid.cb > 2) ? (p->mkid.abID[0] & 0x70) == 0x30 : FALSE;
33 }
35 {
37 return p && p->mkid.cb > FIELD_OFFSET(FS95, name) && IsFS(p) ? (FS95*)p : NULL;
38 }
39};
40
42{
43 C_ASSERT(FIELD_OFFSET(FS95, att) == 12);
44 FS95 *p = FS95::Validate(pidl);
45 return p ? p->att : (UINT(1) << 31);
46}
47
48#define TEST_CLSID(pidl, type, offset, clsid) \
49 do { \
50 ok_long(GetPIDLType(pidl), (type)); \
51 ok_int(*(CLSID*)((&pidl->mkid.abID[(offset) - sizeof(WORD)])) == clsid, TRUE); \
52 } while (0)
53
55{
56 HRESULT hr;
59
60 // We compare pidl1 and pidl2
61 CComHeapPtr<ITEMIDLIST> pidl1(SHSimpleIDListFromPath(szPath));
62 CComHeapPtr<ITEMIDLIST> pidl2(ILCreateFromPathW(szPath));
63
64 // Yes, they are equal logically
65 LPITEMIDLIST pidl1Last = ILFindLastID(pidl1), pidl2Last = ILFindLastID(pidl2);
66 ok_int(ILIsEqual(pidl1, pidl2), TRUE);
67 ok_int(ILIsEqual(pidl1Last, pidl2Last), TRUE);
68
69 // Bind to parent
70 CComPtr<IShellFolder> psf1, psf2;
72 ok_long(hr, S_OK);
74 ok_long(hr, S_OK);
75
76 // Get attributes
77 DWORD attrs1 = SFGAO_FOLDER, attrs2 = SFGAO_FOLDER;
78 hr = (psf1 ? psf1->GetAttributesOf(1, &pidl1Last, &attrs1) : E_UNEXPECTED);
79 ok_long(hr, S_OK);
80 hr = (psf2 ? psf2->GetAttributesOf(1, &pidl2Last, &attrs2) : E_UNEXPECTED);
81 ok_long(hr, S_OK);
82
83 // There is the difference in attributes because SHSimpleIDListFromPath
84 // cannot create PIDLs to folders, only files and drives:
85 ok_long((attrs1 & SFGAO_FOLDER), 0);
86 ok_long((attrs2 & SFGAO_FOLDER), SFGAO_FOLDER);
87
88
89 // Make sure the internal details match Windows NT5+
92 CComHeapPtr<ITEMIDLIST> pidlSys32(SHSimpleIDListFromPath(szPath));
93 if (szPath[1] != ':' || PathFindFileNameW(szPath) <= szPath)
94 {
95 skip("Not a local directory %ls\n", szPath);
96 }
97 else if (!(LPITEMIDLIST)pidlSys32)
98 {
99 skip("?\n");
100 }
101 else
102 {
103 item = ILFindLastID(pidlSys32);
104 ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT); // This is actually a file PIDL
105 ok_long(FileStruct_Att(item), 0); // Simple PIDL without attributes
106 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
107
108 ILRemoveLastID(pidlSys32); // Now we should have "c:\Windows"
109 item = ILFindLastID(pidlSys32);
110 ok_long(item->mkid.abID[0] & 0x73, 0x30 | DIRBIT);
111 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
112 }
113
114 WCHAR drive[4] = { szPath[0], szPath[1], L'\\', L'\0' };
115 CComHeapPtr<ITEMIDLIST> pidlDrive(SHSimpleIDListFromPath(drive));
116 if (drive[1] != ':')
117 {
118 skip("Not a local drive %ls\n", drive);
119 }
120 else if (!(LPITEMIDLIST)pidlDrive)
121 {
122 skip("?\n");
123 }
124 else
125 {
126 item = ILFindLastID(pidlDrive);
127 ok_long(item->mkid.abID[0] & 0x70, 0x20); // Something in My Computer
128 ok_char(item->mkid.abID[1] | 32, drive[0] | 32);
129 }
130
131 CComHeapPtr<ITEMIDLIST> pidlVirt(SHSimpleIDListFromPath(L"x:\\IDontExist"));
132 if (!(LPITEMIDLIST)pidlVirt)
133 {
134 skip("?\n");
135 }
136 else
137 {
138 item = ILFindLastID(pidlVirt);
139 ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT); // Yes, a file
140 ok_long(FileStruct_Att(item), 0); // Simple PIDL, no attributes
141 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
142
143 ILRemoveLastID(pidlVirt); // "x:\"
144 item = ILFindLastID(pidlVirt);
145 ok_long(item->mkid.abID[0] & 0x70, 0x20); // Something in My Computer
146 ok_char(item->mkid.abID[1] | 32, 'x' | 32); // x:
147 }
148}
149
151{
154
155 ok_ptr(ILCreateFromPathW(L"c:\\IDontExist"), NULL);
156
158 CComHeapPtr<ITEMIDLIST> pidlDir(ILCreateFromPathW(szPath));
159 if (szPath[1] != ':' || PathFindFileNameW(szPath) <= szPath)
160 {
161 skip("Not a local directory %ls\n", szPath);
162 }
163 else if (!(LPITEMIDLIST)pidlDir)
164 {
165 skip("?\n");
166 }
167 else
168 {
169 item = ILFindLastID(pidlDir);
170 ok_long(item->mkid.abID[0] & 0x73, 0x30 | DIRBIT);
171 ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
172 }
173 PathAppendW(szPath, L"kernel32.dll");
174 CComHeapPtr<ITEMIDLIST> pidlFile(ILCreateFromPathW(szPath));
175 if (!(LPITEMIDLIST)pidlFile)
176 {
177 skip("?\n");
178 }
179 else
180 {
181 item = ILFindLastID(pidlFile);
182 ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT);
183 ok_int(*(UINT*)(&item->mkid.abID[2]) > 1024 * 42, TRUE); // At least this large
184 }
185}
186
188{
189 LPITEMIDLIST pidl;
190
192 if (pidl)
193 TEST_CLSID(ILFindLastID(pidl), 0x1f, 4, CLSID_MyComputer);
194 else
195 skip("?\n");
196 ILFree(pidl);
197
199 if (pidl)
200 TEST_CLSID(ILFindLastID(pidl), 0x71, 14, CLSID_Printers);
201 else
202 skip("?\n");
203 ILFree(pidl);
204}
static int FileStruct_Att(LPCITEMIDLIST pidl)
Definition: ItemIDList.cpp:41
static BYTE GetPIDLType(LPCITEMIDLIST pidl)
Definition: ItemIDList.cpp:14
#define TEST_CLSID(pidl, type, offset, clsid)
Definition: ItemIDList.cpp:48
@ FILEBIT
Definition: ItemIDList.cpp:12
@ DIRBIT
Definition: ItemIDList.cpp:12
#define ok_long(expression, result)
Definition: atltest.h:133
#define skip(...)
Definition: atltest.h:64
#define ok_char(expression, result)
Definition: atltest.h:122
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
#define ok_ptr(expression, result)
Definition: atltest.h:108
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLfloat GLfloat p
Definition: glext.h:8902
#define S_OK
Definition: intsafe.h:52
#define C_ASSERT(e)
Definition: intsafe.h:73
LPCWSTR szPath
Definition: env.c:37
static ATOM item
Definition: dde.c:856
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define PathAppendW
Definition: pathcch.h:309
LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner, int nFolder, BOOL fCreate)
Definition: pidl.c:443
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:946
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:221
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1356
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1003
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:548
HRESULT hr
Definition: shlfolder.c:183
#define ILCreateFromPath
Definition: shlobj.h:2506
#define CSIDL_PRINTERS
Definition: shlobj.h:2177
PIDLIST_ABSOLUTE WINAPI SHSimpleIDListFromPath(PCWSTR)
#define CSIDL_DRIVES
Definition: shlobj.h:2189
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
WORD time
Definition: ItemIDList.cpp:26
WORD att
Definition: ItemIDList.cpp:27
BYTE unknown
Definition: ItemIDList.cpp:24
WORD cb
Definition: ItemIDList.cpp:22
BYTE type
Definition: ItemIDList.cpp:23
static FS95 * Validate(LPCITEMIDLIST p)
Definition: ItemIDList.cpp:34
WORD date
Definition: ItemIDList.cpp:26
UINT size
Definition: ItemIDList.cpp:25
static BOOL IsFS(LPCITEMIDLIST p)
Definition: ItemIDList.cpp:30
Definition: name.c:39
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define E_UNEXPECTED
Definition: winerror.h:2456
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193