From: Thomas Faber Date: Tue, 1 Dec 2015 14:22:17 +0000 (+0000) Subject: [KMTESTS:FSRTL] X-Git-Tag: ReactOS-0.4.0~59^2~95 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7a677edbeb33615402ec42fb159b3b162f6e1137 [KMTESTS:FSRTL] - Add tests for FsRtlDissectName/FsRtlDissectDbcs and FsRtlIsFatDbcsLegal/FsRtlIsHpfsDbcsLegal svn path=/trunk/; revision=70226 --- diff --git a/rostests/kmtests/CMakeLists.txt b/rostests/kmtests/CMakeLists.txt index 864371c35cf..4b250400928 100644 --- a/rostests/kmtests/CMakeLists.txt +++ b/rostests/kmtests/CMakeLists.txt @@ -47,7 +47,9 @@ list(APPEND KMTEST_DRV_SOURCE ntos_ex/ExSequencedList.c ntos_ex/ExSingleList.c ntos_ex/ExTimer.c + ntos_fsrtl/FsRtlDissect.c ntos_fsrtl/FsRtlExpression.c + ntos_fsrtl/FsRtlLegal.c ntos_fsrtl/FsRtlMcb.c ntos_fsrtl/FsRtlTunnel.c ntos_io/IoCreateFile.c diff --git a/rostests/kmtests/kmtest_drv/testlist.c b/rostests/kmtests/kmtest_drv/testlist.c index e2cbcbd5ebe..485bf562128 100644 --- a/rostests/kmtests/kmtest_drv/testlist.c +++ b/rostests/kmtests/kmtest_drv/testlist.c @@ -20,7 +20,9 @@ KMT_TESTFUNC Test_ExResource; KMT_TESTFUNC Test_ExSequencedList; KMT_TESTFUNC Test_ExSingleList; KMT_TESTFUNC Test_ExTimer; +KMT_TESTFUNC Test_FsRtlDissect; KMT_TESTFUNC Test_FsRtlExpression; +KMT_TESTFUNC Test_FsRtlLegal; KMT_TESTFUNC Test_FsRtlMcb; KMT_TESTFUNC Test_FsRtlTunnel; KMT_TESTFUNC Test_IoCreateFile; @@ -85,7 +87,9 @@ const KMT_TEST TestList[] = { "ExSingleList", Test_ExSingleList }, { "-ExTimer", Test_ExTimer }, { "Example", Test_Example }, + { "FsRtlDissect", Test_FsRtlDissect }, { "FsRtlExpression", Test_FsRtlExpression }, + { "FsRtlLegal", Test_FsRtlLegal }, { "FsRtlMcb", Test_FsRtlMcb }, { "FsRtlTunnel", Test_FsRtlTunnel }, { "IoCreateFile", Test_IoCreateFile }, diff --git a/rostests/kmtests/ntos_fsrtl/FsRtlDissect.c b/rostests/kmtests/ntos_fsrtl/FsRtlDissect.c new file mode 100644 index 00000000000..bb16983032a --- /dev/null +++ b/rostests/kmtests/ntos_fsrtl/FsRtlDissect.c @@ -0,0 +1,123 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for FsRtlDissectName/FsRtlDissectDbcs + * PROGRAMMER: Thomas Faber + */ + +#include + +static struct +{ + PCSTR Name; + INT Offset1; + INT Offset2; + INT Length1; + INT Length2; +} Tests[] = +{ + { NULL, -1, -1 }, + { "", -1, -1 }, + { "a", 0, -1, 1, 1 }, + { "a\\b", 0, 2, 1, 1 }, + { "a\\", 0, 2, 1, 0 }, + { "\\b", 1, -1, 1 }, + { "\\", 1, -1, 0 }, + { "a\\b\\c", 0, 2, 1, 3 }, + { "\\a\\b\\c", 1, 3, 1, 3 }, + /* Forward slashes are not separators */ + { "/", 0, -1, 1 }, + { "/a", 0, -1, 2 }, + { "/a/b", 0, -1, 4 }, + /* Normal parsing cycle */ + { "Good Morning!\\Good Evening!\\Good Night", 0, 14, 13, 24 }, + { "Good Evening!\\Good Night", 0, 14, 13, 10 }, + { "Good Night", 0, -1, 10 }, + /* Double backslashes */ + { "\\\\", 1, 2, 0, 0 }, + { "a\\\\", 0, 2, 1, 1 }, + { "\\\\b", 1, 2, 0, 1 }, + { "a\\\\b", 0, 2, 1, 2 }, + /* Even more backslashes */ + { "\\\\\\", 1, 2, 0, 1 }, + { "a\\\\\\", 0, 2, 1, 2 }, + { "\\\\\\b", 1, 2, 0, 2 }, + { "a\\\\\\b", 0, 2, 1, 3 }, + { "a\\\\\\\\b", 0, 2, 1, 4 }, +}; + +START_TEST(FsRtlDissect) +{ + NTSTATUS Status; + ANSI_STRING NameA; + ANSI_STRING FirstA; + ANSI_STRING RemainingA; + UNICODE_STRING NameU; + UNICODE_STRING FirstU; + UNICODE_STRING RemainingU; + ULONG i; + + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + RtlInitAnsiString(&NameA, Tests[i].Name); + RtlFillMemory(&FirstA, sizeof(FirstA), 0x55); + RtlFillMemory(&RemainingA, sizeof(RemainingA), 0x55); + FsRtlDissectDbcs(NameA, &FirstA, &RemainingA); + if (Tests[i].Offset1 == -1) + { + ok(FirstA.Buffer == NULL, "[%s] First=%p, expected NULL\n", Tests[i].Name, FirstA.Buffer); + ok(FirstA.Length == 0, "[%s] FirstLen=%u, expected 0\n", Tests[i].Name, FirstA.Length); + ok(FirstA.MaximumLength == 0, "[%s] FirstMaxLen=%u, expected 0\n", Tests[i].Name, FirstA.MaximumLength); + } + else + { + ok(FirstA.Buffer == NameA.Buffer + Tests[i].Offset1, "[%s] First=%p, expected %p\n", Tests[i].Name, FirstA.Buffer, NameA.Buffer + Tests[i].Offset1); + ok(FirstA.Length == Tests[i].Length1, "[%s] FirstLen=%u, expected %d\n", Tests[i].Name, FirstA.Length, Tests[i].Length1); + ok(FirstA.MaximumLength == Tests[i].Length1, "[%s] FirstMaxLen=%u, expected %d\n", Tests[i].Name, FirstA.MaximumLength, Tests[i].Length1); + } + if (Tests[i].Offset2 == -1) + { + ok(RemainingA.Buffer == NULL, "[%s] Remaining=%p, expected NULL\n", Tests[i].Name, RemainingA.Buffer); + ok(RemainingA.Length == 0, "[%s] RemainingLen=%u, expected 0\n", Tests[i].Name, RemainingA.Length); + ok(RemainingA.MaximumLength == 0, "[%s] RemainingMaxLen=%u, expected 0\n", Tests[i].Name, RemainingA.MaximumLength); + } + else + { + ok(RemainingA.Buffer == NameA.Buffer + Tests[i].Offset2, "[%s] Remaining=%p, expected %p\n", Tests[i].Name, RemainingA.Buffer, NameA.Buffer + Tests[i].Offset2); + ok(RemainingA.Length == Tests[i].Length2, "[%s] RemainingLen=%u, expected %d\n", Tests[i].Name, RemainingA.Length, Tests[i].Length2); + ok(RemainingA.MaximumLength == Tests[i].Length2, "[%s] RemainingMaxLen=%u, expected %d\n", Tests[i].Name, RemainingA.MaximumLength, Tests[i].Length2); + } + + Status = RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE); + if (skip(NT_SUCCESS(Status), "Conversion failed with %lx\n", Status)) + continue; + RtlFillMemory(&FirstU, sizeof(FirstU), 0x55); + RtlFillMemory(&RemainingU, sizeof(RemainingU), 0x55); + FsRtlDissectName(NameU, &FirstU, &RemainingU); + if (Tests[i].Offset1 == -1) + { + ok(FirstU.Buffer == NULL, "[%s] First=%p, expected NULL\n", Tests[i].Name, FirstU.Buffer); + ok(FirstU.Length == 0, "[%s] FirstLen=%u, expected 0\n", Tests[i].Name, FirstU.Length); + ok(FirstU.MaximumLength == 0, "[%s] FirstMaxLen=%u, expected 0\n", Tests[i].Name, FirstU.MaximumLength); + } + else + { + ok(FirstU.Buffer == NameU.Buffer + Tests[i].Offset1, "[%s] First=%p, expected %p\n", Tests[i].Name, FirstU.Buffer, NameU.Buffer + Tests[i].Offset1); + ok(FirstU.Length == Tests[i].Length1 * sizeof(WCHAR), "[%s] FirstLen=%u, expected %d\n", Tests[i].Name, FirstU.Length, Tests[i].Length1 * sizeof(WCHAR)); + ok(FirstU.MaximumLength == Tests[i].Length1 * sizeof(WCHAR), "[%s] FirstMaxLen=%u, expected %d\n", Tests[i].Name, FirstU.MaximumLength, Tests[i].Length1 * sizeof(WCHAR)); + } + if (Tests[i].Offset2 == -1) + { + ok(RemainingU.Buffer == NULL, "[%s] Remaining=%p, expected NULL\n", Tests[i].Name, RemainingU.Buffer); + ok(RemainingU.Length == 0, "[%s] RemainingLen=%u, expected 0\n", Tests[i].Name, RemainingU.Length); + ok(RemainingU.MaximumLength == 0, "[%s] RemainingMaxLen=%u, expected 0\n", Tests[i].Name, RemainingU.MaximumLength); + } + else + { + ok(RemainingU.Buffer == NameU.Buffer + Tests[i].Offset2, "[%s] Remaining=%p, expected %p\n", Tests[i].Name, RemainingU.Buffer, NameU.Buffer + Tests[i].Offset2); + ok(RemainingU.Length == Tests[i].Length2 * sizeof(WCHAR), "[%s] RemainingLen=%u, expected %d\n", Tests[i].Name, RemainingU.Length, Tests[i].Length2 * sizeof(WCHAR)); + ok(RemainingU.MaximumLength == Tests[i].Length2 * sizeof(WCHAR), "[%s] RemainingMaxLen=%u, expected %d\n", Tests[i].Name, RemainingU.MaximumLength, Tests[i].Length2 * sizeof(WCHAR)); + } + RtlFreeUnicodeString(&NameU); + } +} diff --git a/rostests/kmtests/ntos_fsrtl/FsRtlLegal.c b/rostests/kmtests/ntos_fsrtl/FsRtlLegal.c new file mode 100644 index 00000000000..41fbd59c34f --- /dev/null +++ b/rostests/kmtests/ntos_fsrtl/FsRtlLegal.c @@ -0,0 +1,146 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for FsRtlIsFatDbcsLegal/FsRtlIsHpfsDbcsLegal + * PROGRAMMER: Thomas Faber + */ + +#include + +static struct +{ + PCSTR Dbcs; + BOOLEAN LegalFat; + BOOLEAN LegalHpfs; + BOOLEAN HasWildCards; + BOOLEAN IsPath; + BOOLEAN LeadingBackslash; +} Tests[] = +{ + { "", FALSE, FALSE }, + { "a", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "A", TRUE, TRUE, FALSE, FALSE, FALSE }, + { ".", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "..", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "...", FALSE, FALSE }, + { "A ", FALSE, FALSE }, + { " ", FALSE, FALSE }, + { " A", TRUE, TRUE, FALSE, FALSE, FALSE }, + { " A ", FALSE, FALSE }, + { "A.", FALSE, FALSE }, + { ".A", FALSE, TRUE, FALSE, FALSE, FALSE }, + { ".A.", FALSE, FALSE }, + { "*", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "?", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "????????.???", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "????????????", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "????????.????", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "??????????????????", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "?*?*?*?*?*?*?*?*?*", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "ABCDEFGHIJKLMNOPQ*", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "ABCDEFGHI\\*", FALSE, TRUE, TRUE, TRUE, FALSE }, + { "*\\ABCDEFGHI", FALSE, TRUE, TRUE, TRUE, FALSE }, + { "?.?.?", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "?..?", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "? ", TRUE, FALSE, TRUE, FALSE, FALSE }, + { " ?", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "?.", TRUE, FALSE, TRUE, FALSE, FALSE }, + { ".?", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "? .?", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "A?A", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "A*A", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "AA", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "A\"A", TRUE, TRUE, TRUE, FALSE, FALSE }, + { "A'A", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "A:A", FALSE, FALSE }, + { "A\x1fG", FALSE, FALSE }, + { "A\x01G", FALSE, FALSE }, + { "A\x0aG", FALSE, FALSE }, + { "A\x0dG", FALSE, FALSE }, + { "\x7f", TRUE, TRUE, FALSE, FALSE, FALSE }, + /* FIXME: these two are probably locale-specific */ + { "\x80", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "\xff", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGH.IJK", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGHX.IJK", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGHX.IJ", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGH.IJKX", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFG.IJKX", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGH", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGHX", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "A.B", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "A..B", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "A.B.", FALSE, FALSE }, + { "A.B.C", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "A .B", FALSE, TRUE, FALSE, FALSE, FALSE }, + { " A .B", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "A. B", TRUE, TRUE, FALSE, FALSE, FALSE }, + { "A. B ", FALSE, FALSE }, + { "A. B ", FALSE, FALSE }, + { " A . B", FALSE, TRUE, FALSE, FALSE, FALSE }, + { " A . B ", FALSE, FALSE }, + { "\\ABCDEFGH.IJK", TRUE, TRUE, FALSE, FALSE, TRUE }, + { "ABCDEFGH.IJK\\", TRUE, TRUE, FALSE, TRUE, FALSE }, + { "\\ABCDEFGH.IJK\\", TRUE, TRUE, FALSE, TRUE, TRUE }, + { "\\", TRUE, TRUE, FALSE, FALSE, TRUE }, + { "\\\\", FALSE, FALSE }, + { "\\\\B", FALSE, FALSE }, + { "A\\", TRUE, TRUE, FALSE, TRUE, FALSE }, + { "A\\B", TRUE, TRUE, FALSE, TRUE, FALSE }, + { "A\\\\", FALSE, FALSE }, + { "A\\\\B", FALSE, FALSE }, + /* We can exceed MAX_PATH (260) characters */ + { "0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7BCDEF.HI\\8BCDEF.HI\\9BCDEF.HI\\0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7BCDEF.HI\\8BCDEF.HI\\9BCDEF.HI\\0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI", TRUE, TRUE, FALSE, TRUE, FALSE }, + { "0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7BCDEF.HI\\8BCDEF.HI\\9BCDEF.HI\\0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7BCDEF.HI\\8BCDEF.HI\\9BCDEF.HI\\0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\", TRUE, TRUE, FALSE, TRUE, FALSE }, + { "0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7BCDEF.HI\\8BCDEF.HI\\9BCDEF.HI\\0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7BCDEF.HI\\8BCDEF.HI\\9BCDEF.HI\\0BCDEF.HI\\1BCDEF.HI\\2BCDEF.HI\\3BCDEF.HI\\4BCDEF.HI\\5BCDEF.HI\\6BCDEF.HI\\7", TRUE, TRUE, FALSE, TRUE, FALSE }, + /* Max component length for HPFS is 255 characters */ + { "ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDE", FALSE, TRUE, FALSE, FALSE, FALSE }, + { "ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEF", FALSE, FALSE }, + { "ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDE\\ABC", FALSE, TRUE, FALSE, TRUE, FALSE }, +}; + +START_TEST(FsRtlLegal) +{ + ULONG i; + BOOLEAN Result; + ANSI_STRING DbcsName; + ULONG Flags; + + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + RtlInitAnsiString(&DbcsName, Tests[i].Dbcs); + for (Flags = 0; Flags < 8; Flags++) + { + Result = FsRtlIsFatDbcsLegal(DbcsName, + BooleanFlagOn(Flags, 1), + BooleanFlagOn(Flags, 2), + BooleanFlagOn(Flags, 4)); + if (Tests[i].HasWildCards && !FlagOn(Flags, 1)) + ok(Result == FALSE, "[%s] Result = %u but has wildcards\n", Tests[i].Dbcs, Result); + else if (Tests[i].IsPath && !FlagOn(Flags, 2)) + ok(Result == FALSE, "[%s] Result = %u but is path\n", Tests[i].Dbcs, Result); + else if (Tests[i].LeadingBackslash && !FlagOn(Flags, 4)) + ok(Result == FALSE, "[%s] Result = %u but has leading backslash\n", Tests[i].Dbcs, Result); + else if (!Tests[i].LegalFat) + ok(Result == FALSE, "[%s] Result = %u but is NOT legal FAT\n", Tests[i].Dbcs, Result); + else + ok(Result == TRUE, "[%s] Result = %u but IS legal FAT\n", Tests[i].Dbcs, Result); + + Result = FsRtlIsHpfsDbcsLegal(DbcsName, + BooleanFlagOn(Flags, 1), + BooleanFlagOn(Flags, 2), + BooleanFlagOn(Flags, 4)); + if (Tests[i].HasWildCards && !FlagOn(Flags, 1)) + ok(Result == FALSE, "[%s] Result = %u but has wildcards\n", Tests[i].Dbcs, Result); + else if (Tests[i].IsPath && !FlagOn(Flags, 2)) + ok(Result == FALSE, "[%s] Result = %u but is path\n", Tests[i].Dbcs, Result); + else if (Tests[i].LeadingBackslash && !FlagOn(Flags, 4)) + ok(Result == FALSE, "[%s] Result = %u but has leading backslash\n", Tests[i].Dbcs, Result); + else if (!Tests[i].LegalHpfs) + ok(Result == FALSE, "[%s] Result = %u but is NOT legal HPFS\n", Tests[i].Dbcs, Result); + else + ok(Result == TRUE, "[%s] Result = %u but IS legal HPFS\n", Tests[i].Dbcs, Result); + } + } +}