- Return correct error codes.
- Fix behaviour if files are on different Wine drives - delete source if copy successful - try rename() - files may be on the same Unix file system. - Try copy/delete if rename() fails: files may be on the same DOS drive, but on different Unix file systems.
This commit is contained in:
parent
848d50dc0f
commit
6a504be56f
44
files/file.c
44
files/file.c
|
@ -2623,6 +2623,7 @@ BOOL WINAPI MoveFileExW( LPCWSTR fn1, LPCWSTR fn2, DWORD flag )
|
||||||
{
|
{
|
||||||
DOS_FULL_NAME full_name1, full_name2;
|
DOS_FULL_NAME full_name1, full_name2;
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
|
DWORD attr = INVALID_FILE_ATTRIBUTES;
|
||||||
|
|
||||||
TRACE("(%s,%s,%04lx)\n", debugstr_w(fn1), debugstr_w(fn2), flag);
|
TRACE("(%s,%s,%04lx)\n", debugstr_w(fn1), debugstr_w(fn2), flag);
|
||||||
|
|
||||||
|
@ -2663,8 +2664,7 @@ BOOL WINAPI MoveFileExW( LPCWSTR fn1, LPCWSTR fn2, DWORD flag )
|
||||||
/* target exists, check if we may overwrite */
|
/* target exists, check if we may overwrite */
|
||||||
if (!(flag & MOVEFILE_REPLACE_EXISTING))
|
if (!(flag & MOVEFILE_REPLACE_EXISTING))
|
||||||
{
|
{
|
||||||
/* FIXME: Use right error code */
|
SetLastError( ERROR_FILE_EXISTS );
|
||||||
SetLastError( ERROR_ACCESS_DENIED );
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2691,17 +2691,17 @@ BOOL WINAPI MoveFileExW( LPCWSTR fn1, LPCWSTR fn2, DWORD flag )
|
||||||
return FILE_AddBootRenameEntry( fn1, fn2, flag );
|
return FILE_AddBootRenameEntry( fn1, fn2, flag );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr = GetFileAttributesW( fn1 );
|
||||||
|
if ( attr == INVALID_FILE_ATTRIBUTES ) return FALSE;
|
||||||
|
|
||||||
/* check if we are allowed to rename the source */
|
/* check if we are allowed to rename the source */
|
||||||
hFile = FILE_CreateFile( full_name1.long_name, 0, 0,
|
hFile = FILE_CreateFile( full_name1.long_name, 0, 0,
|
||||||
NULL, OPEN_EXISTING, 0, 0, TRUE,
|
NULL, OPEN_EXISTING, 0, 0, TRUE,
|
||||||
GetDriveTypeW( full_name1.short_name ) );
|
GetDriveTypeW( full_name1.short_name ) );
|
||||||
if (!hFile)
|
if (!hFile)
|
||||||
{
|
{
|
||||||
DWORD attr;
|
|
||||||
|
|
||||||
if (GetLastError() != ERROR_ACCESS_DENIED) return FALSE;
|
if (GetLastError() != ERROR_ACCESS_DENIED) return FALSE;
|
||||||
attr = GetFileAttributesA( full_name1.long_name );
|
if ( !(attr & FILE_ATTRIBUTE_DIRECTORY) ) return FALSE;
|
||||||
if (attr == (DWORD)-1 || !(attr & FILE_ATTRIBUTE_DIRECTORY)) return FALSE;
|
|
||||||
/* if it's a directory we can continue */
|
/* if it's a directory we can continue */
|
||||||
}
|
}
|
||||||
else CloseHandle(hFile);
|
else CloseHandle(hFile);
|
||||||
|
@ -2716,20 +2716,36 @@ BOOL WINAPI MoveFileExW( LPCWSTR fn1, LPCWSTR fn2, DWORD flag )
|
||||||
|
|
||||||
if (full_name1.drive != full_name2.drive)
|
if (full_name1.drive != full_name2.drive)
|
||||||
{
|
{
|
||||||
/* use copy, if allowed */
|
|
||||||
if (!(flag & MOVEFILE_COPY_ALLOWED))
|
if (!(flag & MOVEFILE_COPY_ALLOWED))
|
||||||
{
|
{
|
||||||
/* FIXME: Use right error code */
|
SetLastError( ERROR_NOT_SAME_DEVICE );
|
||||||
SetLastError( ERROR_FILE_EXISTS );
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if ( attr & FILE_ATTRIBUTE_DIRECTORY )
|
||||||
|
{
|
||||||
|
/* Strange, but that's what Windows returns */
|
||||||
|
SetLastError ( ERROR_ACCESS_DENIED );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return CopyFileW( fn1, fn2, !(flag & MOVEFILE_REPLACE_EXISTING) );
|
|
||||||
}
|
}
|
||||||
if (rename( full_name1.long_name, full_name2.long_name ) == -1)
|
if (rename( full_name1.long_name, full_name2.long_name ) == -1)
|
||||||
{
|
/* Try copy/delete unless it's a directory. */
|
||||||
FILE_SetDosError();
|
/* FIXME: This does not handle the (unlikely) case that the two locations
|
||||||
return FALSE;
|
are on the same Wine drive, but on different Unix file systems. */
|
||||||
}
|
{
|
||||||
|
if ( attr & FILE_ATTRIBUTE_DIRECTORY )
|
||||||
|
{
|
||||||
|
FILE_SetDosError();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( ! CopyFileW( fn1, fn2, !(flag & MOVEFILE_REPLACE_EXISTING) ))
|
||||||
|
return FALSE;
|
||||||
|
if ( ! DeleteFileW ( fn1 ) )
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (is_executable( full_name1.long_name ) != is_executable( full_name2.long_name ))
|
if (is_executable( full_name1.long_name ) != is_executable( full_name2.long_name ))
|
||||||
{
|
{
|
||||||
struct stat fstat;
|
struct stat fstat;
|
||||||
|
|
Loading…
Reference in New Issue