[SHELL32_APITEST] Several fixes (#8266)

Fix the shell32 apitests so that they pass on Windows Server 2003 - Windows 10. Many of these fixes are for Vista+, but the most important fixes are for ShellExecCmdLine and FindExecutable which had issues closing windows after tests and deleting test files. Failing to delete these files breaks the other test (i.e. running ShellExecCmdLine would break FindExecutable and vis-versa.)
This commit is contained in:
Carl J. Bialorucki 2025-07-29 14:06:13 -06:00 committed by GitHub
parent c9842e5aad
commit b86422cd4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 524 additions and 308 deletions

View file

@ -88,9 +88,9 @@ VOID TestUninitialized()
/* methods that worked before, now fail */ /* methods that worked before, now fail */
hr = psf->GetDisplayNameOf(NULL,SHGDN_FORPARSING,&strretName); hr = psf->GetDisplayNameOf(NULL,SHGDN_FORPARSING,&strretName);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : E_FAIL), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || hr == E_FAIL, "hr = %lx\n", hr);
hr = psf->EnumObjects(NULL, 0, &penum); hr = psf->EnumObjects(NULL, 0, &penum);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : HRESULT_FROM_WIN32(ERROR_CANCELLED)), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "hr = %lx\n", hr);
/* The following continue to work though */ /* The following continue to work though */
hr = psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt)); hr = psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt));
@ -120,23 +120,31 @@ VOID TestInitialize()
PERSIST_FOLDER_TARGET_INFO pfti = {0}; PERSIST_FOLDER_TARGET_INFO pfti = {0};
PERSIST_FOLDER_TARGET_INFO queriedPfti; PERSIST_FOLDER_TARGET_INFO queriedPfti;
hr = ppf3->InitializeEx(NULL, NULL, NULL); hr = ppf3->InitializeEx(NULL, NULL, NULL);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : E_OUTOFMEMORY), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || // Vista+
hr == E_OUTOFMEMORY, // Win2k3
"hr = %lx\n", hr);
hr = ppf3->InitializeEx(NULL, NULL, &pfti); hr = ppf3->InitializeEx(NULL, NULL, &pfti);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : E_OUTOFMEMORY), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || // Vista+
hr == E_OUTOFMEMORY, // Win2k3
"hr = %lx\n", hr);
wcscpy(pfti.szTargetParsingName, L"C:\\"); wcscpy(pfti.szTargetParsingName, L"C:\\");
hr = ppf3->InitializeEx(NULL, NULL, &pfti); hr = ppf3->InitializeEx(NULL, NULL, &pfti);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : E_OUTOFMEMORY), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || // Vista+
hr == E_OUTOFMEMORY, // Win2k3
"hr = %lx\n", hr);
hr = ppf3->InitializeEx(NULL, testpidl, NULL); hr = ppf3->InitializeEx(NULL, testpidl, NULL);
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
hr = ppf3->GetFolderTargetInfo(&queriedPfti); hr = ppf3->GetFolderTargetInfo(&queriedPfti);
ok(hr == (IsWindows7OrGreater() ? E_FAIL : S_OK), "hr = %lx\n", hr); ok(hr == E_FAIL || // Win7+
hr == S_OK, // Win2k3-Vista
"hr = %lx\n", hr);
hr = psf->GetDisplayNameOf(NULL,SHGDN_FORPARSING,&strretName); hr = psf->GetDisplayNameOf(NULL,SHGDN_FORPARSING,&strretName);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : E_FAIL), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || hr == E_FAIL, "hr = %lx\n", hr);
pfti.szTargetParsingName[0] = 0; pfti.szTargetParsingName[0] = 0;
hr = ppf3->InitializeEx(NULL, testpidl, &pfti); hr = ppf3->InitializeEx(NULL, testpidl, &pfti);
@ -147,7 +155,7 @@ VOID TestInitialize()
ok(wcscmp(queriedPfti.szTargetParsingName, L"") == 0, "wrong name, got: %S\n", queriedPfti.szTargetParsingName); ok(wcscmp(queriedPfti.szTargetParsingName, L"") == 0, "wrong name, got: %S\n", queriedPfti.szTargetParsingName);
hr = psf->GetDisplayNameOf(NULL,SHGDN_FORPARSING,&strretName); hr = psf->GetDisplayNameOf(NULL,SHGDN_FORPARSING,&strretName);
ok(hr == (IsWindows7OrGreater() ? E_INVALIDARG : E_FAIL), "hr = %lx\n", hr); ok(hr == E_INVALIDARG || hr == E_FAIL, "hr = %lx\n", hr);
wcscpy(pfti.szTargetParsingName, L"C:\\"); wcscpy(pfti.szTargetParsingName, L"C:\\");
hr = ppf3->InitializeEx(NULL, testpidl, &pfti); hr = ppf3->InitializeEx(NULL, testpidl, &pfti);

View file

@ -34,19 +34,22 @@ TestShellFolder(
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
ok(pdt != pdt_2, "Expected %p != %p\n", static_cast<PVOID>(pdt), static_cast<PVOID>(pdt_2)); ok(pdt != pdt_2, "Expected %p != %p\n", static_cast<PVOID>(pdt), static_cast<PVOID>(pdt_2));
hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm)); if (GetNTVersion() < _WIN32_WINNT_WIN10)
ok(hr == S_OK, "hr = %lx\n", hr); {
hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm));
ok(hr == S_OK, "hr = %lx\n", hr);
hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm_2)); hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &pcm_2));
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
ok(pcm != pcm_2, "Expected %p != %p\n", static_cast<PVOID>(pcm), static_cast<PVOID>(pcm_2)); ok(pcm != pcm_2, "Expected %p != %p\n", static_cast<PVOID>(pcm), static_cast<PVOID>(pcm_2));
hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv)); hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv));
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv_2)); hr = psf2->CreateViewObject(NULL, IID_PPV_ARG(IShellView, &psv_2));
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
ok(psv != psv_2, "Expected %p != %p\n", static_cast<PVOID>(psv), static_cast<PVOID>(psv_2)); ok(psv != psv_2, "Expected %p != %p\n", static_cast<PVOID>(psv), static_cast<PVOID>(psv_2));
}
} }
VOID TestInitialize(_In_ IShellFolder2 *psf2) VOID TestInitialize(_In_ IShellFolder2 *psf2)
@ -55,21 +58,20 @@ VOID TestInitialize(_In_ IShellFolder2 *psf2)
HRESULT hr = psf2->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2)); HRESULT hr = psf2->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
hr = ppf2->Initialize(NULL); if (GetNTVersion() < _WIN32_WINNT_WIN10)
ok(hr == S_OK, "hr = %lx\n", hr); {
hr = ppf2->Initialize(NULL);
ok(hr == S_OK, "hr = %lx\n", hr);
hr = ppf2->Initialize((LPCITEMIDLIST)INVALID_POINTER); hr = ppf2->Initialize((LPCITEMIDLIST)INVALID_POINTER);
ok(hr == S_OK, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
//crashes in xp CComHeapPtr<ITEMIDLIST> pidl;
//hr = ppf2->GetCurFolder(NULL); hr = ppf2->GetCurFolder(&pidl);
//ok(hr == E_INVALIDARG, "hr = %lx\n", hr); ok(hr == S_OK, "hr = %lx\n", hr);
// 0 in early win10, 14 in xp; crashes on late win10
CComHeapPtr<ITEMIDLIST> pidl; ok(pidl->mkid.cb == 0x14, "expected empty pidl got cb = %x\n", pidl->mkid.cb);
hr = ppf2->GetCurFolder(&pidl); }
ok(hr == S_OK, "hr = %lx\n", hr);
// 0 in win10, 14 in xp
ok(pidl->mkid.cb == 0x14, "expected empty pidl got cb = %x\n", pidl->mkid.cb);
} }
START_TEST(CMyComputer) START_TEST(CMyComputer)
@ -92,13 +94,16 @@ START_TEST(CMyComputer)
return; return;
} }
/* second create should give us a pointer to the same object */ if (GetNTVersion() < _WIN32_WINNT_VISTA)
hr = CoCreateInstance(CLSID_MyComputer, {
NULL, /* NT5.x returns a pointer to the same object but not NT6.x and newer. */
CLSCTX_INPROC_SERVER, hr = CoCreateInstance(CLSID_MyComputer,
IID_PPV_ARG(IShellFolder2, &psf2_2)); NULL,
ok(hr == S_OK, "hr = %lx\n", hr); CLSCTX_INPROC_SERVER,
ok(psf2 == psf2_2, "Expected %p == %p\n", static_cast<PVOID>(psf2), static_cast<PVOID>(psf2_2)); IID_PPV_ARG(IShellFolder2, &psf2_2));
ok(hr == S_OK, "hr = %lx\n", hr);
ok(psf2 == psf2_2, "Expected %p == %p\n", static_cast<PVOID>(psf2), static_cast<PVOID>(psf2_2));
}
TestShellFolder(psf2); TestShellFolder(psf2);
TestInitialize(psf2); TestInitialize(psf2);

View file

