Andrey Turkin : kernel32: Send debug strings to system-wide monitor.

Alexandre Julliard julliard at winehq.org
Tue Oct 6 10:35:50 CDT 2009


Module: wine
Branch: master
Commit: 02ce96f425642e7863f15350dad2139ab5c040c1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=02ce96f425642e7863f15350dad2139ab5c040c1

Author: Andrey Turkin <andrey.turkin at gmail.com>
Date:   Mon Oct  5 21:42:36 2009 +0400

kernel32: Send debug strings to system-wide monitor.

---

 dlls/kernel32/debugger.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/dlls/kernel32/debugger.c b/dlls/kernel32/debugger.c
index f0dae2d..50a7428 100644
--- a/dlls/kernel32/debugger.c
+++ b/dlls/kernel32/debugger.c
@@ -240,6 +240,10 @@ BOOL WINAPI DebugActiveProcessStop( DWORD pid )
  */
 void WINAPI OutputDebugStringA( LPCSTR str )
 {
+    static HANDLE DBWinMutex = NULL;
+    static BOOL mutex_inited = FALSE;
+
+    /* send string to attached debugger */
     SERVER_START_REQ( output_debug_string )
     {
         req->string  = wine_server_client_ptr( str );
@@ -247,7 +251,82 @@ void WINAPI OutputDebugStringA( LPCSTR str )
         wine_server_call( req );
     }
     SERVER_END_REQ;
+
     WARN("%s\n", str);
+
+    /* send string to a system-wide monitor */
+    /* FIXME should only send to monitor if no debuggers are attached */
+
+    if (!mutex_inited)
+    {
+        /* first call to OutputDebugString, initialize mutex handle */
+        static const WCHAR mutexname[] = {'D','B','W','i','n','M','u','t','e','x',0};
+        HANDLE mutex = CreateMutexExW( NULL, mutexname, 0, SYNCHRONIZE );
+        if (mutex)
+        {
+            if (InterlockedCompareExchangePointer( &DBWinMutex, mutex, 0 ) != 0)
+            {
+                /* someone beat us here... */
+                CloseHandle( mutex );
+            }
+        }
+        mutex_inited = TRUE;
+    }
+
+    if (DBWinMutex)
+    {
+        static const WCHAR shmname[] = {'D','B','W','I','N','_','B','U','F','F','E','R',0};
+        static const WCHAR eventbuffername[] = {'D','B','W','I','N','_','B','U','F','F','E','R','_','R','E','A','D','Y',0};
+        static const WCHAR eventdataname[] = {'D','B','W','I','N','_','D','A','T','A','_','R','E','A','D','Y',0};
+        HANDLE mapping;
+
+        mapping = OpenFileMappingW( FILE_MAP_WRITE, FALSE, shmname );
+        if (mapping)
+        {
+            LPVOID buffer;
+            HANDLE eventbuffer, eventdata;
+
+            buffer = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
+            eventbuffer = OpenEventW( SYNCHRONIZE, FALSE, eventbuffername );
+            eventdata = OpenEventW( EVENT_MODIFY_STATE, FALSE, eventdataname );
+
+            if (buffer && eventbuffer && eventdata)
+            {
+                /* monitor is present, synchronize with other OutputDebugString invokations */
+                WaitForSingleObject( DBWinMutex, INFINITE );
+
+                /* acquire control over the buffer */
+                if (WaitForSingleObject( eventbuffer, 10000 ) == WAIT_OBJECT_0)
+                {
+                    int str_len;
+                    struct _mon_buffer_t {
+                        DWORD pid;
+                        char buffer[1];
+                    } *mon_buffer = (struct _mon_buffer_t*) buffer;
+
+                    str_len = strlen( str );
+                    if (str_len > (4096 - sizeof(DWORD) - 1))
+                        str_len = 4096 - sizeof(DWORD) - 1;
+
+                    mon_buffer->pid = GetCurrentProcessId();
+                    memcpy( mon_buffer->buffer, str, str_len );
+                    mon_buffer->buffer[str_len] = 0;
+
+                    /* signal data ready */
+                    SetEvent( eventdata );
+                }
+                ReleaseMutex( DBWinMutex );
+            }
+
+            if (buffer)
+                UnmapViewOfFile( buffer );
+            if (eventbuffer)
+                CloseHandle( eventbuffer );
+            if (eventdata)
+                CloseHandle( eventdata );
+            CloseHandle( mapping );
+        }
+    }
 }
 
 




More information about the wine-cvs mailing list