mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
[SHELL32_APITEST] Stricter SHSimpleIDListFromPath tests (#6894)
The first x number of bytes in PIDLs for drive letters, folders and files are set in stone and should match Windows.
This commit is contained in:
parent
3da9e7e251
commit
c3ec1b9ac6
4 changed files with 209 additions and 44 deletions
|
@ -20,6 +20,7 @@ list(APPEND SOURCE
|
|||
GUIDFromString.cpp
|
||||
Int64ToString.cpp
|
||||
IShellFolderViewCB.cpp
|
||||
ItemIDList.cpp
|
||||
OpenAs_RunDLL.cpp
|
||||
PathIsEqualOrSubFolder.cpp
|
||||
PathIsTemporary.cpp
|
||||
|
@ -32,7 +33,6 @@ list(APPEND SOURCE
|
|||
SHCreateFileExtractIconW.cpp
|
||||
SHParseDisplayName.cpp
|
||||
SHRestricted.cpp
|
||||
SHSimpleIDListFromPath.cpp
|
||||
She.cpp
|
||||
ShellExecCmdLine.cpp
|
||||
ShellExecuteEx.cpp
|
||||
|
|
204
modules/rostests/apitests/shell32/ItemIDList.cpp
Normal file
204
modules/rostests/apitests/shell32/ItemIDList.cpp
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Test for SHSimpleIDListFromPath
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
* Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
|
||||
*/
|
||||
|
||||
#include "shelltest.h"
|
||||
#include <shellutils.h>
|
||||
|
||||
enum { DIRBIT = 1, FILEBIT = 2 };
|
||||
|
||||
static BYTE GetPIDLType(LPCITEMIDLIST pidl)
|
||||
{
|
||||
// Return the type without the 0x80 flag
|
||||
return pidl && pidl->mkid.cb >= 3 ? (pidl->mkid.abID[0] & 0x7F) : 0;
|
||||
}
|
||||
|
||||
struct FS95 // FileSystem item header
|
||||
{
|
||||
WORD cb;
|
||||
BYTE type;
|
||||
BYTE unknown;
|
||||
UINT size;
|
||||
WORD date, time;
|
||||
WORD att;
|
||||
CHAR name[ANYSIZE_ARRAY];
|
||||
|
||||
static BOOL IsFS(LPCITEMIDLIST p)
|
||||
{
|
||||
return (p && p->mkid.cb > 2) ? (p->mkid.abID[0] & 0x70) == 0x30 : FALSE;
|
||||
}
|
||||
static FS95* Validate(LPCITEMIDLIST p)
|
||||
{
|
||||
C_ASSERT(FIELD_OFFSET(FS95, name) == 14);
|
||||
return p && p->mkid.cb > FIELD_OFFSET(FS95, name) && IsFS(p) ? (FS95*)p : NULL;
|
||||
}
|
||||
};
|
||||
|
||||
static int FileStruct_Att(LPCITEMIDLIST pidl)
|
||||
{
|
||||
C_ASSERT(FIELD_OFFSET(FS95, att) == 12);
|
||||
FS95 *p = FS95::Validate(pidl);
|
||||
return p ? p->att : (UINT(1) << 31);
|
||||
}
|
||||
|
||||
#define TEST_CLSID(pidl, type, offset, clsid) \
|
||||
do { \
|
||||
ok_long(GetPIDLType(pidl), (type)); \
|
||||
ok_int(*(CLSID*)((&pidl->mkid.abID[(offset) - sizeof(WORD)])) == clsid, TRUE); \
|
||||
} while (0)
|
||||
|
||||
START_TEST(SHSimpleIDListFromPath)
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR szPath[MAX_PATH];
|
||||
GetWindowsDirectoryW(szPath, _countof(szPath));
|
||||
|
||||
// We compare pidl1 and pidl2
|
||||
CComHeapPtr<ITEMIDLIST> pidl1(SHSimpleIDListFromPath(szPath));
|
||||
CComHeapPtr<ITEMIDLIST> pidl2(ILCreateFromPathW(szPath));
|
||||
|
||||
// Yes, they are equal logically
|
||||
LPITEMIDLIST pidl1Last = ILFindLastID(pidl1), pidl2Last = ILFindLastID(pidl2);
|
||||
ok_int(ILIsEqual(pidl1, pidl2), TRUE);
|
||||
ok_int(ILIsEqual(pidl1Last, pidl2Last), TRUE);
|
||||
|
||||
// Bind to parent
|
||||
CComPtr<IShellFolder> psf1, psf2;
|
||||
hr = SHBindToParent(pidl1, IID_PPV_ARG(IShellFolder, &psf1), NULL);
|
||||
ok_long(hr, S_OK);
|
||||
hr = SHBindToParent(pidl2, IID_PPV_ARG(IShellFolder, &psf2), NULL);
|
||||
ok_long(hr, S_OK);
|
||||
|
||||
// Get attributes
|
||||
DWORD attrs1 = SFGAO_FOLDER, attrs2 = SFGAO_FOLDER;
|
||||
hr = (psf1 ? psf1->GetAttributesOf(1, &pidl1Last, &attrs1) : E_UNEXPECTED);
|
||||
ok_long(hr, S_OK);
|
||||
hr = (psf2 ? psf2->GetAttributesOf(1, &pidl2Last, &attrs2) : E_UNEXPECTED);
|
||||
ok_long(hr, S_OK);
|
||||
|
||||
// There is the difference in attributes because SHSimpleIDListFromPath
|
||||
// cannot create PIDLs to folders, only files and drives:
|
||||
ok_long((attrs1 & SFGAO_FOLDER), 0);
|
||||
ok_long((attrs2 & SFGAO_FOLDER), SFGAO_FOLDER);
|
||||
|
||||
|
||||
// Make sure the internal details match Windows NT5+
|
||||
LPITEMIDLIST item;
|
||||
GetSystemDirectoryW(szPath, _countof(szPath));
|
||||
CComHeapPtr<ITEMIDLIST> pidlSys32(SHSimpleIDListFromPath(szPath));
|
||||
if (szPath[1] != ':' || PathFindFileNameW(szPath) <= szPath)
|
||||
{
|
||||
skip("Not a local directory %ls\n", szPath);
|
||||
}
|
||||
else if (!(LPITEMIDLIST)pidlSys32)
|
||||
{
|
||||
skip("?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
item = ILFindLastID(pidlSys32);
|
||||
ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT); // This is actually a file PIDL
|
||||
ok_long(FileStruct_Att(item), 0); // Simple PIDL without attributes
|
||||
ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
|
||||
|
||||
ILRemoveLastID(pidlSys32); // Now we should have "c:\Windows"
|
||||
item = ILFindLastID(pidlSys32);
|
||||
ok_long(item->mkid.abID[0] & 0x73, 0x30 | DIRBIT);
|
||||
ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
|
||||
}
|
||||
|
||||
WCHAR drive[4] = { szPath[0], szPath[1], L'\\', L'\0' };
|
||||
CComHeapPtr<ITEMIDLIST> pidlDrive(SHSimpleIDListFromPath(drive));
|
||||
if (drive[1] != ':')
|
||||
{
|
||||
skip("Not a local drive %ls\n", drive);
|
||||
}
|
||||
else if (!(LPITEMIDLIST)pidlDrive)
|
||||
{
|
||||
skip("?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
item = ILFindLastID(pidlDrive);
|
||||
ok_long(item->mkid.abID[0] & 0x70, 0x20); // Something in My Computer
|
||||
ok_char(item->mkid.abID[1] | 32, drive[0] | 32);
|
||||
}
|
||||
|
||||
CComHeapPtr<ITEMIDLIST> pidlVirt(SHSimpleIDListFromPath(L"x:\\IDontExist"));
|
||||
if (!(LPITEMIDLIST)pidlVirt)
|
||||
{
|
||||
skip("?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
item = ILFindLastID(pidlVirt);
|
||||
ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT); // Yes, a file
|
||||
ok_long(FileStruct_Att(item), 0); // Simple PIDL, no attributes
|
||||
ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
|
||||
|
||||
ILRemoveLastID(pidlVirt); // "x:\"
|
||||
item = ILFindLastID(pidlVirt);
|
||||
ok_long(item->mkid.abID[0] & 0x70, 0x20); // Something in My Computer
|
||||
ok_char(item->mkid.abID[1] | 32, 'x' | 32); // x:
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(ILCreateFromPath)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
LPITEMIDLIST item;
|
||||
|
||||
ok_ptr(ILCreateFromPathW(L"c:\\IDontExist"), NULL);
|
||||
|
||||
GetSystemDirectoryW(szPath, _countof(szPath));
|
||||
CComHeapPtr<ITEMIDLIST> pidlDir(ILCreateFromPathW(szPath));
|
||||
if (szPath[1] != ':' || PathFindFileNameW(szPath) <= szPath)
|
||||
{
|
||||
skip("Not a local directory %ls\n", szPath);
|
||||
}
|
||||
else if (!(LPITEMIDLIST)pidlDir)
|
||||
{
|
||||
skip("?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
item = ILFindLastID(pidlDir);
|
||||
ok_long(item->mkid.abID[0] & 0x73, 0x30 | DIRBIT);
|
||||
ok_int(*(UINT*)(&item->mkid.abID[2]), 0); // No size
|
||||
}
|
||||
PathAppendW(szPath, L"kernel32.dll");
|
||||
CComHeapPtr<ITEMIDLIST> pidlFile(ILCreateFromPathW(szPath));
|
||||
if (!(LPITEMIDLIST)pidlFile)
|
||||
{
|
||||
skip("?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
item = ILFindLastID(pidlFile);
|
||||
ok_long(item->mkid.abID[0] & 0x73, 0x30 | FILEBIT);
|
||||
ok_int(*(UINT*)(&item->mkid.abID[2]) > 1024 * 42, TRUE); // At least this large
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(PIDL)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
|
||||
pidl = SHCloneSpecialIDList(NULL, CSIDL_DRIVES, FALSE);
|
||||
if (pidl)
|
||||
TEST_CLSID(ILFindLastID(pidl), 0x1f, 4, CLSID_MyComputer);
|
||||
else
|
||||
skip("?\n");
|
||||
ILFree(pidl);
|
||||
|
||||
pidl = SHCloneSpecialIDList(NULL, CSIDL_PRINTERS, FALSE);
|
||||
if (pidl)
|
||||
TEST_CLSID(ILFindLastID(pidl), 0x71, 14, CLSID_Printers);
|
||||
else
|
||||
skip("?\n");
|
||||
ILFree(pidl);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Test for SHSimpleIDListFromPath
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "shelltest.h"
|
||||
#include <shellutils.h>
|
||||
|
||||
START_TEST(SHSimpleIDListFromPath)
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR szPath[MAX_PATH];
|
||||
GetWindowsDirectoryW(szPath, _countof(szPath));
|
||||
|
||||
// We compare pidl1 and pidl2
|
||||
CComHeapPtr<ITEMIDLIST> pidl1(SHSimpleIDListFromPath(szPath));
|
||||
CComHeapPtr<ITEMIDLIST> pidl2(ILCreateFromPathW(szPath));
|
||||
|
||||
// Yes, they are equal logically
|
||||
LPITEMIDLIST pidl1Last = ILFindLastID(pidl1), pidl2Last = ILFindLastID(pidl2);
|
||||
ok_int(ILIsEqual(pidl1, pidl2), TRUE);
|
||||
ok_int(ILIsEqual(pidl1Last, pidl2Last), TRUE);
|
||||
|
||||
// Bind to parent
|
||||
CComPtr<IShellFolder> psf1, psf2;
|
||||
hr = SHBindToParent(pidl1, IID_PPV_ARG(IShellFolder, &psf1), NULL);
|
||||
ok_long(hr, S_OK);
|
||||
hr = SHBindToParent(pidl2, IID_PPV_ARG(IShellFolder, &psf2), NULL);
|
||||
ok_long(hr, S_OK);
|
||||
|
||||
// Get attributes
|
||||
DWORD attrs1 = SFGAO_FOLDER, attrs2 = SFGAO_FOLDER;
|
||||
hr = (psf1 ? psf1->GetAttributesOf(1, &pidl1Last, &attrs1) : E_UNEXPECTED);
|
||||
ok_long(hr, S_OK);
|
||||
hr = (psf2 ? psf2->GetAttributesOf(1, &pidl2Last, &attrs2) : E_UNEXPECTED);
|
||||
ok_long(hr, S_OK);
|
||||
|
||||
// There is the difference in attributes:
|
||||
ok_long((attrs1 & SFGAO_FOLDER), 0);
|
||||
ok_long((attrs2 & SFGAO_FOLDER), SFGAO_FOLDER);
|
||||
}
|
|
@ -18,6 +18,7 @@ extern void func_ExtractIconEx(void);
|
|||
extern void func_FindExecutable(void);
|
||||
extern void func_GetDisplayNameOf(void);
|
||||
extern void func_GUIDFromString(void);
|
||||
extern void func_ILCreateFromPath(void);
|
||||
extern void func_Int64ToString(void);
|
||||
extern void func_IShellFolderViewCB(void);
|
||||
extern void func_menu(void);
|
||||
|
@ -25,6 +26,7 @@ extern void func_OpenAs_RunDLL(void);
|
|||
extern void func_PathIsEqualOrSubFolder(void);
|
||||
extern void func_PathIsTemporary(void);
|
||||
extern void func_PathResolve(void);
|
||||
extern void func_PIDL(void);
|
||||
extern void func_RealShellExecuteEx(void);
|
||||
extern void func_SHAppBarMessage(void);
|
||||
extern void func_SHChangeNotify(void);
|
||||
|
@ -60,6 +62,7 @@ const struct test winetest_testlist[] =
|
|||
{ "FindExecutable", func_FindExecutable },
|
||||
{ "GetDisplayNameOf", func_GetDisplayNameOf },
|
||||
{ "GUIDFromString", func_GUIDFromString },
|
||||
{ "ILCreateFromPath", func_ILCreateFromPath },
|
||||
{ "Int64ToString", func_Int64ToString },
|
||||
{ "IShellFolderViewCB", func_IShellFolderViewCB },
|
||||
{ "menu", func_menu },
|
||||
|
@ -67,6 +70,7 @@ const struct test winetest_testlist[] =
|
|||
{ "PathIsEqualOrSubFolder", func_PathIsEqualOrSubFolder },
|
||||
{ "PathIsTemporary", func_PathIsTemporary },
|
||||
{ "PathResolve", func_PathResolve },
|
||||
{ "PIDL", func_PIDL },
|
||||
{ "RealShellExecuteEx", func_RealShellExecuteEx },
|
||||
{ "SHAppBarMessage", func_SHAppBarMessage },
|
||||
{ "SHChangeNotify", func_SHChangeNotify },
|
||||
|
|
Loading…
Reference in a new issue