[PATCH] kernelbase: CopyFileExA support COPY_FILE_OPEN_SOURCE_FOR_WRITE flag

Alexandre Julliard julliard at winehq.org
Tue Mar 8 02:32:26 CST 2022


Alistair Leslie-Hughes <leslie_alistair at hotmail.com> writes:

> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
> ---
>  dlls/kernel32/tests/file.c | 65 ++++++++++++++++++++++++++++++++++++++
>  dlls/kernelbase/file.c     | 22 ++++++++++---
>  2 files changed, 83 insertions(+), 4 deletions(-)
>
> diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
> index 77174d43d5b..eb5bc5ceb36 100644
> --- a/dlls/kernel32/tests/file.c
> +++ b/dlls/kernel32/tests/file.c
> @@ -1202,6 +1202,70 @@ static void test_CopyFileEx(void)
>      ok(!ret, "DeleteFileA unexpectedly succeeded\n");
>  }
>  
> +static void test_CopyFileEx_CopyWrite(void)
> +{
> +    char temp_path[MAX_PATH];
> +    char source[MAX_PATH], dest[MAX_PATH];
> +    static const char prefix[] = "pfx";
> +    HANDLE hfile;
> +    DWORD ret;
> +    BOOL retok;
> +
> +    ret = GetTempPathA(MAX_PATH, temp_path);
> +    ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
> +    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
> +
> +    ret = GetTempFileNameA(temp_path, prefix, 0, source);
> +    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
> +
> +    ret = GetTempFileNameA(temp_path, prefix, 0, dest);
> +    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
> +
> +    ret = DeleteFileA(dest);
> +    ok(ret, "DeleteFileA Failed\n");
> +
> +    /* Test with Read access */
> +    hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
> +    ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
> +
> +    retok = CopyFileExA(source, dest, NULL, NULL, NULL, COPY_FILE_OPEN_SOURCE_FOR_WRITE);
> +    ok(retok, "CopyFileExA failed\n");
> +    ok(GetLastError() == 0, "expected 0, got %ld\n", GetLastError());
> +    ok(GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES, "file wasn't created\n");
> +    CloseHandle(hfile);
> +
> +    ret = DeleteFileA(dest);
> +    ok(ret, "DeleteFileA Failed\n");
> +
> +    /* Test with Shared Read access */
> +    hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
> +    ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
> +
> +    retok = CopyFileExA(source, dest, NULL, NULL, NULL, COPY_FILE_OPEN_SOURCE_FOR_WRITE);
> +    ok(retok, "CopyFileExA failed\n");
> +    ok(GetLastError() == 0, "expected 0, got %ld\n", GetLastError());
> +    ok(GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES, "file wasn't created\n");
> +    CloseHandle(hfile);
> +
> +    ret = DeleteFileA(dest);
> +    ok(ret, "DeleteFileA Failed\n");
> +
> +    /* Test with Shared R/W access */
> +    hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
> +    ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
> +
> +    retok = CopyFileExA(source, dest, NULL, NULL, NULL, COPY_FILE_OPEN_SOURCE_FOR_WRITE);
> +    ok(retok, "CopyFileExA failed\n");
> +    ok(GetLastError() == 0, "got %ld\n", GetLastError());
> +    ok(GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES, "file wasn't created\n");
> +    CloseHandle(hfile);
> +
> +    ret = DeleteFileA(source);
> +    ok(ret, "DeleteFileA failed with error %ld\n", GetLastError());
> +    ret = DeleteFileA(dest);
> +    ok(ret, "DeleteFileA unexpectedly succeeded\n");
> +}

This doesn't demonstrate any difference in behavior when using the
flag. The tests succeed even without the code changes.

-- 
Alexandre Julliard
julliard at winehq.org



More information about the wine-devel mailing list