From ef058b3030db46601b5a4a532c481da116ce32d6 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Sun, 14 Mar 2010 21:53:28 +0100 Subject: [PATCH] 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 d732d8bf07c..e9b5992e7ac 100644 --- a/dlls/kernel32/debugger.c +++ b/dlls/kernel32/debugger.c @@ -21,6 +21,8 @@ #include #include +#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 8d3a8024ca2..057b977d93c 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)