[ros-diffs] [ion] 24595: - Implement DbgkpQueueMessage. This is the main bi-directional communication routine for the newer non-LPC Debug Object. - Implement DbgkPostFakeProcessCreateMessages (and stub DbgkpPostFakeThreadMessages and DbgkpPostFakeModuleMessages). These are required when attaching to a process after threads have been created and modules loaded, so that the debugger can have a valid state. - Still missing the two functions to Set/Clear the Debug Object, will do these next.

ion at svn.reactos.org ion at svn.reactos.org
Sat Oct 21 21:26:55 CEST 2006


Author: ion
Date: Sat Oct 21 23:26:54 2006
New Revision: 24595

URL: http://svn.reactos.org/svn/reactos?rev=24595&view=rev
Log:
- Implement DbgkpQueueMessage. This is the main bi-directional communication routine for the newer non-LPC Debug Object.
- Implement DbgkPostFakeProcessCreateMessages (and stub DbgkpPostFakeThreadMessages and DbgkpPostFakeModuleMessages). These are required when attaching to a process after threads have been created and modules loaded, so that the debugger can have a valid state.
- Still missing the two functions to Set/Clear the Debug Object, will do these next.

Modified:
    trunk/reactos/ntoskrnl/dbgk/debug.c

Modified: trunk/reactos/ntoskrnl/dbgk/debug.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/debug.c?rev=24595&r1=24594&r2=24595&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/dbgk/debug.c (original)
+++ trunk/reactos/ntoskrnl/dbgk/debug.c Sat Oct 21 23:26:54 2006
@@ -23,7 +23,35 @@
     DEBUG_OBJECT_ALL_ACCESS
 };
 
+static const INFORMATION_CLASS_INFO DbgkpDebugObjectInfoClass[] =
+{
+    /* DebugObjectUnusedInformation */
+    ICI_SQ_SAME(sizeof(ULONG), sizeof(ULONG), 0),
+    /* DebugObjectKillProcessOnExitInformation */
+    ICI_SQ_SAME(sizeof(DEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION), sizeof(ULONG), ICIF_SET),
+};
+
 /* PRIVATE FUNCTIONS *********************************************************/