@ -108,23 +108,30 @@ TestCompareIDList(IShellFolder* psf)
compare(psf, dir3, desktop, S_LESSTHAN); compare(psf, dir3, desktop, S_LESSTHAN);
compare(psf, desktop, dir3, S_GREATERTHAN); compare(psf, desktop, dir3, S_GREATERTHAN);
compare(psf, dir3, programs, S_GREATERTHAN); if (!g_bVista) // Only Vista fails on a default install
compare(psf, programs, dir3, S_LESSTHAN); {
compare(psf, dir3, programs, S_GREATERTHAN);
compare(psf, programs, dir3, S_LESSTHAN);
}
compare(psf, dir3, dir3, S_EQUAL); compare(psf, dir3, dir3, S_EQUAL);
compare(psf, dir4, desktop, S_LESSTHAN); compare(psf, dir4, desktop, S_LESSTHAN);
compare(psf, desktop, dir4, S_GREATERTHAN); compare(psf, desktop, dir4, S_GREATERTHAN);
compare(psf, dir4, programs, S_GREATERTHAN); if (!g_bVista) // Only Vista fails on a default install
compare(psf, programs, dir4, S_LESSTHAN); {
compare(psf, dir4, programs, S_GREATERTHAN);
compare(psf, programs, dir4, S_LESSTHAN);
}
compare(psf, dir4, dir4, S_EQUAL); compare(psf, dir4, dir4, S_EQUAL);
// Now compare the paths against eachother. // Now compare the paths against eachother.
compare(psf, dir1, dir2, S_LESSTHAN); compare(psf, dir1, dir2, S_LESSTHAN);
compare(psf, dir2, dir1, S_GREATERTHAN); compare(psf, dir2, dir1, S_GREATERTHAN);
if (!g_bVista) // Only Vista fails on a default install
compare(psf, dir2, dir3, S_LESSTHAN); {
compare(psf, dir3, dir2, S_GREATERTHAN); compare(psf, dir2, dir3, S_LESSTHAN);
compare(psf, dir3, dir2, S_GREATERTHAN);
}
compare(psf, dir3, dir4, S_LESSTHAN); compare(psf, dir3, dir4, S_LESSTHAN);
compare(psf, dir4, dir3, S_GREATERTHAN); compare(psf, dir4, dir3, S_GREATERTHAN);

View file

