[PATCH v8 0/8] MR10569: wineandroid: move ioctl handling to dedicated Java-only thread
Move ioctl handling out of the Wine APC/unixlib execution path into a dedicated Java-only thread without Wine context. On Android 10+ a number of syscalls are restricted inside the activity process via seccomp, while processes started via fork/exec are not subject to the same limitations. Decoupling ioctl handling from the Wine context is required to eventually run this code outside of the activity process. This change introduces a new transport and execution model where ioctl dispatch no longer depends on Wine thread state, preparing for moving the Android backend into a separate process. The refactor is intentionally split into multiple bisect-safe commits to keep intermediate states functional while gradually migrating the dispatch path. Since this is a fairly large chunk of work, I’d like to make sure we’re aligned before continuing. -- v8: wineandroid: drop dlsym for ntdll globals wineandroid: remove legacy unixlib ioctl backend wineandroid: drop old ioctl backend startup and switch to socket transport wineandroid: add socket-based ioctl backend (unused) wineandroid: add reply_fd plumbing to ioctl handlers wineandroid: move native window registration to surface_changed wineandroid: migrate ioctl dispatch logging to Android log https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Pass the client pid explicitly in ioctl_android_dequeueBuffer and remove the extra client_id plumbing from the ioctl dispatch path. The pid is only needed for dequeueBuffer handle duplication, so there is no need to thread it through ioctl dispatch state or the Java createWindow/setParent calls. This simplifies the dispatch path and makes pid handling explicit at the single call site that requires it. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/WineActivity.java | 12 ++++++------ dlls/wineandroid.drv/device.c | 27 +++++++++----------------- dlls/wineandroid.drv/dllmain.c | 3 +-- dlls/wineandroid.drv/unixlib.h | 8 -------- 4 files changed, 16 insertions(+), 34 deletions(-) diff --git a/dlls/wineandroid.drv/WineActivity.java b/dlls/wineandroid.drv/WineActivity.java index fd73ff009bf..fc0c13be396 100644 --- a/dlls/wineandroid.drv/WineActivity.java +++ b/dlls/wineandroid.drv/WineActivity.java @@ -779,7 +779,7 @@ public void create_desktop_view() wine_config_changed( getResources().getConfiguration().densityDpi ); } - public void create_window( int hwnd, boolean is_desktop, boolean opengl, int parent, int pid ) + public void create_window( int hwnd, boolean is_desktop, boolean opengl, int parent ) { WineWindow win = get_window( hwnd ); if (win == null) @@ -803,7 +803,7 @@ public void destroy_window( int hwnd ) if (win != null) win.destroy(); } - public void set_window_parent( int hwnd, int parent, int pid ) + public void set_window_parent( int hwnd, int parent ) { WineWindow win = get_window( hwnd ); if (win == null) return; @@ -836,9 +836,9 @@ public void createDesktopView() runOnUiThread( new Runnable() { public void run() { create_desktop_view(); }} ); } - public void createWindow( final int hwnd, final boolean is_desktop, final boolean opengl, final int parent, final int pid ) + public void createWindow( final int hwnd, final boolean is_desktop, final boolean opengl, final int parent ) { - runOnUiThread( new Runnable() { public void run() { create_window( hwnd, is_desktop, opengl, parent, pid ); }} ); + runOnUiThread( new Runnable() { public void run() { create_window( hwnd, is_desktop, opengl, parent ); }} ); } public void destroyWindow( final int hwnd ) @@ -846,9 +846,9 @@ public void destroyWindow( final int hwnd ) runOnUiThread( new Runnable() { public void run() { destroy_window( hwnd ); }} ); } - public void setParent( final int hwnd, final int parent, final int pid ) + public void setParent( final int hwnd, final int parent ) { - runOnUiThread( new Runnable() { public void run() { set_window_parent( hwnd, parent, pid ); }} ); + runOnUiThread( new Runnable() { public void run() { set_window_parent( hwnd, parent ); }} ); } public void setCursor( final int id, final int width, final int height, diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 6131ee627b5..bf362d7f5ac 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -155,6 +155,7 @@ struct ioctl_android_window_pos_changed struct ioctl_android_dequeueBuffer { struct ioctl_header hdr; + DWORD pid; HANDLE handle; int buffer_id; int generation; @@ -222,12 +223,6 @@ static inline BOOL is_in_desktop_process(void) return thread != NULL; } -static inline DWORD current_client_id(void) -{ - DWORD client_id = NtUserGetThreadInfo()->driver_data; - return client_id ? client_id : GetCurrentProcessId(); -} - #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; @@ -608,7 +603,6 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U jobject object; struct ioctl_android_create_window *res = data; struct native_win_data *win_data; - DWORD pid = current_client_id(); if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER; @@ -617,10 +611,10 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U TRACE( "hwnd %08x opengl %u parent %08x\n", res->hdr.hwnd, res->hdr.opengl, res->parent ); - if (!(object = load_java_method( &method, "createWindow", "(IZZII)V" ))) return STATUS_NOT_SUPPORTED; + if (!(object = load_java_method( &method, "createWindow", "(IZZI)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->is_desktop, res->hdr.opengl, res->parent, pid ); + (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->is_desktop, res->hdr.opengl, res->parent ); unwrap_java_call(); return STATUS_SUCCESS; } @@ -718,7 +712,7 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, int sv[2] = { -1, -1 }; HANDLE local = 0; OBJECT_ATTRIBUTES attr = { .Length = sizeof(attr) }; - CLIENT_ID cid = { .UniqueProcess = UlongToHandle( current_client_id() ) }; + CLIENT_ID cid = { .UniqueProcess = UlongToHandle( res->pid ) }; HANDLE process; if (!ahb) @@ -948,7 +942,6 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size jobject object; struct ioctl_android_set_window_parent *res = data; struct native_win_data *win_data; - DWORD pid = current_client_id(); if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER; @@ -956,10 +949,10 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size TRACE( "hwnd %08x parent %08x\n", res->hdr.hwnd, res->parent ); - if (!(object = load_java_method( &method, "setParent", "(III)V" ))) return STATUS_NOT_SUPPORTED; + if (!(object = load_java_method( &method, "setParent", "(II)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent, pid ); + (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent ); unwrap_java_call(); return STATUS_SUCCESS; } @@ -1035,8 +1028,7 @@ static const ioctl_func ioctl_funcs[] = NTSTATUS android_dispatch_ioctl( void *arg ) { - struct ioctl_params *params = arg; - IRP *irp = params->irp; + IRP *irp = arg; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); DWORD code = (irpsp->Parameters.DeviceIoControl.IoControlCode - ANDROID_IOCTL(0)) >> 2; @@ -1049,11 +1041,9 @@ NTSTATUS android_dispatch_ioctl( void *arg ) if (in_size >= sizeof(*header)) { irp->IoStatus.Information = 0; - NtUserGetThreadInfo()->driver_data = params->client_id; irp->IoStatus.Status = func( irp->AssociatedIrp.SystemBuffer, in_size, irpsp->Parameters.DeviceIoControl.OutputBufferLength, &irp->IoStatus.Information ); - NtUserGetThreadInfo()->driver_data = 0; } else irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } @@ -1156,11 +1146,12 @@ static int dequeueBuffer( struct ANativeWindow *window, struct ANativeWindowBuff res.hdr.hwnd = HandleToLong( win->hwnd ); res.hdr.opengl = win->opengl; + res.pid = GetCurrentProcessId(); res.handle = 0; res.buffer_id = -1; res.generation = 0; - ret = android_ioctl( IOCTL_DEQUEUE_BUFFER, &res, sizeof(res.hdr), &res, &size ); + ret = android_ioctl( IOCTL_DEQUEUE_BUFFER, &res, size, &res, &size ); if (ret) return ret; if (size < sizeof(res)) return -EINVAL; diff --git a/dlls/wineandroid.drv/dllmain.c b/dlls/wineandroid.drv/dllmain.c index d9cd94338a0..7f6d04e83df 100644 --- a/dlls/wineandroid.drv/dllmain.c +++ b/dlls/wineandroid.drv/dllmain.c @@ -37,8 +37,7 @@ static HANDLE stop_event; 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 ); + NTSTATUS status = ANDROID_CALL( dispatch_ioctl, irp ); IoCompleteRequest( irp, IO_NO_INCREMENT ); return status; } diff --git a/dlls/wineandroid.drv/unixlib.h b/dlls/wineandroid.drv/unixlib.h index 46c59f8f201..39a4df58283 100644 --- a/dlls/wineandroid.drv/unixlib.h +++ b/dlls/wineandroid.drv/unixlib.h @@ -39,14 +39,6 @@ struct init_params }; -/* android_ioctl params */ -struct ioctl_params -{ - struct _IRP *irp; - DWORD client_id; -}; - - /* android_register_window params */ struct register_window_params { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Route ioctl dispatch related logging in device.c through __android_log_print and map WINEDEBUG levels to Android log priorities. Initialize a per-module verbosity level from the Wine debug channel and use it to filter logcat output, preserving the effective debug level without relying on Wine debug macros at call sites. This prepares the ioctl dispatch path for execution outside of the Wine context (e.g. on the Android activity thread), where the standard Wine debug infrastructure is not available. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/android.h | 1 + dlls/wineandroid.drv/device.c | 89 ++++++++++++++++++++++++---------- dlls/wineandroid.drv/init.c | 1 + 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 00061cf2812..8cec766f1eb 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -119,6 +119,7 @@ enum android_window_messages WM_ANDROID_REFRESH = WM_WINE_FIRST_DRIVER_MSG, }; +extern void init_android_log_verbosity(void); extern void init_ahardwarebuffers(void); extern HWND get_capture_window(void); extern void init_monitors( int width, int height ); diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index bf362d7f5ac..d55825f2caa 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -48,6 +48,45 @@ WINE_DEFAULT_DEBUG_CHANNEL(android); +static int android_log_verbosity = ANDROID_LOG_VERBOSE; + +void init_android_log_verbosity(void) +{ + struct __wine_debug_channel *ch = &__wine_dbch_android; + + if (__WINE_GET_DEBUGGING(_TRACE, ch)) + android_log_verbosity = ANDROID_LOG_VERBOSE; + else if (__WINE_GET_DEBUGGING(_FIXME, ch)) + android_log_verbosity = ANDROID_LOG_WARN; + else if (__WINE_GET_DEBUGGING(_WARN, ch)) + android_log_verbosity = ANDROID_LOG_WARN; + else if (__WINE_GET_DEBUGGING(_ERR, ch)) + android_log_verbosity = ANDROID_LOG_ERROR; + else + android_log_verbosity = ANDROID_LOG_SILENT; +} + +#define __LOG(prio, ...) \ + do { if ((ANDROID_LOG_ ## prio) >= android_log_verbosity) \ + p__android_log_print( ANDROID_LOG_ ## prio, "wine", __VA_ARGS__ ); } while (0) +#define _INFO(...) __LOG(INFO, __VA_ARGS__) +#define _DEBUG(...) __LOG(DEBUG, __VA_ARGS__) +#define _WARN(...) __LOG(WARN, __VA_ARGS__) +#define _FIXME(...) __LOG(WARN, "FIXME: " __VA_ARGS__) +#define _TRACE(...) __LOG(VERBOSE, __VA_ARGS__) +#define _ERR(...) __LOG(ERROR, __VA_ARGS__) +static inline const char *_wine_dbgstr_rect( const RECT *rect ) +{ + enum { N = 4 }; + static __thread char buf[N][64]; + static __thread int idx; + char *ret = buf[idx++ % N]; + + if (!rect) return "(null)"; + snprintf( ret, 64, "(%d,%d)-(%d,%d)", (int)rect->left, (int)rect->top, (int)rect->right, (int)rect->bottom ); + return ret; +} + #define DECL_FUNCPTR(f) static typeof(f) * p##f = NULL struct AHardwareBuffer* ANativeWindowBuffer_getHardwareBuffer(struct ANativeWindowBuffer* anwb) __INTRODUCED_IN(26); @@ -273,7 +312,7 @@ static struct native_win_data *get_native_win_data( HWND hwnd, BOOL opengl ) struct native_win_data *data = data_map[data_map_idx( hwnd, opengl )]; if (data && data->hwnd == hwnd && !data->opengl == !opengl) return data; - WARN( "unknown win %p opengl %u\n", hwnd, opengl ); + _WARN( "unknown win %p opengl %u\n", hwnd, opengl ); return NULL; } @@ -373,7 +412,7 @@ static int register_buffer( struct native_win_data *win, struct AHardwareBuffer i = win->buffer_lru[NB_CACHED_BUFFERS - 1]; assert( i < NB_CACHED_BUFFERS ); - TRACE( "%p %p evicting buffer %p id %d from cache\n", + _TRACE( "%p %p evicting buffer %p id %d from cache\n", win->hwnd, win->parent, win->buffers[i], i ); pAHardwareBuffer_release(win->buffers[i]); } @@ -382,7 +421,7 @@ static int register_buffer( struct native_win_data *win, struct AHardwareBuffer pAHardwareBuffer_acquire(buffer); *is_new = 1; - TRACE( "%p %p %p -> %d\n", win->hwnd, win->parent, buffer, i ); + _TRACE( "%p %p %p -> %d\n", win->hwnd, win->parent, buffer, i ); done: insert_buffer_lru( win, i ); @@ -393,7 +432,7 @@ static struct ANativeWindowBuffer *get_registered_buffer( struct native_win_data { if (id < 0 || id >= NB_CACHED_BUFFERS || !win->buffers[id]) { - ERR( "unknown buffer %d for %p %p\n", id, win->hwnd, win->parent ); + _ERR( "unknown buffer %d for %p %p\n", id, win->hwnd, win->parent ); return NULL; } return anwb_from_ahb(win->buffers[id]); @@ -429,7 +468,7 @@ static struct native_win_data *create_native_win_data( HWND hwnd, BOOL opengl ) if (data) { - WARN( "data for %p not freed correctly\n", data->hwnd ); + _WARN( "data for %p not freed correctly\n", data->hwnd ); free_native_win_data( data ); } if (!(data = calloc( 1, sizeof(*data) ))) return NULL; @@ -456,7 +495,7 @@ NTSTATUS android_register_window( void *arg ) { pANativeWindow_release( win ); if (data) NtUserPostMessage( hwnd, WM_ANDROID_REFRESH, opengl, 0 ); - TRACE( "%p -> %p win %p (unchanged)\n", hwnd, data, win ); + _TRACE( "%p -> %p win %p (unchanged)\n", hwnd, data, win ); return 0; } @@ -469,7 +508,7 @@ NTSTATUS android_register_window( void *arg ) win->setSwapInterval( win, data->swap_interval ); unwrap_java_call(); NtUserPostMessage( hwnd, WM_ANDROID_REFRESH, opengl, 0 ); - TRACE( "%p -> %p win %p\n", hwnd, data, win ); + _TRACE( "%p -> %p win %p\n", hwnd, data, win ); return 0; } @@ -535,7 +574,7 @@ static NTSTATUS android_error_to_status( int err ) case -EBADMSG: return STATUS_INVALID_DEVICE_REQUEST; case -EWOULDBLOCK: return STATUS_DEVICE_NOT_READY; default: - FIXME( "unmapped error %d\n", err ); + _FIXME( "unmapped error %d\n", err ); return STATUS_UNSUCCESSFUL; } } @@ -559,7 +598,7 @@ static int status_to_android_error( unsigned int status ) case STATUS_INVALID_DEVICE_REQUEST: return -EBADMSG; case STATUS_DEVICE_NOT_READY: return -EWOULDBLOCK; default: - FIXME( "unmapped status %08x\n", status ); + _FIXME( "unmapped status %08x\n", status ); return -EINVAL; } } @@ -578,7 +617,7 @@ static jobject load_java_method( jmethodID *method, const char *name, const char unwrap_java_call(); if (!*method) { - FIXME( "method %s not found\n", name ); + _FIXME( "method %s not found\n", name ); return NULL; } } @@ -609,7 +648,7 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U if (!(win_data = create_native_win_data( LongToHandle(res->hdr.hwnd), res->hdr.opengl ))) return STATUS_NO_MEMORY; - TRACE( "hwnd %08x opengl %u parent %08x\n", res->hdr.hwnd, res->hdr.opengl, res->parent ); + _TRACE( "hwnd %08x opengl %u parent %08x\n", res->hdr.hwnd, res->hdr.opengl, res->parent ); if (!(object = load_java_method( &method, "createWindow", "(IZZI)V" ))) return STATUS_NOT_SUPPORTED; @@ -630,7 +669,7 @@ static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, win_data = get_ioctl_native_win_data( &res->hdr ); - TRACE( "hwnd %08x opengl %u\n", res->hdr.hwnd, res->hdr.opengl ); + _TRACE( "hwnd %08x opengl %u\n", res->hdr.hwnd, res->hdr.opengl ); if (!(object = load_java_method( &method, "destroyWindow", "(I)V" ))) return STATUS_NOT_SUPPORTED; @@ -649,9 +688,9 @@ static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_siz if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER; - TRACE( "hwnd %08x win %s client %s visible %s style %08x flags %08x after %08x owner %08x\n", - res->hdr.hwnd, wine_dbgstr_rect(&res->window_rect), wine_dbgstr_rect(&res->client_rect), - wine_dbgstr_rect(&res->visible_rect), res->style, res->flags, res->after, res->owner ); + _TRACE( "hwnd %08x win %s client %s visible %s style %08x flags %08x after %08x owner %08x\n", + res->hdr.hwnd, _wine_dbgstr_rect(&res->window_rect), _wine_dbgstr_rect(&res->client_rect), + _wine_dbgstr_rect(&res->visible_rect), res->style, res->flags, res->after, res->owner ); if (!(object = load_java_method( &method, "windowPosChanged", "(IIIIIIIIIIIIIIIII)V" ))) return STATUS_NOT_SUPPORTED; @@ -690,17 +729,17 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, unwrap_java_call(); if (ret) { - ERR( "%08x failed %d\n", res->hdr.hwnd, ret ); + _ERR( "%08x failed %d\n", res->hdr.hwnd, ret ); return android_error_to_status( ret ); } if (!buffer) { - TRACE( "got invalid buffer\n" ); + _TRACE( "got invalid buffer\n" ); return STATUS_UNSUCCESSFUL; } - TRACE( "%08x got buffer %p fence %d\n", res->hdr.hwnd, buffer, fence ); + _TRACE( "%08x got buffer %p fence %d\n", res->hdr.hwnd, buffer, fence ); ahb = pANativeWindowBuffer_getHardwareBuffer( buffer ); res->buffer_id = register_buffer( win_data, ahb, &is_new ); @@ -780,7 +819,7 @@ static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, U if (!(buffer = get_registered_buffer( win_data, res->buffer_id ))) return STATUS_INVALID_HANDLE; - TRACE( "%08x buffer %p\n", res->hdr.hwnd, buffer ); + _TRACE( "%08x buffer %p\n", res->hdr.hwnd, buffer ); wrap_java_call(); ret = parent->cancelBuffer( parent, buffer, -1 ); unwrap_java_call(); @@ -803,7 +842,7 @@ static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, UL if (!(buffer = get_registered_buffer( win_data, res->buffer_id ))) return STATUS_INVALID_HANDLE; - TRACE( "%08x buffer %p\n", res->hdr.hwnd, buffer ); + _TRACE( "%08x buffer %p\n", res->hdr.hwnd, buffer ); wrap_java_call(); ret = parent->queueBuffer( parent, buffer, -1 ); unwrap_java_call(); @@ -911,7 +950,7 @@ static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_ } case NATIVE_WINDOW_LOCK: default: - FIXME( "unsupported perform op %d\n", res->operation ); + _FIXME( "unsupported perform op %d\n", res->operation ); break; } return android_error_to_status( ret ); @@ -947,7 +986,7 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size if (!(win_data = get_ioctl_native_win_data( &res->hdr ))) return STATUS_INVALID_HANDLE; - TRACE( "hwnd %08x parent %08x\n", res->hdr.hwnd, res->parent ); + _TRACE( "hwnd %08x parent %08x\n", res->hdr.hwnd, res->parent ); if (!(object = load_java_method( &method, "setParent", "(II)V" ))) return STATUS_NOT_SUPPORTED; @@ -965,7 +1004,7 @@ static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULO if (res->hdr.hwnd && !get_ioctl_native_win_data( &res->hdr )) return STATUS_INVALID_HANDLE; - TRACE( "hwnd %08x\n", res->hdr.hwnd ); + _TRACE( "hwnd %08x\n", res->hdr.hwnd ); InterlockedExchangePointer( (void **)&capture_window, LongToHandle( res->hdr.hwnd )); return STATUS_SUCCESS; @@ -987,7 +1026,7 @@ static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULON if (in_size != offsetof( struct ioctl_android_set_cursor, bits[size] )) return STATUS_INVALID_PARAMETER; - TRACE( "hwnd %08x size %d\n", res->hdr.hwnd, size ); + _TRACE( "hwnd %08x size %d\n", res->hdr.hwnd, size ); if (!(object = load_java_method( &method, "setCursor", "(IIIII[I)V" ))) return STATUS_NOT_SUPPORTED; @@ -1049,7 +1088,7 @@ NTSTATUS android_dispatch_ioctl( void *arg ) } else { - FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode ); + _FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode ); irp->IoStatus.Status = STATUS_NOT_SUPPORTED; } return STATUS_SUCCESS; diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index 303655cde58..e8cb360d032 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -386,6 +386,7 @@ static HRESULT android_init( void *arg ) object = *p_java_object; + init_android_log_verbosity(); init_ahardwarebuffers(); pthread_mutexattr_init( &attr ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Move native window registration from the APC/unixlib callback path to the direct JNI surface_changed callback. Keep WM_ANDROID_REFRESH posted from process_events() after updating the native window state. Add a temporary serialization lock around ioctl dispatch and native window registration to keep intermediate migration commits bisectable while moving this code away from the old APC execution path. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/android.h | 2 -- dlls/wineandroid.drv/device.c | 38 +++++++++++++++++----------------- dlls/wineandroid.drv/dllmain.c | 8 ------- dlls/wineandroid.drv/init.c | 3 --- dlls/wineandroid.drv/unixlib.h | 11 ---------- dlls/wineandroid.drv/window.c | 3 ++- 6 files changed, 21 insertions(+), 44 deletions(-) diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 8cec766f1eb..f87c561d2e2 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -105,8 +105,6 @@ extern BOOL has_client_surface( HWND hwnd ); extern NTSTATUS android_dispatch_ioctl( void *arg ); extern NTSTATUS android_java_init( void *arg ); extern NTSTATUS android_java_uninit( void *arg ); -extern NTSTATUS android_register_window( void *arg ); -extern PNTAPCFUNC register_window_callback; extern UINT64 start_device_callback; extern unsigned int screen_width; diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index d55825f2caa..4b06e85b865 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -109,6 +109,8 @@ static JNIEnv *jni_env; static HWND capture_window; static HWND desktop_window; +static pthread_mutex_t dispatch_ioctl_lock = PTHREAD_MUTEX_INITIALIZER; // Temporary lock for bisect-safe serialization of dispatch-related state during the APC-to-JNI registration migration. + #define ANDROIDCONTROLTYPE ((ULONG)'A') #define ANDROID_IOCTL(n) CTL_CODE(ANDROIDCONTROLTYPE, n, METHOD_BUFFERED, FILE_READ_ACCESS) @@ -395,6 +397,7 @@ static void insert_buffer_lru( struct native_win_data *win, int index ) win->buffer_lru[0] = index; } +/* Called from JNI surface_changed() on the Java thread */ static int register_buffer( struct native_win_data *win, struct AHardwareBuffer *buffer, int *is_new ) { unsigned int i; @@ -481,41 +484,36 @@ static struct native_win_data *create_native_win_data( HWND hwnd, BOOL opengl ) return data; } -NTSTATUS android_register_window( void *arg ) +/* register a native window received from the Java side for use in ioctls */ +void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL opengl ) { - struct register_window_params *params = arg; - HWND hwnd = (HWND)params->arg1; - struct ANativeWindow *win = (struct ANativeWindow *)params->arg2; - BOOL opengl = params->arg3; - struct native_win_data *data = get_native_win_data( hwnd, opengl ); + struct native_win_data *data = NULL; - if (!win) return 0; /* do nothing and hold on to the window until we get a new surface */ + pthread_mutex_lock(&dispatch_ioctl_lock); + data = get_native_win_data( hwnd, opengl ); + + if (!win) { + pthread_mutex_unlock(&dispatch_ioctl_lock); + return; /* do nothing and hold on to the window until we get a new surface */ + } if (!data || data->parent == win) { pANativeWindow_release( win ); - if (data) NtUserPostMessage( hwnd, WM_ANDROID_REFRESH, opengl, 0 ); _TRACE( "%p -> %p win %p (unchanged)\n", hwnd, data, win ); - return 0; + pthread_mutex_unlock(&dispatch_ioctl_lock); + return; } release_native_window( data ); data->parent = win; data->generation++; - wrap_java_call(); if (data->api) win->perform( win, NATIVE_WINDOW_API_CONNECT, data->api ); win->perform( win, NATIVE_WINDOW_SET_BUFFERS_FORMAT, data->buffer_format ); win->setSwapInterval( win, data->swap_interval ); - unwrap_java_call(); - NtUserPostMessage( hwnd, WM_ANDROID_REFRESH, opengl, 0 ); _TRACE( "%p -> %p win %p\n", hwnd, data, win ); - return 0; -} - -/* register a native window received from the Java side for use in ioctls */ -void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL opengl ) -{ - NtQueueApcThread( thread, register_window_callback, (ULONG_PTR)hwnd, (ULONG_PTR)win, opengl ); + pthread_mutex_unlock(&dispatch_ioctl_lock); + return; } #define LOAD_FUNCPTR(lib, func) do { \ @@ -1080,9 +1078,11 @@ NTSTATUS android_dispatch_ioctl( void *arg ) if (in_size >= sizeof(*header)) { irp->IoStatus.Information = 0; + pthread_mutex_lock(&dispatch_ioctl_lock); irp->IoStatus.Status = func( irp->AssociatedIrp.SystemBuffer, in_size, irpsp->Parameters.DeviceIoControl.OutputBufferLength, &irp->IoStatus.Information ); + pthread_mutex_unlock(&dispatch_ioctl_lock); } else irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } diff --git a/dlls/wineandroid.drv/dllmain.c b/dlls/wineandroid.drv/dllmain.c index 7f6d04e83df..d1775c4f4e4 100644 --- a/dlls/wineandroid.drv/dllmain.c +++ b/dlls/wineandroid.drv/dllmain.c @@ -90,13 +90,6 @@ static NTSTATUS WINAPI android_start_device(void *param, ULONG size) } -static void CALLBACK register_window_callback( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 ) -{ - struct register_window_params params = { .arg1 = arg1, .arg2 = arg2, .arg3 = arg3 }; - ANDROID_CALL( register_window, ¶ms ); -} - - /*********************************************************************** * dll initialisation routine */ @@ -109,7 +102,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) DisableThreadLibraryCalls( inst ); if (__wine_init_unix_call()) return FALSE; - params.register_window_callback = register_window_callback; params.start_device_callback = (UINT_PTR)android_start_device; return !ANDROID_CALL( init, ¶ms ); } diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index e8cb360d032..f4faaca2216 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -48,7 +48,6 @@ static const unsigned int screen_bpp = 32; /* we don't support other modes */ static RECT monitor_rc_work; static int device_init_done; -PNTAPCFUNC register_window_callback; UINT64 start_device_callback; typedef struct @@ -394,7 +393,6 @@ static HRESULT android_init( void *arg ) pthread_mutex_init( &win_data_mutex, &attr ); pthread_mutexattr_destroy( &attr ); - register_window_callback = params->register_window_callback; start_device_callback = params->start_device_callback; if ((java_vm = *p_java_vm)) /* running under Java */ @@ -423,7 +421,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = android_init, android_java_init, android_java_uninit, - android_register_window, }; diff --git a/dlls/wineandroid.drv/unixlib.h b/dlls/wineandroid.drv/unixlib.h index 39a4df58283..bc15911ebd9 100644 --- a/dlls/wineandroid.drv/unixlib.h +++ b/dlls/wineandroid.drv/unixlib.h @@ -25,7 +25,6 @@ enum android_funcs unix_init, unix_java_init, unix_java_uninit, - unix_register_window, unix_funcs_count }; @@ -34,15 +33,5 @@ enum android_funcs /* android_init params */ struct init_params { - PNTAPCFUNC register_window_callback; UINT64 start_device_callback; }; - - -/* android_register_window params */ -struct register_window_params -{ - UINT_PTR arg1; - UINT_PTR arg2; - UINT_PTR arg3; -}; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 97eb3004ba8..3c6a32a08a7 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -251,6 +251,7 @@ void surface_changed( JNIEnv *env, jobject obj, jint win, jobject surface, jbool data.surface.height = height; p__android_log_print( ANDROID_LOG_INFO, "wine", "surface_changed: %p %s %ux%u", data.surface.hwnd, client ? "client" : "whole", width, height ); + register_native_window( data.surface.hwnd, data.surface.window, data.surface.client ); } data.type = SURFACE_CHANGED; send_event( &data ); @@ -456,7 +457,7 @@ static int process_events( DWORD mask ) event->data.surface.window, event->data.surface.client ? "client" : "whole", event->data.surface.width, event->data.surface.height ); - register_native_window( event->data.surface.hwnd, event->data.surface.window, event->data.surface.client ); + NtUserPostMessage( event->data.surface.hwnd, WM_ANDROID_REFRESH, event->data.surface.client, 0 ); break; case MOTION_EVENT: -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Add an optional reply_fd parameter to all android ioctl handlers and propagate it through android_dispatch_ioctl and android_ioctl. This prepares the ioctl path for passing file descriptors alongside regular responses. The new parameter is not used yet and all callers pass NULL, so there is no change in behavior. This is a preparatory change with no functional impact. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/device.c | 57 ++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 4b06e85b865..73cd13ba3ad 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -634,7 +634,7 @@ static void create_desktop_view(void) unwrap_java_call(); } -static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { static jmethodID method; jobject object; @@ -656,7 +656,7 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U return STATUS_SUCCESS; } -static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { static jmethodID method; jobject object; @@ -678,7 +678,7 @@ static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, return STATUS_SUCCESS; } -static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { static jmethodID method; jobject object; @@ -702,7 +702,7 @@ static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_siz return STATUS_SUCCESS; } -static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ANativeWindow *parent; struct ioctl_android_dequeueBuffer *res = data; @@ -801,7 +801,7 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, return STATUS_SUCCESS; } -static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ioctl_android_cancelBuffer *res = data; struct ANativeWindow *parent; @@ -824,7 +824,7 @@ static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, U return android_error_to_status( ret ); } -static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ioctl_android_queueBuffer *res = data; struct ANativeWindow *parent; @@ -847,7 +847,7 @@ static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, UL return android_error_to_status( ret ); } -static NTSTATUS query_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS query_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ioctl_android_query *res = data; struct ANativeWindow *parent; @@ -867,7 +867,7 @@ static NTSTATUS query_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PT return android_error_to_status( ret ); } -static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ioctl_android_perform *res = data; struct ANativeWindow *parent; @@ -954,7 +954,7 @@ static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_ return android_error_to_status( ret ); } -static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ioctl_android_set_swap_interval *res = data; struct ANativeWindow *parent; @@ -973,7 +973,7 @@ static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size return android_error_to_status( ret ); } -static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { static jmethodID method; jobject object; @@ -994,7 +994,7 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size return STATUS_SUCCESS; } -static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { struct ioctl_android_set_capture *res = data; @@ -1008,7 +1008,7 @@ static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULO return STATUS_SUCCESS; } -static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { static jmethodID method; jobject object; @@ -1046,7 +1046,7 @@ static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULON return STATUS_SUCCESS; } -typedef NTSTATUS (*ioctl_func)( void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ); +typedef NTSTATUS (*ioctl_func)( void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ); static const ioctl_func ioctl_funcs[] = { createWindow_ioctl, /* IOCTL_CREATE_WINDOW */ @@ -1074,6 +1074,7 @@ NTSTATUS android_dispatch_ioctl( void *arg ) struct ioctl_header *header = irp->AssociatedIrp.SystemBuffer; DWORD in_size = irpsp->Parameters.DeviceIoControl.InputBufferLength; ioctl_func func = ioctl_funcs[code]; + int reply_fd = -1; if (in_size >= sizeof(*header)) { @@ -1081,7 +1082,7 @@ NTSTATUS android_dispatch_ioctl( void *arg ) pthread_mutex_lock(&dispatch_ioctl_lock); irp->IoStatus.Status = func( irp->AssociatedIrp.SystemBuffer, in_size, irpsp->Parameters.DeviceIoControl.OutputBufferLength, - &irp->IoStatus.Information ); + &irp->IoStatus.Information, &reply_fd ); pthread_mutex_unlock(&dispatch_ioctl_lock); } else irp->IoStatus.Status = STATUS_INVALID_PARAMETER; @@ -1130,7 +1131,7 @@ void start_android_device(void) /* Client-side ioctl support */ -static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size ) +static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_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; @@ -1153,6 +1154,8 @@ static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void if (InterlockedCompareExchangePointer( &device, file, NULL )) NtClose( file ); } + if (recv_fd) *recv_fd = -1; + status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &iosb, ANDROID_IOCTL(code), in, in_size, out, out_size ? *out_size : 0 ); if (status == STATUS_FILE_DELETED) @@ -1190,7 +1193,7 @@ static int dequeueBuffer( struct ANativeWindow *window, struct ANativeWindowBuff res.buffer_id = -1; res.generation = 0; - ret = android_ioctl( IOCTL_DEQUEUE_BUFFER, &res, size, &res, &size ); + ret = android_ioctl( IOCTL_DEQUEUE_BUFFER, &res, size, &res, &size, NULL ); if (ret) return ret; if (size < sizeof(res)) return -EINVAL; @@ -1246,7 +1249,7 @@ static int cancelBuffer( struct ANativeWindow *window, struct ANativeWindowBuffe cancel.hdr.hwnd = HandleToLong( win->hwnd ); cancel.hdr.opengl = win->opengl; wait_fence_and_close( fence ); - return android_ioctl( IOCTL_CANCEL_BUFFER, &cancel, sizeof(cancel), NULL, NULL ); + return android_ioctl( IOCTL_CANCEL_BUFFER, &cancel, sizeof(cancel), NULL, NULL, NULL ); } static int queueBuffer( struct ANativeWindow *window, struct ANativeWindowBuffer *buffer, int fence ) @@ -1265,7 +1268,7 @@ static int queueBuffer( struct ANativeWindow *window, struct ANativeWindowBuffer queue.hdr.hwnd = HandleToLong( win->hwnd ); queue.hdr.opengl = win->opengl; wait_fence_and_close( fence ); - return android_ioctl( IOCTL_QUEUE_BUFFER, &queue, sizeof(queue), NULL, NULL ); + return android_ioctl( IOCTL_QUEUE_BUFFER, &queue, sizeof(queue), NULL, NULL, NULL ); } static int dequeueBuffer_DEPRECATED( struct ANativeWindow *window, struct ANativeWindowBuffer **buffer ) @@ -1300,7 +1303,7 @@ static int setSwapInterval( struct ANativeWindow *window, int interval ) swap.hdr.hwnd = HandleToLong( win->hwnd ); swap.hdr.opengl = win->opengl; swap.interval = interval; - return android_ioctl( IOCTL_SET_SWAP_INT, &swap, sizeof(swap), NULL, NULL ); + return android_ioctl( IOCTL_SET_SWAP_INT, &swap, sizeof(swap), NULL, NULL, NULL ); } static int query( const ANativeWindow *window, int what, int *value ) @@ -1313,7 +1316,7 @@ static int query( const ANativeWindow *window, int what, int *value ) query.hdr.hwnd = HandleToLong( win->hwnd ); query.hdr.opengl = win->opengl; query.what = what; - ret = android_ioctl( IOCTL_QUERY, &query, sizeof(query), &query, &size ); + ret = android_ioctl( IOCTL_QUERY, &query, sizeof(query), &query, &size, NULL ); TRACE( "hwnd %p what %d got %d -> %p\n", win->hwnd, what, query.value, value ); if (!ret) *value = query.value; return ret; @@ -1455,7 +1458,7 @@ static int perform( ANativeWindow *window, int operation, ... ) break; } va_end( args ); - return android_ioctl( IOCTL_PERFORM, &perf, sizeof(perf), NULL, NULL ); + return android_ioctl( IOCTL_PERFORM, &perf, sizeof(perf), NULL, NULL, NULL ); } struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl ) @@ -1488,7 +1491,7 @@ struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl ) req.hdr.opengl = win->opengl; req.parent = get_ioctl_win_parent( NtUserGetAncestor( hwnd, GA_PARENT )); req.is_desktop = hwnd == desktop_window; - android_ioctl( IOCTL_CREATE_WINDOW, &req, sizeof(req), NULL, NULL ); + android_ioctl( IOCTL_CREATE_WINDOW, &req, sizeof(req), NULL, NULL, NULL ); return &win->win; } @@ -1521,7 +1524,7 @@ void destroy_ioctl_window( HWND hwnd, BOOL opengl ) req.hdr.hwnd = HandleToLong( hwnd ); req.hdr.opengl = opengl; - android_ioctl( IOCTL_DESTROY_WINDOW, &req, sizeof(req), NULL, NULL ); + android_ioctl( IOCTL_DESTROY_WINDOW, &req, sizeof(req), NULL, NULL, NULL ); } int ioctl_window_pos_changed( HWND hwnd, const struct window_rects *rects, @@ -1538,7 +1541,7 @@ int ioctl_window_pos_changed( HWND hwnd, const struct window_rects *rects, req.flags = flags; req.after = HandleToLong( after ); req.owner = HandleToLong( owner ); - return android_ioctl( IOCTL_WINDOW_POS_CHANGED, &req, sizeof(req), NULL, NULL ); + return android_ioctl( IOCTL_WINDOW_POS_CHANGED, &req, sizeof(req), NULL, NULL, NULL ); } int ioctl_set_window_parent( HWND hwnd, HWND parent ) @@ -1548,7 +1551,7 @@ int ioctl_set_window_parent( HWND hwnd, HWND parent ) req.hdr.hwnd = HandleToLong( hwnd ); req.hdr.opengl = FALSE; req.parent = get_ioctl_win_parent( parent ); - return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL ); + return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL, NULL ); } int ioctl_set_capture( HWND hwnd ) @@ -1557,7 +1560,7 @@ int ioctl_set_capture( HWND hwnd ) req.hdr.hwnd = HandleToLong( hwnd ); req.hdr.opengl = FALSE; - return android_ioctl( IOCTL_SET_CAPTURE, &req, sizeof(req), NULL, NULL ); + return android_ioctl( IOCTL_SET_CAPTURE, &req, sizeof(req), NULL, NULL, NULL ); } int ioctl_set_cursor( int id, int width, int height, @@ -1576,7 +1579,7 @@ int ioctl_set_cursor( int id, int width, int height, req->hotspotx = hotspotx; req->hotspoty = hotspoty; memcpy( req->bits, bits, width * height * sizeof(req->bits[0]) ); - ret = android_ioctl( IOCTL_SET_CURSOR, req, size, NULL, NULL ); + ret = android_ioctl( IOCTL_SET_CURSOR, req, size, NULL, NULL, NULL ); free( req ); return ret; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Add a socket-based backend for android ioctl dispatch. This introduces a listener thread implementation based on a Unix seqpacket socket with epoll, along with a new android_ioctl_new() client-side path supporting regular replies and optional file descriptor passing via SCM_RIGHTS. The new backend is not wired up yet and is currently unused. Existing ioctl handling remains unchanged. This is a preparatory step for migrating ioctl dispatch to a socket-based transport. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/device.c | 224 ++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 73cd13ba3ad..9b76ff20e43 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -32,6 +32,9 @@ #include <stdarg.h> #include <sys/ioctl.h> #include <sys/socket.h> +#include <sys/un.h> +#include <sys/epoll.h> +#include <sys/uio.h> #include <unistd.h> #include "ntstatus.h" @@ -163,6 +166,14 @@ struct native_win_wrapper LONG ref; }; +#define IPC_SOCKET_NAME "\0\\Device\\WineAndroid" +#define IPC_SOCKET_ADDR_LEN ((socklen_t)(offsetof(struct sockaddr_un, sun_path) + sizeof(IPC_SOCKET_NAME) - 1)) + +static const struct sockaddr_un ipc_addr = { + .sun_family = AF_UNIX, + .sun_path = IPC_SOCKET_NAME, +}; + struct ioctl_header { int hwnd; @@ -1118,6 +1129,159 @@ NTSTATUS android_java_uninit( void *arg ) return STATUS_SUCCESS; } +static void *ioctl_thread_proc(void *arg) +{ + JavaVM *java_vm; + int listen_fd, epoll_fd; + + if (!(java_vm = *p_java_vm)) return NULL; /* not running under Java */ + init_java_thread( java_vm ); + create_desktop_view(); + + listen_fd = socket( AF_UNIX, SOCK_SEQPACKET, 0 ); + if (listen_fd < 0) { + _ERR( "Failed to open server socket: %s\n", strerror(errno) ); + return NULL; + } + + if (bind( listen_fd, (const struct sockaddr *)&ipc_addr, IPC_SOCKET_ADDR_LEN ) < 0 || + listen( listen_fd, 32 ) < 0) + { + _ERR( "Failed to bind server socket: %s\n", strerror(errno) ); + close( listen_fd ); + return NULL; + } + + epoll_fd = epoll_create1( EPOLL_CLOEXEC ); + if (epoll_fd < 0) + { + _ERR( "Failed to create server epoll: %s\n", strerror(errno) ); + close( listen_fd ); + return NULL; + } + + if (epoll_ctl( epoll_fd, EPOLL_CTL_ADD, listen_fd, + &(struct epoll_event){ .events = EPOLLIN, .data.fd = listen_fd } ) < 0) + { + close( epoll_fd ); + close( listen_fd ); + return NULL; + } + + for (;;) + { + struct epoll_event events[16]; + int i, count = epoll_wait( epoll_fd, events, ARRAY_SIZE(events), -1 ); + + if (count < 0) + { + if (errno == EINTR) continue; + break; + } + + for (i = 0; i < count; i++) + { + int fd = events[i].data.fd; + + if (fd == listen_fd) + { + int client = accept( listen_fd, NULL, NULL ); + if (client < 0) + { + if (errno == EINTR) continue; + continue; + } + + if (epoll_ctl( epoll_fd, EPOLL_CTL_ADD, client, + &(struct epoll_event){ .events = EPOLLIN, .data.fd = client } ) < 0) + close( client ); + continue; + } + + if (events[i].events & (EPOLLHUP | EPOLLERR)) + { + epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL ); + close( fd ); + continue; + } + + for (;;) + { + char buffer[1024], control[CMSG_SPACE(sizeof(int))]; + int code = 0, status = -EINVAL, reply_fd = -1; + ULONG_PTR reply_size = 0; + ssize_t ret; + struct iovec iov[2] = { { &code, sizeof(code) }, { buffer, sizeof(buffer) } }; + struct iovec reply_iov[2] = { { &status, sizeof(status) }, { buffer, 0 } }; + struct msghdr msg = { NULL, 0, iov, 2, NULL, 0, 0 }; + struct msghdr reply = { NULL, 0, reply_iov, 2, NULL, 0, 0 }; + struct cmsghdr *cmsg; + + ret = recvmsg( fd, &msg, MSG_DONTWAIT ); + if (ret < 0) + { + if (errno == EINTR) continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) break; + epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL ); + close( fd ); + break; + } + + if (!ret || ret < sizeof(code)) + { + epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL ); + close( fd ); + break; + } + + ret -= sizeof(code); + + if ((unsigned int)code < NB_IOCTLS) + { + if (ret >= sizeof(struct ioctl_header)) { + pthread_mutex_lock(&dispatch_ioctl_lock); + status = status_to_android_error (ioctl_funcs[code]( buffer, ret, sizeof(buffer), &reply_size, &reply_fd )); + pthread_mutex_unlock(&dispatch_ioctl_lock); + } + } + else + { + _FIXME( "ioctl %x not supported\n", code ); + status = -ENOTSUP; + } + + reply_iov[1].iov_len = reply_size; + if (reply_fd != -1) + { + reply.msg_control = control; + reply.msg_controllen = sizeof(control); + cmsg = CMSG_FIRSTHDR( &reply ); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(reply_fd)); + memcpy( CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd) ); + reply.msg_controllen = cmsg->cmsg_len; + } + + if (sendmsg( fd, &reply, 0 ) < 0) + { + if (reply_fd != -1) close( reply_fd ); + epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL ); + close( fd ); + break; + } + + if (reply_fd != -1) close( reply_fd ); + } + } + } + + close( epoll_fd ); + close( listen_fd ); + (*java_vm)->DetachCurrentThread( java_vm ); + return NULL; +} + void start_android_device(void) { void *ret_ptr; @@ -1167,6 +1331,66 @@ static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void return status_to_android_error( status ); } +static int android_ioctl_new( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_fd ) +{ + static int device_fd = -1; + static pthread_mutex_t device_mutex = PTHREAD_MUTEX_INITIALIZER; + int status, err = -ENOENT; + ssize_t ret; + char control[CMSG_SPACE(sizeof(int))]; + struct iovec iov[2] = { { &status, sizeof(status) }, { out, out_size ? *out_size : 0 } }; + struct msghdr msg = { NULL, 0, iov, (out && out_size) ? 2 : 1, + recv_fd ? control : NULL, recv_fd ? sizeof(control) : 0, 0 }; + struct cmsghdr *cmsg; + + pthread_mutex_lock( &device_mutex ); + + if (recv_fd) *recv_fd = -1; + + if (device_fd == -1) + { + device_fd = socket( AF_UNIX, SOCK_SEQPACKET, 0 ); + if (device_fd < 0) goto done; + if (connect( device_fd, (const struct sockaddr *)&ipc_addr, IPC_SOCKET_ADDR_LEN ) < 0) + { + close( device_fd ); + device_fd = -1; + goto done; + } + } + + ret = writev( device_fd, (struct iovec[]){ { &code, sizeof(code) }, { in, in_size } }, 2 ); + if (ret <= 0 || ret != sizeof(code) + in_size) goto disconnected; + + ret = recvmsg( device_fd, &msg, 0 ); + if (ret <= 0 || ret < sizeof(status)) goto disconnected; + + if (out && out_size) *out_size = ret - sizeof(status); + err = status; + + if (recv_fd) + for (cmsg = CMSG_FIRSTHDR( &msg ); cmsg; cmsg = CMSG_NXTHDR( &msg, cmsg )) + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS && + cmsg->cmsg_len >= CMSG_LEN(sizeof(int))) + { + memcpy( recv_fd, CMSG_DATA(cmsg), sizeof(int) ); + break; + } + + goto done; + +disconnected: + close( device_fd ); + device_fd = -1; + WARN( "parent process is gone\n" ); + NtTerminateProcess( 0, 1 ); + err = -ENOENT; + +done: + pthread_mutex_unlock( &device_mutex ); + return err; +} + static void win_incRef( struct android_native_base_t *base ) { struct native_win_wrapper *win = (struct native_win_wrapper *)base; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Remove the legacy ioctl backend startup via KeUserDispatchCallback and switch fully to the socket-based transport. A dedicated listener thread is now started directly with pthread_create, and the desktop process is tracked via an explicit in_desktop_process flag. dequeueBuffer is updated to use file descriptor passing via SCM_RIGHTS, and all handle-based duplication logic is removed. The old ioctl implementation is kept as android_ioctl_old() but is no longer used. This completes the transition away from the legacy backend startup path. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/device.c | 98 +++++++---------------------------- 1 file changed, 20 insertions(+), 78 deletions(-) diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 9b76ff20e43..f5c2a83127c 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -107,7 +107,7 @@ DECL_FUNCPTR( ANativeWindowBuffer_getHardwareBuffer ); #define SYNC_IOC_WAIT _IOW('>', 0, __s32) #endif -static HANDLE thread; +static BOOL in_desktop_process; static JNIEnv *jni_env; static HWND capture_window; static HWND desktop_window; @@ -207,8 +207,6 @@ struct ioctl_android_window_pos_changed struct ioctl_android_dequeueBuffer { struct ioctl_header hdr; - DWORD pid; - HANDLE handle; int buffer_id; int generation; }; @@ -269,13 +267,7 @@ 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 */ +#if 0 /* 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) ); } @@ -290,7 +282,7 @@ static inline void init_java_thread( JavaVM *java_vm ) __asm__( "mov %0,%%fs" :: "r" (orig_fs) ); } -#elif defined(__x86_64__) +#elif 0 #include <asm/prctl.h> #include <asm/unistd.h> @@ -728,7 +720,6 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, if (!(win_data = get_ioctl_native_win_data( &res->hdr ))) return STATUS_INVALID_HANDLE; if (!(parent = win_data->parent)) return STATUS_DEVICE_NOT_READY; - res->handle = 0; res->buffer_id = -1; res->generation = 0; *ret_size = sizeof(*res); @@ -753,15 +744,10 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, res->buffer_id = register_buffer( win_data, ahb, &is_new ); res->generation = win_data->generation; - res->handle = 0; if (is_new) { int sv[2] = { -1, -1 }; - HANDLE local = 0; - OBJECT_ATTRIBUTES attr = { .Length = sizeof(attr) }; - CLIENT_ID cid = { .UniqueProcess = UlongToHandle( res->pid ) }; - HANDLE process; if (!ahb) { @@ -775,37 +761,16 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, return STATUS_UNSUCCESSFUL; } - if (NtOpenProcess( &process, PROCESS_DUP_HANDLE, &attr, &cid )) - { - close( sv[0] ); - close( sv[1] ); - wait_fence_and_close( fence ); - return STATUS_UNSUCCESSFUL; - } - - if (!wine_server_fd_to_handle( dup(sv[1]), GENERIC_READ | SYNCHRONIZE, 0, &local )) - { - NTSTATUS status = NtDuplicateObject( GetCurrentProcess(), local, process, &res->handle, 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE ); - if (status && local) NtClose( local ); - } - - NtClose( process ); - close( sv[1] ); - - if (!res->handle) - { - close( sv[0] ); - wait_fence_and_close( fence ); - return STATUS_UNSUCCESSFUL; - } - ret = pAHardwareBuffer_sendHandleToUnixSocket( ahb, sv[0] ); close( sv[0] ); if (ret) { + close( sv[1] ); wait_fence_and_close( fence ); return android_error_to_status( ret ); } + + *reply_fd = sv[1]; } wait_fence_and_close( fence ); @@ -1108,24 +1073,11 @@ NTSTATUS android_dispatch_ioctl( void *arg ) NTSTATUS android_java_init( void *arg ) { - JavaVM *java_vm; - - if (!(java_vm = *p_java_vm)) return STATUS_UNSUCCESSFUL; /* not running under Java */ - - init_java_thread( java_vm ); - create_desktop_view(); - return STATUS_SUCCESS; + return STATUS_UNSUCCESSFUL; } NTSTATUS android_java_uninit( void *arg ) { - JavaVM *java_vm; - - 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 STATUS_SUCCESS; } @@ -1135,6 +1087,7 @@ static void *ioctl_thread_proc(void *arg) int listen_fd, epoll_fd; if (!(java_vm = *p_java_vm)) return NULL; /* not running under Java */ + in_desktop_process = TRUE; init_java_thread( java_vm ); create_desktop_view(); @@ -1284,18 +1237,17 @@ static void *ioctl_thread_proc(void *arg) void start_android_device(void) { - void *ret_ptr; - ULONG ret_len; - struct dispatch_callback_params params = {.callback = start_device_callback}; - if (KeUserDispatchCallback( ¶ms, sizeof(params), &ret_ptr, &ret_len )) return; - if (ret_len == sizeof(thread)) thread = *(HANDLE *)ret_ptr; + pthread_t t; + + if (pthread_create( &t, NULL, ioctl_thread_proc, NULL ) == 0) + pthread_detach( t ); } /* Client-side ioctl support */ -static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_fd ) +static int android_ioctl_old( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_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; @@ -1331,7 +1283,7 @@ static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void return status_to_android_error( status ); } -static int android_ioctl_new( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_fd ) +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; static pthread_mutex_t device_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -1408,35 +1360,25 @@ static int dequeueBuffer( struct ANativeWindow *window, struct ANativeWindowBuff struct native_win_wrapper *win = (struct native_win_wrapper *)window; struct ioctl_android_dequeueBuffer res = {0}; DWORD size = sizeof(res); - int ret; + int ret, buffer_fd = -1; res.hdr.hwnd = HandleToLong( win->hwnd ); res.hdr.opengl = win->opengl; - res.pid = GetCurrentProcessId(); - res.handle = 0; res.buffer_id = -1; res.generation = 0; - ret = android_ioctl( IOCTL_DEQUEUE_BUFFER, &res, size, &res, &size, NULL ); + ret = android_ioctl( IOCTL_DEQUEUE_BUFFER, &res, size, &res, &size, &buffer_fd ); if (ret) return ret; if (size < sizeof(res)) return -EINVAL; if (res.buffer_id < 0 || res.buffer_id >= NB_CACHED_BUFFERS) return -EINVAL; - if (res.handle) + if (buffer_fd != -1) { AHardwareBuffer *ahb = NULL; - int fd; - - if (wine_server_handle_to_fd( res.handle, GENERIC_READ | SYNCHRONIZE, &fd, NULL )) - { - NtClose( res.handle ); - return -EINVAL; - } - NtClose( res.handle ); - ret = pAHardwareBuffer_recvHandleFromUnixSocket( fd, &ahb ); - close( fd ); + ret = pAHardwareBuffer_recvHandleFromUnixSocket( buffer_fd, &ahb ); + close( buffer_fd ); if (ret) return ret; if (win->buffers[res.buffer_id].self) @@ -1813,7 +1755,7 @@ int ioctl_set_cursor( int id, int width, int height, */ void ANDROID_SetDesktopWindow( HWND hwnd ) { - if (!is_in_desktop_process()) + if (!in_desktop_process) return; TRACE( "%p\n", hwnd ); desktop_window = hwnd; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Remove the legacy unixlib-based ioctl backend and related plumbing. This drops android_dispatch_ioctl, android_java_init/uninit, the KeUserDispatchCallback startup path, and the associated ntoskrnl driver integration. The unixlib interface is reduced to a single init entry point, and DllMain is simplified accordingly. All ioctl handling is now performed exclusively via the socket-based backend introduced earlier. This completes the removal of the legacy ioctl transport and associated Wine-specific execution context handling. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/android.h | 9 +- dlls/wineandroid.drv/device.c | 168 +-------------------------------- dlls/wineandroid.drv/dllmain.c | 76 +-------------- dlls/wineandroid.drv/init.c | 16 +--- dlls/wineandroid.drv/unixlib.h | 37 -------- 5 files changed, 5 insertions(+), 301 deletions(-) delete mode 100644 dlls/wineandroid.drv/unixlib.h diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index f87c561d2e2..bffbee75145 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -34,7 +34,7 @@ #include "winbase.h" #include "ntgdi.h" #include "wine/gdi_driver.h" -#include "unixlib.h" +#include "wine/unixlib.h" #include "android_native.h" @@ -100,13 +100,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; diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index f5c2a83127c..77817cb7141 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -107,7 +107,6 @@ DECL_FUNCPTR( ANativeWindowBuffer_getHardwareBuffer ); #define SYNC_IOC_WAIT _IOW('>', 0, __s32) #endif -static BOOL in_desktop_process; static JNIEnv *jni_env; static HWND capture_window; static HWND desktop_window; @@ -267,43 +266,6 @@ struct ioctl_android_set_cursor int bits[1]; }; -#if 0 /* 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 ) -{ - java_fs = *p_java_gdt_sel; - __asm__( "mov %%fs,%0" : "=r" (orig_fs) ); - __asm__( "mov %0,%%fs" :: "r" (java_fs) ); - (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); - if (!*p_java_gdt_sel) __asm__( "mov %%fs,%0" : "=r" (java_fs) ); - __asm__( "mov %0,%%fs" :: "r" (orig_fs) ); -} - -#elif 0 - -#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 ) -{ - arch_prctl( ARCH_GET_GS, &orig_teb ); - (*java_vm)->AttachCurrentThread( java_vm, &jni_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 ) { (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); } -#endif /* __i386__ */ - static struct native_win_data *data_map[65536]; static unsigned int data_map_idx( HWND hwnd, BOOL opengl ) @@ -612,10 +574,8 @@ static jobject load_java_method( jmethodID *method, const char *name, const char { jclass class; - wrap_java_call(); class = (*jni_env)->GetObjectClass( jni_env, object ); *method = (*jni_env)->GetMethodID( jni_env, class, name, args ); - unwrap_java_call(); if (!*method) { _FIXME( "method %s not found\n", name ); @@ -632,9 +592,7 @@ static void create_desktop_view(void) if (!(object = load_java_method( &method, "createDesktopView", "()V" ))) return; - wrap_java_call(); (*jni_env)->CallVoidMethod( jni_env, object, method ); - unwrap_java_call(); } static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) @@ -653,9 +611,7 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U if (!(object = load_java_method( &method, "createWindow", "(IZZI)V" ))) return STATUS_NOT_SUPPORTED; - wrap_java_call(); (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->is_desktop, res->hdr.opengl, res->parent ); - unwrap_java_call(); return STATUS_SUCCESS; } @@ -674,9 +630,7 @@ static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, if (!(object = load_java_method( &method, "destroyWindow", "(I)V" ))) return STATUS_NOT_SUPPORTED; - wrap_java_call(); (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd ); - unwrap_java_call(); if (win_data) free_native_win_data( win_data ); return STATUS_SUCCESS; } @@ -696,12 +650,10 @@ static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_siz if (!(object = load_java_method( &method, "windowPosChanged", "(IIIIIIIIIIIIIIIII)V" ))) return STATUS_NOT_SUPPORTED; - wrap_java_call(); (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->flags, res->after, res->owner, res->style, res->window_rect.left, res->window_rect.top, res->window_rect.right, res->window_rect.bottom, res->client_rect.left, res->client_rect.top, res->client_rect.right, res->client_rect.bottom, res->visible_rect.left, res->visible_rect.top, res->visible_rect.right, res->visible_rect.bottom ); - unwrap_java_call(); return STATUS_SUCCESS; } @@ -724,9 +676,7 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, res->generation = 0; *ret_size = sizeof(*res); - wrap_java_call(); ret = parent->dequeueBuffer( parent, &buffer, &fence ); - unwrap_java_call(); if (ret) { _ERR( "%08x failed %d\n", res->hdr.hwnd, ret ); @@ -794,9 +744,7 @@ static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, U if (!(buffer = get_registered_buffer( win_data, res->buffer_id ))) return STATUS_INVALID_HANDLE; _TRACE( "%08x buffer %p\n", res->hdr.hwnd, buffer ); - wrap_java_call(); ret = parent->cancelBuffer( parent, buffer, -1 ); - unwrap_java_call(); return android_error_to_status( ret ); } @@ -817,9 +765,7 @@ static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, UL if (!(buffer = get_registered_buffer( win_data, res->buffer_id ))) return STATUS_INVALID_HANDLE; _TRACE( "%08x buffer %p\n", res->hdr.hwnd, buffer ); - wrap_java_call(); ret = parent->queueBuffer( parent, buffer, -1 ); - unwrap_java_call(); return android_error_to_status( ret ); } @@ -837,9 +783,7 @@ static NTSTATUS query_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PT if (!(parent = win_data->parent)) return STATUS_DEVICE_NOT_READY; *ret_size = sizeof( *res ); - wrap_java_call(); ret = parent->query( parent, res->what, &res->value ); - unwrap_java_call(); return android_error_to_status( ret ); } @@ -858,57 +802,39 @@ static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_ switch (res->operation) { case NATIVE_WINDOW_SET_BUFFERS_FORMAT: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0] ); - unwrap_java_call(); if (!ret) win_data->buffer_format = res->args[0]; break; case NATIVE_WINDOW_API_CONNECT: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0] ); - unwrap_java_call(); if (!ret) win_data->api = res->args[0]; break; case NATIVE_WINDOW_API_DISCONNECT: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0] ); - unwrap_java_call(); if (!ret) win_data->api = 0; break; case NATIVE_WINDOW_SET_USAGE: case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: case NATIVE_WINDOW_SET_SCALING_MODE: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0] ); - unwrap_java_call(); break; case NATIVE_WINDOW_SET_BUFFER_COUNT: - wrap_java_call(); ret = parent->perform( parent, res->operation, (size_t)res->args[0] ); - unwrap_java_call(); break; case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0], res->args[1] ); - unwrap_java_call(); break; case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0], res->args[1], res->args[2] ); - unwrap_java_call(); break; case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: - wrap_java_call(); ret = parent->perform( parent, res->operation, res->args[0] | ((int64_t)res->args[1] << 32) ); - unwrap_java_call(); break; case NATIVE_WINDOW_CONNECT: case NATIVE_WINDOW_DISCONNECT: case NATIVE_WINDOW_UNLOCK_AND_POST: - wrap_java_call(); ret = parent->perform( parent, res->operation ); - unwrap_java_call(); break; case NATIVE_WINDOW_SET_CROP: { @@ -917,9 +843,7 @@ static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_ rect.top = res->args[1]; rect.right = res->args[2]; rect.bottom = res->args[3]; - wrap_java_call(); ret = parent->perform( parent, res->operation, &rect ); - unwrap_java_call(); break; } case NATIVE_WINDOW_LOCK: @@ -943,9 +867,7 @@ static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size win_data->swap_interval = res->interval; if (!(parent = win_data->parent)) return STATUS_SUCCESS; - wrap_java_call(); ret = parent->setSwapInterval( parent, res->interval ); - unwrap_java_call(); return android_error_to_status( ret ); } @@ -964,9 +886,7 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size if (!(object = load_java_method( &method, "setParent", "(II)V" ))) return STATUS_NOT_SUPPORTED; - wrap_java_call(); (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent ); - unwrap_java_call(); return STATUS_SUCCESS; } @@ -1005,8 +925,6 @@ static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULON if (!(object = load_java_method( &method, "setCursor", "(IIIII[I)V" ))) return STATUS_NOT_SUPPORTED; - wrap_java_call(); - if (size) { jintArray array = (*jni_env)->NewIntArray( jni_env, size ); @@ -1017,8 +935,6 @@ static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULON } else (*jni_env)->CallVoidMethod( jni_env, object, method, res->id, 0, 0, 0, 0, 0 ); - unwrap_java_call(); - return STATUS_SUCCESS; } @@ -1039,56 +955,13 @@ 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]; - int reply_fd = -1; - - if (in_size >= sizeof(*header)) - { - irp->IoStatus.Information = 0; - pthread_mutex_lock(&dispatch_ioctl_lock); - irp->IoStatus.Status = func( 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 ) -{ - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS android_java_uninit( void *arg ) -{ - return STATUS_SUCCESS; -} - static void *ioctl_thread_proc(void *arg) { JavaVM *java_vm; int listen_fd, epoll_fd; if (!(java_vm = *p_java_vm)) return NULL; /* not running under Java */ - in_desktop_process = TRUE; - init_java_thread( java_vm ); + (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); create_desktop_view(); listen_fd = socket( AF_UNIX, SOCK_SEQPACKET, 0 ); @@ -1247,42 +1120,6 @@ void start_android_device(void) /* Client-side ioctl support */ -static int android_ioctl_old( enum android_ioctl code, void *in, DWORD in_size, void *out, DWORD *out_size, int *recv_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 ); - } - - if (recv_fd) *recv_fd = -1; - - 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; @@ -1755,8 +1592,5 @@ int ioctl_set_cursor( int id, int width, int height, */ void ANDROID_SetDesktopWindow( HWND hwnd ) { - if (!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 d1775c4f4e4..b83f35e84ba 100644 --- a/dlls/wineandroid.drv/dllmain.c +++ b/dlls/wineandroid.drv/dllmain.c @@ -19,89 +19,17 @@ */ #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 */ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { - struct init_params params; - if (reason != DLL_PROCESS_ATTACH) return TRUE; DisableThreadLibraryCalls( inst ); - if (__wine_init_unix_call()) return FALSE; - - params.start_device_callback = (UINT_PTR)android_start_device; - return !ANDROID_CALL( init, ¶ms ); + return !__wine_init_unix_call(); } diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index f4faaca2216..a7706abf5e0 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -367,9 +367,8 @@ JavaVM **p_java_vm = NULL; jobject *p_java_object = NULL; unsigned short *p_java_gdt_sel = NULL; -static HRESULT android_init( void *arg ) +NTSTATUS __wine_unix_lib_init(void) { - struct init_params *params = arg; pthread_mutexattr_t attr; jclass class; jobject object; @@ -393,8 +392,6 @@ static HRESULT android_init( void *arg ) pthread_mutex_init( &win_data_mutex, &attr ); pthread_mutexattr_destroy( &attr ); - start_device_callback = params->start_device_callback; - if ((java_vm = *p_java_vm)) /* running under Java */ { #ifdef __i386__ @@ -414,14 +411,3 @@ static HRESULT android_init( void *arg ) __wine_set_user_driver( &android_drv_funcs, WINE_GDI_DRIVER_VERSION ); 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 bc15911ebd9..00000000000 --- a/dlls/wineandroid.drv/unixlib.h +++ /dev/null @@ -1,37 +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 ) - -/* android_init params */ -struct init_params -{ - UINT64 start_device_callback; -}; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
From: Twaik Yont <9674930+twaik@users.noreply.github.com> ntdll symbols used by wineandroid are already available through the link-time dependency, making the manual dlsym lookup unnecessary. Switch to direct symbol references and remove the corresponding function pointer indirection. This simplifies the code and avoids redundant runtime symbol resolution. Dynamic loading is still used for Android system libraries where appropriate. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/ntdll/unix/loader.c | 2 -- dlls/wineandroid.drv/android.h | 5 ++--- dlls/wineandroid.drv/device.c | 9 +++------ dlls/wineandroid.drv/init.c | 23 ++++------------------- 4 files changed, 9 insertions(+), 30 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 9d70aa421f0..9fe91046811 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1883,7 +1883,6 @@ static void start_main_thread(void) DECLSPEC_EXPORT JavaVM *java_vm = NULL; DECLSPEC_EXPORT jobject java_object = 0; -DECLSPEC_EXPORT unsigned short java_gdt_sel = 0; /* main Wine initialisation */ static jstring wine_init_jni( JNIEnv *env, jobject obj, jobjectArray cmdline, jobjectArray environment ) @@ -1966,7 +1965,6 @@ static jstring wine_init_jni( JNIEnv *env, jobject obj, jobjectArray cmdline, jo { unsigned short java_fs; __asm__( "mov %%fs,%0" : "=r" (java_fs) ); - if (!(java_fs & 4)) java_gdt_sel = java_fs; __asm__( "mov %0,%%fs" :: "r" (0) ); start_main_thread(); __asm__( "mov %0,%%fs" :: "r" (java_fs) ); diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index bffbee75145..d53f89c2957 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -176,9 +176,8 @@ union event_data int send_event( const union event_data *data ); -extern JavaVM **p_java_vm; -extern jobject *p_java_object; -extern unsigned short *p_java_gdt_sel; +extern JavaVM *java_vm; +extern jobject java_object; /* string helpers */ diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 77817cb7141..b1d307fd62c 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -568,13 +568,11 @@ static int status_to_android_error( unsigned int status ) static jobject load_java_method( jmethodID *method, const char *name, const char *args ) { - jobject object = *p_java_object; - if (!*method) { jclass class; - class = (*jni_env)->GetObjectClass( jni_env, object ); + class = (*jni_env)->GetObjectClass( jni_env, java_object ); *method = (*jni_env)->GetMethodID( jni_env, class, name, args ); if (!*method) { @@ -582,7 +580,7 @@ static jobject load_java_method( jmethodID *method, const char *name, const char return NULL; } } - return object; + return java_object; } static void create_desktop_view(void) @@ -957,10 +955,9 @@ static const ioctl_func ioctl_funcs[] = static void *ioctl_thread_proc(void *arg) { - JavaVM *java_vm; int listen_fd, epoll_fd; - if (!(java_vm = *p_java_vm)) return NULL; /* not running under Java */ + if (!java_vm) return NULL; /* not running under Java */ (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); create_desktop_view(); diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index a7706abf5e0..08570fb165a 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -83,7 +83,7 @@ void init_monitors( int width, int height ) wine_dbgstr_rect( &rect ), wine_dbgstr_rect( &monitor_rc_work )); /* if we're notified from Java thread, update registry */ - if (*p_java_vm) NtUserCallNoParam( NtUserCallNoParam_DisplayModeChanged ); + if (java_vm) NtUserCallNoParam( NtUserCallNoParam_DisplayModeChanged ); } @@ -167,7 +167,7 @@ void set_screen_dpi( DWORD dpi ) */ static void fetch_display_metrics(void) { - if (*p_java_vm) return; /* for Java threads it will be set when the top view is created */ + if (java_vm) return; /* for Java threads it will be set when the top view is created */ SERVER_START_REQ( get_window_rectangles ) { @@ -363,26 +363,11 @@ static void load_android_libs(void) #undef DECL_FUNCPTR #undef LOAD_FUNCPTR -JavaVM **p_java_vm = NULL; -jobject *p_java_object = NULL; -unsigned short *p_java_gdt_sel = NULL; - NTSTATUS __wine_unix_lib_init(void) { pthread_mutexattr_t attr; jclass class; - jobject object; JNIEnv *jni_env; - JavaVM *java_vm; - void *ntdll; - - if (!(ntdll = dlopen( "ntdll.so", RTLD_NOW ))) return STATUS_UNSUCCESSFUL; - - p_java_vm = dlsym( ntdll, "java_vm" ); - p_java_object = dlsym( ntdll, "java_object" ); - p_java_gdt_sel = dlsym( ntdll, "java_gdt_sel" ); - - object = *p_java_object; init_android_log_verbosity(); init_ahardwarebuffers(); @@ -392,7 +377,7 @@ NTSTATUS __wine_unix_lib_init(void) pthread_mutex_init( &win_data_mutex, &attr ); pthread_mutexattr_destroy( &attr ); - if ((java_vm = *p_java_vm)) /* running under Java */ + if (java_vm) /* running under Java */ { #ifdef __i386__ WORD old_fs; @@ -400,7 +385,7 @@ NTSTATUS __wine_unix_lib_init(void) #endif load_android_libs(); (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); - class = (*jni_env)->GetObjectClass( jni_env, object ); + class = (*jni_env)->GetObjectClass( jni_env, java_object ); (*jni_env)->RegisterNatives( jni_env, class, methods, ARRAY_SIZE( methods )); (*jni_env)->DeleteLocalRef( jni_env, class ); #ifdef __i386__ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569
Hi @julliard, could you please take a quick look at this PR when you have time and share any initial concerns or things you’d like changed first? I’m planning to rework parts of it anyway, and I now also have a version that runs not only in the emulator but on a modern real device (Android 16, Samsung S24FE). <details> <summary>Demo</summary> {width=900 height=416} </details> -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10569#note_135914
participants (2)
-
Twaik Yont -
Twaik Yont (@twaik)