- 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 kernel
* FILE: lib/ntdll/dbg/dbgui.c
* PURPOSE: User-Mode DbgUI Support
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
* PROJECT: ReactOS NT Layer/System API
* LICENSE: GPL - See COPYING in the top level directory
* FILE: dll/ntdll/dbg/dbgui.c
* PURPOSE: Native Wrappers for the NT Debug Implementation
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *****************************************************************/
@ -135,4 +135,52 @@ DbgUiIssueRemoteBreakin(HANDLE Process)
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 */

View 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

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$
*
* 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);
/* Make sure we have an output and process*/
if (!(pbDebuggerPresent) || !(hProcess))
{
/* 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;
}
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
*/
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 */

View file

@ -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,

View 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>

View 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;
}

View 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

View 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
//

View 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