Index: kmtest/testlist.c =================================================================== --- kmtest/testlist.c (revision 60823) +++ kmtest/testlist.c (working copy) @@ -15,19 +15,23 @@ KMT_TESTFUNC Test_RtlMemory; KMT_TESTFUNC Test_RtlRegistry; KMT_TESTFUNC Test_RtlSplayTree; +KMT_TESTFUNC Test_RtlAnsiStringToUnicodeSize; +KMT_TESTFUNC Test_RtlCompareString; +KMT_TESTFUNC Test_RtlCompareUnicodeString; KMT_TESTFUNC Test_RtlUnicodeString; +KMT_TESTFUNC Test_RtlUpcaseUnicodeString; /* tests with a leading '-' will not be listed */ const KMT_TEST TestList[] = { - { "Example", Test_Example }, - { "FindFile", Test_FindFile }, - { "IoDeviceObject", Test_IoDeviceObject }, - { "RtlAvlTree", Test_RtlAvlTree }, - { "RtlException", Test_RtlException }, - { "RtlMemory", Test_RtlMemory }, - { "RtlRegistry", Test_RtlRegistry }, - { "RtlSplayTree", Test_RtlSplayTree }, - { "RtlUnicodeString", Test_RtlUnicodeString }, + { "Example", Test_Example }, + { "FindFile", Test_FindFile }, + { "IoDeviceObject", Test_IoDeviceObject }, + { "RtlAvlTree", Test_RtlAvlTree }, + { "RtlException", Test_RtlException }, + { "RtlMemory", Test_RtlMemory }, + { "RtlRegistry", Test_RtlRegistry }, + { "RtlSplayTree", Test_RtlSplayTree }, + { "RtlUnicodeString", Test_RtlUnicodeString }, { NULL, NULL }, }; Index: rtl/RtlUnicodeString.c =================================================================== --- rtl/RtlUnicodeString.c (revision 60823) +++ rtl/RtlUnicodeString.c (working copy) @@ -7,6 +7,7 @@ #define KMT_EMULATE_KERNEL #include +NTSYSAPI LONG NTAPI RtlCompareString(const PSTRING String1, const PSTRING String2, BOOLEAN CaseInSensitive); static VOID @@ -173,7 +174,327 @@ #endif } +static +VOID +TestRtlAnsiStringToUnicodeSize(VOID) +{ + + ULONG Length; + ANSI_STRING Ansi; + INT i; + CHAR string[]="a"; + PCHAR stringPtr = string; + + *stringPtr = 0; + RtlInitAnsiString(&Ansi, string); + Length = RtlAnsiStringToUnicodeSize(&Ansi); + ok_eq_long(Length,2); + ok_eq_str(Ansi.Buffer, string); + + for( i = 1; i < 256; i++){ + *stringPtr = i; + RtlInitAnsiString(&Ansi, string); + Length = RtlAnsiStringToUnicodeSize(&Ansi); + ok_eq_long(Length,4); + //Check the Ansi string didnt change + ok_eq_str(Ansi.Buffer, string); + } + +} + +static +VOID +TestRtlCompareString(VOID) +{ + + ANSI_STRING String1; + ANSI_STRING String2; + LONG Length; + + //TEST #1:CASING.string vs STRING. + RtlInitAnsiString(&String1, "react\\#s"); + RtlInitAnsiString(&String2, "REACT\\#S"); + Length = RtlCompareString(&String1, &String2, TRUE); + ok_eq_long( Length, 0); + + //--- Originals shouldn't have been modified at all. + ok_eq_str(String1.Buffer, "react\\#s"); + ok_eq_str(String2.Buffer, "REACT\\#S"); + + //TEST #2:NON-CASING.string vs STRING. + RtlInitAnsiString(&String1, "re\"act\\.s"); + RtlInitAnsiString(&String2, "RE\"ACT\\.S"); + Length = RtlCompareString(&String1, &String2, FALSE); + ok( Length != 0, "Expected Length !=0, current Length is: %l", Length); + + //--- Originals shouldn't have been modified at all. + ok_eq_str(String1.Buffer, "re\"act\\.s"); + ok_eq_str(String2.Buffer, "RE\"ACT\\.S"); + + + //TEST #3: String1 is EMPTY STRING. + RtlInitAnsiString(&String1, ""); + RtlInitAnsiString(&String2, "REACT\\#S"); + Length = RtlCompareString(&String1, &String2, FALSE); + ok( Length != 0, "Expected Length !=0, current Length is: %l", Length); + + //--- Originals shouldn't have been modified at all. + ok_eq_str(String1.Buffer, ""); + ok_eq_str(String2.Buffer, "REACT\\#S"); + + + //TEST #4: String2 is EMPTY STRING. + RtlInitAnsiString(&String1, "\\/REaCTO@|S"); + RtlInitAnsiString(&String2, ""); + Length = RtlCompareString(&String1, &String2, FALSE); + ok( Length != 0, "Expected Length !=0, current Length is: %l", Length); + + //--- Originals shouldn't have been modified at all. + ok_eq_str(String1.Buffer, "\\/REaCTO@|S"); + ok_eq_str(String2.Buffer, ""); + + + //TEST #5: RtlCompareString doesn't accept String1 as NULL. + RtlInitAnsiString(&String2, "../RE\/ac.tOS"); + KmtStartSeh() + RtlCompareString(NULL, &String2, FALSE); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + + //--- Originals shouldn't have been modified at all. + ok_eq_str(String2.Buffer, "../RE\/ac.tOS"); + + + //TEST #7: RtlCompareString doesn't accept String2 as NULL. + RtlInitAnsiString(&String1, "\n\t((RE\/ac.tOS"); + KmtStartSeh() + RtlCompareString(&String1, NULL, FALSE); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + + //--- Originals shouldn't have been modified at all. + ok_eq_str(String1.Buffer, "\n\t((RE\/ac.tOS"); + +} + +static +VOID +TestRtlCompareUnicodeString(VOID) +{ + + UNICODE_STRING String1; + UNICODE_STRING String2; + LONG Length; + + //TEST #1:CASING.string vs STRING. + RtlInitUnicodeString(&String1, L"react\\#s"); + RtlInitUnicodeString(&String2, L"REACT\\#S"); + Length = RtlCompareUnicodeString(&String1, &String2, TRUE); + ok_eq_long( Length, 0); + + //--- Originals shouldn't have been modified at all. + ok_eq_wstr(String1.Buffer, L"react\\#s"); + ok_eq_wstr(String2.Buffer, L"REACT\\#S"); + + //TEST #2:NON-CASING.string vs STRING. + RtlInitUnicodeString(&String1, L"re\"act\\.s"); + RtlInitUnicodeString(&String2, L"RE\"ACT\\.S"); + Length = RtlCompareUnicodeString(&String1, &String2, FALSE); + ok( Length != 0, "Expected Length !=0, current Length is: %l", Length); + + //--- Originals shouldn't have been modified at all. + ok_eq_wstr(String1.Buffer, L"re\"act\\.s"); + ok_eq_wstr(String2.Buffer, L"RE\"ACT\\.S"); + + + //TEST #3: String1 is EMPTY STRING. + RtlInitUnicodeString(&String1, L""); + RtlInitUnicodeString(&String2, L"REACT\\#S"); + Length = RtlCompareUnicodeString(&String1, &String2, FALSE); + ok( Length != 0, "Expected Length !=0, current Length is: %l", Length); + + //--- Originals shouldn't have been modified at all. + ok_eq_wstr(String1.Buffer, L""); + ok_eq_wstr(String2.Buffer, L"REACT\\#S"); + + + //TEST #4: String2 is EMPTY STRING. + RtlInitUnicodeString(&String1, L"\\/REaCTO@|S"); + RtlInitUnicodeString(&String2, L""); + Length = RtlCompareUnicodeString(&String1, &String2, FALSE); + ok( Length != 0, "Expected Length !=0, current Length is: %l", Length); + + //--- Originals shouldn't have been modified at all. + ok_eq_wstr(String1.Buffer, L"\\/REaCTO@|S"); + ok_eq_wstr(String2.Buffer, L""); + + + //TEST #5: RtlCompareString doesn't accept String1 as NULL. + RtlInitUnicodeString(&String2, L"../RE\/ac.tOS"); + KmtStartSeh() + RtlCompareUnicodeString(NULL, &String2, FALSE); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + + //--- Originals shouldn't have been modified at all. + ok_eq_wstr(String2.Buffer, L"../RE\/ac.tOS"); + + + //TEST #7: RtlCompareString doesn't accept String2 as NULL. + RtlInitUnicodeString(&String1, L"\n\t((RE\/ac.tOS"); + KmtStartSeh() + RtlCompareUnicodeString(&String1, NULL, FALSE); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + + //--- Originals shouldn't have been modified at all. + ok_eq_wstr(String1.Buffer, L"\n\t((RE\/ac.tOS"); + +} +static +VOID +TestRtlUpcaseUnicodeString(VOID) +{ + NTSTATUS Status; + LONG Comparison; + USHORT i; + + UNICODE_STRING StringUpcased; + UNICODE_STRING StringUpcasedRef; + UNICODE_STRING StringToUpcase; + UNICODE_STRING StringZeroed; + + WCHAR Max[UNICODE_STRING_MAX_BYTES]; + WCHAR MaxRef[UNICODE_STRING_MAX_BYTES]; + WCHAR StringBuffer[10]; + + UNICODE_STRING StringToUpcase2 = RTL_CONSTANT_STRING(L"aBcde"); + UNICODE_STRING StringUpcasedRef2 = RTL_CONSTANT_STRING(L"ABCDE0"); + +// TEST#1: Allocate buffer. + + RtlInitUnicodeString(&StringToUpcase, L" rEactOS rO#ks !!\"??"); + RtlInitUnicodeString(&StringUpcasedRef, L" REACTOS RO#KS !!\"??"); + RtlInitUnicodeString(&StringUpcased, L"ILOVETOEATDEADBEEF!!!"); + + Status = RtlUpcaseUnicodeString(&StringUpcased, &StringToUpcase, TRUE); + ok_eq_hex(Status, STATUS_SUCCESS); + + /*Check the API has Upcased correctly*/ + Comparison = RtlCompareUnicodeString(&StringUpcasedRef, &StringUpcased, FALSE); + ok_eq_long(Comparison, 0); + ok(StringUpcased.Length == 40, "Expected 40, StringUpcased.Length: %u \n", StringUpcased.Length); + ok(StringUpcased.MaximumLength == 40, "Expected 40, StringUpcased.MaximumLength: %u \n", StringUpcased.MaximumLength); + + /*Check the API didn't overwrite the original */ + ok_eq_wstr(StringToUpcase.Buffer, L" rEactOS rO#ks !!\"??"); + + RtlFreeUnicodeString(&StringUpcased); + +// TEST#2: Allocate UNICODE_STRING_MAX_CHARS buffer + + for (i = 0; i < UNICODE_STRING_MAX_CHARS-2; i++) + Max[i] = L'r'; + Max[UNICODE_STRING_MAX_CHARS-1] = L'\0'; + + for (i = 0; i < UNICODE_STRING_MAX_CHARS-2; i++) + MaxRef[i]= L'R'; + MaxRef[UNICODE_STRING_MAX_CHARS-1] = L'\0'; + RtlInitUnicodeString(&StringToUpcase, Max); + RtlInitUnicodeString(&StringUpcasedRef, MaxRef); + RtlInitUnicodeString(&StringUpcased, L"ILOVETOEATDEADBEEF!!!"); + + Status = RtlUpcaseUnicodeString(&StringUpcased, &StringToUpcase, TRUE); + ok_eq_hex(Status, STATUS_SUCCESS); + Comparison = RtlCompareUnicodeString(&StringUpcased, &StringUpcasedRef, FALSE); + ok_eq_long(Comparison, 0); + ok(StringUpcased.Length == UNICODE_STRING_MAX_BYTES-4, "Expected %u, StringUpcased.Length: %u \n", UNICODE_STRING_MAX_BYTES-4, StringUpcased.Length); + ok(StringUpcased.MaximumLength == UNICODE_STRING_MAX_BYTES-4, "Expected %u, StringUpcased.MaximumLength: %u \n", UNICODE_STRING_MAX_BYTES-4, StringUpcased.MaximumLength); + + /*Check the API didn't overwrite the original */ + ok_eq_wstr(StringToUpcase.Buffer, Max); + + RtlFreeUnicodeString(&StringUpcased); + +// TEST#3: Allocate UNICODE_STRING_MAX_CHARS + 5 buffer + + for (i = 0; i < UNICODE_STRING_MAX_CHARS+3; i++) + Max[i] = L'r'; + Max[UNICODE_STRING_MAX_CHARS+4] = L'\0'; + + for (i = 0; i < UNICODE_STRING_MAX_CHARS+3; i++) + MaxRef[i]= L'R'; + MaxRef[UNICODE_STRING_MAX_CHARS+4] = L'\0'; + RtlInitUnicodeString(&StringToUpcase, Max); + RtlInitUnicodeString(&StringUpcasedRef, MaxRef); + RtlInitUnicodeString(&StringUpcased, L"ILOVETOEATDEADBEEF!!!"); + + Status = RtlUpcaseUnicodeString(&StringUpcased, &StringToUpcase, TRUE); + ok_eq_hex(Status, STATUS_SUCCESS); + Comparison = RtlCompareUnicodeString(&StringUpcased, &StringUpcasedRef, FALSE); + ok_eq_long(Comparison, 0); + ok(StringUpcased.Length == UNICODE_STRING_MAX_BYTES - 2, "Expected %u, StringUpcased.Length: %u \n", UNICODE_STRING_MAX_BYTES - 2, StringUpcased.Length); + ok(StringUpcased.MaximumLength == UNICODE_STRING_MAX_BYTES - 2, "Expected %u, StringUpcased.MaximumLength: %u \n", UNICODE_STRING_MAX_BYTES - 2, StringUpcased.MaximumLength); + + //Check the API didn't overwrite the original + ok_eq_wstr(StringToUpcase.Buffer, Max); + + RtlFreeUnicodeString(&StringUpcased); + +// TEST#4: Allocate Buffer. RtlUpcaseUnicodeString accepts an empty UNICODE_STRING as StringToUpcase argument. + + RtlInitUnicodeString(&StringToUpcase, NULL); + RtlInitUnicodeString(&StringUpcased, L"ILOVETOEATDEADBEEF!!!"); + + Status = RtlUpcaseUnicodeString(&StringUpcased, &StringToUpcase, TRUE); + ok_eq_hex(Status, STATUS_SUCCESS); + ok(StringUpcased.Length == 0, "Expected zero, StringUpcased.Length: %u \n", StringUpcased.Length); + ok(StringUpcased.MaximumLength == 0, "Expected zero, StringUpcased.MaximumLength: %u \n", StringUpcased.MaximumLength); + + RtlFreeUnicodeString(&StringUpcased); + +// TEST#5: Don't allocate Buffer. RtlUpcaseUnicodeString accepts an empty UNICODE_STRING as StringToUpcase argument. + + + RtlInitUnicodeString(&StringToUpcase, NULL); + RtlInitUnicodeString(&StringUpcased, L"ILOVETOEATDEADBEEF!!!"); + + Status = RtlUpcaseUnicodeString(&StringUpcased, &StringToUpcase, FALSE); + ok_eq_hex(Status, STATUS_SUCCESS); + ok(StringUpcased.Length == 0, "Expected zero, StringUpcased.Length: %u \n", StringUpcased.Length); + ok(StringUpcased.MaximumLength == 44, "Expected zero, StringUpcased.MaximumLength: %u \n", StringUpcased.MaximumLength); + + RtlFreeUnicodeString(&StringUpcased); + + +// TEST#6: RtlUpcaseUnicodeString doesn't accept NULL as StringToUpcase argument. + + RtlInitUnicodeString(&StringUpcased, L"ILOVETOEATDEADBEEF!!!"); + KmtStartSeh() + Status = RtlUpcaseUnicodeString(&StringUpcased, NULL, TRUE); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + + RtlFreeUnicodeString(&StringUpcased); + + +// PTEST#7: Don't allocate buffer. Also RtlUpcaseUnicodeString doesnt NULL terminate the StringUpcased + RtlInitEmptyUnicodeString(&StringZeroed, StringBuffer, sizeof(StringBuffer)); + RtlAppendUnicodeToString(&StringZeroed, L"000000"); + + Status = RtlUpcaseUnicodeString(&StringZeroed, &StringToUpcase2, FALSE); + ok_eq_hex(Status, STATUS_SUCCESS); + Comparison = RtlCompareUnicodeString(&StringZeroed, &StringUpcasedRef2, FALSE); + + //Why comparison is -2? + ok_eq_long(Comparison, 0); + ok_eq_wstr(StringZeroed.Buffer, StringUpcasedRef2.Buffer); + + /*Check the API didn't overwrite the original */ + ok_eq_wstr(StringToUpcase2.Buffer, L"aBcde"); + +} + START_TEST(RtlUnicodeString) { TestFindCharInUnicodeString(); + TestRtlAnsiStringToUnicodeSize(); + TestRtlCompareString(); + TestRtlCompareUnicodeString(); + TestRtlUpcaseUnicodeString(); }