[ros-diffs] [ion] 24980: - Implement DbgkPostFakeThreadMessages. - Add Dbgk-calls to NtMap/UnmapViewOfSection to nodify debugging services of new DLL image load. - Dbgk support is now skeletally complete, I will write a simple test app to test some functionality and start finding/fixing bugs.

ion at svn.reactos.org ion at svn.reactos.org
Thu Nov 30 02:57:26 CET 2006


Author: ion
Date: Thu Nov 30 04:57:25 2006
New Revision: 24980

URL: http://svn.reactos.org/svn/reactos?rev=24980&view=rev
Log:
- Implement DbgkPostFakeThreadMessages.
- Add Dbgk-calls to NtMap/UnmapViewOfSection to nodify debugging services of new DLL image load.
- Dbgk support is now skeletally complete, I will write a simple test app to test some functionality and start finding/fixing bugs.

Modified:
    trunk/reactos/ntoskrnl/dbgk/debug.c
    trunk/reactos/ntoskrnl/include/internal/dbgk.h
    trunk/reactos/ntoskrnl/include/internal/ps.h
    trunk/reactos/ntoskrnl/mm/section.c

Modified: trunk/reactos/ntoskrnl/dbgk/debug.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/debug.c?rev=24980&r1=24979&r2=24980&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/dbgk/debug.c (original)
+++ trunk/reactos/ntoskrnl/dbgk/debug.c Thu Nov 30 04:57:25 2006
@@ -551,8 +551,168 @@
                             OUT PETHREAD *FirstThread,
                             OUT PETHREAD *LastThread)
 {
-    /* FIXME: TODO */
-    return STATUS_UNSUCCESSFUL;
+    PETHREAD pFirstThread = NULL, ThisThread, OldThread = NULL, pLastThread;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    BOOLEAN IsFirstThread;
+    ULONG Flags;
+    DBGKM_MSG ApiMessage;
+    PDBGKM_CREATE_THREAD CreateThread = &ApiMessage.CreateThread;
+    PDBGKM_CREATE_PROCESS CreateProcess = &ApiMessage.CreateProcess;
+    BOOLEAN First;
+    PIMAGE_NT_HEADERS NtHeader;
+    PAGED_CODE();
+
+    /* Check if we have a start thread */
+    if (StartThread)
+    {
+        /* Then the one we'll find won't be the first one */
+        IsFirstThread = FALSE;
+        pFirstThread = StartThread;
+        ThisThread = StartThread;
+
+        /* Reference it */
+        ObReferenceObject(StartThread);
+    }
+    else
+    {
+        /* Get the first thread ourselves */
+        ThisThread = PsGetNextProcessThread(Process, OldThread);
+        IsFirstThread = TRUE;
+    }
+
+    /* Start thread loop */
+    do
+    {
+        /* Dereference the previous thread if we had one */
+        if (OldThread) ObDereferenceObject(OldThread);
+
+        /* Set this as the last thread and lock it */
+        pLastThread = ThisThread;
+        ObReferenceObject(ThisThread);
+        if (ExAcquireRundownProtection(&ThisThread->RundownProtect))
+        {
+            /* Acquire worked, set flags */
+            Flags = 0x8 | 0x2;
+
+            /* Check if this is a user thread */
+            if (!ThisThread->SystemThread)
+            {
+                /* Suspend it */
+                if (NT_SUCCESS(PsSuspendThread(ThisThread, NULL)))
+                {
+                    /* Remember this */
+                    Flags = 0x8 | 0x2 | 0x20;
+                }
+            }
+        }
+        else
+        {
+            /* Couldn't acquire rundown */
+            Flags = 0x10 | 0x2;
+        }
+
+        /* Clear the API Message */
+        RtlZeroMemory(&ApiMessage, sizeof(ApiMessage));
+
+        /* Check if this is the first thread */
+        if ((IsFirstThread) &&
+            !(Flags & 0x10) &&
+            !(ThisThread->SystemThread) &&
+            (ThisThread->GrantedAccess))
+        {
+            /* It is, save the flag */
+            First = TRUE;
+        }
+        else
+        {
+            /* It isn't, save the flag */
+            First = FALSE;
+        }
+
+        /* Check if this is the first */
+        if (First)
+        {
+            /* So we'll start with the create process message */
+            ApiMessage.ApiNumber = DbgKmCreateProcessApi;
+
+            /* Get the file handle */
+            if (Process->SectionObject)
+            {
+                /* Use the section object */
+                CreateProcess->FileHandle =
+                    DbgkpSectionToFileHandle(Process->SectionObject);
+            }
+            else
+            {
+                /* Don't return any handle */
+                CreateProcess->FileHandle = NULL;
+            }
+
+            /* Set the base address */
+            CreateProcess->BaseOfImage = Process->SectionBaseAddress;
+
+            /* Get the NT Header */
+            NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
+            if (NtHeader)
+            {
+                /* Fill out data from the header */
+                CreateProcess->DebugInfoFileOffset = NtHeader->FileHeader.
+                                                     PointerToSymbolTable;
+                CreateProcess->DebugInfoSize = NtHeader->FileHeader.
+                                               NumberOfSymbols;
+            }
+        }
+        else
+        {
+            /* Otherwise it's a thread message */
+            ApiMessage.ApiNumber = DbgKmCreateThreadApi;
+            CreateThread->StartAddress = ThisThread->StartAddress;
+        }
+
+        /* Queue the message */
+        Status = DbgkpQueueMessage(Process,
+                                   ThisThread,
+                                   &ApiMessage,
+                                   Flags,
+                                   DebugObject);
+        if (!NT_SUCCESS(Status))
+        {
+            /* We failed. FIXME: Handle this */
+            DPRINT1("Unhandled Dbgk codepath!\n");
+            KEBUGCHECK(0);
+        }
+
+        /* Check if this was the first message */
+        if (First)
+        {
+            /* It isn't the first thread anymore */
+            IsFirstThread = FALSE;
+
+            /* Reference this thread and set it as first */
+            ObDereferenceObject(ThisThread);
+            pFirstThread = ThisThread;
+        }
+
+        /* Get the next thread */
+        ThisThread = PsGetNextProcessThread(Process, ThisThread);
+        OldThread = pLastThread;
+    } while(ThisThread);
+
+    /* Check the API status */
+    if (!NT_SUCCESS(Status))
+    {
+        /* We failed. FIXME: Handle this */
+        DPRINT1("Unhandled Dbgk codepath!\n");
+        KEBUGCHECK(0);
+    }
+
+    /* Make sure we have a first thread */
+    if (!pFirstThread) return STATUS_UNSUCCESSFUL;
+
+    /* Return thread pointers */
+    *FirstThread = pFirstThread;
+    *LastThread = pLastThread;
+    return Status;
 }
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/include/internal/dbgk.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/dbgk.h?rev=24980&r1=24979&r2=24980&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/dbgk.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/dbgk.h Thu Nov 30 04:57:25 2006
@@ -19,6 +19,21 @@
     IN NTSTATUS ExitStatus
 );
 
