- 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).

svn path=/trunk/; revision=24614
This commit is contained in:
Alex Ionescu 2006-10-22 20:56:24 +00:00
parent 024e1d9725
commit 756da82c2f
4 changed files with 229 additions and 9 deletions

View file

@ -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 @@ VOID
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 */
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
DbgkpSuspendProcess(VOID)
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
DbgkpResumeProcess(VOID)
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 */

View file

@ -19,7 +19,7 @@ DbgkExitThread(
IN NTSTATUS ExitStatus
);
VOID
BOOLEAN
NTAPI
DbgkpSuspendProcess(
VOID
@ -31,6 +31,13 @@ DbgkpResumeProcess(
VOID
);
NTSTATUS
NTAPI
DbgkpSendApiMessage(
IN OUT PDBGKM_MSG ApiMsg,
IN ULONG Flags
);
VOID
NTAPI
DbgkCopyProcessDebugPort(

View file

@ -1322,6 +1322,13 @@ MmGetFileNameForAddress(
OUT PUNICODE_STRING ModuleName
);
NTSTATUS
NTAPI
MmGetFileNameForSection(
IN PROS_SECTION_OBJECT Section,
OUT PUNICODE_STRING ModuleName
);
PVOID
NTAPI
MmAllocateSection(

View file

@ -106,6 +106,16 @@ MmGetFileObjectForSection(IN PROS_SECTION_OBJECT Section)
return Section->FileObject; // Section->ControlArea->FileObject on NT
}
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,
@ -118,10 +128,8 @@ MmGetFileNameForAddress(IN PVOID Address,
* 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;