- Implement, export and NDKize: DbgUiGetThreadDebugObject, DbgUiDebugActiveProcess...
authorAlex Ionescu <aionescu@gmail.com>
Wed, 28 Jun 2006 17:02:37 +0000 (17:02 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Wed, 28 Jun 2006 17:02:37 +0000 (17:02 +0000)
- Make CheckRemoteDebuggerPresent fail if no process was specified.
- Implement DebugActiveProcess, DebugActiveProcessStop, DebugBreakProcess, DebugSetProcessKillOnExit.
- Add *.vcproj to ignore lists.

svn path=/trunk/; revision=22675

reactos/dll/ntdll/dbg/dbgui.c
reactos/dll/ntdll/def/ntdll.def
reactos/dll/win32/kernel32/debug/break.c [deleted file]
reactos/dll/win32/kernel32/debug/debugger.c
reactos/dll/win32/kernel32/include/kernel32.h
reactos/dll/win32/kernel32/kernel32.rbuild
reactos/dll/win32/kernel32/misc/console.c
reactos/include/ndk/dbgkfuncs.h
reactos/include/ndk/umfuncs.h
reactos/tools/nci/sysfuncs.lst

index 33c37b2..b1d3423 100644 (file)
@@ -1,9 +1,9 @@
 /*\r
- * COPYRIGHT:       See COPYING in the top level directory\r
- * PROJECT:         ReactOS kernel\r
- * FILE:            lib/ntdll/dbg/dbgui.c\r
- * PURPOSE:         User-Mode DbgUI Support\r
- * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)\r
+ * PROJECT:         ReactOS NT Layer/System API\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            dll/ntdll/dbg/dbgui.c\r
+ * PURPOSE:         Native Wrappers for the NT Debug Implementation\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
  */\r
 \r
 /* INCLUDES *****************************************************************/\r
@@ -135,4 +135,52 @@ DbgUiIssueRemoteBreakin(HANDLE Process)
     return Status;\r
 }\r
 \r
+/*\r
+ * @implemented\r
+ */\r
+HANDLE\r
+NTAPI\r
+DbgUiGetThreadDebugObject(VOID)\r
+{\r
+    /* Just return the handle from the TEB */\r
+    return NtCurrentTeb()->DbgSsReserved[0];\r
+}\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+DbgUiDebugActiveProcess(IN HANDLE Process)\r
+{\r
+    NTSTATUS Status;\r
+\r
+    /* Tell the kernel to start debugging */\r
+    Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[0]);\r
+    if (NT_SUCCESS(Status))\r
+    {\r
+        /* Now break-in the process */\r
+        Status = DbgUiIssueRemoteBreakin(Process);\r
+        if (!NT_SUCCESS(Status))\r
+        {\r
+            /* We couldn't break-in, cancel debugging */\r
+            DbgUiStopDebugging(Process);\r
+        }\r
+    }\r
+\r
+    /* Return status */\r
+    return Status;\r
+}\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+DbgUiStopDebugging(IN HANDLE Process)\r
+{\r
+    /* Call the kernel to remove the debug object */\r
+    return NtRemoveProcessDebug(Process, NtCurrentTeb()->DbgSsReserved[0]);\r
+}\r
+\r
 /* EOF */\r
index 8c9f10e..c0d5eaf 100644 (file)
@@ -24,10 +24,13 @@ DbgBreakPoint@0
 DbgPrint
 DbgPrintEx
 DbgPrompt@12
+DbgUiDebugActiveProcess@4
 DbgUiConnectToDbg@0
 DbgUiContinue@8
+DbgUiGetThreadDebugObject@0
 DbgUiIssueRemoteBreakin@4
 DbgUiRemoteBreakin@0
+DbgUiStopDebugging@4
 DbgUiWaitStateChange@8
 DbgUserBreakPoint@0
 KiRaiseUserExceptionDispatcher@0
@@ -230,6 +233,7 @@ NtSetEaFile@16
 NtSetEvent@8
 NtSetHighEventPair@4
 NtSetHighWaitLowEventPair@4
+NtSetInformationDebugObject@20
 NtSetInformationFile@20
 NtSetInformationJobObject@16
 NtSetInformationKey@16