+VOID
+NTAPI
+DbgkMapViewOfSection(
+    IN HANDLE SectionHandle,
+    IN PVOID BaseAddress,
+    IN ULONG SectionOffset,
+    IN ULONG_PTR ViewSize
+);
+
+VOID
+NTAPI
+DbgkUnMapViewOfSection(
+    IN PVOID BaseAddress
+);
+
 BOOLEAN
 NTAPI
 DbgkpSuspendProcess(
@@ -36,6 +51,12 @@
 DbgkpSendApiMessage(
     IN OUT PDBGKM_MSG ApiMsg,
     IN ULONG Flags
+);
+
+HANDLE
+NTAPI
+DbgkpSectionToFileHandle(
+    IN PVOID Section
 );
 
 VOID

Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ps.h?rev=24980&r1=24979&r2=24980&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ps.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h Thu Nov 30 04:57:25 2006
@@ -338,6 +338,13 @@
 NTSTATUS
 NTAPI
 PsResumeThread(
+    IN PETHREAD Thread,
+    OUT PULONG PreviousCount OPTIONAL
+);
+
+NTSTATUS
+NTAPI
+PsSuspendThread(
     IN PETHREAD Thread,
     OUT PULONG PreviousCount OPTIONAL
 );

Modified: trunk/reactos/ntoskrnl/mm/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=24980&r1=24979&r2=24980&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c (original)
+++ trunk/reactos/ntoskrnl/mm/section.c Thu Nov 30 04:57:25 2006
@@ -3742,6 +3742,18 @@
                                AllocationType,
                                Protect);
 
+   /* Check if this is an image for the current process */
+   if ((Section->AllocationAttributes & SEC_IMAGE) &&
+       (Process == PsGetCurrentProcess()) &&
+       (Status != STATUS_IMAGE_NOT_AT_BASE))
+   {
+        /* Notify the debugger */
+       DbgkMapViewOfSection(SectionHandle,
+                            SafeBaseAddress,
+                            SafeSectionOffset.LowPart,
+                            SafeViewSize);
+   }
+
    ObDereferenceObject(Section);
    ObDereferenceObject(Process);
 
@@ -3945,6 +3957,7 @@
    PROS_SECTION_OBJECT Section;
    PMM_PAGEOP PageOp;
    ULONG_PTR Offset;
+    PVOID ImageBaseAddress = 0;
 
    DPRINT("Opening memory area Process %x BaseAddress %x\n",
           Process, BaseAddress);
@@ -4007,7 +4020,6 @@
       ULONG NrSegments;
       PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
       PMM_SECTION_SEGMENT SectionSegments;
-      PVOID ImageBaseAddress = 0;
       PMM_SECTION_SEGMENT Segment;
 
       Segment = MemoryArea->Data.SectionData.Segment;
@@ -4048,6 +4060,10 @@
    {
       Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
    }
+
+   /* Notify debugger */
+   if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress);
+
    MmUnlockAddressSpace(AddressSpace);
    return(STATUS_SUCCESS);
 }




More information about the Ros-diffs mailing list