kernel32: Implement ReplaceFileA/ReplaceFileW
Erich Hoover
ehoover at mines.edu
Mon Feb 26 20:23:35 CST 2007
Skipped content of type multipart/alternative-------------- next part --------------
/**************************************************************************
* ReplaceFileW (KERNEL32.@)
* ReplaceFile (KERNEL32.@)
*/
BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,
LPCWSTR lpBackupFileName, DWORD dwReplaceFlags,
LPVOID lpExclude, LPVOID lpReserved)
{
HANDLE hReplaced, hReplacement;
BOOL skipBackup = FALSE;
if(dwReplaceFlags)
FIXME("Ignoring flags %x\n", dwReplaceFlags);
/* First two arguments are mandatory */
if(!lpReplacedFileName || !lpReplacementFileName)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
/*
* Lock the "replacement" file, fail if it does not exist
*/
if((hReplacement = CreateFileW(lpReplacementFileName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if(!LockFile( hReplacement, 0, 0, 0, 0 ))
{
CloseHandle( hReplacement );
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
/*
* Lock the "replaced" file while we're working.
*/
if((hReplaced = CreateFileW(lpReplacedFileName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
{
/* If "replaced" does not exist then create it for the lock, but skip backup */
if((hReplaced = CreateFileW(lpReplacedFileName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE)
{
UnlockFile( hReplacement, 0, 0, 0, 0 );
CloseHandle( hReplacement );
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
skipBackup = TRUE;
}
if(!LockFile( hReplaced, 0, 0, 0, 0 ))
{
UnlockFile( hReplacement, 0, 0, 0, 0 );
CloseHandle( hReplacement );
CloseHandle( hReplaced );
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
/*
* If the user wants a backup then that needs to be performed first
*/
if( lpBackupFileName && !skipBackup )
{
/* If an existing backup exists then copy over it */
if(!CopyFileW( lpReplacedFileName, lpBackupFileName, FALSE ))
{
SetLastError( ERROR_INVALID_PARAMETER );
goto replace_fail;
}
}
/*
* Now that the backup has been performed (if requested), copy the replacement
* into place
*/
if(!CopyFileW( lpReplacementFileName, lpReplacedFileName, FALSE ))
{
/* Assume that all access denied errors are a write problem. */
if(GetLastError() == ERROR_ACCESS_DENIED)
SetLastError( ERROR_UNABLE_TO_REMOVE_REPLACED );
else
SetLastError( ERROR_UNABLE_TO_MOVE_REPLACEMENT );
goto replace_fail;
}
/* Delete the replacement file */
if(!DeleteFileW( lpReplacementFileName ))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
/* Unlock the handles */
UnlockFile( hReplacement, 0, 0, 0, 0 );
CloseHandle( hReplacement );
UnlockFile( hReplaced, 0, 0, 0, 0 );
CloseHandle( hReplaced );
/* All done, file replacement successful */
return TRUE;
replace_fail:
UnlockFile( hReplacement, 0, 0, 0, 0 );
CloseHandle( hReplacement );
UnlockFile( hReplaced, 0, 0, 0, 0 );
CloseHandle( hReplaced );
return FALSE;
}
More information about the wine-devel
mailing list