Zhiyi Zhang : kernelbase: Implement PathIsUNCEx.

Alexandre Julliard julliard at winehq.org
Thu Nov 22 17:00:30 CST 2018


Module: wine
Branch: master
Commit: c02419ed360a2c1538e916911cdb55572d877381
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c02419ed360a2c1538e916911cdb55572d877381

Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date:   Thu Nov 22 14:46:17 2018 +0800

kernelbase: Implement PathIsUNCEx.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 .../api-ms-win-core-path-l1-1-0.spec               |  2 +-
 dlls/kernelbase/kernelbase.spec                    |  2 +-
 dlls/kernelbase/path.c                             | 21 +++++++
 dlls/kernelbase/tests/path.c                       | 72 ++++++++++++++++++++++
 include/pathcch.h                                  |  1 +
 5 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/dlls/api-ms-win-core-path-l1-1-0/api-ms-win-core-path-l1-1-0.spec b/dlls/api-ms-win-core-path-l1-1-0/api-ms-win-core-path-l1-1-0.spec
index 0524e7c..d874f8c 100644
--- a/dlls/api-ms-win-core-path-l1-1-0/api-ms-win-core-path-l1-1-0.spec
+++ b/dlls/api-ms-win-core-path-l1-1-0/api-ms-win-core-path-l1-1-0.spec
@@ -19,4 +19,4 @@
 @ stub PathCchSkipRoot
 @ stub PathCchStripPrefix
 @ stub PathCchStripToRoot
-@ stub PathIsUNCEx
+@ stdcall PathIsUNCEx(wstr ptr) kernelbase.PathIsUNCEx
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 286dae0..b3b2887 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -1082,7 +1082,7 @@
 @ stdcall PathIsSameRootA(str str) shlwapi.PathIsSameRootA
 @ stdcall PathIsSameRootW(wstr wstr) shlwapi.PathIsSameRootW
 @ stdcall PathIsUNCA(str) shlwapi.PathIsUNCA
-# @ stub PathIsUNCEx
+@ stdcall PathIsUNCEx(wstr ptr)
 @ stdcall PathIsUNCServerA(str) shlwapi.PathIsUNCServerA
 @ stdcall PathIsUNCServerShareA(str) shlwapi.PathIsUNCServerShareA
 @ stdcall PathIsUNCServerShareW(wstr) shlwapi.PathIsUNCServerShareW
diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c
index 047017e..4aa39b4 100644
--- a/dlls/kernelbase/path.c
+++ b/dlls/kernelbase/path.c
@@ -38,6 +38,12 @@ static SIZE_T strnlenW(const WCHAR *string, SIZE_T maxlen)
     return i;
 }
 
