[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, &params );
+    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