reactos/modules/rostests/apitests/shlwapi/PathFindOnPath.c

351 lines
14 KiB
C

/*
* Copyright 2017 Katayama Hirofumi MZ
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <apitest.h>
#include <shlwapi.h>
#include <assert.h>
#include <pseh/pseh2.h>
#define EF_FULLPATH 1
#define EF_TESTDATA 2
#define EF_WIN_DIR 4
#define EF_SYS_DIR 8
#define EF_TYPE_MASK 0xF
#define EF_NAME_ONLY 16
typedef struct ENTRY
{
INT EntryNumber; /* # */
INT Ret;
DWORD Error;
UINT EF_;
LPCWSTR NameBefore;
LPCWSTR NameExpected;
LPCWSTR PathExpected;
LPWSTR * Dirs;
} ENTRY;
#define BEEF 0xBEEF /* Error Code 48879 */
#define DEAD 0xDEAD /* Error Code 57005 */
#define IGNORE_ERR 0x7F7F7F7F /* Ignore Error Code */
#define RAISED 9999 /* exception raised */
static WCHAR s_TestDataPath[MAX_PATH];
static LPWSTR s_Dirs[2];
static WCHAR s_WinDir[MAX_PATH];
static WCHAR s_SysDir[MAX_PATH];
static WCHAR s_FontsDir[MAX_PATH];
static WCHAR s_NotepadPath[MAX_PATH];
static const ENTRY s_Entries[] =
{
/* NULL or empty path */
{ 0, 0, BEEF, EF_FULLPATH, NULL, NULL },
{ 1, 1, BEEF, EF_FULLPATH, L"", s_SysDir },
/* path without dirs in Windows */
{ 2, 0, BEEF, EF_WIN_DIR, L"", L"" },
{ 3, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts" },
{ 4, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad" },
{ 5, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe" },
{ 6, 0, BEEF, EF_WIN_DIR, L"system32", L"system32" },
{ 7, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name" },
/* path with dirs in Windows */
{ 8, 0, BEEF, EF_WIN_DIR, L"", L"", NULL, s_Dirs },
{ 9, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
{ 10, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad", NULL, s_Dirs },
{ 11, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
{ 12, 0, BEEF, EF_WIN_DIR, L"system32", L"system32", NULL, s_Dirs },
{ 13, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
/* name only without dirs in Windows */
{ 14, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", L"system32" },
{ 15, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts" },
{ 16, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad" },
{ 17, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
{ 18, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32" },
{ 19, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
/* name only with dirs in Windows */
{ 20, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
{ 21, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", NULL, s_Dirs },
{ 22, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
{ 23, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath, s_Dirs },
{ 24, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32", L"system32", NULL, s_Dirs },
{ 25, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
/* path without dirs in system32 */
{ 26, 0, BEEF, EF_SYS_DIR, L"", L"" },
{ 27, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts" },
{ 28, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad" },
{ 29, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe" },
{ 30, 0, BEEF, EF_SYS_DIR, L"system32", L"system32" },
{ 31, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name" },
/* path with dirs in system32 */
{ 32, 0, BEEF, EF_SYS_DIR, L"", L"", NULL, s_Dirs },
{ 33, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
{ 34, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad", NULL, s_Dirs },
{ 35, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
{ 36, 0, BEEF, EF_SYS_DIR, L"system32", L"system32", NULL, s_Dirs },
{ 37, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
/* name only without dirs in system32 */
{ 38, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_SysDir },
{ 39, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir },
{ 40, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
{ 41, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe" },
{ 42, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
{ 43, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
/* name only with dirs in system32 */
{ 44, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
{ 45, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir, s_Dirs },
{ 46, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
{ 47, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
{ 48, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir, s_Dirs },
{ 49, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
/* path without dirs in testdata dir */
{ 50, 0, BEEF, EF_TESTDATA, L"", L"" },
{ 51, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts" },
{ 52, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad" },
{ 53, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe" },
{ 54, 0, BEEF, EF_TESTDATA, L"system32", L"system32" },
{ 55, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name" },
{ 56, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt" },
{ 57, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils" },
{ 58, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe" },
/* path with dirs in testdata dir */
{ 59, 0, BEEF, EF_TESTDATA, L"", L"", NULL, s_Dirs },
{ 60, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts", NULL, s_Dirs },
{ 61, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad", NULL, s_Dirs },
{ 62, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
{ 63, 0, BEEF, EF_TESTDATA, L"system32", L"system32", NULL, s_Dirs },
{ 64, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name", NULL, s_Dirs },
{ 65, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt", NULL, s_Dirs },
{ 66, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", NULL, s_Dirs },
{ 67, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", NULL, s_Dirs },
/* name only without dirs in testdata dir */
{ 68, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_SysDir },
{ 69, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir },
{ 70, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
{ 71, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
{ 72, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
{ 73, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
{ 74, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
{ 75, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
{ 76, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
/* name only with dirs in testdata dir */
{ 77, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_TestDataPath, s_Dirs },
{ 78, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"Fonts", NULL, s_FontsDir, s_Dirs },
{ 79, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
{ 80, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath, s_Dirs },
{ 81, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir, s_Dirs },
{ 82, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
{ 83, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
{ 84, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
{ 85, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
};
static void DoEntry(INT EntryNumber, const ENTRY *pEntry, const WCHAR *PathVar)
{
WCHAR Path[MAX_PATH], PathExpected[MAX_PATH], OldPathVar[256];
INT Ret;
DWORD Error;
if (pEntry->NameBefore == NULL)
{
assert(pEntry->NameExpected == NULL);
assert(pEntry->PathExpected == NULL);
}
switch (pEntry->EF_ & EF_TYPE_MASK)
{
case EF_FULLPATH:
if (pEntry->NameBefore)
{
lstrcpyW(Path, pEntry->NameBefore);
}
if (pEntry->NameExpected)
{
lstrcpyW(PathExpected, pEntry->NameExpected);
}
break;
case EF_TESTDATA:
if (pEntry->EF_ & EF_NAME_ONLY)
{
lstrcpyW(Path, pEntry->NameBefore);
}
else
{
lstrcpyW(Path, s_TestDataPath);
lstrcatW(Path, L"\\");
lstrcatW(Path, pEntry->NameBefore);
}
if (pEntry->NameExpected)
{
lstrcpyW(PathExpected, s_TestDataPath);
lstrcatW(PathExpected, L"\\");
lstrcatW(PathExpected, pEntry->NameExpected);
}
break;
case EF_WIN_DIR:
if (pEntry->EF_ & EF_NAME_ONLY)
{
lstrcpyW(Path, pEntry->NameBefore);
}
else
{
GetWindowsDirectoryW(Path, _countof(Path));
lstrcatW(Path, L"\\");
lstrcatW(Path, pEntry->NameBefore);
}
if (pEntry->NameExpected)
{
GetWindowsDirectoryW(PathExpected, _countof(PathExpected));
lstrcatW(PathExpected, L"\\");
lstrcatW(PathExpected, pEntry->NameExpected);
}
break;
case EF_SYS_DIR:
if (pEntry->EF_ & EF_NAME_ONLY)
{
lstrcpyW(Path, pEntry->NameBefore);
}
else
{
GetSystemDirectoryW(Path, _countof(Path));
lstrcatW(Path, L"\\");
lstrcatW(Path, pEntry->NameBefore);
}
if (pEntry->NameExpected)
{
GetSystemDirectoryW(PathExpected, _countof(PathExpected));
lstrcatW(PathExpected, L"\\");
lstrcatW(PathExpected, pEntry->NameExpected);
}
break;
}
if (PathVar)
{
if (!GetEnvironmentVariableW(L"PATH", OldPathVar, _countof(OldPathVar)))
{
skip("#%d: GetEnvironmentVariableW failed\n", EntryNumber);
return;
}
if (!SetEnvironmentVariableW(L"PATH", PathVar))
{
skip("#%d: SetEnvironmentVariableW failed\n", EntryNumber);
return;
}
}
_SEH2_TRY
{
SetLastError(BEEF);
if (pEntry->NameBefore)
{
Ret = PathFindOnPathW(Path, (LPCWSTR *)pEntry->Dirs);
}
else
{
Ret = PathFindOnPathW(NULL, (LPCWSTR *)pEntry->Dirs);
}
Error = GetLastError();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = RAISED;
Error = DEAD;
}
_SEH2_END;
if (PathVar)
{
ok(SetEnvironmentVariableW(L"PATH", OldPathVar),
"#%d: SetEnvironmentVariableW failed\n", EntryNumber);
}
ok(Ret == pEntry->Ret, "#%d: Ret expected %d, was %d.\n",
EntryNumber, pEntry->Ret, Ret);
if (pEntry->Error != IGNORE_ERR)
{
ok(Error == pEntry->Error, "#%d: last error expected %ld, was %ld.\n",
EntryNumber, pEntry->Error, Error);
}
if (pEntry->PathExpected)
{
ok(lstrcmpiW(Path, pEntry->PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
EntryNumber, wine_dbgstr_w(pEntry->PathExpected), wine_dbgstr_w(Path));
}
else if (pEntry->NameExpected)
{
ok(lstrcmpiW(Path, PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
EntryNumber, wine_dbgstr_w(PathExpected), wine_dbgstr_w(Path));
}
}
static void Test_PathFindOnPathW(void)
{
UINT i;
for (i = 0; i < _countof(s_Entries); ++i)
{
DoEntry(s_Entries[i].EntryNumber, &s_Entries[i], NULL);
}
}
START_TEST(PathFindOnPath)
{
LPWSTR pch;
GetWindowsDirectoryW(s_WinDir, _countof(s_WinDir));
GetSystemDirectoryW(s_SysDir, _countof(s_SysDir));
lstrcpyW(s_FontsDir, s_WinDir);
lstrcatW(s_FontsDir, L"\\Fonts");
lstrcpyW(s_NotepadPath, s_SysDir);
lstrcatW(s_NotepadPath, L"\\notepad.exe");
GetModuleFileNameW(NULL, s_TestDataPath, _countof(s_TestDataPath));
pch = wcsrchr(s_TestDataPath, L'\\');
if (pch == NULL)
pch = wcsrchr(s_TestDataPath, L'/');
if (pch == NULL)
{
skip("GetModuleFileName and/or wcsrchr are insane.\n");
return;
}
lstrcpyW(pch, L"\\testdata");
if (GetFileAttributesW(s_TestDataPath) == INVALID_FILE_ATTRIBUTES)
{
skip("testdata is not found.\n");
return;
}
s_Dirs[0] = s_TestDataPath;
s_Dirs[1] = NULL;
Test_PathFindOnPathW();
}