+
+NTSTATUS
+NTAPI
+DbgkpSetProcessDebugObject(IN PEPROCESS Process,
+                           IN PDEBUG_OBJECT DebugObject,
+                           IN NTSTATUS MsgStatus,
+                           IN PETHREAD LastThread)
+{
+    /* FIXME: TODO */
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+DbgkClearProcessDebugObject(IN PEPROCESS Process,
+                            IN PDEBUG_OBJECT SourceDebugObject)
+{
+    /* FIXME: TODO */
+    return STATUS_UNSUCCESSFUL;
+}
 
 NTSTATUS
 NTAPI
@@ -33,8 +61,157 @@
                   IN ULONG Flags,
                   IN PDEBUG_OBJECT TargetObject OPTIONAL)
 {
-    /* FIXME: TODO */
-    return STATUS_UNSUCCESSFUL;
+    PDEBUG_EVENT DebugEvent;
+    DEBUG_EVENT LocalDebugEvent;
+    PDEBUG_OBJECT DebugObject;
+    NTSTATUS Status;
+    BOOLEAN NewEvent;
+    PAGED_CODE();
+
+    /* Check if we have to allocate a debug event */
+    NewEvent = (Flags & 2) ? TRUE : FALSE;
+    if (NewEvent)
+    {
+        /* Allocate it */
+        DebugEvent = ExAllocatePoolWithTag(NonPagedPool,
+                                           sizeof(DEBUG_EVENT),
+                                           TAG('D', 'b', 'g', 'E'));
+        if (!DebugEvent) return STATUS_INSUFFICIENT_RESOURCES;
+
+        /* Set flags */
+        DebugEvent->Flags = Flags | 4;
+
+        /* Reference the thread and process */
+        ObReferenceObject(Thread);
+        ObReferenceObject(Process);
+
+        /* Set the current thread */
+        DebugEvent->BackoutThread = PsGetCurrentThread();
+
+        /* Set the debug object */
+        DebugObject = TargetObject;
+    }
+    else
+    {
+        /* Use the debug event on the stack */
+        DebugEvent = &LocalDebugEvent;
+        DebugEvent->Flags = Flags;
+
+        /* Acquire the port lock */
+        ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
+
+        /* Get the debug object */
+        DebugObject = Process->DebugPort;
+
+        /* Check what kind of API message this is */
+        switch (Message->ApiNumber)
+        {
+            /* Process or thread creation */
+            case DbgKmCreateThreadApi:
+            case DbgKmCreateProcessApi:
+
+                /* Make sure we're not skipping creation messages */
+                if (Thread->SkipCreationMsg) DebugObject = NULL;
+                break;
+
+            /* Process or thread exit */
+            case DbgKmExitThreadApi:
+            case DbgKmExitProcessApi:
+
+                /* Make sure we're not skipping exit messages */
+                if (Thread->SkipTerminationMsg) DebugObject = NULL;
+
+            /* No special handling for other messages */
+            default:
+                break;
+        }
+    }
+
+    /* Setup the Debug Event */
+    KeInitializeEvent(&DebugEvent->ContinueEvent, SynchronizationEvent, FALSE);
+    DebugEvent->Process = Process;
+    DebugEvent->Thread = Thread;
+    RtlMoveMemory(&DebugEvent->ApiMsg, Message, sizeof(DBGKM_MSG));
+    DebugEvent->ClientId = Thread->Cid;
+
+    /* Check if we have a port object */
+    if (!DebugObject)
+    {
+        /* Fail */
+        Status = STATUS_PORT_NOT_SET;
+    }
+    else
+    {
+        /* Acquire the debug object mutex */
+        ExAcquireFastMutex(&DebugObject->Mutex);
+
+        /* Check if a debugger is active */
+        if (!DebugObject->DebuggerInactive)
+        {
+            /* Add the event into the object's list */
+            InsertTailList(&DebugObject->EventList, &DebugEvent->EventList);
+
+            /* Check if we have to signal it */
+            if (!NewEvent)
+            {
+                /* Signal it */
+                KeSetEvent(&DebugObject->EventsPresent,
+                           IO_NO_INCREMENT,
+                           FALSE);
+            }
+
+            /* Set success */
+            Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* No debugger */
+            Status = STATUS_DEBUGGER_INACTIVE;
+        }
+
+        /* Release the object lock */
+        ExReleaseFastMutex(&DebugObject->Mutex);
+    }
+
+    /* Check if we had acquired the port lock */
+    if (!NewEvent)
+    {
+        /* Release it */
+        ExReleaseFastMutex(&DbgkpProcessDebugPortMutex);
+
+        /* Check if we got here through success */
+        if (NT_SUCCESS(Status))
+        {
+            /* Wait on the continue event */
+            KeWaitForSingleObject(&DebugEvent->ContinueEvent,
+                                  Executive,
+                                  KernelMode,
+                                  FALSE,
+                                  NULL);
+
+            /* Copy API Message back */
+            RtlMoveMemory(Message, &DebugEvent->ApiMsg, sizeof(DBGKM_MSG));
+
+            /* Set return status */
+            Status = DebugEvent->Status;
+        }
+    }
+    else
+    {
+        /* Check if we failed */
+        if (!NT_SUCCESS(Status))
+        {
+            /* Dereference the process and thread */
+            ObDereferenceObject(Thread);
+            ObDereferenceObject(Process);
+
+            /* Free the debug event */
+            ExFreePool(DebugEvent);
+        }
+    }
+
+    /* Return status */
+    return Status;
 }
 
 NTSTATUS
@@ -283,33 +460,74 @@
 
 NTSTATUS
 NTAPI
