From 9cca65dc0d6ecc1da030a35a693e53c959ec9b45 Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Mon, 1 Apr 2002 03:43:45 -0700 Subject: Implement ReplaceFileA/ReplaceFileW (2/2) --- dlls/kernel32/tests/file.c | 254 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 253 insertions(+), 1 deletions(-) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index d115a57..3db9cb5 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -23,6 +23,9 @@ #include #include +/* ReplaceFile requires Windows 2000 or newer */ +#define _WIN32_WINNT 0x0500 + #include "wine/test.h" #include "windef.h" #include "winbase.h" @@ -1854,6 +1857,253 @@ static void test_RemoveDirectory(void) ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() ); } } + +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) { @@ -1886,5 +2136,7 @@ START_TEST(file) test_read_write(); test_OpenFile(); test_overlapped(); - test_RemoveDirectory(); + test_RemoveDirectory(); + test_ReplaceFileA(); + test_ReplaceFileW(); } -- 1.4.4.2