Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kernel32/tests/file.c | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 63a67ca1a1..a2511beef2 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5065,6 +5065,17 @@ todo_wine ok(ret, "Failed to get basic info, error %d.\n", GetLastError()); ok(atime.QuadPart + 1 == basicinfo.LastAccessTime.QuadPart, "Unexpected access time.\n");
+ memset(&basicinfo, 0, sizeof(basicinfo)); + basicinfo.LastAccessTime.QuadPart = -1; + ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); +todo_wine + ok(ret, "Failed to set basic info, error %d.\n", GetLastError()); + + memset(&basicinfo, 0, sizeof(basicinfo)); + ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); + ok(ret, "Failed to get basic info, error %d.\n", GetLastError()); + ok(atime.QuadPart + 1 == basicinfo.LastAccessTime.QuadPart, "Unexpected access time.\n"); + dispinfo.DeleteFile = TRUE; ret = pSetFileInformationByHandle(file, FileDispositionInfo, &dispinfo, sizeof(dispinfo)); ok(ret, "setting FileDispositionInfo failed, error %d\n", GetLastError()); @@ -5357,6 +5368,50 @@ static void test_find_file_stream(void) ok(error == ERROR_HANDLE_EOF, "Expected ERROR_HANDLE_EOF, got %d\n", error); }
+static void test_SetFileTime(void) +{ + static const WCHAR prefix[] = {'p','f','x',0}; + WCHAR path[MAX_PATH], temp_path[MAX_PATH]; + FILETIME ft1, ft2; + DWORD ret, len; + HANDLE hfile; + + ret = GetTempPathW(MAX_PATH, temp_path); + 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, path); + ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError()); + + hfile = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n"); + ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL ); + ok(ret && len == sizeof(prefix), "WriteFile error %d\n", GetLastError()); + ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n"); + + ret = GetFileTime(hfile, NULL, NULL, &ft1); + ok(ret, "GetFileTime error %d\n", GetLastError()); + ft2 = ft1; + ft2.dwLowDateTime -= 600000000; /* 60 second */ + ret = SetFileTime(hfile, NULL, NULL, &ft2); + ok(ret, "SetFileTime error %d\n", GetLastError()); + memset(&ft2, 0, sizeof(ft2)); + ret = GetFileTime(hfile, NULL, NULL, &ft2); /* get the actual time back */ + ok(ret, "GetFileTime error %d\n", GetLastError()); + ok(memcmp(&ft1, &ft2, sizeof(ft1)), "Unexpected write time.\n"); + + memset(&ft1, 0xff, sizeof(ft1)); + ret = SetFileTime(hfile, NULL, NULL, &ft1); +todo_wine + ok(ret, "SetFileTime error %d\n", GetLastError()); + memset(&ft1, 0, sizeof(ft1)); + ret = GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */ + ok(ret, "GetFileTime error %d\n", GetLastError()); + ok(!memcmp(&ft1, &ft2, sizeof(ft1)), "Unexpected write time.\n"); + + CloseHandle(hfile); +} + START_TEST(file) { char temp_path[MAX_PATH]; @@ -5429,4 +5484,5 @@ START_TEST(file) test_overlapped_read(); test_file_readonly_access(); test_find_file_stream(); + test_SetFileTime(); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ntdll/tests/file.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 8e54dbb541..63854b5482 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1313,8 +1313,8 @@ static void test_file_full_size_information(void)
static void test_file_basic_information(void) { + FILE_BASIC_INFORMATION fbi, fbi2; IO_STATUS_BLOCK io; - FILE_BASIC_INFORMATION fbi; HANDLE h; int res; int attrib_mask = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL; @@ -1328,6 +1328,30 @@ static void test_file_basic_information(void) ok ( (fbi.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE, "attribute %x not expected\n", fbi.FileAttributes );
+ memset(&fbi2, 0, sizeof(fbi2)); + fbi2.LastWriteTime.QuadPart = -1; + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); +todo_wine { + ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res ); + ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status ); +} + memset(&fbi2, 0, sizeof(fbi2)); + res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); + ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); + ok ( fbi2.LastWriteTime.QuadPart == fbi.LastWriteTime.QuadPart, "unexpected write time.\n"); + + memset(&fbi2, 0, sizeof(fbi2)); + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); + ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res ); + ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status ); + + memset(&fbi2, 0, sizeof(fbi2)); + res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); + ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); + ok ( fbi2.LastWriteTime.QuadPart == fbi.LastWriteTime.QuadPart, "unexpected write time.\n"); + /* Then SYSTEM */ /* Clear fbi to avoid setting times */ memset(&fbi, 0, sizeof(fbi));
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
CoreFX is using -1 for time fields to ignore when calling SetFileInformationByHandle().
dlls/kernel32/tests/file.c | 2 -- dlls/ntdll/file.c | 8 ++++++-- dlls/ntdll/tests/file.c | 3 +-- 3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index a2511beef2..9be4ecd136 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5068,7 +5068,6 @@ todo_wine memset(&basicinfo, 0, sizeof(basicinfo)); basicinfo.LastAccessTime.QuadPart = -1; ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); -todo_wine ok(ret, "Failed to set basic info, error %d.\n", GetLastError());
memset(&basicinfo, 0, sizeof(basicinfo)); @@ -5402,7 +5401,6 @@ static void test_SetFileTime(void)
memset(&ft1, 0xff, sizeof(ft1)); ret = SetFileTime(hfile, NULL, NULL, &ft1); -todo_wine ok(ret, "SetFileTime error %d\n", GetLastError()); memset(&ft1, 0, sizeof(ft1)); ret = GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */ diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 1cbaa1b293..cd1775a98c 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -2513,12 +2513,16 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, { struct stat st; const FILE_BASIC_INFORMATION *info = ptr; + LARGE_INTEGER mtime, atime;
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) return io->u.Status;
- if (info->LastAccessTime.QuadPart || info->LastWriteTime.QuadPart) - io->u.Status = set_file_times( fd, &info->LastWriteTime, &info->LastAccessTime ); + mtime.QuadPart = info->LastWriteTime.QuadPart == -1 ? 0 : info->LastWriteTime.QuadPart; + atime.QuadPart = info->LastAccessTime.QuadPart == -1 ? 0 : info->LastAccessTime.QuadPart; + + if (atime.QuadPart || mtime.QuadPart) + io->u.Status = set_file_times( fd, &mtime, &atime );
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes) { diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 63854b5482..31fc7ae7b0 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1332,10 +1332,9 @@ static void test_file_basic_information(void) fbi2.LastWriteTime.QuadPart = -1; U(io).Status = 0xdeadbeef; res = pNtSetInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); -todo_wine { ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res ); ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status ); -} + memset(&fbi2, 0, sizeof(fbi2)); res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55320
Your paranoid android.
=== wvistau64_he (32 bit report) ===
kernel32: file.c:3648: Test failed: replaced file has wrong filetime 1d54e816791f4c0 / 1d54e8166105600