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?re... ============================================================================== --- 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=2... ============================================================================== --- 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