diff --git a/reactos/dll/win32/kernel32/debug/break.c b/reactos/dll/win32/kernel32/debug/break.c
deleted file mode 100644 (file)
index c91b62f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/kernel32/debug/debugger.c
- * PURPOSE:         DebugBreakProcess()
- * PROGRAMMER:      KJK::Hyperion <noog@libero.it>
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <k32.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-WINBASEAPI BOOL WINAPI DebugBreakProcess(HANDLE Process)
-{
- NTSTATUS nErrCode = DbgUiIssueRemoteBreakin(Process);
-
- if(!NT_SUCCESS(nErrCode))
- {
-  SetLastErrorByStatus(nErrCode);
-  return FALSE;
- }
-
- return TRUE;
-}
-
-/* EOF */
index b827b7b..4a9688b 100644 (file)
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/kernel32/debug/debugger.c
- * PURPOSE:         Win32 Debugger API
- * PROGRAMMER:      Thomas Weidenmueller
- *                  KJK::Hyperion
+/*
+ * PROJECT:         ReactOS Win32 Base API
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            dll/win32/kernel32/debug/debugger.c
+ * PURPOSE:         Wrappers for the NT Debug Implementation
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
  */
 
-/* INCLUDES ******************************************************************/
+/* INCLUDES *****************************************************************/
 
 #include <k32.h>
 
+#define NDEBUG
+#include "debug.h"
+
 /* FUNCTIONS *****************************************************************/
 
 /*
  * @implemented
  */
-BOOL WINAPI
-CheckRemoteDebuggerPresent (
-    HANDLE hProcess,
-    PBOOL pbDebuggerPresent
-    )
+BOOL
+WINAPI
+CheckRemoteDebuggerPresent(IN HANDLE hProcess,
+                           OUT PBOOL pbDebuggerPresent)
 {
-  HANDLE DebugPort;
-  NTSTATUS Status;
+    HANDLE DebugPort;
+    NTSTATUS Status;
 
-  if (pbDebuggerPresent == NULL)
-  {
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
-  }
-
-  Status = NtQueryInformationProcess(hProcess,
-                                     ProcessDebugPort,
-                                     (PVOID)&DebugPort,
-                                     sizeof(HANDLE),
-                                     NULL);
-  if (NT_SUCCESS(Status))
-  {
-    *pbDebuggerPresent = ((DebugPort != NULL) ? TRUE : FALSE);
-    return TRUE;
-  }
+    /* Make sure we have an output and process*/
+    if (!(pbDebuggerPresent) || !(hProcess))
+    {
+        /* Fail */
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 
-  SetLastErrorByStatus(Status);
-  return FALSE;
-}
+    /* Check if the process has a debug object/port */
+    Status = NtQueryInformationProcess(hProcess,
+                                       ProcessDebugPort,
+                                       (PVOID)&DebugPort,
+                                       sizeof(HANDLE),
+                                       NULL);
+    if (NT_SUCCESS(Status))
+    {
+        /* Return the current state */
+        *pbDebuggerPresent = (DebugPort) ? TRUE : FALSE;
+        return TRUE;
+    }
 
+    /* Otherwise, fail */
+    SetLastErrorByStatus(Status);
+    return FALSE;
+}
 
 /*
  * @implemented
  */
-BOOL WINAPI
-ContinueDebugEvent (
-    DWORD dwProcessId,
-    DWORD dwThreadId,
-    DWORD dwContinueStatus
-    )
+BOOL
+WINAPI
+ContinueDebugEvent(IN DWORD dwProcessId,
+                   IN DWORD dwThreadId,
+                   IN DWORD dwContinueStatus)
 {
-  CLIENT_ID ClientId;
-  NTSTATUS Status;
+    CLIENT_ID ClientId;
+    NTSTATUS Status;
 
-  ClientId.UniqueProcess = (HANDLE)dwProcessId;
-  ClientId.UniqueThread = (HANDLE)dwThreadId;
+    /* Set the Client ID */
+    ClientId.UniqueProcess = (HANDLE)dwProcessId;
+    ClientId.UniqueThread = (HANDLE)dwThreadId;
 
-  Status = DbgUiContinue(&ClientId, dwContinueStatus);
-  if (!NT_SUCCESS(Status))
-  {
-    SetLastErrorByStatus(Status);
-    return FALSE;
-  }
+    /* Continue debugging */
+    Status = DbgUiContinue(&ClientId, dwContinueStatus);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
 
-  return TRUE;
+    /* Succes */
+    return TRUE;
 }
 