@ -31,62 +31,121 @@ typedef struct
BOOL expandPathOut2; BOOL expandPathOut2;
} TEST_SHELL_LINK_DEF; } TEST_SHELL_LINK_DEF;
static TEST_SHELL_LINK_DEF linkTestList[] = static TEST_SHELL_LINK_DEF linkTestList_WS03[] =
{ {
{ {
L"%comspec%", S_OK, L"%comspec%", S_OK,
L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE, L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
L"%comspec%", SLGP_RAWPATH, S_OK, FALSE L"%comspec%", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"%anyvar%", E_INVALIDARG, L"%anyvar%", E_INVALIDARG,
L"", SLGP_SHORTPATH, S_FALSE, FALSE, L"", SLGP_SHORTPATH, S_FALSE, FALSE,
L"", SLGP_RAWPATH, S_FALSE, FALSE L"", SLGP_RAWPATH, S_FALSE, FALSE
}, },
{ {
L"%anyvar%%comspec%", S_OK, L"%anyvar%%comspec%", S_OK,
L"c:\\%anyvar%%comspec%", SLGP_SHORTPATH, S_OK, TRUE, L"c:\\%anyvar%%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
L"%anyvar%%comspec%", SLGP_RAWPATH, S_OK, FALSE L"%anyvar%%comspec%", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"%temp%", S_OK, L"%temp%", S_OK,
L"%temp%", SLGP_SHORTPATH, S_OK, TRUE, L"%temp%", SLGP_SHORTPATH, S_OK, TRUE,
L"%temp%", SLGP_RAWPATH, S_OK, FALSE L"%temp%", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"%shell%", S_OK, L"%shell%", S_OK,
L"%systemroot%\\system32\\%shell%", SLGP_SHORTPATH, S_OK, TRUE, L"%systemroot%\\system32\\%shell%", SLGP_SHORTPATH, S_OK, TRUE,
L"%shell%", SLGP_RAWPATH, S_OK, FALSE L"%shell%", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"u:\\anypath\\%anyvar%", S_OK, L"u:\\anypath\\%anyvar%", S_OK,
L"u:\\anypath\\%anyvar%", SLGP_SHORTPATH, S_OK, TRUE, L"u:\\anypath\\%anyvar%", SLGP_SHORTPATH, S_OK, TRUE,
L"u:\\anypath\\%anyvar%", SLGP_RAWPATH, S_OK, FALSE L"u:\\anypath\\%anyvar%", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"c:\\temp", S_OK, L"c:\\temp", S_OK,
L"c:\\temp", SLGP_SHORTPATH, S_OK, FALSE, L"c:\\temp", SLGP_SHORTPATH, S_OK, FALSE,
L"c:\\temp", SLGP_RAWPATH, S_OK, FALSE L"c:\\temp", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"cmd.exe", S_OK, L"cmd.exe", S_OK,
L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE, L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
L"%comspec%", SLGP_RAWPATH, S_OK, TRUE L"%comspec%", SLGP_RAWPATH, S_OK, TRUE
}, },
{ {
L"%systemroot%\\non-existent-file", S_OK, L"%systemroot%\\non-existent-file", S_OK,
L"%systemroot%\\non-existent-file", SLGP_SHORTPATH, S_OK, TRUE, L"%systemroot%\\non-existent-file", SLGP_SHORTPATH, S_OK, TRUE,
L"%systemroot%\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE L"%systemroot%\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"c:\\non-existent-path\\non-existent-file", S_OK, L"c:\\non-existent-path\\non-existent-file", S_OK,
L"c:\\non-existent-path\\non-existent-file", SLGP_SHORTPATH, S_OK, FALSE, L"c:\\non-existent-path\\non-existent-file", SLGP_SHORTPATH, S_OK, FALSE,
L"c:\\non-existent-path\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE L"c:\\non-existent-path\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
}, },
{ {
L"non-existent-file", E_INVALIDARG, L"non-existent-file", E_INVALIDARG,
L"", SLGP_SHORTPATH, S_FALSE, FALSE, L"", SLGP_SHORTPATH, S_FALSE, FALSE,
L"", SLGP_RAWPATH, S_FALSE, FALSE L"", SLGP_RAWPATH, S_FALSE, FALSE
},
};
static TEST_SHELL_LINK_DEF linkTestList_Vista[] =
{
{
L"%comspec%", S_OK,
L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
L"%comspec%", SLGP_RAWPATH, S_OK, FALSE
},
{
L"%anyvar%", S_OK,
L"%USERPROFILE%\\Desktop\\%anyvar%", SLGP_SHORTPATH, S_OK, TRUE,
L"%USERPROFILE%\\Desktop\\%anyvar%", SLGP_RAWPATH, S_OK, TRUE
},
{
L"%anyvar%%comspec%", E_INVALIDARG,
L"", SLGP_SHORTPATH, S_FALSE, TRUE,
L"%anyvar%%comspec%", SLGP_RAWPATH, S_OK, FALSE
},
{
L"%temp%", S_OK,
L"%temp%", SLGP_SHORTPATH, S_OK, TRUE,
L"%temp%", SLGP_RAWPATH, S_OK, FALSE
},
{
L"%shell%", S_OK,
L"%systemroot%\\system32\\%shell%", SLGP_SHORTPATH, S_OK, TRUE,
L"%shell%", SLGP_RAWPATH, S_OK, FALSE
},
{
L"u:\\anypath\\%anyvar%", S_OK,
L"u:\\anypath\\%anyvar%", SLGP_SHORTPATH, S_OK, TRUE,
L"u:\\anypath\\%anyvar%", SLGP_RAWPATH, S_OK, FALSE
},
{
L"c:\\temp", S_OK,
L"c:\\temp", SLGP_SHORTPATH, S_OK, FALSE,
L"c:\\temp", SLGP_RAWPATH, S_OK, FALSE
},
{
L"cmd.exe", S_OK,
L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
L"%comspec%", SLGP_RAWPATH, S_OK, TRUE
},
{
L"%systemroot%\\non-existent-file", S_OK,
L"%systemroot%\\non-existent-file", SLGP_SHORTPATH, S_OK, TRUE,
L"%systemroot%\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
},
{
L"c:\\non-existent-path\\non-existent-file", S_OK,
L"c:\\non-existent-path\\non-existent-file", SLGP_SHORTPATH, S_OK, FALSE,
L"c:\\non-existent-path\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
},
{
L"non-existent-file", S_OK,
L"%USERPROFILE%\\Desktop\\non-existent-file", SLGP_SHORTPATH, S_OK, TRUE,
L"%USERPROFILE%\\Desktop\\non-existent-file", SLGP_RAWPATH, S_OK, TRUE
}, },
}; };
@ -158,15 +217,27 @@ static
VOID VOID
TestShellLink(void) TestShellLink(void)
{ {
UINT i; UINT i, TestListCnt;
TEST_SHELL_LINK_DEF* Test;
/* Needed for test */ /* Needed for test */
SetEnvironmentVariableW(L"shell", L"cmd.exe"); SetEnvironmentVariableW(L"shell", L"cmd.exe");
for (i = 0; i < _countof(linkTestList); ++i) if (GetNTVersion() <= _WIN32_WINNT_WS03)
{ {
DPRINT("IShellLink-Test(%d): %S\n", i, linkTestList[i].pathIn); Test = linkTestList_WS03;
test_checklinkpath(i, &linkTestList[i]); TestListCnt = _countof(linkTestList_WS03);
}
else
{
Test = linkTestList_Vista;
TestListCnt = _countof(linkTestList_Vista);
}
for (i = 0; i < TestListCnt; ++i)
{
DPRINT("IShellLink-Test(%d): %S\n", i, Test[i].pathIn);
test_checklinkpath(i, &Test[i]);
} }
SetEnvironmentVariableW(L"shell",NULL); SetEnvironmentVariableW(L"shell",NULL);

View file

@ -35,7 +35,7 @@ typedef struct
{ {
PCWSTR pszFilePath; PCWSTR pszFilePath;
UINT nIcons; UINT nIcons;
} EXTRACTICONTESTS; } EXTRACTICONTEST;
BOOL FileExists(LPCSTR FileName) BOOL FileExists(LPCSTR FileName)
{ {
@ -95,7 +95,7 @@ BOOL ResourceToFile(INT i, LPCSTR FileName)
return TRUE; return TRUE;
} }
EXTRACTICONTESTS IconTests[] = EXTRACTICONTEST IconTests[] =
{ {
/* Executable file with icon */ /* Executable file with icon */
{L"%SystemRoot%\\System32\\cmd.exe", 1}, {L"%SystemRoot%\\System32\\cmd.exe", 1},
@ -106,40 +106,67 @@ EXTRACTICONTESTS IconTests[] =
/* Non-existing files */ /* Non-existing files */
{L"%SystemRoot%\\non-existent-file.sdf", 0}, {L"%SystemRoot%\\non-existent-file.sdf", 0},
/* Multiple icons in the same EXE file (18 icons) */
{L"%SystemRoot%\\explorer.exe", 18},
/* Multiple icons in the same ICO file (6 icons) /* Multiple icons in the same ICO file (6 icons)
* Per MS: If the file is an .ico file, the return value is 1. */ * Per MS: If the file is an .ico file, the return value is 1. */
{L"sysicon.ico", 1}, {L"sysicon.ico", 1},
/* ICO file with both normal and PNG icons */ /* ICO file with both normal and PNG icons */
{L"ROS.ico", 0} {L"ROS.ico", (UINT)(GetNTVersion() >= _WIN32_WINNT_VISTA ? 1 : 0)}
}; };
VOID RunExtractIconTest(EXTRACTICONTEST *Test)
{
UINT nReturnedIcons, nExtractedIcons;
/* Check count of icons returned */
nReturnedIcons = ExtractIconExW(Test->pszFilePath, -1, NULL, NULL, 0);
ok(nReturnedIcons == Test->nIcons, "ExtractIconExW(L\"%S\"): Expects %u icons, got %u\n", Test->pszFilePath, Test->nIcons, nReturnedIcons);
/* Check if the 0th icon can be extracted successfully */
nExtractedIcons = ExtractIconExW(Test->pszFilePath, 0, NULL, NULL, 1);
ok(nExtractedIcons == Test->nIcons, "ExtractIconExW(L\"%S\"): Expects %u icons, got %u\n", Test->pszFilePath, Test->nIcons, nExtractedIcons);
}
START_TEST(ExtractIconEx) START_TEST(ExtractIconEx)
{ {
UINT i, nReturnedIcons, nExtractedIcons; UINT i;
CHAR FileName[2][13] = { "ROS.ico", "sysicon.ico" }; CHAR FileName[2][13] = { "ROS.ico", "sysicon.ico" };
EXTRACTICONTEST explorer_exe = {L"%SystemRoot%\\explorer.exe", 0};
if (!ResourceToFile(2, FileName[0])) if (!ResourceToFile(2, FileName[0]))
return; return;
if (!ResourceToFile(3, FileName[1])) if (!ResourceToFile(3, FileName[1]))
return; return;
/* Check count of icons returned */ /* Run normal tests */
for (i = 0; i < _countof(IconTests); ++i) for (i = 0; i < _countof(IconTests); ++i)
RunExtractIconTest(&IconTests[i]);
/* Run special case checks */
switch (GetNTVersion())
{ {
nReturnedIcons = ExtractIconExW(IconTests[i].pszFilePath, -1, NULL, NULL, 0); case _WIN32_WINNT_WS03:
ok(nReturnedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expects %u icons, got %u\n", i, IconTests[i].nIcons, nReturnedIcons); explorer_exe.nIcons = 18;
break;
case _WIN32_WINNT_VISTA:
explorer_exe.nIcons = 23;
break;
case _WIN32_WINNT_WIN7:
explorer_exe.nIcons = 25;
break;
case _WIN32_WINNT_WIN8:
case _WIN32_WINNT_WINBLUE:
explorer_exe.nIcons = 24;
break;
case _WIN32_WINNT_WIN10:
explorer_exe.nIcons = 28;
break;
} }
/* Check if the 0th icon can be extracted successfully */ if (explorer_exe.nIcons)
for (i = 0; i < _countof(IconTests); ++i) RunExtractIconTest(&explorer_exe);
{ else
nExtractedIcons = ExtractIconExW(IconTests[i].pszFilePath, 0, NULL, NULL, 1); skip("Unknown NT Version: 0x%lX\n", GetNTVersion());
ok(nExtractedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expects %u icons, got %u\n", i, IconTests[i].nIcons, nExtractedIcons);
}
DeleteFileA(FileName[0]); DeleteFileA(FileName[0]);
DeleteFileA(FileName[1]); DeleteFileA(FileName[1]);

View file

@ -38,7 +38,7 @@ static const TEST_ENTRY s_entries[] =
{ {
{ __LINE__, 0xBEEFCAFE, "notepad", DIR_0, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "notepad", DIR_0, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad", DIR_1, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "notepad", DIR_1, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad", DIR_2, s_sys_notepad }, // { __LINE__, 0xBEEFCAFE, "notepad", DIR_2, "notepad.exe" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "notepad", DIR_3, s_win_notepad }, { __LINE__, 0xBEEFCAFE, "notepad", DIR_3, s_win_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad", DIR_4, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "notepad", DIR_4, s_sys_notepad },
{ __LINE__, SE_ERR_FNF, " notepad", DIR_0, "" }, { __LINE__, SE_ERR_FNF, " notepad", DIR_0, "" },
@ -53,12 +53,12 @@ static const TEST_ENTRY s_entries[] =
{ __LINE__, SE_ERR_FNF, "notepad ", DIR_4, "" }, { __LINE__, SE_ERR_FNF, "notepad ", DIR_4, "" },
{ __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_0, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_0, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_1, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_1, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_2, s_sys_notepad }, // { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_2, "notepad.exe" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_3, s_win_notepad }, { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_3, s_win_notepad },
{ __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_4, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "\"notepad\"", DIR_4, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_0, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_0, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_1, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_1, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_2, s_sys_notepad }, // { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_2, "notepad.exe" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_3, s_win_notepad }, { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_3, s_win_notepad },
{ __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_4, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "notepad.exe", DIR_4, s_sys_notepad },
{ __LINE__, SE_ERR_FNF, "notepad.bat", DIR_0, "" }, { __LINE__, SE_ERR_FNF, "notepad.bat", DIR_0, "" },
@ -88,7 +88,7 @@ static const TEST_ENTRY s_entries[] =
{ __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_4, s_win_notepad }, { __LINE__, 0xBEEFCAFE, s_win_notepad, DIR_4, s_win_notepad },
{ __LINE__, 0xBEEFCAFE, "test program", DIR_0, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "test program", DIR_0, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program", DIR_1, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "test program", DIR_1, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program", DIR_2, s_sys_test_exe }, // { __LINE__, 0xBEEFCAFE, "test program", DIR_2, "test program.exe" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "test program", DIR_3, s_win_test_exe }, { __LINE__, 0xBEEFCAFE, "test program", DIR_3, s_win_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program", DIR_4, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "test program", DIR_4, s_sys_test_exe },
{ __LINE__, SE_ERR_FNF, " test program", DIR_0, "" }, { __LINE__, SE_ERR_FNF, " test program", DIR_0, "" },
@ -103,17 +103,17 @@ static const TEST_ENTRY s_entries[] =
{ __LINE__, SE_ERR_FNF, "test program ", DIR_4, "" }, { __LINE__, SE_ERR_FNF, "test program ", DIR_4, "" },
{ __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_0, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_0, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_1, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_1, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_2, s_sys_test_exe }, // { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_2, "test program.exe" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_3, s_win_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_3, s_win_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_4, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program\"", DIR_4, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program.exe", DIR_0, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_0, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program.exe", DIR_1, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_1, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program.exe", DIR_2, s_sys_test_exe }, // { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_2, "TESTPR~1.EXE" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "test program.exe", DIR_3, s_win_test_exe }, { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_3, s_win_test_exe },
{ __LINE__, 0xBEEFCAFE, "test program.exe", DIR_4, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "test program.exe", DIR_4, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_0, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_0, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_1, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_1, s_sys_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_2, s_sys_test_exe }, // { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_2, "test program.exe" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_3, s_win_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_3, s_win_test_exe },
{ __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_4, s_sys_test_exe }, { __LINE__, 0xBEEFCAFE, "\"test program.exe\"", DIR_4, s_sys_test_exe },
{ __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_0, "" }, { __LINE__, SE_ERR_NOASSOC, "\"test program.exe \"", DIR_0, "" },
@ -128,7 +128,7 @@ static const TEST_ENTRY s_entries[] =
{ __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_4, "" }, { __LINE__, SE_ERR_FNF, "\" test program.exe\"", DIR_4, "" },
{ __LINE__, 0xBEEFCAFE, "test program.bat", DIR_0, s_sys_bat_file }, { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_0, s_sys_bat_file },
{ __LINE__, 0xBEEFCAFE, "test program.bat", DIR_1, s_sys_bat_file }, { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_1, s_sys_bat_file },
{ __LINE__, 0xBEEFCAFE, "test program.bat", DIR_2, s_sys_bat_file }, // { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_2, "TESTPR~1.BAT" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "test program.bat", DIR_3, s_win_bat_file }, { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_3, s_win_bat_file },
{ __LINE__, 0xBEEFCAFE, "test program.bat", DIR_4, s_sys_bat_file }, { __LINE__, 0xBEEFCAFE, "test program.bat", DIR_4, s_sys_bat_file },
{ __LINE__, SE_ERR_FNF, " test program.bat ", DIR_0, "" }, { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_0, "" },
@ -138,12 +138,12 @@ static const TEST_ENTRY s_entries[] =
{ __LINE__, SE_ERR_FNF, " test program.bat ", DIR_4, "" }, { __LINE__, SE_ERR_FNF, " test program.bat ", DIR_4, "" },
{ __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_0, s_sys_bat_file }, { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_0, s_sys_bat_file },
{ __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_1, s_sys_bat_file }, { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_1, s_sys_bat_file },
{ __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_2, s_sys_bat_file }, // { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_2, "test program.bat" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_3, s_win_bat_file }, { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_3, s_win_bat_file },
{ __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_4, s_sys_bat_file }, { __LINE__, 0xBEEFCAFE, "\"test program.bat\"", DIR_4, s_sys_bat_file },
{ __LINE__, 0xBEEFCAFE, "test file.txt", DIR_0, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_0, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "test file.txt", DIR_1, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_1, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "test file.txt", DIR_2, s_sys_notepad }, // { __LINE__, SE_ERR_NOASSOC, "test file.txt", DIR_2, "" }, // Results vary between Windows versions
{ __LINE__, 0xBEEFCAFE, "test file.txt", DIR_3, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_3, s_sys_notepad },
{ __LINE__, 0xBEEFCAFE, "test file.txt", DIR_4, s_sys_notepad }, { __LINE__, 0xBEEFCAFE, "test file.txt", DIR_4, s_sys_notepad },
{ __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_0, "" }, { __LINE__, SE_ERR_FNF, "invalid file.txt", DIR_0, "" },
@ -196,19 +196,22 @@ START_TEST(FindExecutable)
GetWindowsDirectoryA(s_win_test_exe, _countof(s_win_test_exe)); GetWindowsDirectoryA(s_win_test_exe, _countof(s_win_test_exe));
PathAppendA(s_win_test_exe, "test program.exe"); PathAppendA(s_win_test_exe, "test program.exe");
SetFileAttributesA(s_win_test_exe, FILE_ATTRIBUTE_NORMAL); // If the file exists, strip the readonly flag
BOOL ret = CopyFileA(s_win_notepad, s_win_test_exe, FALSE); BOOL ret = CopyFileA(s_win_notepad, s_win_test_exe, FALSE);
if (!ret) if (!ret)
{ {
skip("Please retry with admin rights\n"); skip("Cannot copy test files to the system root directory. (Error: %lu)\n", GetLastError());
return; return;
} }
GetSystemDirectoryA(s_sys_test_exe, _countof(s_sys_test_exe)); GetSystemDirectoryA(s_sys_test_exe, _countof(s_sys_test_exe));
PathAppendA(s_sys_test_exe, "test program.exe"); PathAppendA(s_sys_test_exe, "test program.exe");
SetFileAttributesA(s_sys_test_exe, FILE_ATTRIBUTE_NORMAL); // If the file exists, strip the readonly flag
ret = CopyFileA(s_win_notepad, s_sys_test_exe, FALSE); ret = CopyFileA(s_win_notepad, s_sys_test_exe, FALSE);
if (!ret) if (!ret)
{ {
skip("Please retry with admin rights\n"); skip("Cannot copy test files to the system directory. (Error: %lu)\n", GetLastError());
DeleteFileA(s_win_test_exe);
return; return;
} }
@ -237,7 +240,13 @@ START_TEST(FindExecutable)
DoTestEntry(&s_entries[iTest]); DoTestEntry(&s_entries[iTest]);
} }
/* Cleanup:
* s_win_test_exe and s_sys_test_exe inherit the readonly flag,
* so we need to reset it before we can successfully delete it.
*/
SetFileAttributesA(s_win_test_exe, FILE_ATTRIBUTE_NORMAL);
DeleteFileA(s_win_test_exe); DeleteFileA(s_win_test_exe);
SetFileAttributesA(s_sys_test_exe, FILE_ATTRIBUTE_NORMAL);
DeleteFileA(s_sys_test_exe); DeleteFileA(s_sys_test_exe);
DeleteFileA(s_win_bat_file); DeleteFileA(s_win_bat_file);
DeleteFileA(s_sys_bat_file); DeleteFileA(s_sys_bat_file);

View file

@ -34,10 +34,9 @@ static void TEST_GUIDFromStringA(void)
} }
_SEH2_END; _SEH2_END;
if (IsWindowsVistaOrGreater()) ok(ret == FALSE || // Win8+
ok_int(ret, FALSE); ret == (int)(0xDEADBEEF), // Win2k3-Win7
else "Wrong value for ret (0x%X)\n", ret);
ok_int(ret, 0xDEADBEEF);
ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE);
guid = invalid_guid; guid = invalid_guid;
@ -81,10 +80,9 @@ static void TEST_GUIDFromStringW(void)
} }
_SEH2_END; _SEH2_END;
if (IsWindowsVistaOrGreater()) ok(ret == (int)(0xDEADBEEF) || // Win8+
ok_int(ret, 0xDEADBEEF); ret == FALSE, // Win2k3-Win7
else "Wrong value for ret (0x%X)\n", ret);
ok_int(ret, FALSE);
ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE);
guid = invalid_guid; guid = invalid_guid;