+static BOOL is_prefixed_unc(const WCHAR *string)
+{
+    static const WCHAR prefixed_unc[] = {'\\', '\\', '?', '\\', 'U', 'N', 'C', '\\'};
+    return !strncmpiW(string, prefixed_unc, ARRAY_SIZE(prefixed_unc));
+}
+
 HRESULT WINAPI PathCchAddBackslash(WCHAR *path, SIZE_T size)
 {
     return PathCchAddBackslashEx(path, size, NULL, NULL);
@@ -183,3 +189,18 @@ HRESULT WINAPI PathCchRenameExtension(WCHAR *path, SIZE_T size, const WCHAR *ext
     hr = PathCchAddExtension(path, size, extension);
     return FAILED(hr) ? hr : S_OK;
 }
+
+BOOL WINAPI PathIsUNCEx(const WCHAR *path, const WCHAR **server)
+{
+    const WCHAR *result = NULL;
+
+    TRACE("%s %p\n", wine_dbgstr_w(path), server);
+
+    if (is_prefixed_unc(path))
+        result = path + 8;
+    else if (path[0] == '\\' && path[1] == '\\' && path[2] != '?')
+        result = path + 2;
+
+    if (server) *server = result;
+    return result ? TRUE : FALSE;
+}
diff --git a/dlls/kernelbase/tests/path.c b/dlls/kernelbase/tests/path.c
index 1d6f44e..3f7925d 100644
--- a/dlls/kernelbase/tests/path.c
+++ b/dlls/kernelbase/tests/path.c
@@ -37,6 +37,7 @@ HRESULT (WINAPI *pPathCchCombineEx)(WCHAR *out, SIZE_T size, const WCHAR *path1,
 HRESULT (WINAPI *pPathCchFindExtension)(const WCHAR *path, SIZE_T size, const WCHAR **extension);
 HRESULT (WINAPI *pPathCchRemoveExtension)(WCHAR *path, SIZE_T size);
 HRESULT (WINAPI *pPathCchRenameExtension)(WCHAR *path, SIZE_T size, const WCHAR *extension);
+BOOL    (WINAPI *pPathIsUNCEx)(const WCHAR *path, const WCHAR **server);
 
 static const struct
 {
@@ -632,6 +633,75 @@ static void test_PathCchRenameExtension(void)
     }
 }
 
+struct isuncex_test
+{
+    const CHAR *path;
+    INT server_offset;
+    BOOL ret;
+};
+
+static const struct isuncex_test isuncex_tests[] =
+{
+    {"\\\\", 2, TRUE},
+    {"\\\\a\\", 2, TRUE},
+    {"\\\\.\\", 2, TRUE},
+    {"\\\\?\\UNC\\", 8, TRUE},
+    {"\\\\?\\UNC\\a", 8, TRUE},
+    {"\\\\?\\unc\\", 8, TRUE},
+    {"\\\\?\\unc\\a", 8, TRUE},
+
+    {"", 0, FALSE},
+    {"\\", 0, FALSE},
+    {"C:\\", 0, FALSE},
+    {"\\??\\", 0, FALSE},
+    {"\\\\?\\", 0, FALSE},
+    {"\\\\?\\UNC", 0, FALSE},
+    {"\\\\?\\C:", 0, FALSE},
+    {"\\\\?\\C:\\", 0, FALSE},
+    {"\\\\?\\C:\\a", 0, FALSE},
+    {"\\\\?\\Volume{e51a1864-6f2d-4019-b73d-f4e60e600c26}\\", 0, FALSE}
+};
+
+static void test_PathIsUNCEx(void)
+{
+    WCHAR pathW[MAX_PATH];
+    const WCHAR *server;
+    BOOL ret;
+    INT i;
+
+    if (!pPathIsUNCEx)
+    {
+        win_skip("PathIsUNCEx(() is not available.\n");
+        return;
+    }
+
+    /* No NULL check for path pointers on Windows */
+    if (0)
+    {
+        ret = pPathIsUNCEx(NULL, &server);
+        ok(ret == FALSE, "expect FALSE\n");
+    }
+
+    MultiByteToWideChar(CP_ACP, 0, "C:\\", -1, pathW, ARRAY_SIZE(pathW));
+    ret = pPathIsUNCEx(pathW, NULL);
+    ok(ret == FALSE, "expect FALSE\n");
+
+    for (i = 0; i < ARRAY_SIZE(isuncex_tests); i++)
+    {
+        const struct isuncex_test *t = isuncex_tests + i;
+
+        MultiByteToWideChar(CP_ACP, 0, t->path, -1, pathW, ARRAY_SIZE(pathW));
+        server = (const WCHAR *)0xdeadbeef;
+        ret = pPathIsUNCEx(pathW, &server);
+        ok(ret == t->ret, "path \"%s\" expect return %d, got %d\n", t->path, t->ret, ret);
+        if (ret)
+            ok(server == pathW + t->server_offset, "path \"%s\" expect server offset %d, got %ld\n", t->path,
+               t->server_offset, (INT_PTR)(server - pathW));
+        else
+            ok(!server, "expect server is null, got %p\n", server);
+    }
+}
+
 START_TEST(path)
 {
     HMODULE hmod = LoadLibraryA("kernelbase.dll");
@@ -643,6 +713,7 @@ START_TEST(path)
     pPathCchFindExtension = (void *)GetProcAddress(hmod, "PathCchFindExtension");
     pPathCchRemoveExtension = (void *)GetProcAddress(hmod, "PathCchRemoveExtension");
     pPathCchRenameExtension = (void *)GetProcAddress(hmod, "PathCchRenameExtension");
+    pPathIsUNCEx = (void *)GetProcAddress(hmod, "PathIsUNCEx");
 
     test_PathCchCombineEx();
     test_PathCchAddBackslash();
@@ -651,4 +722,5 @@ START_TEST(path)
     test_PathCchFindExtension();
     test_PathCchRemoveExtension();
     test_PathCchRenameExtension();
+    test_PathIsUNCEx();
 }
diff --git a/include/pathcch.h b/include/pathcch.h
index 3057b6c..6973d6d 100644
--- a/include/pathcch.h
+++ b/include/pathcch.h
@@ -32,3 +32,4 @@ HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, con
 HRESULT WINAPI PathCchFindExtension(const WCHAR *path, SIZE_T size, const WCHAR **extension);
 HRESULT WINAPI PathCchRemoveExtension(WCHAR *path, SIZE_T size);
 HRESULT WINAPI PathCchRenameExtension(WCHAR *path, SIZE_T size, const WCHAR *extension);
+BOOL    WINAPI PathIsUNCEx(const WCHAR *path, const WCHAR **server);




More information about the wine-cvs mailing list