diff --git a/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch b/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch index 877388e4..1eace01e 100644 --- a/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch +++ b/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch @@ -1,18 +1,18 @@ -From 36762a2034391d67fc73ac037f8a7913cee911e7 Mon Sep 17 00:00:00 2001 +From 6a09d34647aa517e45bc0bb20a92d0d94a1da888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 5 Aug 2017 03:39:55 +0200 Subject: [PATCH] ntdll: Implement process token elevation through manifests. --- - dlls/ntdll/loader.c | 39 ++++++++++++++++++++++++++++++++++++++- + dlls/ntdll/loader.c | 37 +++++++++++++++++++++++++++++++++++++ server/process.c | 8 ++++++++ server/process.h | 1 + server/protocol.def | 7 +++++++ server/token.c | 14 ++++++++++++++ - 5 files changed, 68 insertions(+), 1 deletion(-) + 5 files changed, 67 insertions(+) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c -index 031bf83b4..c2810d50b 100644 +index 2f203447e..7c5dd308b 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3804,6 +3804,32 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow @@ -48,22 +48,6 @@ index 031bf83b4..c2810d50b 100644 /*********************************************************************** * load_global_options */ -@@ -3866,6 +3892,7 @@ static void load_global_options(void) - } - - -+ - /*********************************************************************** - * RtlImageDirectoryEntryToData (NTDLL.@) - */ -@@ -3901,7 +3928,6 @@ PVOID WINAPI RtlImageDirectoryEntryToData( HMODULE module, BOOL image, WORD dir, - return RtlImageRvaToVa( nt, module, addr, NULL ); - } - -- - /*********************************************************************** - * RtlImageRvaToSection (NTDLL.@) - */ @@ -4233,6 +4259,7 @@ void __wine_process_init(void) 's','y','s','t','e','m','3','2','\\', 'k','e','r','n','e','l','3','2','.','d','l','l',0}; @@ -72,7 +56,7 @@ index 031bf83b4..c2810d50b 100644 WINE_MODREF *wm; NTSTATUS status; ANSI_STRING func_name; -@@ -4305,6 +4332,16 @@ void __wine_process_init(void) +@@ -4324,6 +4351,16 @@ void __wine_process_init(void) virtual_set_large_address_space(); @@ -90,7 +74,7 @@ index 031bf83b4..c2810d50b 100644 RemoveEntryList( &wm->ldr.InLoadOrderModuleList ); InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList ); diff --git a/server/process.c b/server/process.c -index b4b239d2f..3cfc6f88f 100644 +index 4c7da9223..d6f71a774 100644 --- a/server/process.c +++ b/server/process.c @@ -1107,6 +1107,14 @@ struct process_snapshot *process_snap( int *count ) @@ -109,7 +93,7 @@ index b4b239d2f..3cfc6f88f 100644 DECL_HANDLER(new_process) { diff --git a/server/process.h b/server/process.h -index 20ff6beda..e072a35ba 100644 +index 5b83e111a..dfe5c4e52 100644 --- a/server/process.h +++ b/server/process.h @@ -139,6 +139,7 @@ extern void kill_debugged_processes( struct thread *debugger, int exit_code ); @@ -119,12 +103,12 @@ index 20ff6beda..e072a35ba 100644 +extern void replace_process_token( struct process *process, struct token *token ); /* console functions */ - extern void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin); + extern void inherit_console( struct thread *parent_thread, struct process *parent, diff --git a/server/protocol.def b/server/protocol.def -index 72fab786a..042072f58 100644 +index 6022e1715..45ab670ea 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -3743,6 +3743,13 @@ struct handle_info +@@ -3755,6 +3755,13 @@ struct handle_info @END @@ -161,5 +145,5 @@ index fcab79955..181219d21 100644 + } +} -- -2.23.0 +2.24.0 diff --git a/patches/advapi32-Token_Integrity_Level/0010-server-Implement-support-for-creating-processes-usin.patch b/patches/advapi32-Token_Integrity_Level/0010-server-Implement-support-for-creating-processes-usin.patch index c07d426c..3eafa10d 100644 --- a/patches/advapi32-Token_Integrity_Level/0010-server-Implement-support-for-creating-processes-usin.patch +++ b/patches/advapi32-Token_Integrity_Level/0010-server-Implement-support-for-creating-processes-usin.patch @@ -1,4 +1,4 @@ -From b052f3aa98d77d3ab68cdb2622b8e77478abeb6f Mon Sep 17 00:00:00 2001 +From 51830c6683b199e79cb9e782ee51555054a4da7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sun, 6 Aug 2017 02:08:05 +0200 Subject: [PATCH] server: Implement support for creating processes using a @@ -16,28 +16,28 @@ Subject: [PATCH] server: Implement support for creating processes using a 8 files changed, 66 insertions(+), 18 deletions(-) diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c -index 51b75470c..16396cb73 100644 +index a07dddb1f..99985ab89 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c -@@ -235,7 +235,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename +@@ -242,7 +242,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename /*********************************************************************** * create_nt_process */ -static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa, +static NTSTATUS create_nt_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params, - RTL_USER_PROCESS_INFORMATION *info ) + RTL_USER_PROCESS_INFORMATION *info, HANDLE parent ) { -@@ -250,7 +250,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES +@@ -257,7 +257,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES status = RtlCreateUserProcess( &nameW, OBJ_CASE_INSENSITIVE, params, psa ? psa->lpSecurityDescriptor : NULL, tsa ? tsa->lpSecurityDescriptor : NULL, -- 0, inherit, 0, 0, info ); -+ 0, inherit, 0, token, info ); +- parent, inherit, 0, 0, info ); ++ parent, inherit, 0, token, info ); RtlFreeUnicodeString( &nameW ); } return status; -@@ -260,7 +260,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES +@@ -267,7 +267,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES /*********************************************************************** * create_vdm_process */ @@ -46,16 +46,16 @@ index 51b75470c..16396cb73 100644 BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params, RTL_USER_PROCESS_INFORMATION *info ) { -@@ -281,7 +281,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE +@@ -288,7 +288,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer ); RtlInitUnicodeString( ¶ms->ImagePathName, winevdm ); RtlInitUnicodeString( ¶ms->CommandLine, newcmdline ); -- status = create_nt_process( psa, tsa, inherit, flags, params, info ); -+ status = create_nt_process( token, psa, tsa, inherit, flags, params, info ); +- status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL ); ++ status = create_nt_process( token, psa, tsa, inherit, flags, params, info, NULL ); HeapFree( GetProcessHeap(), 0, newcmdline ); return status; } -@@ -290,7 +290,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE +@@ -297,7 +297,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE /*********************************************************************** * create_cmd_process */ @@ -64,16 +64,16 @@ index 51b75470c..16396cb73 100644 BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params, RTL_USER_PROCESS_INFORMATION *info ) { -@@ -309,7 +309,7 @@ static NTSTATUS create_cmd_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE +@@ -316,7 +316,7 @@ static NTSTATUS create_cmd_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer ); RtlInitUnicodeString( ¶ms->ImagePathName, comspec ); RtlInitUnicodeString( ¶ms->CommandLine, newcmdline ); -- status = create_nt_process( psa, tsa, inherit, flags, params, info ); -+ status = create_nt_process( token, psa, tsa, inherit, flags, params, info ); +- status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL ); ++ status = create_nt_process( token, psa, tsa, inherit, flags, params, info, NULL ); RtlFreeHeap( GetProcessHeap(), 0, newcmdline ); return status; } -@@ -422,7 +422,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR +@@ -448,7 +448,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR TRACE( "app %s cmdline %s\n", debugstr_w(app_name), debugstr_w(cmd_line) ); @@ -84,16 +84,16 @@ index 51b75470c..16396cb73 100644 if (new_token) FIXME( "No support for returning created process token\n" ); if (app_name) -@@ -466,7 +468,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR - goto done; +@@ -521,7 +523,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR + } } -- status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info ); -+ status = create_nt_process( token, process_attr, thread_attr, inherit, flags, params, &rtl_info ); +- status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info, parent ); ++ status = create_nt_process( token, process_attr, thread_attr, inherit, flags, params, &rtl_info, parent ); switch (status) { case STATUS_SUCCESS: -@@ -475,7 +477,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR +@@ -530,7 +532,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR case STATUS_INVALID_IMAGE_NE_FORMAT: case STATUS_INVALID_IMAGE_PROTECT: TRACE( "starting %s as Win16/DOS binary\n", debugstr_w(app_name) ); @@ -102,7 +102,7 @@ index 51b75470c..16396cb73 100644 break; case STATUS_INVALID_IMAGE_NOT_MZ: /* check for .com or .bat extension */ -@@ -483,12 +485,12 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR +@@ -538,12 +540,12 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR if (!wcsicmp( p, L".com" ) || !wcsicmp( p, L".pif" )) { TRACE( "starting %s as DOS binary\n", debugstr_w(app_name) ); @@ -118,7 +118,7 @@ index 51b75470c..16396cb73 100644 break; } diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c -index e24691b8a..89403167b 100644 +index f3d9079f8..2fa553091 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -1667,7 +1667,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, @@ -130,7 +130,7 @@ index e24691b8a..89403167b 100644 RTL_USER_PROCESS_INFORMATION *info ) { NTSTATUS status; -@@ -1734,6 +1734,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, +@@ -1735,6 +1735,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, req->access = PROCESS_ALL_ACCESS; req->cpu = pe_info.cpu; req->info_size = startup_info_size; @@ -139,7 +139,7 @@ index e24691b8a..89403167b 100644 wine_server_add_data( req, startup_info, startup_info_size ); wine_server_add_data( req, params->Environment, env_size ); diff --git a/server/process.c b/server/process.c -index 3cfc6f88f..b4466cf43 100644 +index d6f71a774..aa66814d8 100644 --- a/server/process.c +++ b/server/process.c @@ -491,7 +491,7 @@ static void start_sigkill_timer( struct process *process ) @@ -165,10 +165,10 @@ index 3cfc6f88f..b4466cf43 100644 const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); struct process *process = NULL; + struct token *token = NULL; - struct process *parent = current->process; + struct process *parent; + struct thread *parent_thread = current; int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); - -@@ -1164,10 +1165,39 @@ DECL_HANDLER(new_process) +@@ -1177,10 +1178,39 @@ DECL_HANDLER(new_process) return; } @@ -205,10 +205,10 @@ index 3cfc6f88f..b4466cf43 100644 { close( socket_fd ); + if (token) release_object( token ); + release_object( parent ); return; } - info->process = NULL; -@@ -1214,7 +1244,7 @@ DECL_HANDLER(new_process) +@@ -1228,7 +1258,7 @@ DECL_HANDLER(new_process) #undef FIXUP_LEN } @@ -217,15 +217,15 @@ index 3cfc6f88f..b4466cf43 100644 process->startup_info = (struct startup_info *)grab_object( info ); -@@ -1276,6 +1306,7 @@ DECL_HANDLER(new_process) - reply->handle = alloc_handle_no_access_check( parent, process, req->access, objattr->attributes ); +@@ -1289,6 +1319,7 @@ DECL_HANDLER(new_process) + reply->handle = alloc_handle_no_access_check( current->process, process, req->access, objattr->attributes ); done: + if (token) release_object( token ); if (process) release_object( process ); + release_object( parent ); release_object( info ); - } -@@ -1308,7 +1339,7 @@ DECL_HANDLER(exec_process) +@@ -1322,7 +1353,7 @@ DECL_HANDLER(exec_process) close( socket_fd ); return; } @@ -235,7 +235,7 @@ index 3cfc6f88f..b4466cf43 100644 release_object( process ); } diff --git a/server/process.h b/server/process.h -index e072a35ba..9cf757cec 100644 +index dfe5c4e52..61b83abf6 100644 --- a/server/process.h +++ b/server/process.h @@ -118,7 +118,7 @@ extern unsigned int alloc_ptid( void *ptr ); @@ -248,10 +248,10 @@ index e072a35ba..9cf757cec 100644 extern struct thread *get_process_first_thread( struct process *process ); extern struct process *get_process_from_id( process_id_t id ); diff --git a/server/protocol.def b/server/protocol.def -index 81a90f7d4..aa68ceedb 100644 +index 45ab670ea..c763da4ca 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -790,6 +790,7 @@ struct rawinput_device +@@ -791,6 +791,7 @@ struct rawinput_device unsigned int access; /* access rights for process object */ client_cpu_t cpu; /* CPU that the new process will use */ data_size_t info_size; /* size of startup info */ @@ -260,10 +260,10 @@ index 81a90f7d4..aa68ceedb 100644 VARARG(info,startup_info,info_size); /* startup information */ VARARG(env,unicode_str); /* environment for new process */ diff --git a/server/request.c b/server/request.c -index d2adb08a1..139d643e8 100644 +index 200c2697d..f743b720a 100644 --- a/server/request.c +++ b/server/request.c -@@ -578,7 +578,7 @@ static void master_socket_poll_event( struct fd *fd, int event ) +@@ -582,7 +582,7 @@ static void master_socket_poll_event( struct fd *fd, int event ) int client = accept( get_unix_fd( master_socket->fd ), (struct sockaddr *) &dummy, &len ); if (client == -1) return; fcntl( client, F_SETFL, O_NONBLOCK ); @@ -315,5 +315,5 @@ index 181219d21..858ec25d7 100644 { GENERIC_MAPPING mapping; -- -2.23.0 +2.24.0 diff --git a/patches/kernelbase-ReOpenFile/0001-kernelbase-Implement-ReOpenFile.patch b/patches/kernelbase-ReOpenFile/0001-kernelbase-Implement-ReOpenFile.patch new file mode 100644 index 00000000..f40d4cc3 --- /dev/null +++ b/patches/kernelbase-ReOpenFile/0001-kernelbase-Implement-ReOpenFile.patch @@ -0,0 +1,296 @@ +From d0b5fb1fa826ede3c1b9270465601bcf981fb10b Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Fri, 13 Dec 2019 21:43:41 -0600 +Subject: [PATCH] kernelbase: Implement ReOpenFile(). + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47668 +Signed-off-by: Zebediah Figura +--- + dlls/kernel32/tests/file.c | 103 +++++++++++++++++++++++++++++++++++++ + dlls/kernelbase/file.c | 99 ++++++++++++++++++++++++++--------- + 2 files changed, 179 insertions(+), 23 deletions(-) + +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index 5bd168276f9..7dd138c7eb7 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -59,6 +59,7 @@ static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR, PUNICODE_STRING, PW + static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN); + static BOOL (WINAPI *pSetFileInformationByHandle)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, void*, DWORD); + static BOOL (WINAPI *pGetQueuedCompletionStatusEx)(HANDLE, OVERLAPPED_ENTRY*, ULONG, ULONG*, DWORD, BOOL); ++static HANDLE (WINAPI *pReOpenFile)(HANDLE, DWORD, DWORD, DWORD); + static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); + static void (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); + static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR); +@@ -111,6 +112,7 @@ static void InitFunctionPointers(void) + pGetFinalPathNameByHandleW = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleW"); + pSetFileInformationByHandle = (void *) GetProcAddress(hkernel32, "SetFileInformationByHandle"); + pGetQueuedCompletionStatusEx = (void *) GetProcAddress(hkernel32, "GetQueuedCompletionStatusEx"); ++ pReOpenFile = (void *) GetProcAddress(hkernel32, "ReOpenFile"); + pSetFileCompletionNotificationModes = (void *)GetProcAddress(hkernel32, "SetFileCompletionNotificationModes"); + pFindFirstStreamW = (void *)GetProcAddress(hkernel32, "FindFirstStreamW"); + } +@@ -4410,6 +4412,104 @@ static void test_SetFileValidData(void) + DeleteFileA(filename); + } + ++static void test_ReOpenFile(void) ++{ ++ char path[MAX_PATH], filename[MAX_PATH], buffer[4]; ++ HANDLE file, new; ++ unsigned int i; ++ DWORD size; ++ BOOL ret; ++ ++ static const DWORD invalid_attributes[] = ++ { ++ FILE_ATTRIBUTE_ARCHIVE, ++ FILE_ATTRIBUTE_ENCRYPTED, ++ FILE_ATTRIBUTE_HIDDEN, ++ FILE_ATTRIBUTE_NORMAL, ++ FILE_ATTRIBUTE_OFFLINE, ++ FILE_ATTRIBUTE_READONLY, ++ FILE_ATTRIBUTE_SYSTEM, ++ FILE_ATTRIBUTE_TEMPORARY, ++ }; ++ ++ static const DWORD valid_attributes[] = ++ { ++ FILE_FLAG_BACKUP_SEMANTICS, ++ FILE_FLAG_NO_BUFFERING, ++ FILE_FLAG_OVERLAPPED, ++ FILE_FLAG_RANDOM_ACCESS, ++ FILE_FLAG_SEQUENTIAL_SCAN, ++ FILE_FLAG_WRITE_THROUGH, ++ }; ++ ++ if (!pReOpenFile) ++ { ++ win_skip("ReOpenFile() is not available\n"); ++ return; ++ } ++ ++ GetTempPathA(sizeof(path), path); ++ GetTempFileNameA(path, "tst", 0, filename); ++ ++ file = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, ++ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); ++ ok(file != INVALID_HANDLE_VALUE, "failed to create file, error %u\n", GetLastError()); ++ ret = WriteFile(file, "foo", 4, &size, NULL); ++ ok(ret, "failed to write file, error %u\n", GetLastError()); ++ ++ for (i = 0; i < ARRAY_SIZE(invalid_attributes); ++i) ++ { ++ SetLastError(0xdeadbeef); ++ new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, invalid_attributes[i]); ++ ok(new == INVALID_HANDLE_VALUE, "got %p\n", new); ++ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError()); ++ } ++ ++ new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); ++ ok(new != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); ++ ++ ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL); ++ ok(ret, "failed to read file, error %u\n", GetLastError()); ++ ok(size == 4, "got size %u\n", size); ++ ok(!strcmp(buffer, "foo"), "got wrong data\n"); ++ CloseHandle(new); ++ ++ for (i = 0; i < ARRAY_SIZE(valid_attributes); ++i) ++ { ++ new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, valid_attributes[i]); ++ ok(new != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); ++ CloseHandle(new); ++ } ++ ++ SetLastError(0xdeadbeef); ++ new = pReOpenFile(file, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); ++ ok(new == INVALID_HANDLE_VALUE, "got %p\n", new); ++ ok(GetLastError() == ERROR_SHARING_VIOLATION, "got error %u\n", GetLastError()); ++ ++ CloseHandle(file); ++ ret = DeleteFileA(filename); ++ ok(ret, "failed to delete file, error %u\n", GetLastError()); ++ ++ file = CreateNamedPipeA("\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, 0, 1, 1000, 1000, 1000, NULL); ++ ok(file != INVALID_HANDLE_VALUE, "failed to create pipe, error %u\n", GetLastError()); ++ ++ new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); ++ todo_wine ok(new != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); ++ ++ ret = WriteFile(file, "foo", 4, &size, NULL); ++ todo_wine ok(ret, "failed to write file, error %u\n", GetLastError()); ++ ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL); ++ todo_wine ok(ret, "failed to read file, error %u\n", GetLastError()); ++ if (ret) ++ { ++ ok(size == 4, "got size %u\n", size); ++ ok(!strcmp(buffer, "foo"), "got wrong data\n"); ++ } ++ ++ CloseHandle(new); ++ CloseHandle(file); ++} ++ + static void test_WriteFileGather(void) + { + char temp_path[MAX_PATH], filename[MAX_PATH]; +@@ -5424,6 +5524,8 @@ START_TEST(file) + ret = DeleteFileA(filename); + ok(ret != 0, "DeleteFile error %u\n", GetLastError()); + ++ test_ReOpenFile(); return; ++ + test__hread( ); + test__hwrite( ); + test__lclose( ); +@@ -5483,4 +5585,5 @@ START_TEST(file) + test_file_readonly_access(); + test_find_file_stream(); + test_SetFileTime(); ++ test_ReOpenFile(); + } +diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c +index eb2ef57c7d6..66f0cbfedc4 100644 +--- a/dlls/kernelbase/file.c ++++ b/dlls/kernelbase/file.c +@@ -432,6 +432,26 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileA( LPCSTR name, DWORD access, DWORD sh + return CreateFileW( nameW, access, sharing, sa, creation, attributes, template ); + } + ++static UINT get_nt_file_options( DWORD attributes ) ++{ ++ UINT options = 0; ++ ++ if (attributes & FILE_FLAG_BACKUP_SEMANTICS) ++ options |= FILE_OPEN_FOR_BACKUP_INTENT; ++ else ++ options |= FILE_NON_DIRECTORY_FILE; ++ if (attributes & FILE_FLAG_DELETE_ON_CLOSE) ++ options |= FILE_DELETE_ON_CLOSE; ++ if (attributes & FILE_FLAG_NO_BUFFERING) ++ options |= FILE_NO_INTERMEDIATE_BUFFERING; ++ if (!(attributes & FILE_FLAG_OVERLAPPED)) ++ options |= FILE_SYNCHRONOUS_IO_NONALERT; ++ if (attributes & FILE_FLAG_RANDOM_ACCESS) ++ options |= FILE_RANDOM_ACCESS; ++ if (attributes & FILE_FLAG_WRITE_THROUGH) ++ options |= FILE_WRITE_THROUGH; ++ return options; ++} + + /************************************************************************* + * CreateFileW (kernelbase.@) +@@ -441,7 +461,6 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileW( LPCWSTR filename, DWORD access, DWO + DWORD attributes, HANDLE template ) + { + NTSTATUS status; +- UINT options; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + IO_STATUS_BLOCK io; +@@ -543,25 +562,8 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileW( LPCWSTR filename, DWORD access, DWO + + /* now call NtCreateFile */ + +- options = 0; +- if (attributes & FILE_FLAG_BACKUP_SEMANTICS) +- options |= FILE_OPEN_FOR_BACKUP_INTENT; +- else +- options |= FILE_NON_DIRECTORY_FILE; + if (attributes & FILE_FLAG_DELETE_ON_CLOSE) +- { +- options |= FILE_DELETE_ON_CLOSE; + access |= DELETE; +- } +- if (attributes & FILE_FLAG_NO_BUFFERING) +- options |= FILE_NO_INTERMEDIATE_BUFFERING; +- if (!(attributes & FILE_FLAG_OVERLAPPED)) +- options |= FILE_SYNCHRONOUS_IO_NONALERT; +- if (attributes & FILE_FLAG_RANDOM_ACCESS) +- options |= FILE_RANDOM_ACCESS; +- if (attributes & FILE_FLAG_WRITE_THROUGH) +- options |= FILE_WRITE_THROUGH; +- attributes &= FILE_ATTRIBUTE_VALID_FLAGS; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; +@@ -582,8 +584,9 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileW( LPCWSTR filename, DWORD access, DWO + if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT; + + status = NtCreateFile( &ret, access | SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &io, +- NULL, attributes, sharing, nt_disposition[creation - CREATE_NEW], +- options, NULL, 0 ); ++ NULL, attributes & FILE_ATTRIBUTE_VALID_FLAGS, sharing, ++ nt_disposition[creation - CREATE_NEW], ++ get_nt_file_options( attributes ), NULL, 0 ); + if (status) + { + if (vxd_name && vxd_name[0]) +@@ -2550,10 +2553,60 @@ HANDLE WINAPI DECLSPEC_HOTPATCH OpenFileById( HANDLE handle, LPFILE_ID_DESCRIPTO + /*********************************************************************** + * ReOpenFile (kernelbase.@) + */ +-HANDLE WINAPI /* DECLSPEC_HOTPATCH */ ReOpenFile( HANDLE handle, DWORD access, DWORD sharing, DWORD flags ) ++HANDLE WINAPI DECLSPEC_HOTPATCH ReOpenFile( HANDLE handle, DWORD access, DWORD sharing, DWORD attributes ) + { +- FIXME( "(%p, %d, %d, %d): stub\n", handle, access, sharing, flags ); +- return INVALID_HANDLE_VALUE; ++ SECURITY_QUALITY_OF_SERVICE qos; ++ OBJECT_NAME_INFORMATION *name; ++ OBJECT_ATTRIBUTES attr = {}; ++ IO_STATUS_BLOCK io; ++ NTSTATUS status; ++ HANDLE file; ++ DWORD size; ++ ++ TRACE("handle %p, access %#x, sharing %#x, attributes %#x.\n", handle, access, sharing, attributes); ++ ++ if (attributes & 0x7ffff) /* FILE_ATTRIBUTE_* flags are invalid */ ++ { ++ SetLastError(ERROR_INVALID_PARAMETER); ++ return INVALID_HANDLE_VALUE; ++ } ++ ++ status = NtQueryObject( handle, ObjectNameInformation, NULL, 0, &size ); ++ if (status != STATUS_INFO_LENGTH_MISMATCH && !set_ntstatus( status )) ++ return INVALID_HANDLE_VALUE; ++ ++ if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, size ))) ++ { ++ SetLastError( ERROR_NOT_ENOUGH_MEMORY ); ++ return INVALID_HANDLE_VALUE; ++ } ++ ++ status = NtQueryObject( handle, ObjectNameInformation, name, size, NULL ); ++ if (!set_ntstatus( status )) ++ return INVALID_HANDLE_VALUE; ++ ++ if (attributes & FILE_FLAG_DELETE_ON_CLOSE) ++ access |= DELETE; ++ ++ attr.Length = sizeof(attr); ++ attr.Attributes = OBJ_CASE_INSENSITIVE; ++ attr.ObjectName = &name->Name; ++ if (attributes & SECURITY_SQOS_PRESENT) ++ { ++ qos.Length = sizeof(qos); ++ qos.ImpersonationLevel = (attributes >> 16) & 0x3; ++ qos.ContextTrackingMode = attributes & SECURITY_CONTEXT_TRACKING ? SECURITY_DYNAMIC_TRACKING : SECURITY_STATIC_TRACKING; ++ qos.EffectiveOnly = (attributes & SECURITY_EFFECTIVE_ONLY) != 0; ++ attr.SecurityQualityOfService = &qos; ++ } ++ else ++ attr.SecurityQualityOfService = NULL; ++ ++ status = NtCreateFile( &file, access | SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &io, NULL, ++ 0, sharing, FILE_OPEN, get_nt_file_options( attributes ), NULL, 0 ); ++ if (!set_ntstatus( status )) ++ return INVALID_HANDLE_VALUE; ++ return file; + } + + +-- +2.24.0 + diff --git a/patches/kernelbase-ReOpenFile/0001-kernelbase-Improve-stub-for-ReOpenFile-and-add-small.patch b/patches/kernelbase-ReOpenFile/0001-kernelbase-Improve-stub-for-ReOpenFile-and-add-small.patch deleted file mode 100644 index 14a5622e..00000000 --- a/patches/kernelbase-ReOpenFile/0001-kernelbase-Improve-stub-for-ReOpenFile-and-add-small.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 540abe549f414881f5e0bd2afb0e4f81d4674850 Mon Sep 17 00:00:00 2001 -From: Louis Lenders -Date: Fri, 4 Oct 2019 23:10:29 +0200 -Subject: [PATCH] kernelbase: Improve stub for ReOpenFile and add small test - -Wine-bug: bug https://bugs.winehq.org/show_bug.cgi?id=47668 - -Signed-off-by: Louis Lenders ---- - dlls/kernel32/tests/file.c | 47 ++++++++++++++++++++++++++++++++++++++ - dlls/kernelbase/file.c | 31 +++++++++++++++++++++++-- - 2 files changed, 76 insertions(+), 2 deletions(-) - -diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c -index 5bd168276f9..0ed5aa6f03c 100644 ---- a/dlls/kernel32/tests/file.c -+++ b/dlls/kernel32/tests/file.c -@@ -59,6 +59,7 @@ static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR, PUNICODE_STRING, PW - static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN); - static BOOL (WINAPI *pSetFileInformationByHandle)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, void*, DWORD); - static BOOL (WINAPI *pGetQueuedCompletionStatusEx)(HANDLE, OVERLAPPED_ENTRY*, ULONG, ULONG*, DWORD, BOOL); -+static HANDLE (WINAPI *pReOpenFile)(HANDLE, DWORD, DWORD, DWORD); - static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); - static void (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); - static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR); -@@ -111,6 +112,7 @@ static void InitFunctionPointers(void) - pGetFinalPathNameByHandleW = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleW"); - pSetFileInformationByHandle = (void *) GetProcAddress(hkernel32, "SetFileInformationByHandle"); - pGetQueuedCompletionStatusEx = (void *) GetProcAddress(hkernel32, "GetQueuedCompletionStatusEx"); -+ pReOpenFile = (void *) GetProcAddress(hkernel32, "ReOpenFile"); - pSetFileCompletionNotificationModes = (void *)GetProcAddress(hkernel32, "SetFileCompletionNotificationModes"); - pFindFirstStreamW = (void *)GetProcAddress(hkernel32, "FindFirstStreamW"); - } -@@ -4410,6 +4412,50 @@ static void test_SetFileValidData(void) - DeleteFileA(filename); - } - -+static void test_ReOpenFile(void) -+{ -+ static WCHAR prefix[] = {'R','e','O','p','e','n','F','i','l','e','\0'}; -+ WCHAR temp_path[MAX_PATH], test_path[MAX_PATH]; -+ HANDLE file, h; -+ DWORD count; -+ UINT ret; -+ -+ if (!pReOpenFile) -+ { -+ win_skip("ReOpenFile is missing\n"); -+ return; -+ } -+ -+ /* Test calling with invalid handle */ -+ SetLastError(0xcafecafe); -+ h = pReOpenFile(INVALID_HANDLE_VALUE, GENERIC_WRITE, FILE_SHARE_WRITE, FILE_FLAG_DELETE_ON_CLOSE); -+ ok(h == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %u\n", h); -+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %u\n", GetLastError()); -+ -+ count = GetTempPathW(MAX_PATH, temp_path); -+ ok(count, "Failed to get temp path, error %u\n", GetLastError()); -+ ret = GetTempFileNameW(temp_path, prefix, 0, test_path); -+ ok(ret != 0, "GetTempFileNameW error %u\n", GetLastError()); -+ -+ file = CreateFileW(test_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, -+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); -+ ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %u\n", GetLastError()); -+ trace("Created file %s\n", wine_dbgstr_w(test_path)); -+ -+ SetLastError(0xcafecafe); -+ h = pReOpenFile(file, GENERIC_WRITE, FILE_SHARE_WRITE, FILE_ATTRIBUTE_NORMAL); -+ ok(h == INVALID_HANDLE_VALUE, "ReOpenFile returned unexpected handle %u\n",h); -+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); -+ -+ /* Logos Bible calls ReOpenFile with flags being 0, what Flags/Attributes is that?????? */ -+ SetLastError(0xcafecafe); -+ h = pReOpenFile(file, GENERIC_WRITE, FILE_SHARE_WRITE, 0); -+ ok(h != INVALID_HANDLE_VALUE, "ReOpenFile returned unexpected INVALID_HANDLE_VALUE\n"); -+ ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", GetLastError()); -+ -+ CloseHandle(file); -+} -+ - static void test_WriteFileGather(void) - { - char temp_path[MAX_PATH], filename[MAX_PATH]; -@@ -5469,6 +5515,7 @@ START_TEST(file) - test_RemoveDirectory(); - test_ReplaceFileA(); - test_ReplaceFileW(); -+ test_ReOpenFile(); - test_GetFileInformationByHandleEx(); - test_OpenFileById(); - test_SetFileValidData(); -diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c -index 89c5f85cb20..c2922fac68b 100644 ---- a/dlls/kernelbase/file.c -+++ b/dlls/kernelbase/file.c -@@ -64,6 +64,8 @@ typedef struct - - static const UINT max_entry_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ); - -+extern DWORD WINAPI GetFinalPathNameByHandleW(HANDLE,LPWSTR,DWORD,DWORD); -+ - const WCHAR windows_dir[] = {'C',':','\\','w','i','n','d','o','w','s',0}; - const WCHAR system_dir[] = {'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2',0}; - -@@ -2555,8 +2557,33 @@ HANDLE WINAPI DECLSPEC_HOTPATCH OpenFileById( HANDLE handle, LPFILE_ID_DESCRIPTO - */ - HANDLE WINAPI /* DECLSPEC_HOTPATCH */ ReOpenFile( HANDLE handle, DWORD access, DWORD sharing, DWORD flags ) - { -- FIXME( "(%p, %d, %d, %d): stub\n", handle, access, sharing, flags ); -- return INVALID_HANDLE_VALUE; -+ WCHAR name[MAX_PATH]; -+ DWORD size = MAX_PATH; -+ HANDLE h; -+ DWORD ret; -+ DWORD mask = 0xFFFFF; -+ -+ FIXME("(%p, %d, %d, %d): mostly stub\n", handle, access, sharing, flags); -+ -+ if(flags & mask) /* FILE_ATTRIBUTE_* flags are invalid */ -+ { -+ SetLastError(ERROR_INVALID_PARAMETER); -+ return INVALID_HANDLE_VALUE; -+ } -+ -+ ret = GetFinalPathNameByHandleW(handle, name, size, VOLUME_NAME_DOS); -+ -+ if(ret) -+ TRACE("Trying to reopen file %s\n", debugstr_w(name)); -+ else -+ { -+ SetLastError(ERROR_INVALID_HANDLE); -+ return INVALID_HANDLE_VALUE; -+ } -+ -+ h = CreateFileW(name, access, sharing, NULL, OPEN_EXISTING, flags, NULL); -+ -+ return h; - } - - --- -2.17.1 - diff --git a/patches/kernelbase-ReOpenFile/definition b/patches/kernelbase-ReOpenFile/definition index 1c53ed0b..4a9ea27f 100644 --- a/patches/kernelbase-ReOpenFile/definition +++ b/patches/kernelbase-ReOpenFile/definition @@ -1 +1 @@ -Fixes: [47668 ] kernelbase: Improve stub for ReOpenFile and add small test +Fixes: [47668] Logos 8 (.NET/WPF 4.7.2 application) fails to download resources (needs ReOpenFile implementation) diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 6d3c9aee..f595458a 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,7 +52,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "750d382f54e494771128c6b331122be2bc747484" + echo "ce7e10868a1279573acc5be5a9659d254e936b27" } # Show version information @@ -4293,15 +4293,15 @@ fi # Patchset kernelbase-ReOpenFile # | # | This patchset fixes the following Wine bugs: -# | * [#47668] kernelbase: Improve stub for ReOpenFile and add small test +# | * [#47668] Logos 8 (.NET/WPF 4.7.2 application) fails to download resources (needs ReOpenFile implementation) # | # | Modified files: # | * dlls/kernel32/tests/file.c, dlls/kernelbase/file.c # | if test "$enable_kernelbase_ReOpenFile" -eq 1; then - patch_apply kernelbase-ReOpenFile/0001-kernelbase-Improve-stub-for-ReOpenFile-and-add-small.patch + patch_apply kernelbase-ReOpenFile/0001-kernelbase-Implement-ReOpenFile.patch ( - printf '%s\n' '+ { "Louis Lenders", "kernelbase: Improve stub for ReOpenFile and add small test.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "kernelbase: Implement ReOpenFile().", 1 },'; ) >> "$patchlist" fi diff --git a/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch b/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch index 09bc7b97..90a0bbd4 100644 --- a/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch +++ b/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch @@ -1,4 +1,4 @@ -From 36d71109397421a6f2fefd82cf431b0897ebb389 Mon Sep 17 00:00:00 2001 +From 79d25c2b499fb98239acd7cc0af19bb0eee7577c Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 16 Dec 2016 18:10:30 +0800 Subject: [PATCH] gdiplus/tests: Add some tests for loading TIFF images in @@ -9,11 +9,11 @@ Subject: [PATCH] gdiplus/tests: Add some tests for loading TIFF images in 1 file changed, 181 insertions(+) diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c -index fc5dcbbe..dce61e16 100644 +index cb7de3009..a1b141223 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c -@@ -5483,6 +5483,186 @@ todo_wine - HeapFree(GetProcessHeap(), 0, data); +@@ -5525,6 +5525,186 @@ static void test_graphics_clear(void) + GdipDisposeImage((GpImage *)bitmap); } +#include "pshpack2.h" @@ -199,7 +199,7 @@ index fc5dcbbe..dce61e16 100644 START_TEST(image) { HMODULE mod = GetModuleHandleA("gdiplus.dll"); -@@ -5507,6 +5687,7 @@ START_TEST(image) +@@ -5549,6 +5729,7 @@ START_TEST(image) pGdipBitmapGetHistogram = (void*)GetProcAddress(mod, "GdipBitmapGetHistogram"); pGdipImageSetAbort = (void*)GetProcAddress(mod, "GdipImageSetAbort"); @@ -208,5 +208,5 @@ index fc5dcbbe..dce61e16 100644 test_png_color_formats(); test_supported_encoders(); -- -2.20.1 +2.24.0