+DbgkpPostFakeModuleMessages(IN PEPROCESS Process,
+                            IN PETHREAD Thread,
+                            IN PDEBUG_OBJECT DebugObject)
+{
+    /* FIXME: TODO */
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+DbgkpPostFakeThreadMessages(IN PEPROCESS Process,
+                            IN PDEBUG_OBJECT DebugObject,
+                            IN PETHREAD StartThread,
+                            OUT PETHREAD *FirstThread,
+                            OUT PETHREAD *LastThread)
+{
+    /* FIXME: TODO */
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
 DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process,
                                    IN PDEBUG_OBJECT DebugObject,
-                                   IN PETHREAD *LastThread)
-{
-    /* FIXME: Implement */
-    *LastThread = NULL;
-    return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-DbgkpSetProcessDebugObject(IN PEPROCESS Process,
-                           IN PDEBUG_OBJECT DebugObject,
-                           IN NTSTATUS MsgStatus,
-                           IN PETHREAD LastThread)
-{
-    /* FIXME: TODO */
-    return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-NTAPI
-DbgkClearProcessDebugObject(IN PEPROCESS Process,
-                            IN PDEBUG_OBJECT SourceDebugObject)
-{
-    /* FIXME: TODO */
-    return STATUS_UNSUCCESSFUL;
+                                   OUT PETHREAD *LastThread)
+{
+    KAPC_STATE ApcState;
+    PETHREAD FirstThread, FinalThread;
+    PETHREAD ReturnThread = NULL;
+    NTSTATUS Status;
+    PAGED_CODE();
+
+    /* Attach to the process */
+    KeStackAttachProcess(&Process->Pcb, &ApcState);
+
+    /* Post the fake thread messages */
+    Status = DbgkpPostFakeThreadMessages(Process,
+                                         DebugObject,
+                                         NULL,
+                                         &FirstThread,
+                                         &FinalThread);
+    if (NT_SUCCESS(Status))
+    {
+        /* Send the fake module messages too */
+        Status = DbgkpPostFakeModuleMessages(Process,
+                                             FirstThread,
+                                             DebugObject);
+        if (!NT_SUCCESS(Status))
+        {
+            /* We failed, dereference the final thread */
+            ObDereferenceObject(FinalThread);
+        }
+        else
+        {
+            /* Set the final thread */
+            ReturnThread = FinalThread;
+        }
+
+        /* Dereference the first thread */
+        ObDereferenceObject(FirstThread);
+    }
+
+    /* Detach from the process */
+    KeUnstackDetachProcess(&ApcState);
+
+    /* Return the last thread */
+    *LastThread = ReturnThread;
+    return Status;
 }
 
 VOID
@@ -1003,14 +1221,6 @@
     return Status;
 }
 
-static const INFORMATION_CLASS_INFO DbgkpDebugObjectInfoClass[] =
-{
-    /* DebugObjectUnusedInformation */
-    ICI_SQ_SAME(sizeof(ULONG), sizeof(ULONG), 0),
-    /* DebugObjectKillProcessOnExitInformation */
-    ICI_SQ_SAME(sizeof(DEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION), sizeof(ULONG), ICIF_SET),
-};
-
 NTSTATUS
 NTAPI
 NtSetInformationDebugObject(IN HANDLE DebugHandle,
@@ -1034,16 +1244,19 @@
                                        DebugInformationLength,
                                        PreviousMode);
 
-    /* Return required length to user-mode */
+    /* Check if the caller wanted the return length */
     if (ReturnLength)
     {
+        /* Enter SEH for probe */
         _SEH_TRY
         {
+            /* Return required length to user-mode */
             ProbeForWriteUlong(ReturnLength);
             *ReturnLength = sizeof(*DebugInfo);
         }
         _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
         {
+            /* Get SEH Exception code */
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
@@ -1108,11 +1321,13 @@
     /* Clear the initial wait state change structure */
     RtlZeroMemory(&WaitStateChange, sizeof(WaitStateChange));
 
-    /* Check if we came with a timeout from user mode */
+    /* Check if the call was from user mode */
     if (PreviousMode != KernelMode)
     {
+        /* Protect probe in SEH */
         _SEH_TRY
         {
+            /* Check if we came with a timeout */
             if (Timeout)
             {
                 /* Make a copy on the stack */
@@ -1120,6 +1335,7 @@
                 Timeout = &SafeTimeOut;
             }
 
+            /* Probe the state change structure */
             ProbeForWrite(StateChange, sizeof(*StateChange), sizeof(ULONG));
         }
         _SEH_HANDLE
@@ -1279,19 +1495,22 @@
     /* We're, dereference the object */
     ObDereferenceObject(DebugObject);
 
-    /* Return our wait state change structure */
+    /* Protect write with SEH */
     _SEH_TRY
     {
-        RtlCopyMemory(StateChange,
+        /* Return our wait state change structure */
+        RtlMoveMemory(StateChange,
                       &WaitStateChange,
                       sizeof(DBGUI_WAIT_STATE_CHANGE));
     }
     _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
     {
+        /* Get SEH Exception code */
         Status = _SEH_GetExceptionCode();
     }
     _SEH_END;
 
+    /* Return status */
     return Status;
 }
 




More information about the Ros-diffs mailing list