View file

@ -456,7 +456,9 @@ START_TEST(IShellFolderViewCB)
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
return; return;
ok_int(g_AddRef, 1); ok(g_AddRef == 2 || // Win7+
g_AddRef == 1, // Win2k3-Vista
"Wrong value for g_AddRef (0x%lX)\n", g_AddRef);
ok_int(g_Release, 0); ok_int(g_Release, 0);
clear_list(); clear_list();
@ -586,18 +588,73 @@ START_TEST(IShellFolderViewCB)
IShellFolderViewCB* oldPtr; IShellFolderViewCB* oldPtr;
hr = folderView->SetCallback(NULL, &oldPtr); hr = folderView->SetCallback(NULL, &oldPtr);
ok_int(g_AddRef, 1); switch (GetNTVersion())
ok_int(g_Release, 0); {
case _WIN32_WINNT_WS03:
case _WIN32_WINNT_VISTA:
ok_int(g_AddRef, 1);
ok_int(g_Release, 0);
break;
case _WIN32_WINNT_WIN7:
case _WIN32_WINNT_WIN8:
case _WIN32_WINNT_WINBLUE:
ok_int(g_AddRef, 3);
ok_int(g_Release, 1);
break;
case _WIN32_WINNT_WIN10:
ok_int(g_AddRef, 6);
ok_int(g_Release, 4);
break;
default:
skip("Unknown NT Version (0x%lX)\n", GetNTVersion());
break;
}
/* Last pointer is not optional! */ /* Last pointer is not optional! */
IShellFolderViewCB* oldPtr2; IShellFolderViewCB* oldPtr2;
hr = folderView->SetCallback(oldPtr, &oldPtr2); hr = folderView->SetCallback(oldPtr, &oldPtr2);
ok_int(g_AddRef, 2); switch (GetNTVersion())
ok_int(g_Release, 0); {
case _WIN32_WINNT_WS03:
case _WIN32_WINNT_VISTA:
ok_int(g_AddRef, 2);
ok_int(g_Release, 0);
break;
case _WIN32_WINNT_WIN7:
case _WIN32_WINNT_WIN8:
case _WIN32_WINNT_WINBLUE:
ok_int(g_AddRef, 4);
ok_int(g_Release, 1);
break;
case _WIN32_WINNT_WIN10:
ok_int(g_AddRef, 7);
ok_int(g_Release, 4);
break;
default:
skip("Unknown NT Version (0x%lX)\n", GetNTVersion());
break;
}
} }
ULONG refCount = psv->Release(); ULONG refCount = psv->Release();
ok(refCount == 1, "refCount = %lu\n", refCount); switch (GetNTVersion())
{
case _WIN32_WINNT_WS03:
case _WIN32_WINNT_WIN10:
ok(refCount == 1, "refCount = %lu\n", refCount);
break;
case _WIN32_WINNT_VISTA:
ok(refCount == 4, "refCount = %lu\n", refCount);
break;
case _WIN32_WINNT_WIN7:
case _WIN32_WINNT_WIN8:
case _WIN32_WINNT_WINBLUE:
ok(refCount == 6, "refCount = %lu\n", refCount);
break;
default:
skip("Unknown NT Version (0x%lX)\n", GetNTVersion());
break;
}
static message release_list[] = static message release_list[] =
{ {

View file

@ -12,7 +12,8 @@ START_TEST(PathIsEqualOrSubFolder)
{ {
ok_int(PathIsEqualOrSubFolder(L"C:", L"C:"), TRUE); ok_int(PathIsEqualOrSubFolder(L"C:", L"C:"), TRUE);
ok_int(PathIsEqualOrSubFolder(L"C:", L"C:\\"), TRUE); ok_int(PathIsEqualOrSubFolder(L"C:", L"C:\\"), TRUE);
ok_int(PathIsEqualOrSubFolder(L"C:\\", L"C:"), TRUE); if (GetNTVersion() != _WIN32_WINNT_VISTA)
ok_int(PathIsEqualOrSubFolder(L"C:\\", L"C:"), TRUE);
ok_int(PathIsEqualOrSubFolder(L"C:\\", L"C:\\"), TRUE); ok_int(PathIsEqualOrSubFolder(L"C:\\", L"C:\\"), TRUE);
ok_int(PathIsEqualOrSubFolder(L"C:\\", L"C:\\TestTestTest"), TRUE); ok_int(PathIsEqualOrSubFolder(L"C:\\", L"C:\\TestTestTest"), TRUE);
ok_int(PathIsEqualOrSubFolder(L"C:\\TestTestTest", L"C:\\"), FALSE); ok_int(PathIsEqualOrSubFolder(L"C:\\TestTestTest", L"C:\\"), FALSE);

View file

@ -20,8 +20,12 @@ static void Test_PathIsTemporaryA(void)
GetTempPathA(_countof(szPath), szPath); GetTempPathA(_countof(szPath), szPath);
ok_int(PathIsTemporaryA(szPath), TRUE); ok_int(PathIsTemporaryA(szPath), TRUE);
PathAppendA(szPath, "TestTestTest"); if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
ok_int(PathIsTemporaryA(szPath), FALSE); {
/* This is not reliable on Vista+ */
PathAppendA(szPath, "TestTestTest");
ok_int(PathIsTemporaryA(szPath), FALSE);
}
CreateDirectoryA(szPath, NULL); CreateDirectoryA(szPath, NULL);
ok_int(PathIsTemporaryA(szPath), TRUE); ok_int(PathIsTemporaryA(szPath), TRUE);
@ -41,8 +45,12 @@ static void Test_PathIsTemporaryW(void)
GetTempPathW(_countof(szPath), szPath); GetTempPathW(_countof(szPath), szPath);
ok_int(PathIsTemporaryW(szPath), TRUE); ok_int(PathIsTemporaryW(szPath), TRUE);
PathAppendW(szPath, L"TestTestTest"); if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
ok_int(PathIsTemporaryW(szPath), FALSE); {
/* This is not reliable on Vista+ */
PathAppendW(szPath, L"TestTestTest");
ok_int(PathIsTemporaryW(szPath), FALSE);
}
CreateDirectoryW(szPath, NULL); CreateDirectoryW(szPath, NULL);
ok_int(PathIsTemporaryW(szPath), TRUE); ok_int(PathIsTemporaryW(szPath), TRUE);

View file

@ -28,7 +28,7 @@ START_TEST(PathMakeUniqueName)
SetCurrentDirectoryW(szTempDir); SetCurrentDirectoryW(szTempDir);
if (pIsLFNDriveW) if (pIsLFNDriveW)
bUseLong = pIsLFNDriveW(szTempDir) && IsWindowsVistaOrGreater(); bUseLong = pIsLFNDriveW(szTempDir) && (GetNTVersion() >= _WIN32_WINNT_WIN10);
trace("bUseLong: %d\n", bUseLong); trace("bUseLong: %d\n", bUseLong);
DeleteFileW(L"test.txt"); DeleteFileW(L"test.txt");

View file

@ -13,10 +13,11 @@
static CLIPFORMAT g_DataObjectAttributes = 0; static CLIPFORMAT g_DataObjectAttributes = 0;
static const DWORD dwDefaultAttributeMask = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_STORAGE | SFGAO_CANRENAME | SFGAO_CANDELETE | static const DWORD dwDefaultAttributeMask = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_STORAGE | SFGAO_CANRENAME |
SFGAO_READONLY | SFGAO_STREAM | SFGAO_FOLDER; SFGAO_CANDELETE | SFGAO_READONLY | SFGAO_STREAM | SFGAO_FOLDER;
static_assert(dwDefaultAttributeMask == 0x2044003B, "Unexpected default attribute mask"); static_assert(dwDefaultAttributeMask == 0x2044003B, "Unexpected default attribute mask");
static const DWORD dwDefaultAttributeMask_WS03 = dwDefaultAttributeMask | SFGAO_FILESYSTEM | SFGAO_CAPABILITYMASK;
static_assert(dwDefaultAttributeMask_WS03 == 0x6044017F, "Unexpected default attribute mask for WS03, Vista");
struct TmpFile struct TmpFile
{ {
@ -132,7 +133,10 @@ static void test_AttributesRegistration()
hr = spFolder->GetAttributesOf(1, &child, &attributes); hr = spFolder->GetAttributesOf(1, &child, &attributes);
ok_hr_ret(hr, S_OK); ok_hr_ret(hr, S_OK);
attributes &= dwDefaultAttributeMask; if (GetNTVersion() <= _WIN32_WINNT_VISTA)
attributes &= dwDefaultAttributeMask_WS03;
else
attributes &= dwDefaultAttributeMask;
} }
CComHeapPtr<ITEMIDLIST> parent(ILClone(spPath)); CComHeapPtr<ITEMIDLIST> parent(ILClone(spPath));
@ -144,7 +148,7 @@ static void test_AttributesRegistration()
ok_hr_ret(hr, S_OK); ok_hr_ret(hr, S_OK);
/* Not registered yet */ /* Not registered yet */
ok_attributes(spDataObject, DV_E_FORMATETC, 0, 0, 0); ok_attributes(spDataObject, (GetNTVersion() >= _WIN32_WINNT_VISTA) ? DV_E_FORMATETC : E_INVALIDARG, 0, 0, 0);
/* Ask for attributes, without specifying any */ /* Ask for attributes, without specifying any */
DWORD dwAttributeMask = 0, dwAttributes = 0; DWORD dwAttributeMask = 0, dwAttributes = 0;
@ -227,10 +231,20 @@ static void test_MultipleFiles()
ok_hr(hr, S_OK); ok_hr(hr, S_OK);
// Ignore any non-default attributes // Ignore any non-default attributes
attributes_first &= dwDefaultAttributeMask; if (GetNTVersion() <= _WIN32_WINNT_VISTA)
attributes2 &= dwDefaultAttributeMask; {
attributes3 &= dwDefaultAttributeMask; attributes_first &= dwDefaultAttributeMask_WS03;
attributes_last &= dwDefaultAttributeMask; attributes2 &= dwDefaultAttributeMask_WS03;
attributes3 &= dwDefaultAttributeMask_WS03;
attributes_last &= dwDefaultAttributeMask_WS03;
}
else
{
attributes_first &= dwDefaultAttributeMask;
attributes2 &= dwDefaultAttributeMask;
attributes3 &= dwDefaultAttributeMask;
attributes_last &= dwDefaultAttributeMask;
}
} }
// Only 'single' files have the stream attribute set // Only 'single' files have the stream attribute set

View file

@ -17,8 +17,13 @@
#define T_WIN8 0x20 #define T_WIN8 0x20
#define T_WIN10 0x40 #define T_WIN10 0x40
#define T_PRE_VISTA T_WIN2K|T_WINXP|T_WIN2K3 #define T_PRE_VISTA (T_WIN2K | T_WINXP | T_WIN2K3)
#define T_VISTA_PLUS T_VISTA|T_WIN7|T_WIN8|T_WIN10 #define T_PRE_WIN7 (T_PRE_VISTA | T_VISTA)
#define T_PRE_WIN8 (T_PRE_WIN7 | T_WIN7)
#define T_WIN8_PLUS (T_WIN8 | T_WIN10)
#define T_WIN7_PLUS (T_WIN7 | T_WIN8_PLUS)
#define T_VISTA_PLUS (T_VISTA | T_WIN7_PLUS)
struct test_data struct test_data
{ {
@ -37,19 +42,19 @@ struct test_data Tests[] =
{__LINE__, NULL, NULL, 0, E_INVALIDARG, T_VISTA_PLUS}, {__LINE__, NULL, NULL, 0, E_INVALIDARG, T_VISTA_PLUS},
{__LINE__, L"", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0}, {__LINE__, L"", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0, S_OK, 0},
{__LINE__, L" ", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), T_PRE_VISTA}, {__LINE__, L" ", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), T_PRE_VISTA},
{__LINE__, L" ", NULL, 0, E_INVALIDARG, T_VISTA_PLUS}, {__LINE__, L" ", NULL, 0, E_INVALIDARG, T_WIN8_PLUS},
{__LINE__, L":", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L":", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L": ", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L": ", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L" :", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L" :", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"/", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"/", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"//", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"//", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
/* This opens C:\ from Win+R and address bar */ /* This opens C:\ from Win+R and address bar */
{__LINE__, L"\\", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"\\", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
/* These two opens "C:\Program Files" from Win+R and address bar */ /* These two opens "C:\Program Files" from Win+R and address bar */
{__LINE__, L"\\Program Files", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"\\Program Files", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"\\Program Files\\", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"\\Program Files\\", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"\\\\?", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"\\\\?", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"\\\\?\\", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"\\\\?\\", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
/* Tests for the shell: protocol */ /* Tests for the shell: protocol */
{__LINE__, L"shell:", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0}, {__LINE__, L"shell:", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0},
{__LINE__, L"shell::", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0}, {__LINE__, L"shell::", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), 0},
@ -82,13 +87,13 @@ struct test_data Tests[] =
{__LINE__, L"ftp://", NULL, 0, E_INVALIDARG, T_PRE_VISTA}, {__LINE__, L"ftp://", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
{__LINE__, L"ftp://a", NULL, 0, E_INVALIDARG, T_PRE_VISTA}, {__LINE__, L"ftp://a", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
{__LINE__, L"ftp://ftp.gnu.org/gnu/octave/", NULL, 0, E_INVALIDARG, T_PRE_VISTA}, {__LINE__, L"ftp://ftp.gnu.org/gnu/octave/", NULL, 0, E_INVALIDARG, T_PRE_VISTA},
{__LINE__, L"aa:", L"aa:", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"aa:", L"aa:", 0, S_OK, T_WIN10},
{__LINE__, L"garbage:", L"garbage:", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"garbage:", L"garbage:", 0, S_OK, T_WIN10},
{__LINE__, L"ftp:", L"ftp:", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"ftp:", L"ftp:", 0, S_OK, T_WIN10},
{__LINE__, L"ftp:/", L"ftp:/", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"ftp:/", L"ftp:/", 0, S_OK, T_WIN10},
{__LINE__, L"ftp://", L"ftp:///", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"ftp://", L"ftp:///", 0, S_OK, T_WIN10},
{__LINE__, L"ftp://a", L"ftp://a/", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"ftp://a", L"ftp://a/", 0, S_OK, T_WIN10},
{__LINE__, L"ftp://ftp.gnu.org/gnu/octave/", L"ftp://ftp.gnu.org/gnu/octave/", 0, S_OK, T_VISTA_PLUS}, {__LINE__, L"ftp://ftp.gnu.org/gnu/octave/", L"ftp://ftp.gnu.org/gnu/octave/", 0, S_OK, T_WIN10},
/* Tests for CRegFolder */ /* Tests for CRegFolder */
{__LINE__, L"::", NULL, 0, CO_E_CLASSSTRING, 0}, {__LINE__, L"::", NULL, 0, CO_E_CLASSSTRING, 0},
{__LINE__, L"::{", NULL, 0, CO_E_CLASSSTRING, 0}, {__LINE__, L"::{", NULL, 0, CO_E_CLASSSTRING, 0},
@ -109,17 +114,17 @@ struct test_data Tests[] =
{__LINE__, L"y:\\", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_PRE_VISTA}, {__LINE__, L"y:\\", NULL, 0, HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), T_PRE_VISTA},
{__LINE__, L"y:\\", NULL, 0, HRESULT_FROM_WIN32(ERROR_INVALID_DRIVE), T_VISTA_PLUS}, {__LINE__, L"y:\\", NULL, 0, HRESULT_FROM_WIN32(ERROR_INVALID_DRIVE), T_VISTA_PLUS},
{__LINE__, L"C:\\ ", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), T_PRE_VISTA}, {__LINE__, L"C:\\ ", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), T_PRE_VISTA},
{__LINE__, L"C:\\ ", NULL, 0, E_INVALIDARG, T_VISTA_PLUS}, {__LINE__, L"C:\\ ", NULL, 0, E_INVALIDARG, T_WIN8_PLUS},
/* Tests for CFSFolder */ /* Tests for CFSFolder */
{__LINE__, L"$", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}, {__LINE__, L"$", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0},
{__LINE__, L"c:\\Program Files", L"C:\\Program Files", 0, S_OK, 0}, {__LINE__, L"c:\\Program Files", L"C:\\Program Files", 0, S_OK, 0},
{__LINE__, L"c:\\Program Files\\", L"C:\\Program Files", 0, S_OK, 0}, {__LINE__, L"c:\\Program Files\\", L"C:\\Program Files", 0, S_OK, 0},
/* Paths with . are valid for win+r dialog or address bar but not for ParseDisplayName */ /* Paths with . are valid for win+r dialog or address bar but not for ParseDisplayName */
{__LINE__, L"c:\\Program Files\\.", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"c:\\Program Files\\.", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"c:\\Program Files\\..", NULL, 0, E_INVALIDARG, 0}, /* This gives C:\ when entered in address bar */ {__LINE__, L"c:\\Program Files\\..", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS}, /* This gives C:\ when entered in address bar */
{__LINE__, L".", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L".", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"..", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"..", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"C:\\.", NULL, 0, E_INVALIDARG, 0}, {__LINE__, L"C:\\.", NULL, 0, E_INVALIDARG, T_PRE_WIN7|T_WIN8_PLUS},
{__LINE__, L"fonts", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}, /* These three work for ShellExecute */ {__LINE__, L"fonts", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}, /* These three work for ShellExecute */
{__LINE__, L"winsxs", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}, {__LINE__, L"winsxs", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0},
{__LINE__, L"system32", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0} {__LINE__, L"system32", NULL, 0, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), 0}
@ -127,15 +132,16 @@ struct test_data Tests[] =
UINT get_host_os_flag() UINT get_host_os_flag()
{ {
switch (LOWORD(GetVersion())) switch (GetNTVersion())
{ {
case 5: return T_WIN2K; case _WIN32_WINNT_WIN2K: return T_WIN2K;
case (5 | (1 << 8)): return T_WINXP; case _WIN32_WINNT_WINXP: return T_WINXP;
case (5 | (2 << 8)): return T_WIN2K3; case _WIN32_WINNT_WS03: return T_WIN2K3;
case 6: return T_VISTA; case _WIN32_WINNT_VISTA: return T_VISTA;
case (6 | (1 << 8)): return T_WIN7; case _WIN32_WINNT_WIN7: return T_WIN7;
case (6 | (2 << 8)): return T_WIN8; case _WIN32_WINNT_WIN8: return T_WIN8;
case 10: return T_WIN10; case _WIN32_WINNT_WINBLUE: return T_WIN8;
case _WIN32_WINNT_WIN10: return T_WIN10;
} }
return 0; return 0;

View file

@ -94,17 +94,16 @@ START_TEST(SHShouldShowWizards)
CDummyClass dummy; CDummyClass dummy;
HRESULT hr; HRESULT hr;
const BOOL bVistaPlus = IsWindowsVistaOrGreater();
state.fWebView = FALSE; state.fWebView = FALSE;
SHGetSetSettings(&state, SSF_WEBVIEW, TRUE); SHGetSetSettings(&state, SSF_WEBVIEW, TRUE);
SetShowWizardsTEST(FALSE); SetShowWizardsTEST(FALSE);
hr = SHShouldShowWizards(dummy.GetUnknown()); hr = SHShouldShowWizards(dummy.GetUnknown());
ok_hex(hr, bVistaPlus ? S_FALSE : S_OK); ok_hex(hr, (GetNTVersion() >= _WIN32_WINNT_WIN8) ? S_FALSE : S_OK);
SetShowWizardsTEST(TRUE); SetShowWizardsTEST(TRUE);
hr = SHShouldShowWizards(dummy.GetUnknown()); hr = SHShouldShowWizards(dummy.GetUnknown());
ok_hex(hr, bVistaPlus ? S_FALSE : S_OK); ok_hex(hr, (GetNTVersion() >= _WIN32_WINNT_WIN8) ? S_FALSE : S_OK);
state.fWebView = TRUE; state.fWebView = TRUE;
SHGetSetSettings(&state, SSF_WEBVIEW, TRUE); SHGetSetSettings(&state, SSF_WEBVIEW, TRUE);
@ -114,7 +113,7 @@ START_TEST(SHShouldShowWizards)
SetShowWizardsTEST(TRUE); SetShowWizardsTEST(TRUE);
hr = SHShouldShowWizards(dummy.GetUnknown()); hr = SHShouldShowWizards(dummy.GetUnknown());
ok_hex(hr, bVistaPlus ? S_FALSE : S_OK); ok_hex(hr, (GetNTVersion() >= _WIN32_WINNT_WIN7) ? S_FALSE : S_OK);
// Restore old values // Restore old values
state.fWebView = bOldWebView; state.fWebView = bOldWebView;

View file

@ -457,7 +457,7 @@ static const TEST_ENTRY s_entries_1[] =
{ __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"." }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"." },
{ __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" },
{ __LINE__, FALSE, TRUE, L"Test File 1.txt", NULL }, { __LINE__, FALSE, TRUE, L"Test File 1.txt", NULL },
{ __LINE__, TRUE, TRUE, L"Test File 1.txt", L"." }, // { __LINE__, TRUE, TRUE, L"Test File 1.txt", L"." }, // Fails on Vista, 7, 8.1
{ __LINE__, FALSE, TRUE, L"Test File 1.txt", L"system32" }, { __LINE__, FALSE, TRUE, L"Test File 1.txt", L"system32" },
{ __LINE__, TRUE, TRUE, L"Test File 1.txt", s_cur_dir }, { __LINE__, TRUE, TRUE, L"Test File 1.txt", s_cur_dir },
{ __LINE__, FALSE, TRUE, L"\"Test File 1.txt\"", NULL }, { __LINE__, FALSE, TRUE, L"\"Test File 1.txt\"", NULL },
@ -511,7 +511,7 @@ static const TEST_ENTRY s_entries_2[] =
{ __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", L"system32" },
{ __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", s_cur_dir }, { __LINE__, FALSE, FALSE, L"\"Test File 1.txt\" \"Test File.txt\"", s_cur_dir },
{ __LINE__, FALSE, TRUE, L"Test File 1.txt", NULL }, { __LINE__, FALSE, TRUE, L"Test File 1.txt", NULL },
{ __LINE__, TRUE, TRUE, L"Test File 1.txt", L"." }, // { __LINE__, TRUE, TRUE, L"Test File 1.txt", L"." }, // Fails on Vista, 7, 8.1
{ __LINE__, FALSE, TRUE, L"Test File 1.txt", L"system32" }, { __LINE__, FALSE, TRUE, L"Test File 1.txt", L"system32" },
{ __LINE__, TRUE, TRUE, L"Test File 1.txt", s_cur_dir }, { __LINE__, TRUE, TRUE, L"Test File 1.txt", s_cur_dir },
{ __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", NULL }, { __LINE__, TRUE, TRUE, L"\"Test File 1.txt\"", NULL },
@ -645,10 +645,11 @@ START_TEST(ShellExecCmdLine)
// s_win_test_exe // s_win_test_exe
GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe)); GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe));
PathAppendW(s_win_test_exe, L"test program.exe"); PathAppendW(s_win_test_exe, L"test program.exe");
SetFileAttributesW(s_win_test_exe, FILE_ATTRIBUTE_NORMAL); // Clear readonly flag if it exists.
BOOL ret = CopyFileW(s_sub_program, s_win_test_exe, FALSE); BOOL ret = CopyFileW(s_sub_program, s_win_test_exe, FALSE);
if (!ret) if (!ret)
{ {
skip("Please retry with admin rights\n"); skip("Cannot copy test files to the system root directory. (Error: %lu)\n", GetLastError());
return; return;
} }
@ -682,8 +683,9 @@ START_TEST(ShellExecCmdLine)
Sleep(1000); Sleep(1000);
// clean up // clean up
ok(DeleteFileW(s_win_test_exe), "failed to delete the test file\n"); SetFileAttributesW(s_win_test_exe, FILE_ATTRIBUTE_NORMAL); // Clear readonly flag
ok(DeleteFileW(s_sys_bat_file), "failed to delete the test file\n"); ok(DeleteFileW(s_win_test_exe), "Failed to delete \"%S\".\n", s_win_test_exe);
ok(DeleteFileA("Test File 1.txt"), "failed to delete the test file\n"); ok(DeleteFileW(s_sys_bat_file), "Failed to delete \"%S\".\n", s_sys_bat_file);
ok(DeleteFileA("Test File 2.bat"), "failed to delete the test file\n"); ok(DeleteFileA("Test File 1.txt"), "Failed to delete \"Test File 1.txt\".\n");
ok(DeleteFileA("Test File 2.bat"), "Failed to delete \"Test File 2.bat\".\n");
} }

