[ros-diffs] [ion] 24731: - Fix flags in DbgkpSectionToFileHandle - Implement DbgkpCreateThread. - Implement DbgkpSetProcessDebugObject.

ion at svn.reactos.org ion at svn.reactos.org
Sun Nov 12 23:33:05 CET 2006


Author: ion
Date: Mon Nov 13 01:33:04 2006
New Revision: 24731

URL: http://svn.reactos.org/svn/reactos?rev=24731&view=rev
Log:
- Fix flags in DbgkpSectionToFileHandle
- Implement DbgkpCreateThread.
- Implement DbgkpSetProcessDebugObject.

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

Modified: trunk/reactos/ntoskrnl/dbgk/dbgkutil.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/dbgkutil.c?rev=24731&r1=24730&r2=24731&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/dbgk/dbgkutil.c (original)
+++ trunk/reactos/ntoskrnl/dbgk/dbgkutil.c Mon Nov 13 01:33:04 2006
@@ -10,7 +10,7 @@
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
 
 /* FUNCTIONS *****************************************************************/
 
@@ -32,7 +32,9 @@
     /* Initialize object attributes */
     InitializeObjectAttributes(&ObjectAttributes,
                                &FileName,
-                               OBJ_CASE_INSENSITIVE,
+                               OBJ_CASE_INSENSITIVE |
+                               OBJ_FORCE_ACCESS_CHECK |
+                               OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL);
 
