NTDLL: Collapse slashes [RESENT]

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Sat Mar 20 16:57:10 CST 2004


Changelog:
        dlls/ntdll/path.c: get_full_path_helper
        Add a function and testcase to collapse successive slashes

-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
Index: wine/dlls/ntdll/path.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/path.c,v
retrieving revision 1.17
diff -u -r1.17 path.c
--- wine/dlls/ntdll/path.c	17 Mar 2004 01:58:51 -0000	1.17
+++ wine/dlls/ntdll/path.c	20 Mar 2004 22:54:04 -0000
@@ -370,7 +370,27 @@
         while (*p == '\\') p++;
     }
 }
-
+/******************************************************************
+ *		collapse_path_slash
+ *
+ * Helper for RtlGetFullPathName_U.
+ * Get rid of conmsecutive slashes in the path.
+ */
+static inline void collapse_path_slash( WCHAR *path )
+{
+    WCHAR *p=path,*q;
+    while (*p)
+    {
+	if (*p == '\\')
+	{
+	    q = p +1;
+	    while (*q == '\\')
+		q++;
+	    memmove( p +1, q , (strlenW(q) + 1) * sizeof(WCHAR) );
+	}
+	p++;
+    }
+}
 
 /******************************************************************
  *		get_full_path_helper
@@ -528,6 +548,7 @@
     for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
 
     collapse_path( buffer + mark );
+    collapse_path_slash( buffer + mark );
     reqsize = strlenW(buffer) * sizeof(WCHAR);
 
 done:
Index: wine/dlls/ntdll/tests/path.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/tests/path.c,v
retrieving revision 1.6
diff -u -r1.6 path.c
--- wine/dlls/ntdll/tests/path.c	7 Feb 2004 01:03:17 -0000	1.6
+++ wine/dlls/ntdll/tests/path.c	20 Mar 2004 22:54:05 -0000
@@ -30,10 +30,13 @@
 
 static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
                                                    LPCSTR src, DWORD srclen );
+static NTSTATUS (WINAPI *pRtlUnicodeToMultiByteN)(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD);
 static UINT (WINAPI *pRtlDetermineDosPathNameType_U)( PCWSTR path );
 static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name );
 static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN );
 static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
+static DWORD (WINAPI *pRtlGetFullPathName_U)(const WCHAR*,ULONG,WCHAR*,WCHAR**);
+
 
 static void test_RtlDetermineDosPathNameType(void)
 {
@@ -224,20 +227,69 @@
         }
     }
 }
+static void test_RtlGetFullPathName_U()
+{
+    struct test
+    {
+        const char *path;
+	const char *rname;
+	const char *rfile;
+    };
+
+    static const struct test tests[] =
+	{ 
+	    { "c:/test",               "c:\\test",       "test"},
+	    { "c:/TEST",               "c:\\test",       "test"},
+	    { "c:/test/file",          "c:\\test\\file", "file"},
+	    { "c:/test/././file",      "c:\\test\\file", "file"},
+	    { "c:/test\\.\\.\\file",   "c:\\test\\file", "file"},
+	    { "c:/test/\\.\\.\\file",  "c:\\test\\file", "file"},
+	    { "c:/test\\\\.\\.\\file", "c:\\test\\file", "file"},
+	    { "c:/test\\test1\\..\\.\\file", "c:\\test\\file", "file"},
+	    { NULL, NULL, NULL}
+	};
+    
+    const struct test *test;
+    WCHAR pathbufW[2*MAX_PATH], rbufferW[MAX_PATH];
+    CHAR  rbufferA[MAX_PATH], rfileA[MAX_PATH], *p;
+    ULONG ret;
+    WCHAR *file_part;
+    DWORD reslen;
+    int len;
+
+    for (test = tests; test->path; test++)
+    {
+
+	len= strlen(test->rname) * sizeof(WCHAR);
+        pRtlMultiByteToUnicodeN(pathbufW , sizeof(pathbufW), NULL, test->path, strlen(test->path)+1 );
+        ret = pRtlGetFullPathName_U( pathbufW,MAX_PATH, rbufferW, &file_part);
+        ok( ret == len, "Wrong result %ld/%d for %s\n", ret, len, test->path );
+	ok(pRtlUnicodeToMultiByteN(rbufferA,MAX_PATH,&reslen,rbufferW,MAX_PATH) == STATUS_SUCCESS,
+	   "RtlUnicodeToMultiByteN failed\n");
+	ok(pRtlUnicodeToMultiByteN(rfileA,MAX_PATH,&reslen,file_part,MAX_PATH) == STATUS_SUCCESS,
+	   "RtlUnicodeToMultiByteN failed\n");
+	ok(strcasecmp(rbufferA,test->rname) == 0, "Got \"%s\" expected \"%s\"\n",rbufferA,test->rname);
+	ok(strcasecmp(rfileA,test->rfile) == 0, "Got \"%s\" expected \"%s\"\n",rfileA,test->rfile);
+    }
 
+}
 
 START_TEST(path)
 {
     HMODULE mod = GetModuleHandleA("ntdll.dll");
     pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN");
+    pRtlUnicodeToMultiByteN = (void *)GetProcAddress(mod,"RtlUnicodeToMultiByteN");
     pRtlDetermineDosPathNameType_U = (void *)GetProcAddress(mod,"RtlDetermineDosPathNameType_U");
     pRtlIsDosDeviceName_U = (void *)GetProcAddress(mod,"RtlIsDosDeviceName_U");
     pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString");
     pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3");
+    pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U");
     if (pRtlDetermineDosPathNameType_U)
         test_RtlDetermineDosPathNameType();
     if (pRtlIsDosDeviceName_U)
         test_RtlIsDosDeviceName();
     if (pRtlIsNameLegalDOS8Dot3)
         test_RtlIsNameLegalDOS8Dot3();
+    if (pRtlGetFullPathName_U && pRtlMultiByteToUnicodeN)
+	test_RtlGetFullPathName_U();
 }



More information about the wine-patches mailing list