Author: ion Date: Mon Oct 23 00:56:24 2006 New Revision: 24614
URL: http://svn.reactos.org/svn/reactos?rev=24614&view=rev Log: - Implement helper routine DbgkpSectionToFileHandle and stub MmGetFileNameForSection (easy ObQueryNameString-based implementation to do later). - Implement helpers DbgkpSuspendProcess and DbgkpResumeProcess based on KeFreeze/ThawAllThreads. - Implement DbgkExitProcess, DbgkExitThread, DbgkMapViewOfSection, DbgkUnmapViewOfSection. Apart from DbgkCreateThread, these are the main notification APIs that Dbgk uses for user-mode debug events. (Mm code needs to be changed to call the map/unmap notifications. Ps already calls the exit/create ones).
Modified: trunk/reactos/ntoskrnl/dbgk/dbgkutil.c trunk/reactos/ntoskrnl/include/internal/dbgk.h trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/mm/section.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 Oct 23 00:56:24 2006 @@ -14,6 +14,72 @@
/* FUNCTIONS *****************************************************************/
+HANDLE +NTAPI +DbgkpSectionToFileHandle(IN PVOID Section) +{ + NTSTATUS Status; + UNICODE_STRING FileName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE Handle; + PAGED_CODE(); + + /* Get the filename of the section */ + Status = MmGetFileNameForSection(Section, &FileName); + if (!NT_SUCCESS(Status)) return NULL; + + /* Initialize object attributes */ + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the file */ + Status = ZwOpenFile(&Handle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + + /* Free the name and return the handle if we succeeded */ + ExFreePool(FileName.Buffer); + if (!NT_SUCCESS(Status)) return NULL; + return Handle; +} + +BOOLEAN +NTAPI +DbgkpSuspendProcess(VOID) +{ + PAGED_CODE(); + + /* Make sure this isn't a deleted process */ + if (PsGetCurrentProcess()->ProcessDelete) + { + /* Freeze all the threads */ + KeFreezeAllThreads(); + return TRUE; + } + else + { + /* No suspend was done */ + return FALSE; + } +} + +VOID +NTAPI +DbgkpResumeProcess(VOID) +{ + PAGED_CODE(); + + /* Thaw all the threads */ + KeThawAllThreads(); +} + VOID NTAPI DbgkCreateThread(PVOID StartAddress) @@ -25,28 +91,160 @@ NTAPI DbgkExitProcess(IN NTSTATUS ExitStatus) { - /* FIXME */ + DBGKM_MSG ApiMessage; + PDBGKM_EXIT_PROCESS ExitProcess = &ApiMessage.ExitProcess; + PEPROCESS Process = PsGetCurrentProcess(); + PETHREAD Thread = PsGetCurrentThread(); + PAGED_CODE(); + + /* Check if this thread is hidden, doesn't have a debug port, or died */ + if ((Thread->HideFromDebugger) || + !(Process->DebugPort) || + (Thread->DeadThread)) + { + /* Don't notify the debugger */ + return; + } + + /* Set the exit status */ + ExitProcess->ExitStatus = ExitStatus; + + /* Setup the API Message */ + ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | + (8 + sizeof(DBGKM_EXIT_PROCESS)); + ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT; + ApiMessage.ApiNumber = DbgKmExitProcessApi; + + /* Set the current exit time */ + KeQuerySystemTime(&Process->ExitTime); + + /* Send the message */ + DbgkpSendApiMessage(&ApiMessage, FALSE); }
VOID NTAPI DbgkExitThread(IN NTSTATUS ExitStatus) { - /* FIXME */ -} - -VOID -NTAPI -DbgkpSuspendProcess(VOID) -{ - -} - -VOID -NTAPI -DbgkpResumeProcess(VOID) -{ - + DBGKM_MSG ApiMessage; + PDBGKM_EXIT_THREAD ExitThread = &ApiMessage.ExitThread; + PEPROCESS Process = PsGetCurrentProcess(); + PETHREAD Thread = PsGetCurrentThread(); + BOOLEAN Suspended; + PAGED_CODE(); + + /* Check if this thread is hidden, doesn't have a debug port, or died */ + if ((Thread->HideFromDebugger) || + !(Process->DebugPort) || + (Thread->DeadThread)) + { + /* Don't notify the debugger */ + return; + } + + /* Set the exit status */ + ExitThread->ExitStatus = ExitStatus; + + /* Setup the API Message */ + ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | + (8 + sizeof(DBGKM_EXIT_THREAD)); + ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT; + ApiMessage.ApiNumber = DbgKmExitThreadApi; + + /* Suspend the process */ + Suspended = DbgkpSuspendProcess(); + + /* Send the message */ + DbgkpSendApiMessage(&ApiMessage, FALSE); + + /* Resume the process if needed */ + if (Suspended) DbgkpResumeProcess(); +} + +VOID +NTAPI +DbgkMapViewOfSection(IN HANDLE SectionHandle, + IN PVOID BaseAddress, + IN ULONG SectionOffset, + IN ULONG_PTR ViewSize) +{ + DBGKM_MSG ApiMessage; + PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll; + PEPROCESS Process = PsGetCurrentProcess(); + PETHREAD Thread = PsGetCurrentThread(); + PIMAGE_NT_HEADERS NtHeader; + PAGED_CODE(); + + /* Check if this thread is hidden, doesn't have a debug port, or died */ + if ((Thread->HideFromDebugger) || + !(Process->DebugPort) || + (Thread->DeadThread) || + (KeGetPreviousMode() == KernelMode)) + { + /* Don't notify the debugger */ + return; + } + + /* Setup the parameters */ + LoadDll->FileHandle = DbgkpSectionToFileHandle(SectionHandle); + LoadDll->BaseOfDll = BaseAddress; + LoadDll->DebugInfoFileOffset = 0; + LoadDll->DebugInfoSize = 0; + + /* Get the NT Headers */ + NtHeader = RtlImageNtHeader(BaseAddress); + if (NtHeader) + { + /* Fill out debug information */ + LoadDll->DebugInfoFileOffset = NtHeader->FileHeader. + PointerToSymbolTable; + LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols; + } + + /* 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); +} + +VOID +NTAPI +DbgkUnMapViewOfSection(IN PVOID BaseAddress) +{ + DBGKM_MSG ApiMessage; + PDBGKM_UNLOAD_DLL UnloadDll = &ApiMessage.UnloadDll; + PEPROCESS Process = PsGetCurrentProcess(); + PETHREAD Thread = PsGetCurrentThread(); + PAGED_CODE(); + + /* Check if this thread is hidden, doesn't have a debug port, or died */ + if ((Thread->HideFromDebugger) || + !(Process->DebugPort) || + (Thread->DeadThread) || + (KeGetPreviousMode() == KernelMode)) + { + /* Don't notify the debugger */ + return; + } + + /* Set the DLL Base */ + UnloadDll->BaseAddress = BaseAddress; + + /* Setup the API Message */ + ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | + (8 + sizeof(DBGKM_UNLOAD_DLL)); + ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT; + ApiMessage.ApiNumber = DbgKmUnloadDllApi; + + /* Send the message */ + DbgkpSendApiMessage(&ApiMessage, TRUE); }
/* EOF */
Modified: trunk/reactos/ntoskrnl/include/internal/dbgk.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/d... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/dbgk.h (original) +++ trunk/reactos/ntoskrnl/include/internal/dbgk.h Mon Oct 23 00:56:24 2006 @@ -19,7 +19,7 @@ IN NTSTATUS ExitStatus );
-VOID +BOOLEAN NTAPI DbgkpSuspendProcess( VOID @@ -29,6 +29,13 @@ NTAPI DbgkpResumeProcess( VOID +); + +NTSTATUS +NTAPI +DbgkpSendApiMessage( + IN OUT PDBGKM_MSG ApiMsg, + IN ULONG Flags );
VOID
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/m... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/mm.h (original) +++ trunk/reactos/ntoskrnl/include/internal/mm.h Mon Oct 23 00:56:24 2006 @@ -1322,6 +1322,13 @@ OUT PUNICODE_STRING ModuleName );
+NTSTATUS +NTAPI +MmGetFileNameForSection( + IN PROS_SECTION_OBJECT Section, + OUT PUNICODE_STRING ModuleName +); + PVOID NTAPI MmAllocateSection(
Modified: trunk/reactos/ntoskrnl/mm/section.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/mm/section.c (original) +++ trunk/reactos/ntoskrnl/mm/section.c Mon Oct 23 00:56:24 2006 @@ -108,6 +108,16 @@
NTSTATUS NTAPI +MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section, + OUT PUNICODE_STRING ModuleName) +{ + /* FIXME: TODO. ObQueryNameString on the FileObject */ + RtlCreateUnicodeString(ModuleName, L"C:\ReactOS\system32\ntdll.dll"); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI MmGetFileNameForAddress(IN PVOID Address, OUT PUNICODE_STRING ModuleName) { @@ -118,10 +128,8 @@ * corresponds to the address. Then make sure it's a section * view type (MEMORY_AREA_SECTION_VIEW) and use the marea's * per-type union to get the .u.SectionView.Section pointer to - * the SECTION_OBJECT. Then we can use MmGetFileObjectForSection - * to get the FILE_OBJECT, from which we can then query the name - * to get the full filename (much like we do for creating the - * SeAuditName in EPROCESS. + * the SECTION_OBJECT. Then we can use MmGetFileNameForSection + * to get the full filename. */ RtlCreateUnicodeString(ModuleName, L"C:\ReactOS\system32\ntdll.dll"); return STATUS_SUCCESS;