Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42474 Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- .../api-ms-win-core-path-l1-1-0.spec | 2 +- dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/path.c | 32 +++++++++++++++++++ dlls/kernelbase/tests/path.c | 21 ++++++++++-- 4 files changed, 52 insertions(+), 5 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 f33d589d03..dfa7b81ba0 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 @@ -8,7 +8,7 @@ @ stdcall PathCchCanonicalize(ptr long wstr) kernelbase.PathCchCanonicalize @ stdcall PathCchCanonicalizeEx(ptr long wstr long) kernelbase.PathCchCanonicalizeEx @ stub PathCchCombine -@ stub PathCchCombineEx +@ stdcall PathCchCombineEx(ptr long wstr wstr long) kernelbase.PathCchCombineEx @ stdcall PathCchFindExtension(wstr long ptr) kernelbase.PathCchFindExtension @ stdcall PathCchIsRoot(wstr) kernelbase.PathCchIsRoot @ stdcall PathCchRemoveBackslash(wstr long) kernelbase.PathCchRemoveBackslash diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 303fd3bf47..9040633324 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1037,7 +1037,7 @@ @ stdcall PathCchCanonicalize(ptr long wstr) @ stdcall PathCchCanonicalizeEx(ptr long wstr long) # @ stub PathCchCombine -# @ stub PathCchCombineEx +@ stdcall PathCchCombineEx(ptr long wstr wstr long) @ stdcall PathCchFindExtension(wstr long ptr) @ stdcall PathCchIsRoot(wstr) @ stdcall PathCchRemoveBackslash(wstr long) diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c index 3380b8b4e4..92a747bd0b 100644 --- a/dlls/kernelbase/path.c +++ b/dlls/kernelbase/path.c @@ -496,6 +496,38 @@ HRESULT WINAPI PathCchCanonicalizeEx(WCHAR *out, SIZE_T size, const WCHAR *in, D return hr; }
+HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2, DWORD flags) +{ + HRESULT hr; + WCHAR *buffer; + SIZE_T length; + + TRACE("%p %s %s %#x\n", out, wine_dbgstr_w(path1), wine_dbgstr_w(path2), flags); + + if (!out || !size || size > PATHCCH_MAX_CCH) return E_INVALIDARG; + + hr = PathAllocCombine(path1, path2, flags, &buffer); + if (FAILED(hr)) + { + out[0] = 0; + return hr; + } + + length = strlenW(buffer); + if (length + 1 > size) + { + out[0] = 0; + LocalFree(buffer); + return STRSAFE_E_INSUFFICIENT_BUFFER; + } + else + { + memcpy(out, buffer, (length + 1) * sizeof(WCHAR)); + LocalFree(buffer); + return S_OK; + } +} + HRESULT WINAPI PathCchFindExtension(const WCHAR *path, SIZE_T size, const WCHAR **extension) { const WCHAR *lastpoint = NULL; diff --git a/dlls/kernelbase/tests/path.c b/dlls/kernelbase/tests/path.c index 2c012ab2bc..4061988fb1 100644 --- a/dlls/kernelbase/tests/path.c +++ b/dlls/kernelbase/tests/path.c @@ -485,12 +485,19 @@ static void test_PathCchCombineEx(void)
if (!pPathCchCombineEx) { - skip("PathCchCombineEx() is not available.\n"); + win_skip("PathCchCombineEx() is not available.\n"); return; }
+ output[0] = 0xff; + hr = pPathCchCombineEx(output, 5, NULL, NULL, 0); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + ok(output[0] == 0, "Expected output buffer to be empty\n"); + + output[0] = 0xff; hr = pPathCchCombineEx(NULL, 2, p1, p2, 0); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + ok(output[0] == 0xff, "Expected output buffer to be unchanged\n");
memset(output, 0xff, sizeof(output)); hr = pPathCchCombineEx(output, 0, p1, p2, 0); @@ -507,6 +514,14 @@ static void test_PathCchCombineEx(void) ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Expected STRSAFE_E_INSUFFICIENT_BUFFER, got %08x\n", hr); ok(output[0] == 0x0, "Expected output buffer to contain NULL string\n");
+ output[0] = 0xff; + hr = pPathCchCombineEx(output, PATHCCH_MAX_CCH + 1, p1, p2, 0); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + ok(output[0] == 0xff, "Expected output buffer to be 0xff\n"); + + hr = pPathCchCombineEx(output, PATHCCH_MAX_CCH, p1, p2, 0); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + memset(output, 0xff, sizeof(output)); hr = pPathCchCombineEx(output, 5, p1, p2, 0); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); @@ -2029,12 +2044,12 @@ START_TEST(path)
pPathAllocCanonicalize = (void *)GetProcAddress(hmod, "PathAllocCanonicalize"); pPathAllocCombine = (void *)GetProcAddress(hmod, "PathAllocCombine"); - pPathCchCombineEx = (void *)GetProcAddress(hmod, "PathCchCombineEx"); pPathCchAddBackslash = (void *)GetProcAddress(hmod, "PathCchAddBackslash"); pPathCchAddBackslashEx = (void *)GetProcAddress(hmod, "PathCchAddBackslashEx"); pPathCchAddExtension = (void *)GetProcAddress(hmod, "PathCchAddExtension"); pPathCchCanonicalize = (void *)GetProcAddress(hmod, "PathCchCanonicalize"); pPathCchCanonicalizeEx = (void *)GetProcAddress(hmod, "PathCchCanonicalizeEx"); + pPathCchCombineEx = (void *)GetProcAddress(hmod, "PathCchCombineEx"); pPathCchFindExtension = (void *)GetProcAddress(hmod, "PathCchFindExtension"); pPathCchIsRoot = (void *)GetProcAddress(hmod, "PathCchIsRoot"); pPathCchRemoveBackslash = (void *)GetProcAddress(hmod, "PathCchRemoveBackslash"); @@ -2049,12 +2064,12 @@ START_TEST(path)
test_PathAllocCanonicalize(); test_PathAllocCombine(); - test_PathCchCombineEx(); test_PathCchAddBackslash(); test_PathCchAddBackslashEx(); test_PathCchAddExtension(); test_PathCchCanonicalize(); test_PathCchCanonicalizeEx(); + test_PathCchCombineEx(); test_PathCchFindExtension(); test_PathCchIsRoot(); test_PathCchRemoveBackslash();