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