Author: ion Date: Fri Oct 20 09:16:04 2006 New Revision: 24575
URL: http://svn.reactos.org/svn/reactos?rev=24575&view=rev Log: - Define DBGKM_APINUMBER - Implement DbgkpSendApiMessageLpc, DbgkpSendApiMessage, DbgkCopyProcessDebugPort, DbgkForwardException, DbgkFreeDebugEvent, DbgpWakeTarget. - Close original handle in DbgkOpenHandles.
Modified: trunk/reactos/include/ndk/dbgktypes.h trunk/reactos/ntoskrnl/dbgk/dbgkutil.c trunk/reactos/ntoskrnl/dbgk/debug.c trunk/reactos/ntoskrnl/include/internal/dbgk.h trunk/reactos/ntoskrnl/include/internal/ps.h
Modified: trunk/reactos/include/ndk/dbgktypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/dbgktypes.h?rev... ============================================================================== --- trunk/reactos/include/ndk/dbgktypes.h (original) +++ trunk/reactos/include/ndk/dbgktypes.h Fri Oct 20 09:16:04 2006 @@ -41,6 +41,22 @@ DebugObjectUnusedInformation, DebugObjectKillProcessOnExitInformation } DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS; + +// +// Debug Message API Number +// +typedef enum _DBGKM_APINUMBER +{ + DbgKmExceptionApi = 0, + DbgKmCreateThreadApi = 1, + DbgKmCreateProcessApi = 2, + DbgKmExitThreadApi = 3, + DbgKmExitProcessApi = 4, + DbgKmLoadDllApi = 5, + DbgKmUnloadDllApi = 6, + DbgKmErrorReportApi = 7, + DbgKmMaxApiNumber = 8, +} DBGKM_APINUMBER;
// // Debug Object Information Structures @@ -173,7 +189,7 @@ typedef struct _DBGKM_MSG { PORT_MESSAGE h; - ULONG ApiNumber; + DBGKM_APINUMBER ApiNumber; ULONG ReturnedStatus; union {
Modified: trunk/reactos/ntoskrnl/dbgk/dbgkutil.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/dbgkutil.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/dbgk/dbgkutil.c (original) +++ trunk/reactos/ntoskrnl/dbgk/dbgkutil.c Fri Oct 20 09:16:04 2006 @@ -68,4 +68,18 @@ /* FIXME */ }
+VOID +NTAPI +DbgkpSuspendProcess(VOID) +{ + +} + +VOID +NTAPI +DbgkpResumeProcess(VOID) +{ + +} + /* EOF */
Modified: trunk/reactos/ntoskrnl/dbgk/debug.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/debug.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/dbgk/debug.c (original) +++ trunk/reactos/ntoskrnl/dbgk/debug.c Fri Oct 20 09:16:04 2006 @@ -26,12 +26,127 @@
/* PRIVATE FUNCTIONS *********************************************************/
+NTSTATUS +NTAPI +DbgkpQueueMessage(IN PEPROCESS Process, + IN PETHREAD Thread, + IN PDBGKM_MSG Message, + IN ULONG Flags, + IN PDEBUG_OBJECT TargetObject OPTIONAL) +{ + /* FIXME: TODO */ + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +DbgkpSendApiMessageLpc(IN OUT PDBGKM_MSG Message, + IN PVOID Port, + IN BOOLEAN SuspendProcess) +{ + NTSTATUS Status; + UCHAR Buffer[PORT_MAXIMUM_MESSAGE_LENGTH]; + PAGED_CODE(); + + /* Suspend process if required */ + if (SuspendProcess) DbgkpSuspendProcess(); + + /* Set return status */ + Message->ReturnedStatus = STATUS_PENDING; + + /* Set create process reported state */ + PsGetCurrentProcess()->CreateReported = TRUE; + + /* Send the LPC command */ +#if 0 + Status = LpcRequestWaitReplyPort(Port, + (PPORT_MESSAGE)Message, + (PPORT_MESSAGE)&Buffer[0]); +#else + Status = STATUS_UNSUCCESSFUL; +#endif + + /* Flush the instruction cache */ + ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0); + + /* Copy the buffer back */ + if (NT_SUCCESS(Status)) RtlMoveMemory(Message, Buffer, sizeof(DBGKM_MSG)); + + /* Resume the process if it was suspended */ + if (SuspendProcess) DbgkpResumeProcess(); + return Status; +} + +NTSTATUS +NTAPI +DbgkpSendApiMessage(IN OUT PDBGKM_MSG ApiMsg, + IN ULONG Flags) +{ + NTSTATUS Status; + PAGED_CODE(); + + /* Suspend process if required */ + if (Flags) DbgkpSuspendProcess(); + + /* Set return status */ + ApiMsg->ReturnedStatus = STATUS_PENDING; + + /* Set create process reported state */ + PsGetCurrentProcess()->CreateReported = TRUE; + + /* Send the LPC command */ + Status = DbgkpQueueMessage(PsGetCurrentProcess(), + PsGetCurrentThread(), + ApiMsg, + 0, + NULL); + + /* Flush the instruction cache */ + ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0); + + /* Resume the process if it was suspended */ + if (Flags) DbgkpResumeProcess(); + return Status; +} + VOID NTAPI DbgkCopyProcessDebugPort(IN PEPROCESS Process, IN PEPROCESS Parent) { - /* FIXME: Implement */ + PDEBUG_OBJECT DebugObject; + PAGED_CODE(); + + /* Clear this process's port */ + Process->DebugPort = NULL; + + /* Check if the parent has one */ + if (!Parent->DebugPort) return; + + /* It does, acquire the mutex */ + ExAcquireFastMutex(&DbgkpProcessDebugPortMutex); + + /* Make sure it still has one, and that we should inherit */ + DebugObject = Parent->DebugPort; + if ((DebugObject) && !(Process->NoDebugInherit)) + { + /* Acquire the debug object's lock */ + ExAcquireFastMutex(&DebugObject->Mutex); + + /* Make sure the debugger is active */ + if (!DebugObject->DebuggerInactive) + { + /* Reference the object and set it */ + ObReferenceObject(DebugObject); + Process->DebugPort = DebugObject; + } + + /* Release the debug object */ + ExReleaseFastMutex(&DebugObject->Mutex); + } + + /* Release the port mutex */ + ExReleaseFastMutex(&DbgkpProcessDebugPortMutex); }
BOOLEAN @@ -40,16 +155,131 @@ IN BOOLEAN DebugPort, IN BOOLEAN SecondChance) { - /* FIXME: Implement */ - return FALSE; + DBGKM_MSG ApiMessage; + PDBGKM_EXCEPTION DbgKmException = &ApiMessage.Exception; + NTSTATUS Status; + PEPROCESS Process = PsGetCurrentProcess(); + PVOID Port; + BOOLEAN UseLpc = FALSE; + PAGED_CODE(); + + /* Setup the API Message */ + ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | + (8 + sizeof(DBGKM_EXCEPTION)); + ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT; + ApiMessage.ApiNumber = DbgKmExceptionApi; + + /* Check if this is to be sent on the debug port */ + if (DebugPort) + { + /* Use the debug port, onless the thread is being hidden */ + Port = PsGetCurrentThread()->HideFromDebugger ? + NULL : Process->DebugPort; + } + else + { + /* Otherwise, use the exception port */ + Port = Process->ExceptionPort; + ApiMessage.h.u2.ZeroInit = LPC_EXCEPTION; + UseLpc = TRUE; + } + + /* Break out if there's no port */ + if (!Port) return FALSE; + + /* Fill out the exception information */ + DbgKmException->ExceptionRecord = *ExceptionRecord; + DbgKmException->FirstChance = !SecondChance; + + /* Check if we should use LPC */ + if (UseLpc) + { + /* Send the message on the LPC Port */ + Status = DbgkpSendApiMessageLpc(&ApiMessage, Port, DebugPort); + } + else + { + /* Use native debug object */ + Status = DbgkpSendApiMessage(&ApiMessage, DebugPort); + } + + /* Check if we failed, and for a debug port, also check the return status */ + if (!(NT_SUCCESS(Status)) || + ((DebugPort) && + (!(NT_SUCCESS(ApiMessage.ReturnedStatus)) || + (ApiMessage.ReturnedStatus == DBG_EXCEPTION_NOT_HANDLED)))) + { + /* Fail */ + return FALSE; + } + + /* Otherwise, we're ok */ + return TRUE; }
VOID NTAPI +DbgkpFreeDebugEvent(IN PDEBUG_EVENT DebugEvent) +{ + PHANDLE Handle = NULL; + PAGED_CODE(); + + /* Check if this event had a file handle */ + switch (DebugEvent->ApiMsg.ApiNumber) + { + /* Create process has a handle */ + case DbgKmCreateProcessApi: + + /* Get the pointer */ + Handle = &DebugEvent->ApiMsg.CreateProcess.FileHandle; + + /* As does DLL load */ + case DbgKmLoadDllApi: + + /* Get the pointer */ + Handle = &DebugEvent->ApiMsg.LoadDll.FileHandle; + + default: + break; + } + + /* Close the handle if it exsts */ + if ((Handle) && (*Handle)) ObCloseHandle(*Handle, KernelMode); + + /* Dereference process and thread and free the event */ + ObDereferenceObject(DebugEvent->Process); + ObDereferenceObject(DebugEvent->Thread); + ExFreePool(DebugEvent); +} + +VOID +NTAPI DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent) { - /* FIXME: TODO */ - return; + PETHREAD Thread = DebugEvent->Thread; + PAGED_CODE(); + + /* Check if we have to wake the thread */ + if (DebugEvent->Flags & 20) PsResumeThread(Thread, NULL); + + /* Check if we had locked the thread */ + if (DebugEvent->Flags & 8) + { + /* Unlock it */ + ExReleaseRundownProtection(&Thread->RundownProtect); + } + + /* Check if we have to wake up the event */ + if (DebugEvent->Flags & 2) + { + /* Signal the continue event */ + KeSetEvent(&DebugEvent->ContinueEvent, IO_NO_INCREMENT, FALSE); + } + else + { + /* Otherwise, free the debug event */ + DbgkpFreeDebugEvent(DebugEvent); + } }
NTSTATUS @@ -87,6 +317,14 @@ NTAPI DbgkpConvertKernelToUserStateChange(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, IN PDEBUG_EVENT DebugEvent) +{ + /* FIXME: TODO */ + return; +} + +VOID +NTAPI +DbgkpMarkProcessPeb(IN PEPROCESS Process) { /* FIXME: TODO */ return; @@ -187,6 +425,10 @@ 0, DUPLICATE_SAME_ACCESS, KernelMode); + if (NT_SUCCESS(Status)) *DupHandle = NULL; + + /* Close the original handle */ + ObCloseHandle(Handle, KernelMode); } }
@@ -199,14 +441,6 @@
/* Sanity check */ ASSERT(IsListEmpty(&DebugObject->EventList)); -} - -VOID -NTAPI -DbgkpMarkProcessPeb(IN PEPROCESS Process) -{ - /* FIXME: TODO */ - return; }
VOID
Modified: trunk/reactos/ntoskrnl/include/internal/dbgk.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/d... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/dbgk.h (original) +++ trunk/reactos/ntoskrnl/include/internal/dbgk.h Fri Oct 20 09:16:04 2006 @@ -17,6 +17,18 @@ NTAPI DbgkExitThread( IN NTSTATUS ExitStatus +); + +VOID +NTAPI +DbgkpSuspendProcess( + VOID +); + +VOID +NTAPI +DbgkpResumeProcess( + VOID );
VOID
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/p... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ps.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ps.h Fri Oct 20 09:16:04 2006 @@ -330,6 +330,16 @@ NTAPI PspDeleteJob( IN PVOID ObjectBody +); + +// +// State routines +// +NTSTATUS +NTAPI +PsResumeThread( + IN PETHREAD Thread, + OUT PULONG PreviousCount OPTIONAL );
//