[PATCH 08/11] wineandroid: Move device thread to dllmain.c.
Jacek Caban
wine at gitlab.winehq.org
Mon Jun 6 19:33:07 CDT 2022
From: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
dlls/wineandroid.drv/android.h | 3 ++
dlls/wineandroid.drv/device.c | 71 ++++++++-------------------
dlls/wineandroid.drv/dllmain.c | 89 +++++++++++++++++++++++++++++++++-
dlls/wineandroid.drv/init.c | 3 ++
dlls/wineandroid.drv/unixlib.h | 16 ++++++
5 files changed, 130 insertions(+), 52 deletions(-)
diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h
index 2a09d4195ef..c73ab6bc765 100644
--- a/dlls/wineandroid.drv/android.h
+++ b/dlls/wineandroid.drv/android.h
@@ -115,6 +115,9 @@ extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_fla
/* unixlib interface */
extern NTSTATUS android_create_desktop( void *arg ) DECLSPEC_HIDDEN;
+extern NTSTATUS android_dispatch_ioctl( void *arg ) DECLSPEC_HIDDEN;
+extern NTSTATUS android_java_init( void *arg ) DECLSPEC_HIDDEN;
+extern NTSTATUS android_java_uninit( void *arg ) DECLSPEC_HIDDEN;
extern unsigned int screen_width DECLSPEC_HIDDEN;
extern unsigned int screen_height DECLSPEC_HIDDEN;
diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c
index b4f332d2cef..b49b691b27a 100644
--- a/dlls/wineandroid.drv/device.c
+++ b/dlls/wineandroid.drv/device.c
@@ -47,8 +47,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(android);
#define SYNC_IOC_WAIT _IOW('>', 0, __s32)
#endif
-extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event );
-static HANDLE stop_event;
static HANDLE thread;
static JNIEnv *jni_env;
static HWND capture_window;
@@ -243,7 +241,8 @@ static inline BOOL is_in_desktop_process(void)
static inline DWORD current_client_id(void)
{
- return HandleToUlong( PsGetCurrentProcessId() );
+ DWORD client_id = PtrToUlong( NtUserGetThreadInfo()->driver_data );
+ return client_id ? client_id : GetCurrentProcessId();
}
static inline BOOL is_client_in_process(void)
@@ -1116,8 +1115,10 @@ static const ioctl_func ioctl_funcs[] =
setCursor_ioctl, /* IOCTL_SET_CURSOR */
};
-static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp )
+NTSTATUS android_dispatch_ioctl( void *arg )
{
+ struct ioctl_params *params = arg;
+ IRP *irp = params->irp;
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
DWORD code = (irpsp->Parameters.DeviceIoControl.IoControlCode - ANDROID_IOCTL(0)) >> 2;
@@ -1130,9 +1131,11 @@ static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp )
if (in_size >= sizeof(*header))
{
irp->IoStatus.Information = 0;
+ NtUserGetThreadInfo()->driver_data = UlongToHandle( params->client_id );
irp->IoStatus.u.Status = func( irp->AssociatedIrp.SystemBuffer, in_size,
irpsp->Parameters.DeviceIoControl.OutputBufferLength,
&irp->IoStatus.Information );
+ NtUserGetThreadInfo()->driver_data = 0;
}
else irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
}
@@ -1141,72 +1144,38 @@ static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp )
FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode );
irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
}
- IoCompleteRequest( irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
-static NTSTATUS CALLBACK init_android_driver( DRIVER_OBJECT *driver, UNICODE_STRING *name )
+NTSTATUS android_java_init( void *arg )
{
- static const WCHAR device_nameW[] = {'\\','D','e','v','i','c','e','\\','W','i','n','e','A','n','d','r','o','i','d',0 };
- static const WCHAR device_linkW[] = {'\\','?','?','\\','W','i','n','e','A','n','d','r','o','i','d',0 };
-
- UNICODE_STRING nameW, linkW;
- DEVICE_OBJECT *device;
- NTSTATUS status;
-
- driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ioctl_callback;
-
- RtlInitUnicodeString( &nameW, device_nameW );
- RtlInitUnicodeString( &linkW, device_linkW );
-
- if ((status = IoCreateDevice( driver, 0, &nameW, 0, 0, FALSE, &device ))) return status;
- return IoCreateSymbolicLink( &linkW, &nameW );
-}
-
-static DWORD CALLBACK device_thread( void *arg )
-{
- static const WCHAR driver_nameW[] = {'\\','D','r','i','v','e','r','\\','W','i','n','e','A','n','d','r','o','i','d',0 };
-
- HANDLE start_event = arg;
- UNICODE_STRING nameW;
- NTSTATUS status;
JavaVM *java_vm;
- DWORD ret;
-
- TRACE( "starting process %x\n", GetCurrentProcessId() );
- if (!(java_vm = *p_java_vm)) return 0; /* not running under Java */
+ if (!(java_vm = *p_java_vm)) return STATUS_UNSUCCESSFUL; /* not running under Java */
init_java_thread( java_vm );
-
create_desktop_window( NtUserGetDesktopWindow() );
+ return STATUS_SUCCESS;
+}
- RtlInitUnicodeString( &nameW, driver_nameW );
- if ((status = IoCreateDriver( &nameW, init_android_driver )))
- {
- FIXME( "failed to create driver error %x\n", status );
- return status;
- }
-
- stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
- SetEvent( start_event );
+NTSTATUS android_java_uninit( void *arg )
+{
+ JavaVM *java_vm;
- ret = wine_ntoskrnl_main_loop( stop_event );
+ if (!(java_vm = *p_java_vm)) return STATUS_UNSUCCESSFUL; /* not running under Java */
wrap_java_call();
(*java_vm)->DetachCurrentThread( java_vm );
unwrap_java_call();
- return ret;
+ return STATUS_SUCCESS;
}
void start_android_device(void)
{
- HANDLE handles[2];
-
- handles[0] = CreateEventW( NULL, TRUE, FALSE, NULL );
- handles[1] = thread = CreateThread( NULL, 0, device_thread, handles[0], 0, NULL );
- WaitForMultipleObjects( 2, handles, FALSE, INFINITE );
- CloseHandle( handles[0] );
+ /* FIXME: use KeUserModeCallback instead */
+ NTSTATUS (WINAPI *func)(void *, ULONG) =
+ ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[client_start_device];
+ func( NULL, 0 );
}
diff --git a/dlls/wineandroid.drv/dllmain.c b/dlls/wineandroid.drv/dllmain.c
index 42719798f33..37539fa5756 100644
--- a/dlls/wineandroid.drv/dllmain.c
+++ b/dlls/wineandroid.drv/dllmain.c
@@ -19,9 +19,89 @@
*/
#include <stdarg.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
+#include "winioctl.h"
+#include "ddk/wdm.h"
#include "unixlib.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(android);
+
+
+extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event );
+static HANDLE stop_event;
+static HANDLE thread;
+
+
+static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp )
+{
+ struct ioctl_params params = { .irp = irp, .client_id = HandleToUlong(PsGetCurrentProcessId()) };
+ NTSTATUS status = ANDROID_CALL( dispatch_ioctl, ¶ms );
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ return status;
+}
+
+static NTSTATUS CALLBACK init_android_driver( DRIVER_OBJECT *driver, UNICODE_STRING *name )
+{
+ static const WCHAR device_nameW[] = {'\\','D','e','v','i','c','e','\\','W','i','n','e','A','n','d','r','o','i','d',0 };
+ static const WCHAR device_linkW[] = {'\\','?','?','\\','W','i','n','e','A','n','d','r','o','i','d',0 };
+
+ UNICODE_STRING nameW, linkW;
+ DEVICE_OBJECT *device;
+ NTSTATUS status;
+
+ driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ioctl_callback;
+
+ RtlInitUnicodeString( &nameW, device_nameW );
+ RtlInitUnicodeString( &linkW, device_linkW );
+
+ if ((status = IoCreateDevice( driver, 0, &nameW, 0, 0, FALSE, &device ))) return status;
+ return IoCreateSymbolicLink( &linkW, &nameW );
+}
+
+static DWORD CALLBACK device_thread( void *arg )
+{
+ static const WCHAR driver_nameW[] = {'\\','D','r','i','v','e','r','\\','W','i','n','e','A','n','d','r','o','i','d',0 };
+
+ HANDLE start_event = arg;
+ UNICODE_STRING nameW;
+ NTSTATUS status;
+ DWORD ret;
+
+ TRACE( "starting process %x\n", GetCurrentProcessId() );
+
+ if (ANDROID_CALL( java_init, NULL )) return 0; /* not running under Java */
+
+ RtlInitUnicodeString( &nameW, driver_nameW );
+ if ((status = IoCreateDriver( &nameW, init_android_driver )))
+ {
+ FIXME( "failed to create driver error %x\n", status );
+ return status;
+ }
+
+ stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
+ SetEvent( start_event );
+
+ ret = wine_ntoskrnl_main_loop( stop_event );
+
+ ANDROID_CALL( java_uninit, NULL );
+ return ret;
+}
+
+static NTSTATUS WINAPI android_start_device(void *param, ULONG size)
+{
+ HANDLE handles[2];
+
+ handles[0] = CreateEventW( NULL, TRUE, FALSE, NULL );
+ handles[1] = thread = CreateThread( NULL, 0, device_thread, handles[0], 0, NULL );
+ WaitForMultipleObjects( 2, handles, FALSE, INFINITE );
+ CloseHandle( handles[0] );
+ return HandleToULong( thread );
+}
/***********************************************************************
@@ -29,10 +109,17 @@
*/
BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
{
+ void **callback_table;
+
if (reason == DLL_PROCESS_ATTACH) return TRUE;
DisableThreadLibraryCalls( inst );
- return !ANDROID_CALL(init, NULL);
+ if (ANDROID_CALL( init, NULL )) return FALSE;
+
+ callback_table = NtCurrentTeb()->Peb->KernelCallbackTable;
+ callback_table[client_start_device] = android_start_device;
+
+ return TRUE;
}
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index 3739d4e4cb4..b5f0b69fcec 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -604,7 +604,10 @@ static HRESULT android_init( void *arg )
const unixlib_entry_t __wine_unix_call_funcs[] =
{
android_create_desktop,
+ android_dispatch_ioctl,
android_init,
+ android_java_init,
+ android_java_uninit,
};
diff --git a/dlls/wineandroid.drv/unixlib.h b/dlls/wineandroid.drv/unixlib.h
index 10fe401dea0..2838047f4fe 100644
--- a/dlls/wineandroid.drv/unixlib.h
+++ b/dlls/wineandroid.drv/unixlib.h
@@ -22,10 +22,26 @@
enum android_funcs
{
unix_create_desktop,
+ unix_dispatch_ioctl,
unix_init,
+ unix_java_init,
+ unix_java_uninit,
unix_funcs_count
};
/* FIXME: Use __wine_unix_call when the rest of the stack is ready */
extern NTSTATUS unix_call( enum android_funcs func, void *arg ) DECLSPEC_HIDDEN;
#define ANDROID_CALL(func, params) unix_call( unix_ ## func, params )
+
+/* android_ioctl params */
+struct ioctl_params
+{
+ struct _IRP *irp;
+ DWORD client_id;
+};
+
+
+enum
+{
+ client_start_device = NtUserDriverCallbackFirst,
+};
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/193
More information about the wine-devel
mailing list