kernel32: Add tests for ReplaceFileA and ReplaceFileW.
This commit is contained in:
parent
c72de7bce2
commit
664c68a2c9
|
@ -23,6 +23,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* ReplaceFile requires Windows 2000 or newer */
|
||||
#define _WIN32_WINNT 0x0500
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -1902,6 +1905,253 @@ static void test_RemoveDirectory(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_ReplaceFileA(void)
|
||||
{
|
||||
char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
|
||||
HANDLE hReplacedFile, hReplacementFile, hBackupFile;
|
||||
static const char replacedData[] = "file-to-replace";
|
||||
static const char replacementData[] = "new-file";
|
||||
static const char backupData[] = "backup-file";
|
||||
FILETIME ftReplaced, ftReplacement, ftBackup;
|
||||
static const char prefix[] = "pfx";
|
||||
char temp_path[MAX_PATH];
|
||||
DWORD ret;
|
||||
BOOL retok;
|
||||
|
||||
ret = GetTempPathA(MAX_PATH, temp_path);
|
||||
ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
|
||||
ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
|
||||
|
||||
ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
|
||||
ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameA(temp_path, prefix, 0, backup);
|
||||
ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
|
||||
|
||||
/* place predictable data in the file to be replaced */
|
||||
hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok(hReplacedFile != INVALID_HANDLE_VALUE,
|
||||
"failed to open replaced file\n");
|
||||
retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
|
||||
ok( retok && ret == sizeof(replacedData),
|
||||
"WriteFile error (replaced) %d\n", GetLastError());
|
||||
ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
|
||||
"replaced file has wrong size\n");
|
||||
/* place predictable data in the file to be the replacement */
|
||||
hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok(hReplacementFile != INVALID_HANDLE_VALUE,
|
||||
"failed to open replacement file\n");
|
||||
retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
|
||||
ok( retok && ret == sizeof(replacementData),
|
||||
"WriteFile error (replacement) %d\n", GetLastError());
|
||||
ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
|
||||
"replacement file has wrong size\n");
|
||||
/* place predictable data in the backup file (to be over-written) */
|
||||
hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
ok(hBackupFile != INVALID_HANDLE_VALUE,
|
||||
"failed to open backup file\n");
|
||||
retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
|
||||
ok( retok && ret == sizeof(backupData),
|
||||
"WriteFile error (replacement) %d\n", GetLastError());
|
||||
ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
|
||||
"backup file has wrong size\n");
|
||||
/* change the filetime on the "replaced" file to ensure that it changes */
|
||||
ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
|
||||
ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
|
||||
ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
|
||||
ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
|
||||
ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
|
||||
GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
|
||||
CloseHandle(hReplacedFile);
|
||||
/* change the filetime on the backup to ensure that it changes */
|
||||
ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
|
||||
ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
|
||||
ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
|
||||
ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
|
||||
ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
|
||||
GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
|
||||
CloseHandle(hBackupFile);
|
||||
/* get the filetime on the replacement file to perform checks */
|
||||
ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
|
||||
ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
|
||||
CloseHandle(hReplacementFile);
|
||||
|
||||
/* perform replacement w/ backup
|
||||
* TODO: flags are not implemented
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReplaceFile(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
/* make sure that the backup has the size of the old "replaced" file */
|
||||
hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(hBackupFile != INVALID_HANDLE_VALUE,
|
||||
"failed to open backup file\n");
|
||||
ret = GetFileSize(hBackupFile, NULL);
|
||||
ok(ret == sizeof(replacedData),
|
||||
"backup file has wrong size %d\n", ret);
|
||||
/* make sure that the "replaced" file has the size of the replacement file */
|
||||
hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(hReplacedFile != INVALID_HANDLE_VALUE,
|
||||
"failed to open replaced file\n");
|
||||
ret = GetFileSize(hReplacedFile, NULL);
|
||||
ok(ret == sizeof(replacementData),
|
||||
"replaced file has wrong size %d\n", ret);
|
||||
/* make sure that the replacement file no-longer exists */
|
||||
hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(hReplacementFile == INVALID_HANDLE_VALUE,
|
||||
"unexpected error, replacement file should not exist %d\n", GetLastError());
|
||||
/* make sure that the backup has the old "replaced" filetime */
|
||||
ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
|
||||
ok( ret, "GetFileTime error (backup %d\n", GetLastError());
|
||||
ok(CompareFileTime(&ftBackup, &ftReplaced) == 0,
|
||||
"backup file has wrong filetime\n");
|
||||
CloseHandle(hBackupFile);
|
||||
/* make sure that the "replaced" has the old replacement filetime */
|
||||
ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
|
||||
ok( ret, "GetFileTime error (backup %d\n", GetLastError());
|
||||
ok(CompareFileTime(&ftReplaced, &ftReplacement) == 0,
|
||||
"replaced file has wrong filetime\n");
|
||||
CloseHandle(hReplacedFile);
|
||||
|
||||
/* re-create replacement file for pass w/o backup (blank) */
|
||||
ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
|
||||
/* perform replacement w/o backup
|
||||
* TODO: flags are not implemented
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
|
||||
ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
|
||||
/* re-create replacement file for pass w/ backup (backup-file not existing) */
|
||||
ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
|
||||
ret = DeleteFileA(backup);
|
||||
ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
|
||||
/* perform replacement w/ backup (no pre-existing backup)
|
||||
* TODO: flags are not implemented
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
|
||||
/* re-create replacement file for pass w/ no permissions to "replaced" */
|
||||
ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
|
||||
ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
|
||||
ok(ret, "SetFileAttributesA: error setting to read only %d\n", GetLastError());
|
||||
/* perform replacement w/ backup (no permission to "replaced")
|
||||
* TODO: flags are not implemented
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
/* make sure that the replacement file still exists */
|
||||
hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(hReplacementFile != INVALID_HANDLE_VALUE,
|
||||
"unexpected error, replacement file should still exist %d\n", GetLastError());
|
||||
CloseHandle(hReplacementFile);
|
||||
ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
|
||||
ok(ret, "SetFileAttributesA: error setting to normal %d\n", GetLastError());
|
||||
|
||||
/* replacement file still exists, make pass w/o "replaced" */
|
||||
ret = DeleteFileA(replaced);
|
||||
ok(ret, "DeleteFileA: error (replaced) %d\n", GetLastError());
|
||||
/* perform replacement w/ backup (no pre-existing backup or "replaced")
|
||||
* TODO: flags are not implemented
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
|
||||
/* perform replacement w/o existing "replacement" file
|
||||
* TODO: flags are not implemented
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
|
||||
/*
|
||||
* if the first round (w/ backup) worked then as long as there is no
|
||||
* failure then there is no need to check this round (w/ backup is the
|
||||
* more complete case)
|
||||
*/
|
||||
|
||||
/* delete temporary files, replacement and replaced are already deleted */
|
||||
ret = DeleteFileA(backup);
|
||||
ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
|
||||
}
|
||||
|
||||
/*
|
||||
* ReplaceFileW is a simpler case of ReplaceFileA, there is no
|
||||
* need to be as thorough.
|
||||
*/
|
||||
static void test_ReplaceFileW(void)
|
||||
{
|
||||
WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
|
||||
static const WCHAR prefix[] = {'p','f','x',0};
|
||||
WCHAR temp_path[MAX_PATH];
|
||||
DWORD ret;
|
||||
|
||||
ret = GetTempPathW(MAX_PATH, temp_path);
|
||||
if (ret==0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||
return;
|
||||
ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
|
||||
ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
|
||||
|
||||
ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
|
||||
ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameW(temp_path, prefix, 0, backup);
|
||||
ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
|
||||
|
||||
ret = ReplaceFileW(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(ret, "ReplaceFileW: error %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
|
||||
ret = ReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
|
||||
ok(ret, "ReplaceFileW: error %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
|
||||
ret = DeleteFileW(backup);
|
||||
ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
|
||||
ret = ReplaceFileW(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(ret, "ReplaceFileW: error %d\n", GetLastError());
|
||||
|
||||
ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
|
||||
ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
|
||||
ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
|
||||
ok(ret, "SetFileAttributesW: error setting to read only %d\n", GetLastError());
|
||||
|
||||
ret = ReplaceFileW(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
|
||||
"ReplaceFileW: unexpected error %d\n", GetLastError());
|
||||
ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
|
||||
ok(ret, "SetFileAttributesW: error setting to normal %d\n", GetLastError());
|
||||
|
||||
ret = DeleteFileW(replaced);
|
||||
ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
|
||||
ret = ReplaceFileW(replaced, replacement, backup, 0, 0, 0);
|
||||
ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
|
||||
|
||||
ret = ReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"ReplaceFileW: unexpected error %d\n", GetLastError());
|
||||
|
||||
ret = DeleteFileW(backup);
|
||||
ok(ret, "DeleteFileW: error %d\n", GetLastError());
|
||||
}
|
||||
|
||||
START_TEST(file)
|
||||
{
|
||||
hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||
|
@ -1937,4 +2187,6 @@ START_TEST(file)
|
|||
test_OpenFile();
|
||||
test_overlapped();
|
||||
test_RemoveDirectory();
|
||||
test_ReplaceFileA();
|
||||
test_ReplaceFileW();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue