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?r…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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=…
==============================================================================
--- 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;