From: Twaik Yont <9674930+twaik@users.noreply.github.com> Remove the old wineandroid ioctl transport based on unixlib calls and the ntoskrnl device/IRP dispatch path. This drops the android_dispatch_ioctl entrypoint, the driver creation code, and the unixlib call table, along with the associated device thread and callback-based startup path. With the socket-based dispatch thread now handling all ioctls, the old HANDLE-based transport is no longer needed. Also remove the remaining artifacts of the old execution model, including the global JNIEnv, thread tracking, and the wrap_java_call/unwrap_java_call helpers used to work around JVM/Wine TLS conflicts. Simplify initialization accordingly by using __wine_unix_lib_init() directly, making dllmain.c consistent with winex11.drv. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/android.h | 11 +-- dlls/wineandroid.drv/device.c | 147 +-------------------------------- dlls/wineandroid.drv/dllmain.c | 73 +--------------- dlls/wineandroid.drv/init.c | 16 +--- dlls/wineandroid.drv/unixlib.h | 31 ------- 5 files changed, 8 insertions(+), 270 deletions(-) delete mode 100644 dlls/wineandroid.drv/unixlib.h diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 4882ca91f8b..c79ce31a046 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -35,7 +35,8 @@ #include "winbase.h" #include "ntgdi.h" #include "wine/gdi_driver.h" -#include "unixlib.h" +#include "ntuser.h" +#include "wine/unixlib.h" #include "android_native.h" @@ -120,13 +121,6 @@ extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_h extern ANativeWindow *get_client_window( HWND hwnd ); extern BOOL has_client_surface( HWND hwnd ); -/* unixlib interface */ - -extern NTSTATUS android_dispatch_ioctl( void *arg ); -extern NTSTATUS android_java_init( void *arg ); -extern NTSTATUS android_java_uninit( void *arg ); -extern UINT64 start_device_callback; - extern unsigned int screen_width; extern unsigned int screen_height; extern RECT virtual_screen_rect; @@ -203,7 +197,6 @@ int send_event( const union event_data *data ); extern JavaVM *java_vm; extern jobject java_object; -extern unsigned short java_gdt_sel; /* string helpers */ diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 378328311a4..d95001c2e13 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -78,8 +78,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(android); #define SYNC_IOC_WAIT _IOW('>', 0, __s32) #endif -static HANDLE thread; -static JNIEnv *jni_env; static HWND capture_window; static HWND desktop_window; @@ -238,49 +236,6 @@ struct ioctl_android_set_cursor int bits[1]; }; - -static inline BOOL is_in_desktop_process(void) -{ - return thread != NULL; -} - -#ifdef __i386__ /* the Java VM uses %fs/%gs for its own purposes, so we need to wrap the calls */ - -static WORD orig_fs, java_fs; -static inline void wrap_java_call(void) { __asm__( "mov %0,%%fs" :: "r" (java_fs) ); } -static inline void unwrap_java_call(void) { __asm__( "mov %0,%%fs" :: "r" (orig_fs) ); } -static inline void init_java_thread( JavaVM *java_vm, JNIEnv** env ) -{ - java_fs = java_gdt_sel; - __asm__( "mov %%fs,%0" : "=r" (orig_fs) ); - __asm__( "mov %0,%%fs" :: "r" (java_fs) ); - (*java_vm)->AttachCurrentThread( java_vm, env, 0 ); - if (!java_gdt_sel) __asm__( "mov %%fs,%0" : "=r" (java_fs) ); - __asm__( "mov %0,%%fs" :: "r" (orig_fs) ); -} - -#elif defined(__x86_64__) - -#include <asm/prctl.h> -#include <asm/unistd.h> -static void *orig_teb, *java_teb; -static inline int arch_prctl( int func, void *ptr ) { return syscall( __NR_arch_prctl, func, ptr ); } -static inline void wrap_java_call(void) { arch_prctl( ARCH_SET_GS, java_teb ); } -static inline void unwrap_java_call(void) { arch_prctl( ARCH_SET_GS, orig_teb ); } -static inline void init_java_thread( JavaVM *java_vm, JNIEnv** env ) -{ - arch_prctl( ARCH_GET_GS, &orig_teb ); - (*java_vm)->AttachCurrentThread( java_vm, env, 0 ); - arch_prctl( ARCH_GET_GS, &java_teb ); - arch_prctl( ARCH_SET_GS, orig_teb ); -} - -#else -static inline void wrap_java_call(void) { } -static inline void unwrap_java_call(void) { } -static inline void init_java_thread( JavaVM *java_vm, JNIEnv** env ) { (*java_vm)->AttachCurrentThread( java_vm, env, 0 ); } -#endif /* __i386__ */ - static struct native_win_data *data_map[65536]; static unsigned int data_map_idx( HWND hwnd, BOOL opengl ) @@ -566,12 +521,9 @@ static void create_desktop_view( JNIEnv* env ) static jmethodID method; jobject object; - wrap_java_call(); - if (!(object = load_java_method( env, &method, "createDesktopView", "()V" ))) goto end; + if (!(object = load_java_method( env, &method, "createDesktopView", "()V" ))) return; (*env)->CallVoidMethod( env, object, method ); -end: - unwrap_java_call(); } static NTSTATUS createWindow_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) @@ -934,57 +886,6 @@ static const ioctl_func ioctl_funcs[] = setCursor_ioctl, /* IOCTL_SET_CURSOR */ }; -NTSTATUS android_dispatch_ioctl( void *arg ) -{ - IRP *irp = arg; - IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - DWORD code = (irpsp->Parameters.DeviceIoControl.IoControlCode - ANDROID_IOCTL(0)) >> 2; - - if (code < NB_IOCTLS) - { - struct ioctl_header *header = irp->AssociatedIrp.SystemBuffer; - DWORD in_size = irpsp->Parameters.DeviceIoControl.InputBufferLength; - ioctl_func func = ioctl_funcs[code]; - - if (in_size >= sizeof(*header)) - { - int reply_fd = -1; - irp->IoStatus.Information = 0; - pthread_mutex_lock(&dispatch_ioctl_lock); - irp->IoStatus.Status = func( jni_env, irp->AssociatedIrp.SystemBuffer, in_size, - irpsp->Parameters.DeviceIoControl.OutputBufferLength, - &irp->IoStatus.Information, &reply_fd ); - pthread_mutex_unlock(&dispatch_ioctl_lock); - } - else irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - } - else - { - FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode ); - irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - } - return STATUS_SUCCESS; -} - -NTSTATUS android_java_init( void *arg ) -{ - if (!java_vm) return STATUS_UNSUCCESSFUL; /* not running under Java */ - - init_java_thread( java_vm, &jni_env ); - create_desktop_view( jni_env ); - return STATUS_SUCCESS; -} - -NTSTATUS android_java_uninit( void *arg ) -{ - if (!java_vm) return STATUS_UNSUCCESSFUL; /* not running under Java */ - - wrap_java_call(); - (*java_vm)->DetachCurrentThread( java_vm ); - unwrap_java_call(); - return STATUS_SUCCESS; -} - static ALooper *looper; static JNIEnv *looper_env; /* JNIEnv for the main thread looper. Must only be used from that thread. */ @@ -1144,15 +1045,14 @@ static void *bootstrap_looper_thread( void *arg ) abort(); } + create_desktop_view( env ); + (*java_vm)->DetachCurrentThread( java_vm ); return NULL; } void start_android_device(void) { - void *ret_ptr; - ULONG ret_len; - struct dispatch_callback_params params = {.callback = start_device_callback}; pthread_t t; __wine_dbg_get_channel_flags(&__wine_dbch_android); // force lazy init of debug channel flags for use outside Wine thread context @@ -1169,50 +1069,12 @@ void start_android_device(void) _ERR("Failed to spawn looper bootstrap thread\n"); abort(); } - - if (KeUserDispatchCallback( ¶ms, sizeof(params), &ret_ptr, &ret_len )) return; - if (ret_len == sizeof(thread)) thread = *(HANDLE *)ret_ptr; - return; } /* Client-side ioctl support */ -static int android_ioctl_old( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *reply_fd ) -{ - static const WCHAR deviceW[] = { '\\','D','e','v','i','c','e','\\','W','i','n','e','A','n','d','r','o','i','d', 0 }; - static HANDLE device; - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - if (!device) - { - OBJECT_ATTRIBUTES attr; - UNICODE_STRING name = RTL_CONSTANT_STRING( deviceW ); - IO_STATUS_BLOCK io; - NTSTATUS status; - HANDLE file; - - InitializeObjectAttributes( &attr, &name, OBJ_CASE_INSENSITIVE, NULL, NULL ); - status = NtCreateFile( &file, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, - FILE_NON_DIRECTORY_FILE, NULL, 0 ); - if (status) return -ENOENT; - if (InterlockedCompareExchangePointer( &device, file, NULL )) NtClose( file ); - } - - status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &iosb, ANDROID_IOCTL(code), - in, in_size, out, out_size ? *out_size : 0 ); - if (status == STATUS_FILE_DELETED) - { - WARN( "parent process is gone\n" ); - NtTerminateProcess( 0, 1 ); - } - if (out_size) *out_size = iosb.Information; - return status_to_android_error( status ); -} - static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_fd ) { static int device_fd = -1; @@ -1684,8 +1546,5 @@ int ioctl_set_cursor( int id, int width, int height, */ void ANDROID_SetDesktopWindow( HWND hwnd ) { - if (!is_in_desktop_process()) - return; - TRACE( "%p\n", hwnd ); desktop_window = hwnd; } diff --git a/dlls/wineandroid.drv/dllmain.c b/dlls/wineandroid.drv/dllmain.c index dd2493c6f55..b83f35e84ba 100644 --- a/dlls/wineandroid.drv/dllmain.c +++ b/dlls/wineandroid.drv/dllmain.c @@ -19,76 +19,9 @@ */ #include <stdarg.h> -#include "ntstatus.h" #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 NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp ) -{ - NTSTATUS status = ANDROID_CALL( dispatch_ioctl, irp ); - IoCompleteRequest( irp, IO_NO_INCREMENT ); - return status; -} - -static NTSTATUS CALLBACK init_android_driver( DRIVER_OBJECT *driver, UNICODE_STRING *name ) -{ - UNICODE_STRING nameW = RTL_CONSTANT_STRING( L"\\Device\\WineAndroid" ); - DEVICE_OBJECT *device; - - driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ioctl_callback; - - return IoCreateDevice( driver, 0, &nameW, 0, 0, FALSE, &device ); -} - -static DWORD CALLBACK device_thread( void *arg ) -{ - HANDLE start_event = arg; - UNICODE_STRING nameW = RTL_CONSTANT_STRING( L"\\Driver\\WineAndroid" ); - NTSTATUS status; - DWORD ret; - - TRACE( "starting process %lx\n", GetCurrentProcessId() ); - - if (ANDROID_CALL( java_init, NULL )) return 0; /* not running under Java */ - - if ((status = IoCreateDriver( &nameW, init_android_driver ))) - { - FIXME( "failed to create driver error %lx\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] = CreateThread( NULL, 0, device_thread, handles[0], 0, NULL ); - WaitForMultipleObjects( 2, handles, FALSE, INFINITE ); - CloseHandle( handles[0] ); - return NtCallbackReturn( &handles[1], sizeof(handles[1]), STATUS_SUCCESS ); -} - +#include "wine/unixlib.h" /*********************************************************************** * dll initialisation routine @@ -98,7 +31,5 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) if (reason != DLL_PROCESS_ATTACH) return TRUE; DisableThreadLibraryCalls( inst ); - if (__wine_init_unix_call()) return FALSE; - - return !ANDROID_CALL( init, (void *)(UINT_PTR)android_start_device ); + return !__wine_init_unix_call(); } diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index e6efec88998..4ad3b42b0f5 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -50,8 +50,6 @@ static const unsigned int screen_bpp = 32; /* we don't support other modes */ static RECT monitor_rc_work; static int device_init_done; -UINT64 start_device_callback; - typedef struct { struct gdi_physdev dev; @@ -394,7 +392,7 @@ static void load_android_libs(void) #undef DECL_FUNCPTR #undef LOAD_FUNCPTR -static HRESULT android_init( void *arg ) +NTSTATUS __wine_unix_lib_init(void) { pthread_mutexattr_t attr; jclass class; @@ -407,8 +405,6 @@ static HRESULT android_init( void *arg ) pthread_mutex_init( &win_data_mutex, &attr ); pthread_mutexattr_destroy( &attr ); - start_device_callback = (UINT64)(UINT_PTR)arg; - if (java_vm) /* running under Java */ { #ifdef __i386__ @@ -428,13 +424,3 @@ static HRESULT android_init( void *arg ) return STATUS_SUCCESS; } -const unixlib_entry_t __wine_unix_call_funcs[] = -{ - android_dispatch_ioctl, - android_init, - android_java_init, - android_java_uninit, -}; - - -C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count ); diff --git a/dlls/wineandroid.drv/unixlib.h b/dlls/wineandroid.drv/unixlib.h deleted file mode 100644 index 7549541e48e..00000000000 --- a/dlls/wineandroid.drv/unixlib.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2022 Jacek Caban for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "ntuser.h" -#include "wine/unixlib.h" - -enum android_funcs -{ - unix_dispatch_ioctl, - unix_init, - unix_java_init, - unix_java_uninit, - unix_funcs_count -}; - -#define ANDROID_CALL(func, params) WINE_UNIX_CALL( unix_ ## func, params ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569