+HANDLE
+ProcessIdToHandle(IN DWORD dwProcessId)
+{
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE Handle;
+    CLIENT_ID ClientId;
+
+    /* If we don't have a PID, look it up */
+    if (dwProcessId == 0xFFFFFFFF) dwProcessId = (DWORD)CsrGetProcessId();
+
+    /* Open a handle to the process */
+    ClientId.UniqueProcess = (HANDLE)dwProcessId;
+    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+    Status = NtOpenProcess(&Handle,
+                           PROCESS_ALL_ACCESS,
+                           &ObjectAttributes,
+                           &ClientId);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        SetLastErrorByStatus(Status);
+        return 0;
+    }
+
+    /* Return the handle */
+    return Handle;
+}
 
 /*
- * NOTE: I'm not sure if the function is complete.
- *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
-DebugActiveProcess(
-    DWORD dwProcessId
-    )
+DebugActiveProcess(IN DWORD dwProcessId)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
+    NTSTATUS Status;
+    HANDLE Handle;
+
+    /* Connect to the debugger */
+    Status = DbgUiConnectToDbg();
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
 
+    /* Get the process handle */
+    Handle = ProcessIdToHandle(dwProcessId);
+    if (!Handle) return FALSE;
+
+    /* Now debug the process */
+    Status = DbgUiDebugActiveProcess(Handle);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    /* Success */
+    return TRUE;
+}
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
-DebugActiveProcessStop (
-    DWORD dwProcessId
-    )
+DebugActiveProcessStop(IN DWORD dwProcessId)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
+    NTSTATUS Status;
+    HANDLE Handle;
+
+    /* Get the process handle */
+    Handle = ProcessIdToHandle(dwProcessId);
+    if (!Handle) return FALSE;
+
+    /* Now stop debgging the process */
+    Status = DbgUiStopDebugging(Handle);
+    NtClose(Handle);
+
+    /* Check for failure */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        SetLastError(ERROR_ACCESS_DENIED);
+        return FALSE;
+    }
 
