- 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:
Martin Wilck 2002-09-17 01:27:55 +00:00 committed by Alexandre Julliard
parent 848d50dc0f
commit 6a504be56f
1 changed files with 30 additions and 14 deletions

View File

@ -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. */
/* FIXME: This does not handle the (unlikely) case that the two locations
are on the same Wine drive, but on different Unix file systems. */
{
if ( attr & FILE_ATTRIBUTE_DIRECTORY )
{ {
FILE_SetDosError(); FILE_SetDosError();
return FALSE; 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;