Commit 06de0195 authored by Damjan Jovanovic's avatar Damjan Jovanovic Committed by Alexandre Julliard

kernel32: Stop CopyFile from overwriting a file with itself.

parent d87715c8
......@@ -869,6 +869,24 @@ DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext,
return ret;
}
static BOOL is_same_file(HANDLE h1, HANDLE h2)
{
int fd1;
BOOL ret = FALSE;
if (wine_server_handle_to_fd(h1, 0, &fd1, NULL) == STATUS_SUCCESS)
{
int fd2;
if (wine_server_handle_to_fd(h2, 0, &fd2, NULL) == STATUS_SUCCESS)
{
struct stat stat1, stat2;
if (fstat(fd1, &stat1) == 0 && fstat(fd2, &stat2) == 0)
ret = (stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino);
wine_server_release_fd(h2, fd2);
}
wine_server_release_fd(h1, fd1);
}
return ret;
}
/**************************************************************************
* CopyFileW (KERNEL32.@)
......@@ -911,6 +929,25 @@ BOOL WINAPI CopyFileW( LPCWSTR source, LPCWSTR dest, BOOL fail_if_exists )
return FALSE;
}
if (!fail_if_exists)
{
BOOL same_file = FALSE;
h2 = CreateFileW( dest, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, 0);
if (h2 != INVALID_HANDLE_VALUE)
{
same_file = is_same_file( h1, h2 );
CloseHandle( h2 );
}
if (same_file)
{
HeapFree( GetProcessHeap(), 0, buffer );
CloseHandle( h1 );
SetLastError( ERROR_SHARING_VIOLATION );
return FALSE;
}
}
if ((h2 = CreateFileW( dest, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
fail_if_exists ? CREATE_NEW : CREATE_ALWAYS,
info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE)
......
......@@ -593,7 +593,7 @@ static void test_CopyFileA(void)
/* copying a file to itself must fail */
retok = CopyFileA(source, source, FALSE);
todo_wine ok( !retok && (GetLastError() == ERROR_SHARING_VIOLATION || broken(GetLastError() == ERROR_FILE_EXISTS) /* Win 9x */),
ok( !retok && (GetLastError() == ERROR_SHARING_VIOLATION || broken(GetLastError() == ERROR_FILE_EXISTS) /* Win 9x */),
"copying a file to itself didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
/* make the source have not zero size */
......
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