@@ -84,7 +86,209 @@
 NTAPI
 DbgkCreateThread(PVOID StartAddress)
 {
-    /* FIXME */
+    PETHREAD Thread = PsGetCurrentThread();
+    PEPROCESS Process = PsGetCurrentProcess();
+    ULONG ProcessFlags;
+    IMAGE_INFO ImageInfo;
+    PIMAGE_NT_HEADERS NtHeader;
+    UNICODE_STRING ModuleName;
+    NTSTATUS Status;
+    PVOID DebugPort;
+    DBGKM_MSG ApiMessage;
+    PDBGKM_CREATE_THREAD CreateThread = &ApiMessage.CreateThread;
+    PDBGKM_CREATE_PROCESS CreateProcess = &ApiMessage.CreateProcess;
+    PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    PTEB Teb;
+    PAGED_CODE();
+
+    /* Check if this process has already been notified */
+    ProcessFlags = InterlockedAnd(&Process->Flags,
+                                  PSF_CREATE_REPORTED_BIT |
+                                  PSF_IMAGE_NOTIFY_DONE_BIT);
+    if (!(ProcessFlags & PSF_IMAGE_NOTIFY_DONE_BIT) && (PsImageNotifyEnabled))
+    {
+        /* It hasn't.. set up the image info for the process */
+        ImageInfo.Properties = 0;
+        ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
+        ImageInfo.ImageBase = Process->SectionBaseAddress;
+        ImageInfo.ImageSize = 0;
+        ImageInfo.ImageSelector = 0;
+        ImageInfo.ImageSectionNumber = 0;
+
+        /* Get the NT Headers */
+        NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
+        if (NtHeader)
+        {
+            /* Set image size */
+            ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage;
+        }
+
+        /* Get the image name */
+        Status = MmGetFileNameForSection(Process->SectionObject, &ModuleName);
+        if (NT_SUCCESS(Status))
+        {
+            /* Call the notify routines and free the name */
+            PspRunLoadImageNotifyRoutines(&ModuleName,
+                                          Process->UniqueProcessId,
+                                          &ImageInfo);
+            ExFreePool(ModuleName.Buffer);
+        }
+        else
+        {
+            /* Call the notify routines */
+            PspRunLoadImageNotifyRoutines(NULL,
+                                          Process->UniqueProcessId,
+                                          &ImageInfo);
+        }
+
+        /* Setup the info for ntdll.dll */
+        ImageInfo.Properties = 0;
+        ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
+        ImageInfo.ImageBase = PspSystemDllBase;
+        ImageInfo.ImageSize = 0;
+        ImageInfo.ImageSelector = 0;
+        ImageInfo.ImageSectionNumber = 0;
+
+        /* Get the NT Headers */
+        NtHeader = RtlImageNtHeader(PspSystemDllBase);
+        if (NtHeader)
+        {
+            /* Set image size */
+            ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage;
+        }
+
+        /* Call the notify routines */
+        RtlInitUnicodeString(&ModuleName,
+                             L"\\SystemRoot\\System32\\ntdll.dll");
+        PspRunLoadImageNotifyRoutines(&ModuleName,
+                                      Process->UniqueProcessId,
+                                      &ImageInfo);
+    }
+
+    /* Fail if we have no port */
+    DebugPort = Process->DebugPort;
+    if (DebugPort) return;
+
+    /* Check if create was not already reported */
+    if (!(ProcessFlags & PSF_CREATE_REPORTED_BIT))
+    {
+        /* Setup the information structure for the new thread */
+        CreateThread->SubSystemKey = 0;
+        CreateThread->StartAddress = NULL;
+
+        /* And for the new process */
+        CreateProcess->SubSystemKey = 0;
+        CreateProcess->FileHandle = DbgkpSectionToFileHandle(Process->
+                                                             SectionObject);
+        CreateProcess->BaseOfImage = Process->SectionBaseAddress;
+        CreateProcess->DebugInfoFileOffset = 0;
+        CreateProcess->DebugInfoSize = 0;
+
+        /* Get the NT Header */
+        NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
+        if (NtHeader)
+        {
+            /* Fill out data from the header */
+            CreateThread->StartAddress = (PVOID)((ULONG_PTR)NtHeader->
+                                                 OptionalHeader.ImageBase +
+                                                 NtHeader->OptionalHeader.
+                                                 AddressOfEntryPoint);
+            CreateProcess->DebugInfoFileOffset = NtHeader->FileHeader.
+                                                 PointerToSymbolTable;
+            CreateProcess->DebugInfoSize = NtHeader->FileHeader.
+                                           NumberOfSymbols;
+        }
+
+        /* Setup the API Message */
+        ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
+                                 (8 + sizeof(DBGKM_CREATE_PROCESS));
+        ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
+        ApiMessage.ApiNumber = DbgKmCreateProcessApi;
+
+        /* Send the message */
+        DbgkpSendApiMessage(&ApiMessage, FALSE);
+
+        /* Close the handle */
+        ObCloseHandle(CreateProcess->FileHandle, KernelMode);
+
+        /* Setup the parameters */
+        LoadDll->BaseOfDll = PspSystemDllBase;
+        LoadDll->DebugInfoFileOffset = 0;
+        LoadDll->DebugInfoSize = 0;
+        LoadDll->NamePointer = NULL;
+
+        /* Get the NT Headers */
+        NtHeader = RtlImageNtHeader(PspSystemDllBase);
+        if (NtHeader)
+        {
+            /* Fill out debug information */
+            LoadDll->DebugInfoFileOffset = NtHeader->
+                                           FileHeader.PointerToSymbolTable;
+            LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
+        }
+
+        /* Get the TEB */
+        Teb = Thread->Tcb.Teb;
+        if (Teb)
+        {
+            /* Copy the system library name and link to it */
+            wcsncpy(Teb->StaticUnicodeBuffer,
+                    L"ntdll.dll",
+                    sizeof(Teb->StaticUnicodeBuffer));
+            Teb->Tib.ArbitraryUserPointer = Teb->StaticUnicodeBuffer;
+
+            /* Return it in the debug event as well */
+            LoadDll->NamePointer = Teb->Tib.ArbitraryUserPointer;
+        }
+
+        /* Get a handle */
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &PsNtDllPathName,
+                                   OBJ_CASE_INSENSITIVE |
+                                   OBJ_KERNEL_HANDLE |
+                                   OBJ_FORCE_ACCESS_CHECK,
+                                   NULL,
+                                   NULL);
+        Status = ZwOpenFile(&LoadDll->FileHandle,
+                            GENERIC_READ | SYNCHRONIZE,
+                            &ObjectAttributes,
+                            &IoStatusBlock,
+                            FILE_SHARE_DELETE |
+                            FILE_SHARE_READ |
+                            FILE_SHARE_WRITE,
+                            FILE_SYNCHRONOUS_IO_NONALERT);
+        if (NT_SUCCESS(Status))
+        {
+            /* Setup the API Message */
+            ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
+                                     (8 + sizeof(DBGKM_LOAD_DLL));
+            ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
+            ApiMessage.ApiNumber = DbgKmLoadDllApi;
+
+            /* Send the message */
+            DbgkpSendApiMessage(&ApiMessage, TRUE);
+
+            /* Close the handle */
+            ObCloseHandle(LoadDll->FileHandle, KernelMode);
+        }
+    }
+    else
+    {
+        /* Otherwise, do it just for the thread */
+        CreateThread->SubSystemKey = 0;
+        CreateThread->StartAddress = NULL;
+
+        /* Setup the API Message */
+        ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
+                                 (8 + sizeof(DBGKM_CREATE_THREAD));
+        ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
+        ApiMessage.ApiNumber = DbgKmCreateThreadApi;
+
+        /* Send the message */
+        DbgkpSendApiMessage(&ApiMessage, TRUE);
+    }
 }
 
 VOID

