Commit 33f61ecc authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

kernel32/tests: Some tests for CopyFile2().

parent 2785c83b
......@@ -43,6 +43,7 @@ static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR
static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD);
static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD);
static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG);
static HRESULT (WINAPI *pCopyFile2)(PCWSTR,PCWSTR,COPYFILE2_EXTENDED_PARAMETERS*);
/* keep filename and filenameW the same */
static const char filename[] = "testfile.xxx";
......@@ -80,6 +81,7 @@ static void InitFunctionPointers(void)
pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx");
pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById");
pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData");
pCopyFile2 = (void *) GetProcAddress(hkernel32, "CopyFile2");
}
static void test__hread( void )
......@@ -788,6 +790,234 @@ static void test_CopyFileW(void)
ok(ret, "DeleteFileW: error %d\n", GetLastError());
}
static void test_CopyFile2(void)
{
static const WCHAR doesntexistW[] = {'d','o','e','s','n','t','e','x','i','s','t',0};
static const WCHAR prefix[] = {'p','f','x',0};
WCHAR source[MAX_PATH], dest[MAX_PATH], temp_path[MAX_PATH];
COPYFILE2_EXTENDED_PARAMETERS params;
HANDLE hfile, hmapfile;
FILETIME ft1, ft2;
DWORD ret, len;
char buf[10];
HRESULT hr;
if (!pCopyFile2)
{
skip("CopyFile2 is not available\n");
return;
}
ret = GetTempPathW(MAX_PATH, temp_path);
ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
ret = GetTempFileNameW(temp_path, prefix, 0, source);
ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
ret = GetTempFileNameW(temp_path, prefix, 0, dest);
ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
/* fail if exists */
memset(&params, 0, sizeof(params));
params.dwSize = sizeof(params);
params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %d\n", GetLastError());
/* don't fail if exists */
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, &params);
ok(hr == S_OK, "CopyFile2: error 0x%08x\n", hr);
/* copying a file to itself must fail */
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, source, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: copying a file to itself didn't fail, 0x%08x\n", hr);
ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
/* make the source have not zero size */
hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL );
ok(ret && len == sizeof(prefix), "WriteFile error %d\n", GetLastError());
ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
/* get the file time and change it to prove the difference */
ret = GetFileTime(hfile, NULL, NULL, &ft1);
ok(ret, "GetFileTime error %d\n", GetLastError());
ft1.dwLowDateTime -= 600000000; /* 60 second */
ret = SetFileTime(hfile, NULL, NULL, &ft1);
ok(ret, "SetFileTime error %d\n", GetLastError());
GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
CloseHandle(hfile);
ret = GetTempFileNameW(temp_path, prefix, 0, dest);
ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, &params);
ok(ret, "CopyFile2: error 0x%08x\n", hr);
/* copying from a read-locked source fails */
hfile = CreateFileW(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
/* in addition, the source is opened before the destination */
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(doesntexistW, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "CopyFile2: last error %d\n", GetLastError());
CloseHandle(hfile);
/* copying from a r+w opened, r shared source succeeds */
hfile = CreateFileW(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, &params);
ok(hr == S_OK, "failed 0x%08x\n", hr);
CloseHandle(hfile);
/* copying from a delete-locked source mostly succeeds */
hfile = CreateFileW(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, &params);
ok(hr == S_OK, "failed 0x%08x\n", hr);
CloseHandle(hfile);
/* copying to a write-locked destination fails */
hfile = CreateFileW(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, FALSE);
ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
CloseHandle(hfile);
/* copying to a r+w opened, w shared destination mostly succeeds */
hfile = CreateFileW(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, FALSE);
ok(hr == S_OK, "got 0x%08x\n", hr);
CloseHandle(hfile);
/* copying to a delete-locked destination fails, even when the destination is delete-shared */
hfile = CreateFileW(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
CloseHandle(hfile);
/* copy to a file that's opened the way Wine opens the source */
hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, &params);
ok(hr == S_OK, "got 0x%08x\n", hr);
CloseHandle(hfile);
/* make sure that destination has correct size */
hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
ret = GetFileSize(hfile, NULL);
ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
/* make sure that destination has the same filetime */
ret = GetFileTime(hfile, NULL, NULL, &ft2);
ok(ret, "GetFileTime error %d\n", GetLastError());
ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
/* make sure that destination still has correct size */
ret = GetFileSize(hfile, NULL);
ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
ret = ReadFile(hfile, buf, sizeof(buf), &len, NULL);
ok(ret && len == sizeof(prefix), "ReadFile: error %d\n", GetLastError());
ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
/* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
SetLastError(0xdeadbeef);
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
CloseHandle(hmapfile);
CloseHandle(hfile);
hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
/* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
params.dwSize = sizeof(params);
params.dwCopyFlags = 0;
hr = pCopyFile2(source, dest, &params);
ok(hr == HRESULT_FROM_WIN32(ERROR_USER_MAPPED_FILE), "CopyFile2: unexpected error 0x%08x\n", hr);
ok(GetLastError() == ERROR_USER_MAPPED_FILE, "CopyFile2: last error %d\n", GetLastError());
CloseHandle(hmapfile);
CloseHandle(hfile);
DeleteFileW(source);
DeleteFileW(dest);
}
/*
* Debugging routine to dump a buffer in a hexdump-like fashion.
......@@ -3179,7 +3409,7 @@ static void test_ReplaceFileW(void)
}
}
static void test_CreatFile(void)
static void test_CreateFile(void)
{
static const struct test_data
{
......@@ -3591,7 +3821,8 @@ START_TEST(file)
test_GetTempFileNameA();
test_CopyFileA();
test_CopyFileW();
test_CreatFile();
test_CopyFile2();
test_CreateFile();
test_CreateFileA();
test_CreateFileW();
test_DeleteFileA();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment