- Implement, export and NDKize: DbgUiGetThreadDebugObject, DbgUiDebugActiveProcess, DbgUiStopDebugging, NtSetInformationDebugObject.

- Make CheckRemoteDebuggerPresent fail if no process was specified.
- Implement DebugActiveProcess, DebugActiveProcessStop, DebugBreakProcess, DebugSetProcessKillOnExit.
- Add *.vcproj to ignore lists.

svn path=/trunk/; revision=22675
This commit is contained in:
Alex Ionescu 2006-06-28 17:02:37 +00:00
parent 1a65517f18
commit 561c27e0d3
10 changed files with 340 additions and 122 deletions

View file

@ -1,9 +1,9 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS NT Layer/System API
* PROJECT: ReactOS kernel * LICENSE: GPL - See COPYING in the top level directory
* FILE: lib/ntdll/dbg/dbgui.c * FILE: dll/ntdll/dbg/dbgui.c
* PURPOSE: User-Mode DbgUI Support * PURPOSE: Native Wrappers for the NT Debug Implementation
* PROGRAMMER: Alex Ionescu (alex@relsoft.net) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -135,4 +135,52 @@ DbgUiIssueRemoteBreakin(HANDLE Process)
return Status; return Status;
} }
/*
* @implemented
*/
HANDLE
NTAPI
DbgUiGetThreadDebugObject(VOID)
{
/* Just return the handle from the TEB */
return NtCurrentTeb()->DbgSsReserved[0];
}
/*
* @implemented
*/
NTSTATUS
NTAPI
DbgUiDebugActiveProcess(IN HANDLE Process)
{
NTSTATUS Status;
/* Tell the kernel to start debugging */
Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[0]);
if (NT_SUCCESS(Status))
{
/* Now break-in the process */
Status = DbgUiIssueRemoteBreakin(Process);
if (!NT_SUCCESS(Status))
{
/* We couldn't break-in, cancel debugging */
DbgUiStopDebugging(Process);
}
}
/* Return status */
return Status;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
DbgUiStopDebugging(IN HANDLE Process)
{
/* Call the kernel to remove the debug object */
return NtRemoveProcessDebug(Process, NtCurrentTeb()->DbgSsReserved[0]);
}
/* EOF */ /* EOF */

View file

@ -24,10 +24,13 @@ DbgBreakPoint@0
DbgPrint DbgPrint
DbgPrintEx DbgPrintEx
DbgPrompt@12 DbgPrompt@12
DbgUiDebugActiveProcess@4
DbgUiConnectToDbg@0 DbgUiConnectToDbg@0
DbgUiContinue@8 DbgUiContinue@8
DbgUiGetThreadDebugObject@0
DbgUiIssueRemoteBreakin@4 DbgUiIssueRemoteBreakin@4
DbgUiRemoteBreakin@0 DbgUiRemoteBreakin@0
DbgUiStopDebugging@4
DbgUiWaitStateChange@8 DbgUiWaitStateChange@8
DbgUserBreakPoint@0 DbgUserBreakPoint@0
KiRaiseUserExceptionDispatcher@0 KiRaiseUserExceptionDispatcher@0
@ -230,6 +233,7 @@ NtSetEaFile@16
NtSetEvent@8 NtSetEvent@8
NtSetHighEventPair@4 NtSetHighEventPair@4
NtSetHighWaitLowEventPair@4 NtSetHighWaitLowEventPair@4
NtSetInformationDebugObject@20
NtSetInformationFile@20 NtSetInformationFile@20
NtSetInformationJobObject@16 NtSetInformationJobObject@16
NtSetInformationKey@16 NtSetInformationKey@16

View file

@ -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 */

View file

@ -1,123 +1,239 @@
/* $Id$ /*
* * PROJECT: ReactOS Win32 Base API
* COPYRIGHT: See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS system libraries * FILE: dll/win32/kernel32/debug/debugger.c
* FILE: lib/kernel32/debug/debugger.c * PURPOSE: Wrappers for the NT Debug Implementation
* PURPOSE: Win32 Debugger API * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMER: Thomas Weidenmueller
* KJK::Hyperion
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES *****************************************************************/
#include <k32.h> #include <k32.h>
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*
* @implemented * @implemented
*/ */
BOOL WINAPI BOOL
CheckRemoteDebuggerPresent ( WINAPI
HANDLE hProcess, CheckRemoteDebuggerPresent(IN HANDLE hProcess,
PBOOL pbDebuggerPresent OUT PBOOL pbDebuggerPresent)
)
{ {
HANDLE DebugPort; HANDLE DebugPort;
NTSTATUS Status; NTSTATUS Status;
if (pbDebuggerPresent == NULL) /* Make sure we have an output and process*/
{ if (!(pbDebuggerPresent) || !(hProcess))
SetLastError(ERROR_INVALID_PARAMETER); {
/* Fail */
SetLastError(ERROR_INVALID_PARAMETER);
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; return FALSE;
}
Status = NtQueryInformationProcess(hProcess,
ProcessDebugPort,
(PVOID)&DebugPort,
sizeof(HANDLE),
NULL);
if (NT_SUCCESS(Status))
{
*pbDebuggerPresent = ((DebugPort != NULL) ? TRUE : FALSE);
return TRUE;
}
SetLastErrorByStatus(Status);
return FALSE;
} }
/* /*
* @implemented * @implemented
*/ */
BOOL WINAPI BOOL
ContinueDebugEvent ( WINAPI
DWORD dwProcessId, ContinueDebugEvent(IN DWORD dwProcessId,
DWORD dwThreadId, IN DWORD dwThreadId,
DWORD dwContinueStatus IN DWORD dwContinueStatus)
)
{ {
CLIENT_ID ClientId; CLIENT_ID ClientId;
NTSTATUS Status; NTSTATUS Status;
ClientId.UniqueProcess = (HANDLE)dwProcessId; /* Set the Client ID */
ClientId.UniqueThread = (HANDLE)dwThreadId; ClientId.UniqueProcess = (HANDLE)dwProcessId;
ClientId.UniqueThread = (HANDLE)dwThreadId;
Status = DbgUiContinue(&ClientId, dwContinueStatus); /* Continue debugging */
if (!NT_SUCCESS(Status)) Status = DbgUiContinue(&ClientId, dwContinueStatus);
{ if (!NT_SUCCESS(Status))
SetLastErrorByStatus(Status); {
return FALSE; /* 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. * @implemented
*
* @unimplemented
*/ */
BOOL BOOL
WINAPI WINAPI
DebugActiveProcess( DebugActiveProcess(IN DWORD dwProcessId)
DWORD dwProcessId
)
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); NTSTATUS Status;
return FALSE; 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 BOOL
WINAPI WINAPI
DebugActiveProcessStop ( DebugActiveProcessStop(IN DWORD dwProcessId)
DWORD dwProcessId
)
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); NTSTATUS Status;
return FALSE; 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 BOOL
WINAPI WINAPI
DebugSetProcessKillOnExit ( DebugBreakProcess(IN HANDLE Process)
BOOL KillOnExit
)
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); NTSTATUS Status;
return FALSE;
/* 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 * @implemented
@ -126,22 +242,20 @@ BOOL
WINAPI WINAPI
IsDebuggerPresent (VOID) IsDebuggerPresent (VOID)
{ {
return (BOOL)NtCurrentPeb()->BeingDebugged; return (BOOL)NtCurrentPeb()->BeingDebugged;
} }
/* /*
* @unimplemented * @unimplemented
*/ */
BOOL BOOL
WINAPI WINAPI
WaitForDebugEvent ( WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent,
LPDEBUG_EVENT lpDebugEvent, DWORD dwMilliseconds)
DWORD dwMilliseconds
)
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); /* FIXME: TODO */
return FALSE; SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
} }
/* EOF */ /* EOF */

View file

@ -63,6 +63,9 @@ BOOL STDCALL VerifyConsoleIoHandle(HANDLE Handle);
BOOL STDCALL CloseConsoleHandle(HANDLE Handle); BOOL STDCALL CloseConsoleHandle(HANDLE Handle);
HANDLE STDCALL
GetConsoleInputWaitHandle (VOID);
HANDLE STDCALL OpenConsoleW (LPWSTR wsName, HANDLE STDCALL OpenConsoleW (LPWSTR wsName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
BOOL bInheritHandle, BOOL bInheritHandle,

View file

@ -10,7 +10,6 @@
<define name="WINVER">0x502</define> <define name="WINVER">0x502</define>
<pch>k32.h</pch> <pch>k32.h</pch>
<directory name="debug"> <directory name="debug">
<file>break.c</file>
<file>debugger.c</file> <file>debugger.c</file>
<file>output.c</file> <file>output.c</file>
</directory> </directory>

View file

@ -567,7 +567,7 @@ GetConsoleHardwareState (HANDLE hConsole,
/* /*
* @implemented * @implemented
*/ */
DWORD STDCALL HANDLE STDCALL
GetConsoleInputWaitHandle (VOID) GetConsoleInputWaitHandle (VOID)
/* /*
* Undocumented * Undocumented
@ -585,7 +585,7 @@ GetConsoleInputWaitHandle (VOID)
SetLastErrorByStatus(Status); SetLastErrorByStatus(Status);
return 0; return 0;
} }
return (DWORD) Request.Data.GetConsoleInputWaitHandle.InputWaitHandle; return Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
} }

View file

@ -23,10 +23,19 @@ Author:
// Dependencies // Dependencies
// //
#include <umtypes.h> #include <umtypes.h>
#include <dbgktypes.h>
// //
// Native calls // Native calls
// //
NTSYSCALLAPI
NTSTATUS
NTAPI
NtDebugActiveProcess(
IN HANDLE Process,
IN HANDLE DebugObject
);
NTSYSCALLAPI NTSYSCALLAPI
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -56,6 +65,33 @@ NtWaitForDebugEvent(
OUT PDBGUI_WAIT_STATE_CHANGE StateChange 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 NTSYSAPI
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -75,6 +111,14 @@ ZwDebugContinue(
IN NTSTATUS ContinueStatus IN NTSTATUS ContinueStatus
); );
NTSYSAPI
NTSTATUS
NTAPI
ZwRemoveProcessDebug(
IN HANDLE Process,
IN HANDLE DebugObject
);
NTSYSAPI NTSYSAPI
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -84,4 +128,15 @@ ZwWaitForDebugEvent(
IN PLARGE_INTEGER Timeout OPTIONAL, IN PLARGE_INTEGER Timeout OPTIONAL,
OUT PDBGUI_WAIT_STATE_CHANGE StateChange 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 #endif

View file

@ -89,6 +89,12 @@ CsrFreeCaptureBuffer(
struct _CSR_CAPTURE_BUFFER *CaptureBuffer struct _CSR_CAPTURE_BUFFER *CaptureBuffer
); );
HANDLE
NTAPI
CsrGetProcessId(
VOID
);
NTSTATUS NTSTATUS
NTAPI NTAPI
CsrNewThread(VOID); CsrNewThread(VOID);
@ -139,6 +145,18 @@ DbgUiContinue(
IN ULONG ContinueStatus IN ULONG ContinueStatus
); );
NTSTATUS
NTAPI
DbgUiDebugActiveProcess(
IN HANDLE Process
);
NTSTATUS
NTAPI
DbgUiStopDebugging(
IN HANDLE Process
);
NTSTATUS NTSTATUS
NTAPI NTAPI
DbgUiWaitStateChange( DbgUiWaitStateChange(
@ -158,6 +176,12 @@ DbgUiIssueRemoteBreakin(
IN HANDLE Process IN HANDLE Process
); );
HANDLE
NTAPI
DbgUiGetThreadDebugObject(
VOID
);
// //
// Loader Functions // Loader Functions
// //

View file

@ -42,6 +42,7 @@ NtCreateThread 8
NtCreateTimer 4 NtCreateTimer 4
NtCreateToken 13 NtCreateToken 13
NtCreateWaitablePort 5 NtCreateWaitablePort 5
NtDebugActiveProcess 2
NtDebugContinue 3 NtDebugContinue 3
NtDelayExecution 2 NtDelayExecution 2
NtDeleteAtom 1 NtDeleteAtom 1
@ -162,6 +163,7 @@ NtRegisterThreadTerminatePort 1
NtReleaseMutant 2 NtReleaseMutant 2
NtReleaseSemaphore 3 NtReleaseSemaphore 3
NtRemoveIoCompletion 5 NtRemoveIoCompletion 5
NtRemoveProcessDebug 2
NtReplaceKey 3 NtReplaceKey 3
NtReplyPort 2 NtReplyPort 2
NtReplyWaitReceivePort 4 NtReplyWaitReceivePort 4
@ -188,6 +190,7 @@ NtSetEaFile 4
NtSetEvent 2 NtSetEvent 2
NtSetHighEventPair 1 NtSetHighEventPair 1
NtSetHighWaitLowEventPair 1 NtSetHighWaitLowEventPair 1
NtSetInformationDebugObject 5
NtSetInformationFile 5 NtSetInformationFile 5
NtSetInformationKey 4 NtSetInformationKey 4
NtSetInformationJobObject 4 NtSetInformationJobObject 4