Modified: trunk/reactos/ntoskrnl/dbgk/debug.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/debug.c?rev=24731&r1=24730&r2=24731&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/dbgk/debug.c (original)
+++ trunk/reactos/ntoskrnl/dbgk/debug.c Mon Nov 13 01:33:04 2006
@@ -32,26 +32,6 @@
 };
 
 /* 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
@@ -967,6 +947,159 @@
         DebugEvent->Status = STATUS_DEBUGGER_INACTIVE;
         DbgkpWakeTarget(DebugEvent);
     }
+}
+
+NTSTATUS
+NTAPI
+DbgkpSetProcessDebugObject(IN PEPROCESS Process,
+                           IN PDEBUG_OBJECT DebugObject,
+                           IN NTSTATUS MsgStatus,
+                           IN PETHREAD LastThread)
+{
+    NTSTATUS Status;
+    LIST_ENTRY TempList;
+    BOOLEAN GlobalHeld = FALSE;
+    PETHREAD ThisThread, FirstThread;
+    PLIST_ENTRY NextEntry;
+    PAGED_CODE();
+
+    /* Initialize the temporary list */
+    InitializeListHead(&TempList);
+
+    /* Check if we have a success message */
+    if (NT_SUCCESS(MsgStatus))
+    {
+        /* Then default to STATUS_SUCCESS */
+        Status = STATUS_SUCCESS;
+    }
+    else
+    {
+        /* No last thread, and set the failure code */
+        LastThread = NULL;
+        Status = MsgStatus;
+    }
+
+    /* Now check what status we have here */
+    if (NT_SUCCESS(Status))
+    {
+        /* Acquire the global lock */
+        GlobalHeld = TRUE;
+        ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
+
+        /* Check if we already have a port */
+        if (Process->DebugPort)
+        {
+            /* Set failure */
+            Status = STATUS_PORT_ALREADY_SET;
+        }
+        else
+        {
+ThreadScan:
+            /* Otherwise, set the port and reference the thread */
+            Process->DebugPort = DebugObject;
+            ObReferenceObject(LastThread);
+
+            /* Get the next thread */
+            ThisThread  = PsGetNextProcessThread(Process, LastThread);
+            if (ThisThread)
+            {
+                /* Clear the debug port and release the lock */
+                Process->DebugPort = NULL;
+                ExReleaseFastMutex(&DbgkpProcessDebugPortMutex);
+                GlobalHeld = FALSE;
+
+                /* Dereference the thread */
+                ObDereferenceObject(LastThread);
+
+                /* Post fake messages */
+                Status = DbgkpPostFakeThreadMessages(Process,
+                                                     DebugObject,
+                                                     ThisThread,
+                                                     &FirstThread,
+                                                     &LastThread);
+                if (!NT_SUCCESS(Status))
+                {
+                    /* Clear the last thread */
+                    LastThread = NULL;
+                }
+                else
+                {
+                    /* Dereference the first thread and re-acquire the lock */
+                    ObDereferenceObject(FirstThread);
+                    GlobalHeld = TRUE;
+                    ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
+
+                    /* Check if we should loop again */
+                    if (!Process->DebugPort) goto ThreadScan;
+
+                    /* Otherwise, we already have a port */
+                    Status = STATUS_PORT_ALREADY_SET;
+                }
+            }
+        }
+    }
+
+    /* Acquire the debug object's lock */
+    ExAcquireFastMutex(&DebugObject->Mutex);
+
+    /* Check our status here */
+    if (NT_SUCCESS(Status))
+    {
+        /* Check if we're disconnected */
+        if (DebugObject->DebuggerInactive)
+        {
+            /* Set status */
+            Process->DebugPort = NULL;
+            Status = STATUS_DEBUGGER_INACTIVE;
+        }
+        else
+        {
+            /* Set the process flags */
+            InterlockedOr(&Process->Flags, PSF_NO_DEBUG_INHERIT_BIT |
+                                           PSF_CREATE_REPORTED_BIT);
+
+            /* Reference the debug object */
+            ObDereferenceObject(DebugObject);
+        }
+    }
+
+    /* Loop the events list */
+    NextEntry = DebugObject->EventList.Flink;
+    while (NextEntry != &DebugObject->EventList)
+    {
+        /* FIXME: TODO */
+        KEBUGCHECK(0);
+    }
+
+    /* Release the debug object */
+    ExReleaseFastMutex(&DebugObject->Mutex);
+
+    /* Release the global lock if acquired */
+    if (GlobalHeld) ExReleaseFastMutex(&DbgkpProcessDebugPortMutex);
+
+    /* Check if there's a thread to dereference */
+    if (LastThread) ObDereferenceObject(LastThread);
+
+    /* Loop our temporary list */
+    NextEntry = TempList.Flink;
+    while (NextEntry != &TempList)
+    {
+        /* FIXME: TODO */
+        KEBUGCHECK(0);
+    }
+
+    /* Check if we got here through success and mark the PEB, then return */
+    if (NT_SUCCESS(Status)) DbgkpMarkProcessPeb(Process);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+DbgkClearProcessDebugObject(IN PEPROCESS Process,
+                            IN PDEBUG_OBJECT SourceDebugObject)
+{
+    /* FIXME: TODO */
+    return STATUS_UNSUCCESSFUL;
 }
 
 VOID




More information about the Ros-diffs mailing list