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=…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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=…
==============================================================================
--- 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);
}