kernel32: Stop CopyFile from overwriting a file with itself.
This commit is contained in:
parent
d87715c831
commit
06de0195d0
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user