Henri Verbeet : kernel32: Implement CheckRemoteDebuggerPresent().
Alexandre Julliard
julliard at winehq.org
Mon Mar 15 12:19:43 CDT 2010
Module: wine
Branch: master
Commit: ef058b3030db46601b5a4a532c481da116ce32d6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ef058b3030db46601b5a4a532c481da116ce32d6
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Sun Mar 14 21:53:28 2010 +0100
kernel32: Implement CheckRemoteDebuggerPresent().
---
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)
More information about the wine-cvs
mailing list