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 dfa7b81ba0b..a722f244436 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 @@ -7,7 +7,7 @@ @ stub PathCchAppendEx @ stdcall PathCchCanonicalize(ptr long wstr) kernelbase.PathCchCanonicalize @ stdcall PathCchCanonicalizeEx(ptr long wstr long) kernelbase.PathCchCanonicalizeEx -@ stub PathCchCombine +@ stdcall PathCchCombine(ptr long wstr wstr) kernelbase.PathCchCombine @ stdcall PathCchCombineEx(ptr long wstr wstr long) kernelbase.PathCchCombineEx @ stdcall PathCchFindExtension(wstr long ptr) kernelbase.PathCchFindExtension @ stdcall PathCchIsRoot(wstr) kernelbase.PathCchIsRoot diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 90406333245..bad32e8db44 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1036,7 +1036,7 @@ # @ stub PathCchAppendEx @ stdcall PathCchCanonicalize(ptr long wstr) @ stdcall PathCchCanonicalizeEx(ptr long wstr long) -# @ stub PathCchCombine +@ stdcall PathCchCombine(ptr long wstr wstr) @ stdcall PathCchCombineEx(ptr long wstr wstr long) @ stdcall PathCchFindExtension(wstr long ptr) @ stdcall PathCchIsRoot(wstr) diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c index 92a747bd0bc..a9186a1156b 100644 --- a/dlls/kernelbase/path.c +++ b/dlls/kernelbase/path.c @@ -496,6 +496,13 @@ HRESULT WINAPI PathCchCanonicalizeEx(WCHAR *out, SIZE_T size, const WCHAR *in, D return hr; } +HRESULT WINAPI PathCchCombine(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2) +{ + TRACE("%p %s %s\n", out, wine_dbgstr_w(path1), wine_dbgstr_w(path2)); + + return PathCchCombineEx(out, size, path1, path2, PATHCCH_NONE); +} + HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2, DWORD flags) { HRESULT hr; diff --git a/dlls/kernelbase/tests/path.c b/dlls/kernelbase/tests/path.c index 4061988fb15..30528b7768e 100644 --- a/dlls/kernelbase/tests/path.c +++ b/dlls/kernelbase/tests/path.c @@ -37,6 +37,7 @@ HRESULT (WINAPI *pPathCchAddBackslashEx)(WCHAR *out, SIZE_T size, WCHAR **endptr HRESULT (WINAPI *pPathCchAddExtension)(WCHAR *path, SIZE_T size, const WCHAR *extension); HRESULT (WINAPI *pPathCchCanonicalize)(WCHAR *out, SIZE_T size, const WCHAR *in); HRESULT (WINAPI *pPathCchCanonicalizeEx)(WCHAR *out, SIZE_T size, const WCHAR *in, DWORD flags); +HRESULT (WINAPI *pPathCchCombine)(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2); HRESULT (WINAPI *pPathCchCombineEx)(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2, DWORD flags); HRESULT (WINAPI *pPathCchFindExtension)(const WCHAR *path, SIZE_T size, const WCHAR **extension); BOOL (WINAPI *pPathCchIsRoot)(const WCHAR *path); @@ -474,6 +475,67 @@ static void test_PathAllocCombine(void) } } +static void test_PathCchCombine(void) +{ + WCHAR expected[PATHCCH_MAX_CCH] = {'C', ':', '\\', 'a', 0}; + WCHAR p1[PATHCCH_MAX_CCH] = {'C', ':', '\\', 0}; + WCHAR p2[PATHCCH_MAX_CCH] = {'a', 0}; + WCHAR output[PATHCCH_MAX_CCH]; + HRESULT hr; + INT i; + + if (!pPathCchCombine) + { + win_skip("PathCchCombine() is not available.\n"); + return; + } + + hr = pPathCchCombine(output, 5, NULL, NULL); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + + hr = pPathCchCombine(NULL, 2, p1, p2); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + + memset(output, 0xff, sizeof(output)); + hr = pPathCchCombine(output, 0, p1, p2); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + ok(output[0] == 0xffff, "Expected output buffer to be unchanged\n"); + + memset(output, 0xff, sizeof(output)); + hr = pPathCchCombine(output, 1, p1, p2); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Expected STRSAFE_E_INSUFFICIENT_BUFFER, got %08x\n", hr); + ok(output[0] == 0, "Expected output buffer to contain NULL string\n"); + + memset(output, 0xff, sizeof(output)); + hr = pPathCchCombine(output, 4, p1, p2); + 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"); + + memset(output, 0xff, sizeof(output)); + hr = pPathCchCombine(output, 5, p1, p2); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(!lstrcmpW(output, expected), "Combination of %s + %s returned %s, expected %s\n", wine_dbgstr_w(p1), + wine_dbgstr_w(p2), wine_dbgstr_w(output), wine_dbgstr_w(expected)); + + hr = pPathCchCombine(output, PATHCCH_MAX_CCH + 1, p1, p2); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + + hr = pPathCchCombine(output, PATHCCH_MAX_CCH, p1, p2); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + + for (i = 0; i < ARRAY_SIZE(combine_tests); i++) + { + MultiByteToWideChar(CP_ACP, 0, combine_tests[i].path1, -1, p1, ARRAY_SIZE(p1)); + MultiByteToWideChar(CP_ACP, 0, combine_tests[i].path2, -1, p2, ARRAY_SIZE(p2)); + MultiByteToWideChar(CP_ACP, 0, combine_tests[i].result, -1, expected, ARRAY_SIZE(expected)); + + hr = pPathCchCombine(output, ARRAY_SIZE(output), p1, p2); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(!lstrcmpW(output, expected), "Combining %s with %s returned %s, expected %s\n", wine_dbgstr_w(p1), + wine_dbgstr_w(p2), wine_dbgstr_w(output), wine_dbgstr_w(expected)); + } +} + static void test_PathCchCombineEx(void) { WCHAR expected[MAX_PATH] = {'C',':','\\','a',0}; @@ -2049,6 +2111,7 @@ START_TEST(path) pPathCchAddExtension = (void *)GetProcAddress(hmod, "PathCchAddExtension"); pPathCchCanonicalize = (void *)GetProcAddress(hmod, "PathCchCanonicalize"); pPathCchCanonicalizeEx = (void *)GetProcAddress(hmod, "PathCchCanonicalizeEx"); + pPathCchCombine = (void *)GetProcAddress(hmod, "PathCchCombine"); pPathCchCombineEx = (void *)GetProcAddress(hmod, "PathCchCombineEx"); pPathCchFindExtension = (void *)GetProcAddress(hmod, "PathCchFindExtension"); pPathCchIsRoot = (void *)GetProcAddress(hmod, "PathCchIsRoot"); @@ -2069,6 +2132,7 @@ START_TEST(path) test_PathCchAddExtension(); test_PathCchCanonicalize(); test_PathCchCanonicalizeEx(); + test_PathCchCombine(); test_PathCchCombineEx(); test_PathCchFindExtension(); test_PathCchIsRoot(); diff --git a/include/pathcch.h b/include/pathcch.h index 3cec09cadc6..205d4a23a3f 100644 --- a/include/pathcch.h +++ b/include/pathcch.h @@ -33,6 +33,7 @@ HRESULT WINAPI PathCchAddBackslashEx(WCHAR *path, SIZE_T size, WCHAR **end, SIZE HRESULT WINAPI PathCchAddExtension(WCHAR *path, SIZE_T size, const WCHAR *extension); HRESULT WINAPI PathCchCanonicalize(WCHAR *out, SIZE_T size, const WCHAR *in); HRESULT WINAPI PathCchCanonicalizeEx(WCHAR *out, SIZE_T size, const WCHAR *in, DWORD flags); +HRESULT WINAPI PathCchCombine(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2); HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2, DWORD flags); HRESULT WINAPI PathCchFindExtension(const WCHAR *path, SIZE_T size, const WCHAR **extension); BOOL WINAPI PathCchIsRoot(const WCHAR *path);