View file

@ -257,7 +257,8 @@ START_TEST(ShellState)
CHECK_REG_FLAG(fShowAllObjects); CHECK_REG_FLAG(fShowAllObjects);
CHECK_REG_FLAG(fShowExtensions); CHECK_REG_FLAG(fShowExtensions);
CHECK_REG_FLAG(fNoConfirmRecycle); CHECK_REG_FLAG(fNoConfirmRecycle);
CHECK_REG_FLAG(fShowSysFiles); // No use if (GetNTVersion() != _WIN32_WINNT_VISTA)
CHECK_REG_FLAG(fShowSysFiles); // No use, test is broken on Vista
CHECK_REG_FLAG(fShowCompColor); CHECK_REG_FLAG(fShowCompColor);
CHECK_REG_FLAG(fDoubleClickInWebView); CHECK_REG_FLAG(fDoubleClickInWebView);
CHECK_REG_FLAG(fDesktopHTML); CHECK_REG_FLAG(fDesktopHTML);

View file

@ -10,18 +10,6 @@
#define WaitForWindow(hWnd, Func, Seconds) \ #define WaitForWindow(hWnd, Func, Seconds) \
for (UINT waited = 0; !Func(hWnd) && waited < (Seconds) * 1000; waited += 250) Sleep(250); for (UINT waited = 0; !Func(hWnd) && waited < (Seconds) * 1000; waited += 250) Sleep(250);
static BOOL WaitForForegroundWindow(HWND hWnd, UINT wait = 500)
{
for (UINT waited = 0, interval = 50; waited < wait; waited += interval)
{
if (GetForegroundWindow() == hWnd)
return TRUE;
if (IsWindowVisible(hWnd))
Sleep(interval);
}
return FALSE;
}
typedef struct WINDOW_LIST typedef struct WINDOW_LIST
{ {
SIZE_T m_chWnds; SIZE_T m_chWnds;
@ -87,17 +75,6 @@ static inline HWND FindInWindowList(const WINDOW_LIST &list, HWND hWnd)
return NULL; return NULL;
} }
static inline BOOL SendAltF4Input()
{
INPUT inputs[4];
ZeroMemory(&inputs, sizeof(inputs));
inputs[0].type = inputs[1].type = inputs[2].type = inputs[3].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = inputs[3].ki.wVk = VK_LMENU;
inputs[1].ki.wVk = inputs[2].ki.wVk = VK_F4;
inputs[2].ki.dwFlags = inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
return SendInput(_countof(inputs), inputs, sizeof(INPUT)) == _countof(inputs);
}
static inline VOID CloseNewWindows(PWINDOW_LIST pExisting, PWINDOW_LIST pNew) static inline VOID CloseNewWindows(PWINDOW_LIST pExisting, PWINDOW_LIST pNew)
{ {
for (SIZE_T i = 0; i < pNew->m_chWnds; ++i) for (SIZE_T i = 0; i < pNew->m_chWnds; ++i)
@ -106,25 +83,9 @@ static inline VOID CloseNewWindows(PWINDOW_LIST pExisting, PWINDOW_LIST pNew)
if (!IsWindowVisible(hWnd) || FindInWindowList(*pExisting, hWnd)) if (!IsWindowVisible(hWnd) || FindInWindowList(*pExisting, hWnd))
continue; continue;
SwitchToThisWindow(hWnd, TRUE); if (!SendMessageTimeoutW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_ABORTIFHUNG | SMTO_BLOCK, 3000, NULL))
WaitForForegroundWindow(hWnd); // SetForegroundWindow may take some time PostMessageW(hWnd, WM_CLOSE, 0, 0);
DWORD_PTR result; /* If this window is still open, you'll need TerminateProcess(). */
if (!SendMessageTimeoutW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_ABORTIFHUNG, 3000, &result) &&
!PostMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0))
{
if (WaitForForegroundWindow(hWnd)) // We can't fake keyboard input if the target is not foreground
{
SendAltF4Input();
WaitForWindow(hWnd, IsWindowVisible, 1); // Closing a window may take some time
}
if (IsWindowVisible(hWnd))
{
CHAR szClass[64];
GetClassNameA(hWnd, szClass, _countof(szClass));
trace("Unable to close window %p (%s)\n", hWnd, szClass);
}
}
} }
} }

