Rebase against ce7e10868a1279573acc5be5a9659d254e936b27.

This commit is contained in:
Zebediah Figura 2019-12-13 21:47:52 -06:00
parent 40d020d66e
commit e6aac5d240
7 changed files with 358 additions and 222 deletions

View File

@ -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?= <michael@fds-team.de>
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

View File

@ -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?= <michael@fds-team.de>
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( &params->ImagePathName, winevdm );
RtlInitUnicodeString( &params->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( &params->ImagePathName, comspec );
RtlInitUnicodeString( &params->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

View File

@ -0,0 +1,296 @@
From d0b5fb1fa826ede3c1b9270465601bcf981fb10b Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
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 <z.figura12@gmail.com>
---
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

View File

@ -1,144 +0,0 @@
From 540abe549f414881f5e0bd2afb0e4f81d4674850 Mon Sep 17 00:00:00 2001
From: Louis Lenders <xerox.xerox2000x@gmail.com>
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 <xerox.xerox2000x@gmail.com>
---
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

View File

@ -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)

View File

@ -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

View File

@ -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 <dmitry@baikal.ru>
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