+    /* Success */
+    return TRUE;
+}
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
-DebugSetProcessKillOnExit (
-    BOOL KillOnExit
-    )
+DebugBreakProcess(IN HANDLE Process)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    NTSTATUS Status;
+
+    /* Send the breakin request */
+    Status = DbgUiIssueRemoteBreakin(Process);
+    if(!NT_SUCCESS(Status))
+    {
+        /* Failure */
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    /* Success */
+    return TRUE;
 }
 
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+DebugSetProcessKillOnExit(IN BOOL KillOnExit)
+{
+    HANDLE Handle;
+    NTSTATUS Status;
+    ULONG State;
+
+    /* Get the debug object */
+    Handle = DbgUiGetThreadDebugObject();
+    if (!Handle)
+    {
+        /* Fail */
+        SetLastErrorByStatus(STATUS_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    /* Now set the kill-on-exit state */
+    State = KillOnExit;
+    Status = NtSetInformationDebugObject(Handle,
+                                         DebugObjectKillProcessOnExitInformation,
+                                         &State,
+                                         sizeof(State),
+                                         NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        SetLastError(Status);
+        return FALSE;
+    }
+
+    /* Success */
+    return TRUE;
+}
 
 /*
  * @implemented
@@ -126,22 +242,20 @@ BOOL
 WINAPI
 IsDebuggerPresent (VOID)
 {
-  return (BOOL)NtCurrentPeb()->BeingDebugged;
+    return (BOOL)NtCurrentPeb()->BeingDebugged;
 }
 
-
 /*
  * @unimplemented
  */
 BOOL
 WINAPI
-WaitForDebugEvent (
-    LPDEBUG_EVENT lpDebugEvent,
-    DWORD dwMilliseconds
-    )
+WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent,
+                  DWORD dwMilliseconds)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    /* FIXME: TODO */
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 /* EOF */
index 5decc1c..9966f31 100755 (executable)
@@ -63,6 +63,9 @@ BOOL STDCALL VerifyConsoleIoHandle(HANDLE Handle);
 
 BOOL STDCALL CloseConsoleHandle(HANDLE Handle);
 
+HANDLE STDCALL
+GetConsoleInputWaitHandle (VOID);
+
 HANDLE STDCALL OpenConsoleW (LPWSTR wsName,
                             DWORD  dwDesiredAccess,
                             BOOL   bInheritHandle,
index f1d4195..603704f 100644 (file)
@@ -10,7 +10,6 @@
        <define name="WINVER">0x502</define>
        <pch>k32.h</pch>
        <directory name="debug">
-               <file>break.c</file>
                <file>debugger.c</file>
                <file>output.c</file>
        </directory>
index ed52f71..2f91486 100644 (file)
@@ -567,7 +567,7 @@ GetConsoleHardwareState (HANDLE     hConsole,
 /*
  * @implemented
  */
-DWORD STDCALL
+HANDLE STDCALL
 GetConsoleInputWaitHandle (VOID)
      /*
       * Undocumented
@@ -585,7 +585,7 @@ GetConsoleInputWaitHandle (VOID)
       SetLastErrorByStatus(Status);
       return 0;
     }
-  return (DWORD) Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
+  return Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
 }
 
 
index b53cdf7..a00efca 100644 (file)
@@ -23,10 +23,19 @@ Author:
 // Dependencies
 //
 #include <umtypes.h>
+#include <dbgktypes.h>
 
 //
 // Native calls
 //
+NTSYSCALLAPI
+NTSTATUS
+NTAPI
+NtDebugActiveProcess(
+    IN HANDLE Process,
+    IN HANDLE DebugObject
+);
+
 NTSYSCALLAPI
 NTSTATUS
 NTAPI
@@ -56,6 +65,33 @@ NtWaitForDebugEvent(
     OUT PDBGUI_WAIT_STATE_CHANGE StateChange
 );
 
+NTSYSCALLAPI
+NTSTATUS
+NTAPI
+NtRemoveProcessDebug(
+    IN HANDLE Process,
+    IN HANDLE DebugObject
+);
+
+NTSYSCALLAPI
+NTSTATUS
+NTAPI
+NtSetInformationDebugObject(
+    IN HANDLE DebugObject,
+    IN DEBUGOBJECTINFOCLASS InformationClass,
+    IN PVOID Information,
+    IN ULONG InformationLength,
+    OUT PULONG ReturnLength OPTIONAL
+);
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwDebugActiveProcess(
+    IN HANDLE Process,
+    IN HANDLE DebugObject
+);
+
 NTSYSAPI
 NTSTATUS
 NTAPI
@@ -75,6 +111,14 @@ ZwDebugContinue(
     IN NTSTATUS ContinueStatus
 );
 
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwRemoveProcessDebug(
+    IN HANDLE Process,
+    IN HANDLE DebugObject
+);
+
 NTSYSAPI
 NTSTATUS
 NTAPI
@@ -84,4 +128,15 @@ ZwWaitForDebugEvent(
     IN PLARGE_INTEGER Timeout OPTIONAL,
     OUT PDBGUI_WAIT_STATE_CHANGE StateChange
 );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwSetInformationDebugObject(
+    IN HANDLE DebugObject,
+    IN DEBUGOBJECTINFOCLASS InformationClass,
+    IN PVOID Information,
+    IN ULONG InformationLength,
+    OUT PULONG ReturnLength OPTIONAL
+);
 #endif
index 3747f39..1850090 100644 (file)
@@ -89,6 +89,12 @@ CsrFreeCaptureBuffer(
     struct _CSR_CAPTURE_BUFFER *CaptureBuffer
 );
 
+HANDLE
+NTAPI
+CsrGetProcessId(
+    VOID
+);
+
 NTSTATUS
 NTAPI
 CsrNewThread(VOID);
@@ -139,6 +145,18 @@ DbgUiContinue(
     IN ULONG ContinueStatus
 );
 
+NTSTATUS
+NTAPI
+DbgUiDebugActiveProcess(
+    IN HANDLE Process
+);
+
+NTSTATUS
+NTAPI
+DbgUiStopDebugging(
+    IN HANDLE Process
+);
+
 NTSTATUS
 NTAPI
 DbgUiWaitStateChange(
@@ -158,6 +176,12 @@ DbgUiIssueRemoteBreakin(
     IN HANDLE Process
 );
 
+HANDLE
+NTAPI
+DbgUiGetThreadDebugObject(
+    VOID
+);
+
 //
 // Loader Functions
 //
index 57afeb9..b8c2e5e 100644 (file)
@@ -42,6 +42,7 @@ NtCreateThread 8
 NtCreateTimer 4
 NtCreateToken 13
 NtCreateWaitablePort 5
+NtDebugActiveProcess 2
 NtDebugContinue 3
 NtDelayExecution 2
 NtDeleteAtom 1
@@ -162,6 +163,7 @@ NtRegisterThreadTerminatePort 1
 NtReleaseMutant 2
 NtReleaseSemaphore 3
 NtRemoveIoCompletion 5
+NtRemoveProcessDebug 2
 NtReplaceKey 3
 NtReplyPort 2
 NtReplyWaitReceivePort 4
@@ -188,6 +190,7 @@ NtSetEaFile 4
 NtSetEvent 2
 NtSetHighEventPair 1
 NtSetHighWaitLowEventPair 1
+NtSetInformationDebugObject 5
 NtSetInformationFile 5
 NtSetInformationKey 4
 NtSetInformationJobObject 4