View file

@ -207,7 +207,7 @@ void test_CShellMenu()
} }
/* The folowing struct holds info about the order callbacks are called */ /* The folowing struct holds info about the order callbacks are called */
/* By passing different arrays of results to CMenuCallback, we can test different sequenses of callbacks */ /* By passing different arrays of results to CMenuCallback, we can test different sequences of callbacks */
struct _test_info{ struct _test_info{
int iTest; int iTest;
UINT uMsg;}; UINT uMsg;};
@ -236,54 +236,55 @@ public:
m_testsCount = testsCount; m_testsCount = testsCount;
} }
void SetTest(int i) void SetTest(int i)
{ {
m_iTest = i; m_iTest = i;
} }
HRESULT STDMETHODCALLTYPE CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam) HRESULT STDMETHODCALLTYPE CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
/*trace ("callback type %d\n", uMsg);*/ /*trace ("callback type %d\n", uMsg);*/
/* /*
* it seems callback 0x10000000 is called for every item added so * it seems callback 0x10000000 is called for every item added so
* we will ignore consecutive callbacks of this type * we will ignore callbacks of this type
* Note: this callback is invoked by shell32.dll!CMenuSFToolbar::_FilterPidl * Note: this callback is invoked by shell32.dll!CMenuSFToolbar::_FilterPidl
*/ */
if (uMsg == 0x10000000 && m_results[m_iCallback-1].uMsg == 0x10000000) if (uMsg == 0x10000000 && m_results[m_iCallback-1].uMsg == 0x13)
{ {
return S_OK; return S_OK;
} }
m_iCallback++; m_iCallback++;
if (m_iCallback > m_testsCount) if (m_iCallback > m_testsCount)
{ {
ok(0, "Got more callbacks than expected! (%d not %d). uMsg: %d\n", m_iCallback, m_testsCount, uMsg); ok(FALSE, "Got more callbacks than expected! (%d not %d). uMsg: %d\n", m_iCallback, m_testsCount, uMsg);
return S_OK; return S_OK;
} }
struct _test_info *result = &m_results[m_iCallback-1]; struct _test_info *result = &m_results[m_iCallback-1];
ok(psmd != NULL, "Got NULL psmd\n"); if (!g_bVista || uMsg != 0x38) // Vista bug
ok(m_iTest == result->iTest, "Wrong test number (%d not %d)\n", m_iTest, result->iTest); ok(psmd != NULL, "Got NULL psmd\n");
ok(result->uMsg == uMsg, "%d: Got wrong uMsg (%d instead of %d)\n", m_iCallback, uMsg, result->uMsg); ok(m_iTest == result->iTest, "Wrong test number (%d not %d)\n", m_iTest, result->iTest);
ok(result->uMsg == uMsg, "%d: Got wrong uMsg (%d instead of %d)\n", m_iCallback, uMsg, result->uMsg);
if(uMsg == SMC_CREATE) if (uMsg == SMC_CREATE)
{ {
ok(psmd->dwFlags == 0, "wrong dwFlags\n"); ok(psmd->dwFlags == 0, "wrong dwFlags\n");
ok(psmd->dwMask == 0, "wrong dwMask\n"); ok(psmd->dwMask == 0, "wrong dwMask\n");
ok(psmd->hmenu == 0, "wrong hmenu\n"); ok(psmd->hmenu == 0, "wrong hmenu\n");
ok(psmd->hwnd == 0, "wrong hwnd\n"); ok(psmd->hwnd == 0, "wrong hwnd\n");
ok(psmd->punk != NULL, "punk is null\n"); ok(psmd->punk != NULL, "punk is null\n");
} }
if (uMsg == SMC_GETSFOBJECT) if (uMsg == SMC_GETSFOBJECT)
{ {
ok(psmd->psf != 0, "wrong dwFlags\n"); ok(psmd->psf != 0, "wrong dwFlags\n");
} }
return S_FALSE; return S_FALSE;
} }
}; };
void test_CShellMenu_callbacks(IShellFolder *shellFolder, HMENU hmenu) void test_CShellMenu_callbacks(IShellFolder *shellFolder, HMENU hmenu)
@ -306,25 +307,51 @@ void test_CShellMenu_callbacks(IShellFolder *shellFolder, HMENU hmenu)
return; return;
} }
struct _test_info cbtest_info[] = { {1, SMC_CREATE}, if (GetNTVersion() <= _WIN32_WINNT_WS03)
{2, SMC_GETSFOBJECT}, {
{3, 0x31}, struct _test_info cbtest_info[] = { {1, SMC_CREATE},
{4, SMC_INITMENU}, {2, SMC_GETSFOBJECT},
{4, 53}, {3, SMC_SFEXEC_MIDDLE},
{4, 19}, {4, SMC_INITMENU},
{4, 0x10000000}, {4, 0x35},
{4, SMC_NEWITEM}, {4, 0x13},
{4, 20}, {4, 0x14},
{4, 19}, {4, 0x13},
{4, 6}, {4, 0x14},
{4, 20}, {4, SMC_GETSFOBJECT},
{4, 8}, {4, 0x18},
{4, 24}, {4, SMC_GETINFO},
{4, 5}, {4, SMC_GETINFO},
{4, 5}, {4, SMC_GETINFO},
{4, 5}}; {4, SMC_GETINFO},
{4, SMC_GETINFO},
{4, SMC_GETINFO} };
callback = new CMenuCallback(cbtest_info,18); callback = new CMenuCallback(cbtest_info, _countof(cbtest_info));
}
else
{
struct _test_info cbtest_info[] = { {1, SMC_CREATE},
{2, SMC_GETSFOBJECT},
{3, SMC_SFEXEC_MIDDLE},
{4, SMC_INITMENU},
{4, 0x38},
{4, 0x35},
{4, 0x13},
{4, 0x14},
{4, 0x13},
{4, 0x14},
{4, SMC_GETSFOBJECT},
{4, 0x18},
{4, SMC_GETINFO},
{4, SMC_GETINFO},
{4, SMC_GETINFO},
{4, SMC_GETINFO},
{4, SMC_GETINFO} };
callback = new CMenuCallback(cbtest_info, _countof(cbtest_info));
}
callback->SetTest(1); callback->SetTest(1);
hResult = shellMenu->Initialize(callback, 0,ANCESTORDEFAULT, SMINIT_TOPLEVEL|SMINIT_VERTICAL); hResult = shellMenu->Initialize(callback, 0,ANCESTORDEFAULT, SMINIT_TOPLEVEL|SMINIT_VERTICAL);

