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

Henri Verbeet hverbeet at codeweavers.com
Fri Mar 5 05:28:13 CST 2010


---
 dlls/kernel32/debugger.c       |   15 ++++++++++--
 dlls/kernel32/tests/debugger.c |   44 ++++++++++++++++++++++++++++++++++++++-
 server/debugger.c              |   12 ++++++++++
 server/protocol.def            |    8 +++++++
 4 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/dlls/kernel32/debugger.c b/dlls/kernel32/debugger.c
index d732d8b..bf9334e 100644
--- a/dlls/kernel32/debugger.c
+++ b/dlls/kernel32/debugger.c
@@ -432,14 +432,23 @@ BOOL WINAPI IsDebuggerPresent(void)
  */
 BOOL WINAPI CheckRemoteDebuggerPresent(HANDLE process, PBOOL DebuggerPresent)
 {
+    BOOL ret;
+
     if(!process || !DebuggerPresent)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    FIXME("(%p)->(%p): Stub!\n", process, DebuggerPresent);
-    *DebuggerPresent = FALSE;
-    return TRUE;
+
+    SERVER_START_REQ( is_debugger_present )
+    {
+        req->handle = wine_server_obj_handle( process );
+        if ((ret = !wine_server_call_err( req )))
+            *DebuggerPresent = reply->debugger_present;
+    }
+    SERVER_END_REQ;
+
+    return ret;
 }
 
 /***********************************************************************
diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
index d37217a..36e1498 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;
     }
 
@@ -548,6 +582,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;
@@ -583,6 +621,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)
diff --git a/server/debugger.c b/server/debugger.c
index 727f3be..fcb7fd8 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -721,3 +721,15 @@ DECL_HANDLER(set_debugger_kill_on_exit)
     }
     current->debug_ctx->kill_on_exit = req->kill_on_exit;
 }
+
+/* check if the process is being debugged */
+DECL_HANDLER(is_debugger_present)
+{
+    struct process *process;
+
+    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
+    {
+        reply->debugger_present = !!process->debugger;
+        release_object( process );
+    }
+}
diff --git a/server/protocol.def b/server/protocol.def
index 04f6e2b..6e5e8cb 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1620,6 +1620,14 @@ enum char_info_mode
 @END
 
 
+/* check if the process is being debugged */
+ at REQ(is_debugger_present)
+    obj_handle_t handle;        /* process handle */
+ at REPLY
+    int          debugger_present;
+ at END
+
+
 /* Read data from a process address space */
 @REQ(read_process_memory)
     obj_handle_t handle;       /* process handle */
-- 
1.6.4.4




More information about the wine-patches mailing list