From: Michael Stopa michael.stopa@tensorworks.com.au
The documentation is extremely sparse but it would appear that SetFileInformationByHandle should handle FileRenameInfoEx in basically the same manner as FileRenameInfo, the only difference between the two being how they store the flag for replacing an existing file.
No other flags are being tested as even on MSDN they're only properly explained for NtSetInformationFile, which is wrapped by SetFileInformationByHandle in Wine anyway. --- dlls/kernel32/tests/file.c | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index db3ffc655ce..dcd90803bb1 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5605,6 +5605,73 @@ static void test_SetFileRenameInfo(void) DeleteFileW(tempFileTo2); }
+static void test_SetFileRenameInfoEx(void) +{ + WCHAR tempFileFrom[MAX_PATH], tempFileTo1[MAX_PATH], tempFileTo2[MAX_PATH]; + WCHAR tempPath[MAX_PATH]; + FILE_RENAME_INFORMATION *fri; + HANDLE file; + DWORD size; + BOOL ret; + + if (!pSetFileInformationByHandle) + { + win_skip("SetFileInformationByHandle is not supported\n"); + return; + } + + ret = GetTempPathW(MAX_PATH, tempPath); + ok(ret, "GetTempPathW failed, got error %lu.\n", GetLastError()); + + ret = GetTempFileNameW(tempPath, L"abc", 0, tempFileFrom); + ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError()); + + ret = GetTempFileNameW(tempPath, L"abc", 0, tempFileTo1); + ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError()); + + ret = GetTempFileNameW(tempPath, L"abc", 1, tempFileTo2); + ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError()); + + file = CreateFileW(tempFileFrom, GENERIC_READ | GENERIC_WRITE | DELETE, 0, 0, OPEN_EXISTING, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "failed to create temp file, error %lu.\n", GetLastError()); + + size = sizeof(FILE_RENAME_INFORMATION) + MAX_PATH; + fri = HeapAlloc(GetProcessHeap(), 0, size); + + fri->Flags = 0; + fri->RootDirectory = NULL; + fri->FileNameLength = wcslen(tempFileTo1) * sizeof(WCHAR); + memcpy(fri->FileName, tempFileTo1, fri->FileNameLength + sizeof(WCHAR)); + ret = pSetFileInformationByHandle(file, FileRenameInfoEx, fri, size); + todo_wine ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS, "FileRenameInfoEx unexpected result %ld\n", GetLastError()); + + fri->Flags = FILE_RENAME_REPLACE_IF_EXISTS; + ret = pSetFileInformationByHandle(file, FileRenameInfoEx, fri, size); + todo_wine ok(ret, "FileRenameInfoEx failed, error %ld\n", GetLastError()); + + fri->Flags = 0; + fri->FileNameLength = wcslen(tempFileTo2) * sizeof(WCHAR); + memcpy(fri->FileName, tempFileTo2, fri->FileNameLength + sizeof(WCHAR)); + ret = pSetFileInformationByHandle(file, FileRenameInfoEx, fri, size); + todo_wine ok(ret, "FileRenameInfoEx failed, error %ld\n", GetLastError()); + CloseHandle(file); + + file = CreateFileW(tempFileTo2, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + todo_wine ok(file != INVALID_HANDLE_VALUE, "file not renamed, error %ld\n", GetLastError()); + + fri->FileNameLength = wcslen(tempFileTo1) * sizeof(WCHAR); + memcpy(fri->FileName, tempFileTo1, fri->FileNameLength + sizeof(WCHAR)); + ret = pSetFileInformationByHandle(file, FileRenameInfoEx, fri, size); + todo_wine + ok(!ret && GetLastError() == ERROR_ACCESS_DENIED, "FileRenameInfoEx unexpected result %ld\n", GetLastError()); + CloseHandle(file); + + HeapFree(GetProcessHeap(), 0, fri); + DeleteFileW(tempFileFrom); + DeleteFileW(tempFileTo1); + DeleteFileW(tempFileTo2); +} + static void test_GetFileAttributesExW(void) { static const struct @@ -6385,6 +6452,7 @@ START_TEST(file) test_GetFinalPathNameByHandleW(); test_SetFileInformationByHandle(); test_SetFileRenameInfo(); + test_SetFileRenameInfoEx(); test_GetFileAttributesExW(); test_post_completion(); test_overlapped_read();