[NTDLL_APITEST]
[reactos.git] / rostests / apitests / ntdll / RtlGetFullPathName_UstrEx.c
index b8d49f8..ffd66f1 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #define WIN32_NO_STATUS
+#define UNICODE
 #include <wine/test.h>
 #include <pseh/pseh2.h>
 #include <ndk/rtlfuncs.h>
@@ -25,6 +26,19 @@ RtlGetFullPathName_UstrEx(
 );
 */
 
+NTSTATUS
+(NTAPI
+*pRtlGetFullPathName_UstrEx)(
+    IN PUNICODE_STRING FileName,
+    IN PUNICODE_STRING StaticString,
+    IN PUNICODE_STRING DynamicString,
+    IN PUNICODE_STRING *StringUsed,
+    IN PSIZE_T FilePartSize OPTIONAL,
+    OUT PBOOLEAN NameInvalid,
+    OUT RTL_PATH_TYPE* PathType,
+    OUT PSIZE_T LengthNeeded OPTIONAL
+);
+
 #define StartSeh()                  ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
 #define EndSeh(ExpectedStatus)      } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
 
@@ -40,19 +54,19 @@ CheckStringBuffer(
     PCUNICODE_STRING String,
     PCWSTR Expected)
 {
-    USHORT Length = wcslen(Expected) * sizeof(WCHAR);
+    SIZE_T ExpectedLength = wcslen(Expected) * sizeof(WCHAR);
     SIZE_T EqualLength;
     BOOLEAN Result = TRUE;
     SIZE_T i;
 
-    if (String->Length != Length)
+    if (String->Length != ExpectedLength)
     {
-        ok(0, "String length is %u, expected %u\n", String->Length, Length);
+        ok(0, "String length is %u, expected %lu\n", String->Length, (ULONG)ExpectedLength);
         Result = FALSE;
     }
 
-    EqualLength = RtlCompareMemory(String->Buffer, Expected, Length);
-    if (EqualLength != Length)
+    EqualLength = RtlCompareMemory(String->Buffer, Expected, ExpectedLength);
+    if (EqualLength != ExpectedLength)
     {
         ok(0, "String is '%wZ', expected '%S'\n", String, Expected);
         Result = FALSE;
@@ -81,6 +95,25 @@ CheckStringBuffer(
     return Result;
 }
 
+static
+BOOLEAN
+CheckBuffer(
+    PVOID Buffer,
+    SIZE_T Size,
+    UCHAR Value)
+{
+    PUCHAR Array = Buffer;
+    SIZE_T i;
+
+    for (i = 0; i < Size; i++)
+        if (Array[i] != Value)
+        {
+            trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i);
+            return FALSE;
+        }
+    return TRUE;
+}
+
 #define RtlPathTypeNotSet 123
 #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL)
 
@@ -100,7 +133,8 @@ static
 VOID
 RunTestCases(VOID)
 {
-    /* TODO: don't duplicate this here and in the RtlGetFullPathName_U test */
+    /* 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;
@@ -155,6 +189,7 @@ RunTestCases(VOID)
     SIZE_T ExpectedFilePartSize;
     const INT TestCount = sizeof(TestCases) / sizeof(TestCases[0]);
     INT i;
+    BOOLEAN Okay;
 
     for (i = 0; i < TestCount; i++)
     {
@@ -191,7 +226,7 @@ RunTestCases(VOID)
         NameInvalid = (BOOLEAN)-1;
         LengthNeeded = 1234;
         StartSeh()
-            Status = RtlGetFullPathName_UstrEx(&FileName,
+            Status = pRtlGetFullPathName_UstrEx(&FileName,
                                                &FullPathName,
                                                NULL,
                                                &StringUsed,
@@ -204,8 +239,8 @@ RunTestCases(VOID)
         ok_eq_ustr(&FileName, &TempString);
         ok(FullPathName.Buffer        == FullPathNameBuffer,         "Buffer modified\n");
         ok(FullPathName.MaximumLength == sizeof(FullPathNameBuffer), "MaximumLength modified\n");
-        ok(CheckStringBuffer(&FullPathName, ExpectedPathName),
-            "Wrong path name '%wZ', expected '%S'\n", &FullPathName, ExpectedPathName);
+        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)
         {
@@ -261,31 +296,40 @@ START_TEST(RtlGetFullPathName_UstrEx)
     PUNICODE_STRING StringUsed;
     SIZE_T FilePartSize;
     BOOLEAN NameInvalid;
+    BOOLEAN NameInvalidArray[sizeof(ULONGLONG)];
     RTL_PATH_TYPE PathType;
     SIZE_T LengthNeeded;
+    BOOLEAN Okay;
+
+    pRtlGetFullPathName_UstrEx = (PVOID)GetProcAddress(GetModuleHandle(L"ntdll"), "RtlGetFullPathName_UstrEx");
+    if (!pRtlGetFullPathName_UstrEx)
+    {
+        skip("RtlGetFullPathName_UstrEx unavailable\n");
+        return;
+    }
 
     /* NULL parameters */
     StartSeh()
-        RtlGetFullPathName_UstrEx(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        pRtlGetFullPathName_UstrEx(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
     EndSeh(STATUS_ACCESS_VIOLATION);
 
     RtlInitUnicodeString(&FileName, NULL);
     TempString = FileName;
     StartSeh()
-        RtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
     EndSeh(STATUS_ACCESS_VIOLATION);
     ok_eq_ustr(&FileName, &TempString);
 
     RtlInitUnicodeString(&FileName, L"");
     TempString = FileName;
     StartSeh()
-        RtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
     EndSeh(STATUS_ACCESS_VIOLATION);
     ok_eq_ustr(&FileName, &TempString);
 
     PathType = RtlPathTypeNotSet;
     StartSeh()
-        RtlGetFullPathName_UstrEx(NULL, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
+        pRtlGetFullPathName_UstrEx(NULL, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
     EndSeh(STATUS_ACCESS_VIOLATION);
     ok(PathType == RtlPathTypeUnknown ||
        broken(PathType == RtlPathTypeNotSet) /* Win7 */, "PathType = %d\n", PathType);
@@ -297,7 +341,7 @@ START_TEST(RtlGetFullPathName_UstrEx)
     NameInvalid = (BOOLEAN)-1;
     LengthNeeded = 1234;
     StartSeh()
-        RtlGetFullPathName_UstrEx(NULL, NULL, NULL, &StringUsed, &FilePartSize, &NameInvalid, &PathType, &LengthNeeded);
+        pRtlGetFullPathName_UstrEx(NULL, NULL, NULL, &StringUsed, &FilePartSize, &NameInvalid, &PathType, &LengthNeeded);
     EndSeh(STATUS_ACCESS_VIOLATION);
     ok(StringUsed == NULL, "StringUsed = %p\n", StringUsed);
     ok(FilePartSize == 0, "FilePartSize = %lu\n", (ULONG)FilePartSize);
@@ -313,7 +357,7 @@ START_TEST(RtlGetFullPathName_UstrEx)
     NameInvalid = (BOOLEAN)-1;
     LengthNeeded = 1234;
     StartSeh()
-        RtlGetFullPathName_UstrEx(&FileName, NULL, NULL, &StringUsed, &FilePartSize, &NameInvalid, NULL, &LengthNeeded);
+        pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, &StringUsed, &FilePartSize, &NameInvalid, NULL, &LengthNeeded);
     EndSeh(STATUS_ACCESS_VIOLATION);
     ok_eq_ustr(&FileName, &TempString);
     ok(StringUsed == NULL, "StringUsed = %p\n", StringUsed);
@@ -327,28 +371,43 @@ START_TEST(RtlGetFullPathName_UstrEx)
     TempString = FileName;
     PathType = RtlPathTypeNotSet;
     StartSeh()
-        Status = RtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
+        Status = pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
+        ok(Status == STATUS_OBJECT_NAME_INVALID, "status = %lx\n", Status);
+    EndSeh(STATUS_SUCCESS);
+    ok_eq_ustr(&FileName, &TempString);
+    ok(PathType == RtlPathTypeUnknown, "PathType = %d\n", PathType);
+
+    RtlInitUnicodeString(&FileName, L"");
+    TempString = FileName;
+    PathType = RtlPathTypeNotSet;
+    StartSeh()
+        Status = pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
         ok(Status == STATUS_OBJECT_NAME_INVALID, "status = %lx\n", Status);
     EndSeh(STATUS_SUCCESS);
     ok_eq_ustr(&FileName, &TempString);
     ok(PathType == RtlPathTypeUnknown, "PathType = %d\n", PathType);
 
+    /* Show that NameInvalid is indeed BOOLEAN */
     RtlInitUnicodeString(&FileName, L"");
     TempString = FileName;
     PathType = RtlPathTypeNotSet;
+    RtlFillMemory(NameInvalidArray, sizeof(NameInvalidArray), 0x55);
     StartSeh()
-        Status = RtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
+        Status = pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NameInvalidArray, &PathType, NULL);
         ok(Status == STATUS_OBJECT_NAME_INVALID, "status = %lx\n", Status);
     EndSeh(STATUS_SUCCESS);
     ok_eq_ustr(&FileName, &TempString);
     ok(PathType == RtlPathTypeUnknown, "PathType = %d\n", PathType);
+    ok(NameInvalidArray[0] == FALSE, "NameInvalid = %u\n", NameInvalidArray[0]);
+    Okay = CheckBuffer(NameInvalidArray + 1, sizeof(NameInvalidArray) - sizeof(NameInvalidArray[0]), 0x55);
+    ok(Okay, "CheckBuffer failed\n");
 
     /* Give it a valid path */
     RtlInitUnicodeString(&FileName, L"C:\\test");
     TempString = FileName;
     PathType = RtlPathTypeNotSet;
     StartSeh()
-        Status = RtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
+        Status = pRtlGetFullPathName_UstrEx(&FileName, NULL, NULL, NULL, NULL, NULL, &PathType, NULL);
         ok(Status == STATUS_BUFFER_TOO_SMALL, "status = %lx\n", Status);
     EndSeh(STATUS_SUCCESS);
     ok_eq_ustr(&FileName, &TempString);
@@ -360,7 +419,7 @@ START_TEST(RtlGetFullPathName_UstrEx)
     RtlInitUnicodeString(&StaticString, NULL);
     PathType = RtlPathTypeNotSet;
     StartSeh()
-        Status = RtlGetFullPathName_UstrEx(&FileName, &StaticString, NULL, NULL, NULL, NULL, &PathType, NULL);
+        Status = pRtlGetFullPathName_UstrEx(&FileName, &StaticString, NULL, NULL, NULL, NULL, &PathType, NULL);
         ok(Status == STATUS_BUFFER_TOO_SMALL, "status = %lx\n", Status);
     EndSeh(STATUS_SUCCESS);
     ok_eq_ustr(&FileName, &TempString);