[PATCH 10/10] kernel32: Implement CheckRemoteDebuggerPresent().

Henri Verbeet hverbeet at codeweavers.com
Sun Mar 14 15:53:28 CDT 2010


---
 dlls/kernel32/debugger.c       |   16 ++++++++++++-
 dlls/kernel32/tests/debugger.c |   44 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/dlls/kernel32/debugger.c b/dlls/kernel32/debugger.c
index d732d8b..e9b5992 100644
--- a/dlls/kernel32/debugger.c
+++ b/dlls/kernel32/debugger.c
@@ -21,6 +21,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "winerror.h"
 #include "wine/server.h"
 #include "kernel_private.h"
@@ -432,13 +434,23 @@ BOOL WINAPI IsDebuggerPresent(void)
  */
 BOOL WINAPI CheckRemoteDebuggerPresent(HANDLE process, PBOOL DebuggerPresent)
 {
+    NTSTATUS status;
+    DWORD_PTR port;
+
     if(!process || !DebuggerPresent)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    FIXME("(%p)->(%p): Stub!\n", process, DebuggerPresent);
-    *DebuggerPresent = FALSE;
+
+    status = NtQueryInformationProcess(process, ProcessDebugPort, &port, sizeof(port), NULL);
+    if (status != STATUS_SUCCESS)
+    {
+        SetLastError(RtlNtStatusToDosError(status));
+        return FALSE;
+    }
+
+    *DebuggerPresent = !!port;
     return TRUE;
 }
 
diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
index 8d3a802..057b977 100644
--- a/dlls/kernel32/tests/debugger.c
+++ b/dlls/kernel32/tests/debugger.c
@@ -44,6 +44,7 @@ static char** myARGV;
 static BOOL (WINAPI *pCheckRemoteDebuggerPresent)(HANDLE,PBOOL);
 static BOOL (WINAPI *pDebugActiveProcessStop)(DWORD);
 static BOOL (WINAPI *pDebugSetProcessKillOnExit)(BOOL);
+static struct _TEB * (WINAPI *pNtCurrentTeb)(void);
 
 static LONG child_failures;
 
@@ -498,6 +499,7 @@ static void doChild(int argc, char **argv)
     const char *blackbox_file;
     HANDLE parent;
     DWORD ppid;
+    BOOL debug;
     BOOL ret;
 
     blackbox_file = argv[4];
@@ -506,15 +508,46 @@ static void doChild(int argc, char **argv)
     parent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ppid);
     child_ok(!!parent, "OpenProcess failed, last error %#x.\n", GetLastError());
 
+    ret = pCheckRemoteDebuggerPresent(parent, &debug);
+    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
+    child_ok(!debug, "Expected debug == 0, got %#x.\n", debug);
+
     ret = DebugActiveProcess(ppid);
     child_ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
 
+    ret = pCheckRemoteDebuggerPresent(parent, &debug);
+    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
+    child_ok(debug, "Expected debug != 0, got %#x.\n", debug);
+
     ret = pDebugActiveProcessStop(ppid);
     child_ok(ret, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());
 
+    ret = pCheckRemoteDebuggerPresent(parent, &debug);
+    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
+    child_ok(!debug, "Expected debug == 0, got %#x.\n", debug);
+
     ret = CloseHandle(parent);
     child_ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
 
+    ret = IsDebuggerPresent();
+    child_ok(ret, "Expected ret != 0, got %#x.\n", ret);
+    ret = pCheckRemoteDebuggerPresent(GetCurrentProcess(), &debug);
+    child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
+    child_ok(debug, "Expected debug != 0, got %#x.\n", debug);
+
+    if (pNtCurrentTeb)
+    {
+        pNtCurrentTeb()->Peb->BeingDebugged = FALSE;
+
+        ret = IsDebuggerPresent();
+        child_ok(!ret, "Expected ret != 0, got %#x.\n", ret);
+        ret = pCheckRemoteDebuggerPresent(GetCurrentProcess(), &debug);
+        child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
+        child_ok(debug, "Expected debug != 0, got %#x.\n", debug);
+
+        pNtCurrentTeb()->Peb->BeingDebugged = TRUE;
+    }
+
     blackbox.failures = child_failures;
     save_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
 }
@@ -526,13 +559,14 @@ static void test_debug_loop(int argc, char **argv)
     char blackbox_file[MAX_PATH];
     PROCESS_INFORMATION pi;
     STARTUPINFOA si;
+    BOOL debug;
     DWORD pid;
     char *cmd;
     BOOL ret;
 
-    if (!pDebugActiveProcessStop)
+    if (!pDebugActiveProcessStop || !pCheckRemoteDebuggerPresent)
     {
-        win_skip("DebugActiveProcessStop not available, skipping test.\n");
+        win_skip("DebugActiveProcessStop or CheckRemoteDebuggerPresent not available, skipping test.\n");
         return;
     }
 
@@ -551,6 +585,10 @@ static void test_debug_loop(int argc, char **argv)
 
     HeapFree(GetProcessHeap(), 0, cmd);
 
+    ret = pCheckRemoteDebuggerPresent(pi.hProcess, &debug);
+    ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
+    ok(debug, "Expected debug != 0, got %#x.\n", debug);
+
     for (;;)
     {
         DEBUG_EVENT ev;
@@ -586,6 +624,8 @@ START_TEST(debugger)
     pCheckRemoteDebuggerPresent=(void*)GetProcAddress(hdll, "CheckRemoteDebuggerPresent");
     pDebugActiveProcessStop=(void*)GetProcAddress(hdll, "DebugActiveProcessStop");
     pDebugSetProcessKillOnExit=(void*)GetProcAddress(hdll, "DebugSetProcessKillOnExit");
+    hdll=GetModuleHandle("ntdll.dll");
+    if (hdll) pNtCurrentTeb = (void*)GetProcAddress(hdll, "NtCurrentTeb");
 
     myARGC=winetest_get_mainargs(&myARGV);
     if (myARGC >= 3 && strcmp(myARGV[2], "crash") == 0)
-- 
1.6.4.4




More information about the wine-patches mailing list