/*\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
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
-/* $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
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 */