static
VOID
RunTestCases(VOID)
{
    /* TODO: don't duplicate this in the other tests */
    /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
    struct
    {
        PCWSTR FileName;
        PREFIX_TYPE PrefixType;
        PCWSTR FullPathName;
        RTL_PATH_TYPE PathType;
        PREFIX_TYPE FilePartPrefixType;
        SIZE_T FilePartSize;
    } TestCases[] =
    {
        { L"C:",                 PrefixCurrentPath, L"", RtlPathTypeDriveRelative, PrefixCurrentPathWithoutLastPart },
        { L"C:\\",               PrefixNone, L"C:\\", RtlPathTypeDriveAbsolute },
        { L"C:\\test",           PrefixNone, L"C:\\test", RtlPathTypeDriveAbsolute, PrefixCurrentDrive },
        { L"C:\\test\\",         PrefixNone, L"C:\\test\\", RtlPathTypeDriveAbsolute },
        { L"C:/test/",           PrefixNone, L"C:\\test\\", RtlPathTypeDriveAbsolute },

        { L"C:\\\\test",         PrefixNone, L"C:\\test", RtlPathTypeDriveAbsolute, PrefixCurrentDrive },
        { L"test",               PrefixCurrentPath, L"\\test", RtlPathTypeRelative, PrefixCurrentPath, sizeof(WCHAR) },
        { L"\\test",             PrefixCurrentDrive, L"test", RtlPathTypeRooted, PrefixCurrentDrive },
        { L"/test",              PrefixCurrentDrive, L"test", RtlPathTypeRooted, PrefixCurrentDrive },
        { L".\\test",            PrefixCurrentPath, L"\\test", RtlPathTypeRelative, PrefixCurrentPath, sizeof(WCHAR) },

        { L"\\.",                PrefixCurrentDrive, L"", RtlPathTypeRooted },
        { L"\\.\\",              PrefixCurrentDrive, L"", RtlPathTypeRooted },
        { L"\\\\.",              PrefixNone, L"\\\\.\\", RtlPathTypeRootLocalDevice },
        { L"\\\\.\\",            PrefixNone, L"\\\\.\\", RtlPathTypeLocalDevice },
        { L"\\\\.\\Something\\", PrefixNone, L"\\\\.\\Something\\", RtlPathTypeLocalDevice },

        { L"\\??\\",             PrefixCurrentDrive, L"??\\", RtlPathTypeRooted },
        { L"\\??\\C:",           PrefixCurrentDrive, L"??\\C:", RtlPathTypeRooted, PrefixCurrentDrive, 3 * sizeof(WCHAR) },
        { L"\\??\\C:\\",         PrefixCurrentDrive, L"??\\C:\\", RtlPathTypeRooted },
        { L"\\??\\C:\\test",     PrefixCurrentDrive, L"??\\C:\\test", RtlPathTypeRooted, PrefixCurrentDrive, 6 * sizeof(WCHAR) },
        { L"\\??\\C:\\test\\",   PrefixCurrentDrive, L"??\\C:\\test\\", RtlPathTypeRooted },

        { L"\\\\??\\",           PrefixNone, L"\\\\??\\", RtlPathTypeUncAbsolute },
        { L"\\\\??\\C:",         PrefixNone, L"\\\\??\\C:", RtlPathTypeUncAbsolute },
        { L"\\\\??\\C:\\",       PrefixNone, L"\\\\??\\C:\\", RtlPathTypeUncAbsolute },
        { L"\\\\??\\C:\\test",   PrefixNone, L"\\\\??\\C:\\test", RtlPathTypeUncAbsolute, PrefixNone, sizeof(L"\\\\??\\C:\\") },
        { L"\\\\??\\C:\\test\\", PrefixNone, L"\\\\??\\C:\\test\\", RtlPathTypeUncAbsolute },
    };
    NTSTATUS Status, ExceptionStatus;
    UNICODE_STRING FileName;
    UNICODE_STRING FullPathName;
    WCHAR FullPathNameBuffer[MAX_PATH];
    UNICODE_STRING TempString;
    PUNICODE_STRING StringUsed;
    SIZE_T FilePartSize;
    BOOLEAN NameInvalid;
    RTL_PATH_TYPE PathType;
    SIZE_T LengthNeeded;
    WCHAR ExpectedPathName[MAX_PATH];
    SIZE_T ExpectedFilePartSize;
    const INT TestCount = sizeof(TestCases) / sizeof(TestCases[0]);
    INT i;
    BOOLEAN Okay;

    for (i = 0; i < TestCount; i++)
    {
        trace("i = %d\n", i);
        switch (TestCases[i].PrefixType)
        {
            case PrefixNone:
                ExpectedPathName[0] = UNICODE_NULL;
                break;
            case PrefixCurrentDrive:
                GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
                ExpectedPathName[3] = UNICODE_NULL;
                break;
            case PrefixCurrentPath:
            {
                ULONG Length;
                Length = GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
                if (Length == 3 && TestCases[i].FullPathName[0])
                    ExpectedPathName[2] = UNICODE_NULL;
                break;
            }
            default:
                skip(0, "Invalid test!\n");
                continue;
        }
        wcscat(ExpectedPathName, TestCases[i].FullPathName);
        RtlInitUnicodeString(&FileName, TestCases[i].FileName);
        RtlInitEmptyUnicodeString(&FullPathName, FullPathNameBuffer, sizeof(FullPathNameBuffer));
        RtlFillMemory(FullPathName.Buffer, FullPathName.MaximumLength, 0xAA);
        TempString = FileName;
        PathType = RtlPathTypeNotSet;
        StringUsed = InvalidPointer;
        FilePartSize = 1234;
        NameInvalid = (BOOLEAN)-1;
        LengthNeeded = 1234;
        StartSeh()
            Status = pRtlGetFullPathName_UstrEx(&FileName,
                                               &FullPathName,
                                               NULL,
                                               &StringUsed,
                                               &FilePartSize,
                                               &NameInvalid,
                                               &PathType,
                                               &LengthNeeded);
            ok(Status == STATUS_SUCCESS, "status = %lx\n", Status);
        EndSeh(STATUS_SUCCESS);
        ok_eq_ustr(&FileName, &TempString);
        ok(FullPathName.Buffer        == FullPathNameBuffer,         "Buffer modified\n");
        ok(FullPathName.MaximumLength == sizeof(FullPathNameBuffer), "MaximumLength modified\n");
        Okay = CheckStringBuffer(&FullPathName, ExpectedPathName);
        ok(Okay, "Wrong path name '%wZ', expected '%S'\n", &FullPathName, ExpectedPathName);
        ok(StringUsed == &FullPathName, "StringUsed = %p, expected %p\n", StringUsed, &FullPathName);
        switch (TestCases[i].FilePartPrefixType)
        {
            case PrefixNone:
                ExpectedFilePartSize = 0;
                break;
            case PrefixCurrentDrive:
                ExpectedFilePartSize = sizeof(L"C:\\");
                break;
            case PrefixCurrentPath:
                ExpectedFilePartSize = GetCurrentDirectoryW(0, NULL) * sizeof(WCHAR);
                if (ExpectedFilePartSize == sizeof(L"C:\\"))
                    ExpectedFilePartSize -= sizeof(WCHAR);
                break;
            case PrefixCurrentPathWithoutLastPart:
            {
                WCHAR CurrentPath[MAX_PATH];
                PCWSTR BackSlash;
                ExpectedFilePartSize = GetCurrentDirectoryW(sizeof(CurrentPath) / sizeof(WCHAR), CurrentPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
                if (ExpectedFilePartSize == sizeof(L"C:\\"))
                    ExpectedFilePartSize = 0;
                else
                {
                    BackSlash = wcsrchr(CurrentPath, L'\\');
                    if (BackSlash)
                        ExpectedFilePartSize -= wcslen(BackSlash + 1) * sizeof(WCHAR);
                    else
                        ok(0, "GetCurrentDirectory returned %S\n", CurrentPath);
                }
                break;
            }
            default:
                skip(0, "Invalid test!\n");
                continue;
        }
        ExpectedFilePartSize += TestCases[i].FilePartSize;
        if (ExpectedFilePartSize != 0)
            ExpectedFilePartSize = (ExpectedFilePartSize - sizeof(UNICODE_NULL)) / sizeof(WCHAR);
        ok(FilePartSize == ExpectedFilePartSize,
            "FilePartSize = %lu, expected %lu\n", (ULONG)FilePartSize, (ULONG)ExpectedFilePartSize);
        ok(NameInvalid == FALSE, "NameInvalid = %u\n", NameInvalid);
        ok(PathType == TestCases[i].PathType, "PathType = %d, expected %d\n", PathType, TestCases[i].PathType);
        ok(LengthNeeded == 0, "LengthNeeded = %lu\n", (ULONG)LengthNeeded);
    }
}
Exemple #2
0
static
VOID
RunTestCases(VOID)
{
    /* TODO: don't duplicate this in the other tests */
    /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
    struct
    {
        PCWSTR FileName;
        PREFIX_TYPE PrefixType;
        PCWSTR FullPathName;
        PREFIX_TYPE FilePartPrefixType;
        SIZE_T FilePartSize;
    } TestCases[] =
    {
        { L"C:",                 PrefixCurrentPath, L"", PrefixCurrentPathWithoutLastPart },
        { L"C:\\",               PrefixNone, L"C:\\" },
        { L"C:\\test",           PrefixNone, L"C:\\test", PrefixCurrentDrive },
        { L"C:\\test\\",         PrefixNone, L"C:\\test\\" },
        { L"C:/test/",           PrefixNone, L"C:\\test\\" },

        { L"C:\\\\test",         PrefixNone, L"C:\\test", PrefixCurrentDrive },
        { L"test",               PrefixCurrentPath, L"\\test", PrefixCurrentPath, sizeof(WCHAR) },
        { L"\\test",             PrefixCurrentDrive, L"test", PrefixCurrentDrive },
        { L"/test",              PrefixCurrentDrive, L"test", PrefixCurrentDrive },
        { L".\\test",            PrefixCurrentPath, L"\\test", PrefixCurrentPath, sizeof(WCHAR) },

        { L"\\.",                PrefixCurrentDrive, L"" },
        { L"\\.\\",              PrefixCurrentDrive, L"" },
        { L"\\\\.",              PrefixNone, L"\\\\.\\" },
        { L"\\\\.\\",            PrefixNone, L"\\\\.\\" },
        { L"\\\\.\\Something\\", PrefixNone, L"\\\\.\\Something\\" },

        { L"\\??\\",             PrefixCurrentDrive, L"??\\" },
        { L"\\??\\C:",           PrefixCurrentDrive, L"??\\C:", PrefixCurrentDrive, 3 * sizeof(WCHAR) },
        { L"\\??\\C:\\",         PrefixCurrentDrive, L"??\\C:\\" },
        { L"\\??\\C:\\test",     PrefixCurrentDrive, L"??\\C:\\test", PrefixCurrentDrive, 6 * sizeof(WCHAR) },
        { L"\\??\\C:\\test\\",   PrefixCurrentDrive, L"??\\C:\\test\\" },

        { L"\\\\??\\",           PrefixNone, L"\\\\??\\" },
        { L"\\\\??\\C:",         PrefixNone, L"\\\\??\\C:" },
        { L"\\\\??\\C:\\",       PrefixNone, L"\\\\??\\C:\\" },
        { L"\\\\??\\C:\\test",   PrefixNone, L"\\\\??\\C:\\test", PrefixNone, sizeof(L"\\\\??\\C:\\") },
        { L"\\\\??\\C:\\test\\", PrefixNone, L"\\\\??\\C:\\test\\" },
    };
    WCHAR FullPathNameBuffer[MAX_PATH];
    PWSTR ShortName;
    SIZE_T Length;
    WCHAR ExpectedPathName[MAX_PATH];
    SIZE_T FilePartSize;
    SIZE_T ExpectedFilePartSize;
    const INT TestCount = sizeof(TestCases) / sizeof(TestCases[0]);
    INT i;
    BOOLEAN Okay;

    for (i = 0; i < TestCount; i++)
    {
        trace("i = %d\n", i);
        switch (TestCases[i].PrefixType)
        {
            case PrefixNone:
                ExpectedPathName[0] = UNICODE_NULL;
                break;
            case PrefixCurrentDrive:
                GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
                ExpectedPathName[3] = UNICODE_NULL;
                break;
            case PrefixCurrentPath:
                Length = GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
                if (Length == 3 && TestCases[i].FullPathName[0])
                    ExpectedPathName[2] = UNICODE_NULL;
                break;
            default:
                skip(0, "Invalid test!\n");
                continue;
        }
        wcscat(ExpectedPathName, TestCases[i].FullPathName);
        RtlFillMemory(FullPathNameBuffer, sizeof(FullPathNameBuffer), 0xAA);
        Length = 0;
        StartSeh()
            Length = RtlGetFullPathName_U(TestCases[i].FileName,
                                          sizeof(FullPathNameBuffer),
                                          FullPathNameBuffer,
                                          &ShortName);
        EndSeh(STATUS_SUCCESS);

        Okay = CheckStringBuffer(FullPathNameBuffer, Length, sizeof(FullPathNameBuffer), ExpectedPathName);
        ok(Okay, "Wrong path name '%S', expected '%S'\n", FullPathNameBuffer, ExpectedPathName);

        if (!ShortName)
            FilePartSize = 0;
        else
            FilePartSize = ShortName - FullPathNameBuffer;

        switch (TestCases[i].FilePartPrefixType)
        {
            case PrefixNone:
                ExpectedFilePartSize = 0;
                break;
            case PrefixCurrentDrive:
                ExpectedFilePartSize = sizeof(L"C:\\");
                break;
            case PrefixCurrentPath:
                ExpectedFilePartSize = GetCurrentDirectoryW(0, NULL) * sizeof(WCHAR);
                if (ExpectedFilePartSize == sizeof(L"C:\\"))
                    ExpectedFilePartSize -= sizeof(WCHAR);
                break;
            case PrefixCurrentPathWithoutLastPart:
            {
                WCHAR CurrentPath[MAX_PATH];
                PCWSTR BackSlash;
                ExpectedFilePartSize = GetCurrentDirectoryW(sizeof(CurrentPath) / sizeof(WCHAR), CurrentPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
                if (ExpectedFilePartSize == sizeof(L"C:\\"))
                    ExpectedFilePartSize = 0;
                else
                {
                    BackSlash = wcsrchr(CurrentPath, L'\\');
                    if (BackSlash)
                        ExpectedFilePartSize -= wcslen(BackSlash + 1) * sizeof(WCHAR);
                    else
                        ok(0, "GetCurrentDirectory returned %S\n", CurrentPath);
                }
                break;
            }
            default:
                skip(0, "Invalid test!\n");
                continue;
        }
        ExpectedFilePartSize += TestCases[i].FilePartSize;
        if (ExpectedFilePartSize != 0)
            ExpectedFilePartSize = (ExpectedFilePartSize - sizeof(UNICODE_NULL)) / sizeof(WCHAR);
        ok(FilePartSize == ExpectedFilePartSize,
            "FilePartSize = %lu, expected %lu\n", (ULONG)FilePartSize, (ULONG)ExpectedFilePartSize);
    }
}
static
VOID
RunTestCases(
    PCWSTR CustomPath)
{
    struct
    {
        PCWSTR SearchPath;
        PCWSTR FileName;
        PCWSTR Extension;
        PCWSTR ResultPath;
        PCWSTR ResultFileName;
    } Tests[] =
    {
        { L"",                 L"",                     NULL,    NULL,                           NULL },
        { L"C:\\%ls\\Folder1", L"File1",                NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
        /* No path: current directory */
        { L"",                 L"File1",                NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        /* Full path as FileName */
        { L"",                 L"C:\\",                 NULL,    L"C:\\",                        NULL },
        { L"",                 L"C:\\%ls\\Folder1",     NULL,    L"C:\\%ls\\",                   L"Folder1" },
        /* No FileName */
        { L"C:\\",             L"",                     NULL,    L"C:\\",                        NULL },
        { L"C:\\%ls\\Folder1", L"",                     NULL,    L"C:\\%ls\\Folder1\\",          NULL },
        /* Full path as FileName */
        { L"", L"C:\\%ls\\Folder1\\SomeProgram.exe",    NULL,    L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"", L"C:\\%ls\\Folder1\\SomeProgram.exe",    L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"", L"C:\\%ls\\Folder1\\SomeProgram",        NULL,    NULL,                           NULL },
        // 10
        { L"", L"C:\\%ls\\Folder1\\SomeProgram",        L".exe", NULL,                           NULL },
        /* Both SearchPath and FileName */
        { L"C:\\%ls\\Folder1\\", L"SomeProgram.exe",    NULL,    L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"C:\\%ls\\Folder1\\", L"SomeProgram.exe",    L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"C:\\%ls\\Folder1\\", L"SomeProgram",        NULL,    NULL,                           NULL },
        { L"C:\\%ls\\Folder1\\", L"SomeProgram",        L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"C:\\%ls\\Folder1",   L"SomeProgram.exe",    NULL,    L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"C:\\%ls\\Folder1",   L"SomeProgram.exe",    L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        { L"C:\\%ls\\Folder1",   L"SomeProgram",        NULL,    NULL,                           NULL },
        { L"C:\\%ls\\Folder1",   L"SomeProgram",        L".exe", L"C:\\%ls\\Folder1\\",          L"SomeProgram.exe" },
        /* Full path to file in SearchPath doesn't work */
        { L"C:\\%ls\\Folder1\\SomeProgram.exe", L"",    NULL,    NULL,                           NULL },
        // 20
        { L"C:\\%ls\\Folder1\\SomeProgram.exe", L"",    L".exe", NULL,                           NULL },
        { L"C:\\%ls\\Folder1\\SomeProgram",     L"",    NULL,    NULL,                           NULL },
        { L"C:\\%ls\\Folder1\\SomeProgram",     L"",    L".exe", NULL,                           NULL },
        /* */
        { L"C:\\%ls\\Folder1",          L"File1",       NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
        { L"C:\\%ls\\CurrentDirectory", L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        { L"C:\\%ls\\Folder1 ",         L"File1",       NULL,    NULL,                           NULL },
        { L"C:\\%ls\\CurrentDirectory ",L"File1",       NULL,    NULL,                           NULL },
        { L" C:\\%ls\\Folder1",         L"File1",       NULL,    NULL,                           NULL },
        { L" C:\\%ls\\CurrentDirectory",L"File1",       NULL,    NULL,                           NULL },
        { L" C:\\%ls\\Folder1 ",        L"File1",       NULL,    NULL,                           NULL },
        // 30
        { L" C:\\%ls\\CurrentDirectory ",L"File1",      NULL,    NULL,                           NULL },
        /* Multiple search paths */
        { L"C:\\%ls\\Folder1;C:\\%ls\\CurrentDirectory",
                                        L"File1",       NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
        { L"C:\\%ls\\CurrentDirectory;C:\\%ls\\Folder1",
                                        L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        { L"C:\\%ls\\CurrentDirectory ; C:\\%ls\\Folder1",
                                        L"File1",       NULL,    NULL,                           NULL },
        { L"C:\\%ls\\CurrentDirectory ;C:\\%ls\\Folder1",
                                        L"File1",       NULL,    L"C:\\%ls\\Folder1\\",          L"File1" },
        { L"C:\\%ls\\CurrentDirectory; C:\\%ls\\Folder1",
                                        L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        { L";C:\\%ls\\Folder1",         L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        { L";C:\\%ls\\Folder1;",        L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        { L";C:\\%ls\\Folder1;",        L"File1",       NULL,    L"C:\\%ls\\CurrentDirectory\\", L"File1" },
        { L"C:\\%ls\\Folder1",          L"OnlyInCurr",  NULL,    NULL,                           NULL },
        // 40
        { L"",                          L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"",                          L"OnlyInCurr ", NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"",                          L" OnlyInCurr", NULL,    NULL,                           NULL },
        { L" ",                         L"OnlyInCurr",  NULL,    NULL,                           NULL },
        { L";",                         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"; ",                        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L" ;",                        L"OnlyInCurr",  NULL,    NULL,                           NULL },
        { L" ; ",                       L"OnlyInCurr",  NULL,    NULL,                           NULL },
        { L";C:\\%ls\\Folder1",         L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"C:\\%ls\\Folder1;",         L"OnlyInCurr",  NULL,    NULL,                           NULL },
        // 50
        { L"C:\\%ls\\Folder1;;",        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L";C:\\%ls\\Folder1;",        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2",
                                        L"OnlyInCurr",  NULL,    NULL,                           NULL },
        { L";C:\\%ls\\Folder1;C:\\%ls\\Folder2",
                                        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"C:\\%ls\\Folder1;;C:\\%ls\\Folder2",
                                        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2;",
                                        L"OnlyInCurr",  NULL,    NULL,                           NULL },
        { L"C:\\%ls\\Folder1;C:\\%ls\\Folder2;;",
                                        L"OnlyInCurr",  NULL,    L"C:\\%ls\\CurrentDirectory\\", L"OnlyInCurr" },
        /* Spaces in FileName! */
        { L"", L"C:\\%ls\\Folder1\\SomeProgram With Spaces",
                                                        L".exe", NULL,                           NULL },
        { L"", L"C:\\%ls\\Folder1\\SomeProgram With Spaces.exe",
                                                        L".exe", NULL,                           NULL },
        { L"", L"C:\\%ls\\Folder1\\Program",            L".exe", NULL,                           NULL },
        // 60
        { L"", L"C:\\%ls\\Folder1\\Program.exe",        L".exe", L"C:\\%ls\\Folder1\\",          L"Program.exe" },
        { L"", L"C:\\%ls\\Folder1\\Program With",       L".exe", NULL,                           NULL },
        { L"", L"C:\\%ls\\Folder1\\Program With.exe",   L".exe", L"C:\\%ls\\Folder1\\",          L"Program With.exe" },
        { L"", L"C:\\%ls\\Folder1\\Program With Spaces",L".exe", NULL,                           NULL },
        { L"", L"C:\\%ls\\Folder1\\Program With Spaces.exe",
                                                        L".exe", L"C:\\%ls\\Folder1\\",          L"Program With Spaces.exe" },
        /* Same tests with path in SearchPath - now extensions are appended */
        { L"C:\\%ls\\Folder1", L"SomeProgram With Spaces",
                                                        L".exe", NULL,                           NULL },
        { L"C:\\%ls\\Folder1", L"SomeProgram With Spaces.exe",
                                                        L".exe", NULL,                           NULL },
        { L"C:\\%ls\\Folder1", L"Program",              L".exe", L"C:\\%ls\\Folder1\\",          L"Program.exe" },
        { L"C:\\%ls\\Folder1", L"Program.exe",          L".exe", L"C:\\%ls\\Folder1\\",          L"Program.exe" },
        { L"C:\\%ls\\Folder1", L"Program With",         L".exe", L"C:\\%ls\\Folder1\\",          L"Program With.exe" },
        // 70
        { L"C:\\%ls\\Folder1", L"Program With.exe",     L".exe", L"C:\\%ls\\Folder1\\",          L"Program With.exe" },
        { L"C:\\%ls\\Folder1", L"Program With Spaces",  L".exe", L"C:\\%ls\\Folder1\\",          L"Program With Spaces.exe" },
        { L"C:\\%ls\\Folder1", L"Program With Spaces.exe",
                                                        L".exe", L"C:\\%ls\\Folder1\\",          L"Program With Spaces.exe" },
    };

    ULONG i;
    ULONG Length;
    PWSTR PartName;
    WCHAR SearchPath[MAX_PATH];
    WCHAR FileName[MAX_PATH];
    WCHAR ResultPath[MAX_PATH];
    WCHAR Buffer[MAX_PATH];
    BOOLEAN Okay;

    for (i = 0; i < sizeof(Tests) / sizeof(Tests[0]); i++)
    {
        swprintf(SearchPath, Tests[i].SearchPath, CustomPath, CustomPath, CustomPath, CustomPath);
        swprintf(FileName, Tests[i].FileName, CustomPath, CustomPath, CustomPath, CustomPath);
        RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
        PartName = InvalidPointer;

        StartSeh()
            Length = RtlDosSearchPath_U(SearchPath,
                                        FileName,
                                        Tests[i].Extension,
                                        sizeof(Buffer),
                                        Buffer,
                                        &PartName);
        EndSeh(STATUS_SUCCESS);

        if (Tests[i].ResultPath)
        {
            swprintf(ResultPath, Tests[i].ResultPath, CustomPath, CustomPath, CustomPath, CustomPath);
            if (Tests[i].ResultFileName)
            {
                ok(PartName == &Buffer[wcslen(ResultPath)],
                   "PartName = %p (%ls), expected %p\n",
                   PartName, PrintablePointer(PartName), &Buffer[wcslen(ResultPath)]);
                wcscat(ResultPath, Tests[i].ResultFileName);
            }
            else
            {
                ok(PartName == NULL,
                   "PartName = %p (%ls), expected NULL\n",
                   PartName, PrintablePointer(PartName));
            }
            Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), ResultPath);
            ok(Okay == TRUE, "CheckStringBuffer failed. Got '%ls', expected '%ls'\n", Buffer, ResultPath);
        }
        else
        {
            Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55);
            ok(Okay == TRUE, "CheckBuffer failed\n");
            ok(Length == 0, "Length = %lu\n", Length);
            ok(PartName == InvalidPointer,
               "PartName = %p (%ls), expected %p\n",
               PartName, PrintablePointer(PartName), InvalidPointer);
        }
    }
}
static
VOID
RunTestCases(VOID)
{
    /* TODO: don't duplicate this in the other tests */
    /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
    struct
    {
        PCWSTR FileName;
        PREFIX_TYPE PrefixType;
        PCWSTR FullPathName;
        RTL_PATH_TYPE PathType;
        PREFIX_TYPE FilePartPrefixType;
        SIZE_T FilePartSize;
    } TestCases[] =
    {
        { L"C:",                 PrefixCurrentPath, L"", RtlPathTypeDriveRelative, PrefixCurrentPathWithoutLastPart },
        { L"C:\\",               PrefixNone, L"C:\\", RtlPathTypeDriveAbsolute },
        { L"C:\\test",           PrefixNone, L"C:\\test", RtlPathTypeDriveAbsolute, PrefixCurrentDrive },
        { L"C:\\test\\",         PrefixNone, L"C:\\test\\", RtlPathTypeDriveAbsolute },
        { L"C:/test/",           PrefixNone, L"C:\\test\\", RtlPathTypeDriveAbsolute },

        { L"C:\\\\test",         PrefixNone, L"C:\\test", RtlPathTypeDriveAbsolute, PrefixCurrentDrive },
        { L"test",               PrefixCurrentPath, L"\\test", RtlPathTypeRelative, PrefixCurrentPath, sizeof(WCHAR) },
        { L"\\test",             PrefixCurrentDrive, L"test", RtlPathTypeRooted, PrefixCurrentDrive },
        { L"/test",              PrefixCurrentDrive, L"test", RtlPathTypeRooted, PrefixCurrentDrive },
        { L".\\test",            PrefixCurrentPath, L"\\test", RtlPathTypeRelative, PrefixCurrentPath, sizeof(WCHAR) },

        { L"\\.",                PrefixCurrentDrive, L"", RtlPathTypeRooted },
        { L"\\.\\",              PrefixCurrentDrive, L"", RtlPathTypeRooted },
        { L"\\\\.",              PrefixNone, L"\\\\.\\", RtlPathTypeRootLocalDevice },
        { L"\\\\.\\",            PrefixNone, L"\\\\.\\", RtlPathTypeLocalDevice },
        { L"\\\\.\\Something\\", PrefixNone, L"\\\\.\\Something\\", RtlPathTypeLocalDevice },

        { L"\\??\\",             PrefixCurrentDrive, L"??\\", RtlPathTypeRooted },
        { L"\\??\\C:",           PrefixCurrentDrive, L"??\\C:", RtlPathTypeRooted, PrefixCurrentDrive, 3 * sizeof(WCHAR) },
        { L"\\??\\C:\\",         PrefixCurrentDrive, L"??\\C:\\", RtlPathTypeRooted },
        { L"\\??\\C:\\test",     PrefixCurrentDrive, L"??\\C:\\test", RtlPathTypeRooted, PrefixCurrentDrive, 6 * sizeof(WCHAR) },
        { L"\\??\\C:\\test\\",   PrefixCurrentDrive, L"??\\C:\\test\\", RtlPathTypeRooted },

        { L"\\\\??\\",           PrefixNone, L"\\\\??\\", RtlPathTypeUncAbsolute },
        { L"\\\\??\\C:",         PrefixNone, L"\\\\??\\C:", RtlPathTypeUncAbsolute },
        { L"\\\\??\\C:\\",       PrefixNone, L"\\\\??\\C:\\", RtlPathTypeUncAbsolute },
        { L"\\\\??\\C:\\test",   PrefixNone, L"\\\\??\\C:\\test", RtlPathTypeUncAbsolute, PrefixNone, sizeof(L"\\\\??\\C:\\") },
        { L"\\\\??\\C:\\test\\", PrefixNone, L"\\\\??\\C:\\test\\", RtlPathTypeUncAbsolute },
    };
    ULONG Length;
    UNICODE_STRING FileName;
    WCHAR FullPathNameBuffer[MAX_PATH];
    UNICODE_STRING TempString;
    const WCHAR *ShortName;
    BOOLEAN NameInvalid;
    PATH_TYPE_AND_UNKNOWN PathType;
    WCHAR ExpectedPathName[MAX_PATH];
    SIZE_T ExpectedFilePartSize;
    const WCHAR *ExpectedShortName;
    const INT TestCount = sizeof(TestCases) / sizeof(TestCases[0]);
    INT i;
    BOOLEAN Okay;

    for (i = 0; i < TestCount; i++)
    {
        trace("i = %d\n", i);
        switch (TestCases[i].PrefixType)
        {
            case PrefixNone:
                ExpectedPathName[0] = UNICODE_NULL;
                break;
            case PrefixCurrentDrive:
                GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
                ExpectedPathName[3] = UNICODE_NULL;
                break;
            case PrefixCurrentPath:
            {
                ULONG Length;
                Length = GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
                if (Length == 3 && TestCases[i].FullPathName[0])
                    ExpectedPathName[2] = UNICODE_NULL;
                break;
            }
            default:
                skip("Invalid test!\n");
                continue;
        }
        wcscat(ExpectedPathName, TestCases[i].FullPathName);
        RtlInitUnicodeString(&FileName, TestCases[i].FileName);
        RtlFillMemory(FullPathNameBuffer, sizeof(FullPathNameBuffer), 0xAA);
        TempString = FileName;
        PathType.Type = RtlPathTypeNotSet;
        PathType.Unknown = 1234;
        ShortName = InvalidPointer;
        NameInvalid = (BOOLEAN)-1;
        Length = 1234;
        StartSeh()
            Length = RtlGetFullPathName_Ustr(&FileName,
                                             sizeof(FullPathNameBuffer),
                                             FullPathNameBuffer,
                                             &ShortName,
                                             &NameInvalid,
                                             &PathType);
        EndSeh(STATUS_SUCCESS);
        ok_eq_ustr(&FileName, &TempString);
        Okay = CheckStringBuffer(FullPathNameBuffer, Length, sizeof(FullPathNameBuffer), ExpectedPathName);
        ok(Okay, "Wrong path name '%S', expected '%S'\n", FullPathNameBuffer, ExpectedPathName);
        switch (TestCases[i].FilePartPrefixType)
        {
            case PrefixNone:
                ExpectedFilePartSize = 0;
                break;
            case PrefixCurrentDrive:
                ExpectedFilePartSize = sizeof(L"C:\\");
                break;
            case PrefixCurrentPath:
                ExpectedFilePartSize = GetCurrentDirectoryW(0, NULL) * sizeof(WCHAR);
                if (ExpectedFilePartSize == sizeof(L"C:\\"))
                    ExpectedFilePartSize -= sizeof(WCHAR);
                break;
            case PrefixCurrentPathWithoutLastPart:
            {
                WCHAR CurrentPath[MAX_PATH];
                PCWSTR BackSlash;
                ExpectedFilePartSize = GetCurrentDirectoryW(sizeof(CurrentPath) / sizeof(WCHAR), CurrentPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
                if (ExpectedFilePartSize == sizeof(L"C:\\"))
                    ExpectedFilePartSize = 0;
                else
                {
                    BackSlash = wcsrchr(CurrentPath, L'\\');
                    if (BackSlash)
                        ExpectedFilePartSize -= wcslen(BackSlash + 1) * sizeof(WCHAR);
                    else
                        ok(0, "GetCurrentDirectory returned %S\n", CurrentPath);
                }
                break;
            }
            default:
                skip("Invalid test!\n");
                continue;
        }
        ExpectedFilePartSize += TestCases[i].FilePartSize;
        if (ExpectedFilePartSize == 0)
        {
            ExpectedShortName = NULL;
        }
        else
        {
            ExpectedFilePartSize = (ExpectedFilePartSize - sizeof(UNICODE_NULL)) / sizeof(WCHAR);
            ExpectedShortName = FullPathNameBuffer + ExpectedFilePartSize;
        }
        ok(ShortName == ExpectedShortName,
            "ShortName = %p, expected %p\n", ShortName, ExpectedShortName);
        ok(NameInvalid == FALSE, "NameInvalid = %u\n", NameInvalid);
        ok(PathType.Type == TestCases[i].PathType, "PathType = %d, expected %d\n", PathType.Type, TestCases[i].PathType);
        ok(PathType.Unknown == 1234 ||
            broken(PathType.Unknown == 0) ||
            broken(PathType.Unknown == 32), "Unknown = %lu\n", PathType.Unknown);
    }
}