[RFC PATCH] conhost: Register as a system process.

Torge Matthies openglfreak at googlemail.com
Mon Nov 2 15:34:53 CST 2020


I wrote a program called winestreamproxy [1] that proxys data between a
named pipe in Wine and a unix domain socket outside of Wine. This program
should automatically exit when no other non-system program is running in the
bottle/prefix if the parameter --system is supplied. For this purpose it marks
itself as a system process using __wine_make_process_system() from ntdll, and
waits on the returned event handle to exit.

This worked fine, until a change was introduced that seemingly made every
non-system process spawn a conhost.exe instance. Since conhost.exe is not
a system process, this breaks the auto-exit functionality of winestreamproxy.
I understand that using Wine-internal functions is not supported, however
the desired behavior seems hard if not impossible to implement otherwise.

Making conhost mark itself as a system process would allow the automatic exit
to work again. I don't think this would break anything, because at the point
in the bottle/prefix lifecycle where this becomes relevant there are no
non-system processes anymore, and anything else has either explicitly opted
into this behavior or not received a conhost instance in the first place.

As to why winestreamproxy is necessary at all: It allows Windows games running
under Wine to communicate with Linux-native Discord [2] and show status
messages and invite buttons on a user's profile.

[1] https://github.com/openglfreak/winestreamproxy
[2] https://discord.com/

Signed-off-by: Torge Matthies <openglfreak at googlemail.com>
---
 programs/conhost/conhost.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index 6985a9ca0b0..46b48d086d4 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -42,6 +42,8 @@ static CRITICAL_SECTION console_section = { &critsect_debug, -1, 0, 0, 0, 0 };
 static void *ioctl_buffer;
 static size_t ioctl_buffer_size;
 
+extern HANDLE CDECL __wine_make_process_system(void);
+
 static void *alloc_ioctl_buffer( size_t size )
 {
     if (size > ioctl_buffer_size)
@@ -2526,7 +2528,7 @@ static NTSTATUS process_console_ioctls( struct console *console )
 static int main_loop( struct console *console, HANDLE signal )
 {
     HANDLE signal_event = NULL;
-    HANDLE wait_handles[3];
+    HANDLE wait_handles[4];
     unsigned int wait_cnt = 0;
     unsigned short signal_id;
     IO_STATUS_BLOCK signal_io;
@@ -2544,6 +2546,7 @@ static int main_loop( struct console *console, HANDLE signal )
 
     if (!alloc_ioctl_buffer( 4096 )) return 1;
 
+    wait_handles[wait_cnt++] = __wine_make_process_system();
     wait_handles[wait_cnt++] = console->server;
     if (signal) wait_handles[wait_cnt++] = signal_event;
     if (console->input_thread) wait_handles[wait_cnt++] = console->input_thread;
@@ -2570,13 +2573,14 @@ static int main_loop( struct console *console, HANDLE signal )
         switch (res)
         {
         case WAIT_OBJECT_0:
+        case WAIT_OBJECT_0 + 1:
             EnterCriticalSection( &console_section );
             status = process_console_ioctls( console );
             LeaveCriticalSection( &console_section );
-            if (status) return 0;
+            if (status || res == WAIT_OBJECT_0) return 0;
             break;
 
-        case WAIT_OBJECT_0 + 1:
+        case WAIT_OBJECT_0 + 2:
             if (signal_io.Status || signal_io.Information != sizeof(signal_id))
             {
                 TRACE( "signaled quit\n" );
-- 
2.29.2




More information about the wine-devel mailing list