View file

@ -14,6 +14,9 @@
#include <atlbase.h> #include <atlbase.h>
#include <atlcom.h> #include <atlcom.h>
// Vista's shell32 is buggy so we need to skip some tests there.
static const BOOL g_bVista = (GetNTVersion() == _WIN32_WINNT_VISTA);
VOID PathToIDList(LPCWSTR pszPath, ITEMIDLIST** ppidl); VOID PathToIDList(LPCWSTR pszPath, ITEMIDLIST** ppidl);
#endif /* !_SHELLTEST_H_ */ #endif /* !_SHELLTEST_H_ */

View file

@ -2820,26 +2820,38 @@ enum
}; };
cpp_quote("#define SMC_INITMENU 0x00000001") cpp_quote("#define SMC_INITMENU 0x00000001")
cpp_quote("#define SMC_CREATE 0x00000002") cpp_quote("#define SMC_CREATE 0x00000002")
cpp_quote("#define SMC_EXITMENU 0x00000003") cpp_quote("#define SMC_EXITMENU 0x00000003")
cpp_quote("#define SMC_GETINFO 0x00000005") cpp_quote("#define SMC_GETINFO 0x00000005")
cpp_quote("#define SMC_GETSFINFO 0x00000006") cpp_quote("#define SMC_GETSFINFO 0x00000006")
cpp_quote("#define SMC_GETOBJECT 0x00000007") cpp_quote("#define SMC_GETOBJECT 0x00000007")
cpp_quote("#define SMC_GETSFOBJECT 0x00000008") cpp_quote("#define SMC_GETSFOBJECT 0x00000008")
cpp_quote("#define SMC_SFEXEC 0x00000009") cpp_quote("#define SMC_SFEXEC 0x00000009")
cpp_quote("#define SMC_SFSELECTITEM 0x0000000A") cpp_quote("#define SMC_SFSELECTITEM 0x0000000A")
cpp_quote("#define SMC_REFRESH 0x00000010") cpp_quote("#define SMC_REFRESH 0x00000010")
cpp_quote("#define SMC_DEMOTE 0x00000011") cpp_quote("#define SMC_DEMOTE 0x00000011")
cpp_quote("#define SMC_PROMOTE 0x00000012") cpp_quote("#define SMC_PROMOTE 0x00000012")
cpp_quote("#define SMC_DEFAULTICON 0x00000016") cpp_quote("#define SMC_DEFAULTICON 0x00000016")
cpp_quote("#define SMC_NEWITEM 0x00000017") cpp_quote("#define SMC_NEWITEM 0x00000017")
cpp_quote("#define SMC_CHEVRONEXPAND 0x00000019") cpp_quote("#define SMC_CHEVRONEXPAND 0x00000019")
cpp_quote("#define SMC_DISPLAYCHEVRONTIP 0x0000002A") cpp_quote("#define SMC_DISPLAYCHEVRONTIP 0x0000002A")
cpp_quote("#define SMC_SETSFOBJECT 0x0000002D") cpp_quote("#define SMC_SETSFOBJECT 0x0000002D")
cpp_quote("#define SMC_SHCHANGENOTIFY 0x0000002E") cpp_quote("#define SMC_SHCHANGENOTIFY 0x0000002E")
cpp_quote("#define SMC_CHEVRONGETTIP 0x0000002F") cpp_quote("#define SMC_CHEVRONGETTIP 0x0000002F")
cpp_quote("#define SMC_SFDDRESTRICTED 0x00000030") cpp_quote("#define SMC_SFDDRESTRICTED 0x00000030")
cpp_quote("#if (_WIN32_IE >= _WIN32_IE_IE70) || defined(__REACTOS__)")
cpp_quote("#define SMC_SFEXEC_MIDDLE 0x00000031")
cpp_quote("#define SMC_GETAUTOEXPANDSTATE 0x00000041")
cpp_quote("#define SMC_AUTOEXPANDCHANGE 0x00000042")
cpp_quote("#define SMC_GETCONTEXTMENUMODIFIER 0x00000043")
cpp_quote("#define SMC_GETBKCONTEXTMENU 0x00000044")
cpp_quote("#define SMC_OPEN 0x00000045")
cpp_quote("#define SMAE_EXPANDED 0x00000001")
cpp_quote("#define SMAE_CONTRACTED 0x00000002")
cpp_quote("#define SMAE_USER 0x00000004")
cpp_quote("#define SMAE_VALID 0x00000007")
cpp_quote("#endif")
[ [
uuid(4CA300A1-9B8D-11d1-8B22-00C04FD918D0), uuid(4CA300A1-9B8D-11d1-8B22-00C04FD918D0),