Nikolay Sivov : scrrun: Implement BuildPath method.

Alexandre Julliard julliard at winehq.org
Mon Nov 18 14:51:39 CST 2013


Module: wine
Branch: master
Commit: 70bb23a9acc6abb73005dc221c65c9c682a2d868
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=70bb23a9acc6abb73005dc221c65c9c682a2d868

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Nov 17 11:49:53 2013 +0400

scrrun: Implement BuildPath method.

---

 dlls/scrrun/filesystem.c       |   57 ++++++++++++++++++++++++-
 dlls/scrrun/tests/filesystem.c |   89 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+), 3 deletions(-)

diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c
index 2750108..ee89b76 100644
--- a/dlls/scrrun/filesystem.c
+++ b/dlls/scrrun/filesystem.c
@@ -1073,11 +1073,62 @@ static HRESULT WINAPI filesys_get_Drives(IFileSystem3 *iface, IDriveCollection *
 }
 
 static HRESULT WINAPI filesys_BuildPath(IFileSystem3 *iface, BSTR Path,
-                                            BSTR Name, BSTR *pbstrResult)
+                                            BSTR Name, BSTR *Result)
 {
-    FIXME("%p %s %s %p\n", iface, debugstr_w(Path), debugstr_w(Name), pbstrResult);
+    BSTR ret;
 
-    return E_NOTIMPL;
+    TRACE("%p %s %s %p\n", iface, debugstr_w(Path), debugstr_w(Name), Result);
+
+    if (!Result) return E_POINTER;
+
+    if (Path && Name)
+    {
+        int path_len = SysStringLen(Path), name_len = SysStringLen(Name);
+
+        /* if both parts have backslashes strip one from Path */
+        if (Path[path_len-1] == '\\' && Name[0] == '\\')
+        {
+            path_len -= 1;
+
+            ret = SysAllocStringLen(NULL, path_len + name_len);
+            if (ret)
+            {
+                strcpyW(ret, Path);
+                ret[path_len] = 0;
+                strcatW(ret, Name);
+            }
+        }
+        else if (Path[path_len-1] != '\\' && Name[0] != '\\')
+        {
+            static const WCHAR bsW[] = {'\\',0};
+            ret = SysAllocStringLen(NULL, path_len + name_len + 1);
+            if (ret)
+            {
+                strcpyW(ret, Path);
+                if (Path[path_len-1] != ':')
+                    strcatW(ret, bsW);
+                strcatW(ret, Name);
+            }
+        }
+        else
+        {
+            ret = SysAllocStringLen(NULL, path_len + name_len);
+            if (ret)
+            {
+                strcpyW(ret, Path);
+                strcatW(ret, Name);
+            }
+        }
+    }
+    else if (Path || Name)
+        ret = SysAllocString(Path ? Path : Name);
+    else
+        ret = SysAllocStringLen(NULL, 0);
+
+    if (!ret) return E_OUTOFMEMORY;
+    *Result = ret;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR Path,
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c
index 6016049..630de1b 100644
--- a/dlls/scrrun/tests/filesystem.c
+++ b/dlls/scrrun/tests/filesystem.c
@@ -651,6 +651,94 @@ static void test_CopyFolder(void)
     SysFreeString(bsrc);
 }
 
+static BSTR bstr_from_str(const char *str)
+{
+    int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+    return ret;
+}
+
+struct buildpath_test
+{
+    const char *path;
+    const char *name;
+    const char *result;
+};
+
+static struct buildpath_test buildpath_data[] =
+{
+    { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
+    { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
+    { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
+    { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
+    { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
+    { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
+    { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
+    { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
+    { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
+    { "C:", "name.tmp", "C:name.tmp" },
+    { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
+    { NULL }
+};
+
+static void test_BuildPath(void)
+{
+    struct buildpath_test *ptr = buildpath_data;
+    BSTR ret, path;
+    HRESULT hr;
+    int i = 0;
+
+    hr = IFileSystem3_BuildPath(fs3, NULL, NULL, NULL);
+    ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+    ret = (BSTR)0xdeadbeef;
+    hr = IFileSystem3_BuildPath(fs3, NULL, NULL, &ret);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(*ret == 0, "got %p\n", ret);
+    SysFreeString(ret);
+
+    ret = (BSTR)0xdeadbeef;
+    path = bstr_from_str("path");
+    hr = IFileSystem3_BuildPath(fs3, path, NULL, &ret);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
+    SysFreeString(ret);
+    SysFreeString(path);
+
+    ret = (BSTR)0xdeadbeef;
+    path = bstr_from_str("path");
+    hr = IFileSystem3_BuildPath(fs3, NULL, path, &ret);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
+    SysFreeString(ret);
+    SysFreeString(path);
+
+    while (ptr->path)
+    {
+        BSTR name, result;
+
+        ret = NULL;
+        path = bstr_from_str(ptr->path);
+        name = bstr_from_str(ptr->name);
+        result = bstr_from_str(ptr->result);
+        hr = IFileSystem3_BuildPath(fs3, path, name, &ret);
+        ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
+        if (hr == S_OK)
+        {
+            ok(!lstrcmpW(ret, result), "%d: got wrong path %s, expected %s\n", i, wine_dbgstr_w(ret),
+                wine_dbgstr_w(result));
+            SysFreeString(ret);
+        }
+        SysFreeString(path);
+        SysFreeString(name);
+        SysFreeString(result);
+
+        i++;
+        ptr++;
+    }
+}
+
 START_TEST(filesystem)
 {
     HRESULT hr;
@@ -674,6 +762,7 @@ START_TEST(filesystem)
     test_GetAbsolutePathName();
     test_GetFile();
     test_CopyFolder();
+    test_BuildPath();
 
     IFileSystem3_Release(fs3);
 




More information about the wine-cvs mailing list