FileRenameInfoEx is already handled by NtSetInformationFile, SetFileInformationByHandle need only pass it through correctly.
As of version 5.3, Apple's Metal Developer Tools are dependent on SetFileInformationByHandle to handle FileRenameInfoEx in this fashion.
-- v5: kernelbase: pass FileRenameInfoEx to NtSetInformationFile kernel32/tests: SetFileInfo should accept FileRenameInfoEx
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 | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 83766dfaaa2..c6d3459eb48 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5616,6 +5616,52 @@ static void test_SetFileRenameInfo(void) ok(!ret && GetLastError() == ERROR_ACCESS_DENIED, "FileRenameInfo unexpected result %ld\n", GetLastError()); CloseHandle(file);
+ DeleteFileW(tempFileFrom); + DeleteFileW(tempFileTo1); + DeleteFileW(tempFileTo2); + + // Repeat test again with FileRenameInfoEx + + 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()); + + CloseHandle(file); HeapFree(GetProcessHeap(), 0, fri); DeleteFileW(tempFileFrom); DeleteFileW(tempFileTo1);
From: Michael Stopa michael.stopa@tensorworks.com.au
FileRenameInfoEx is already handled by NtSetInformationFile, SetFileInformationByHandle need only pass it through. --- dlls/kernel32/tests/file.c | 8 ++++---- dlls/kernelbase/file.c | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index c6d3459eb48..bd3f5f6d74d 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5645,21 +5645,21 @@ static void test_SetFileRenameInfo(void) 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()); + 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()); + 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()); + 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()); + ok(file != INVALID_HANDLE_VALUE, "file not renamed, error %ld\n", GetLastError());
CloseHandle(file); HeapFree(GetProcessHeap(), 0, fri); diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 213cb926d7c..3e8f470444f 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -3661,6 +3661,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetFileInformationByHandle( HANDLE file, FILE_INFO status = NtSetInformationFile( file, &io, info, size, FileIoPriorityHintInformation ); break; case FileRenameInfo: + case FileRenameInfoEx: { FILE_RENAME_INFORMATION *rename_info; UNICODE_STRING nt_name; @@ -3676,7 +3677,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetFileInformationByHandle( HANDLE file, FILE_INFO memcpy( rename_info, info, sizeof(*rename_info) ); memcpy( rename_info->FileName, nt_name.Buffer, nt_name.Length + sizeof(WCHAR) ); rename_info->FileNameLength = nt_name.Length; - status = NtSetInformationFile( file, &io, rename_info, size, FileRenameInformation ); + status = NtSetInformationFile( file, &io, rename_info, size, + class == FileRenameInfo ? FileRenameInformation : FileRenameInformationEx ); HeapFree( GetProcessHeap(), 0, rename_info ); } RtlFreeUnicodeString( &nt_name );