2009-10-12 11:35:35 +08:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: ntoskrnl/kd64/kdapi.c
|
|
|
|
* PURPOSE: KD64 Public Routines and Internal Support
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
2009-10-24 06:51:39 +08:00
|
|
|
* Stefan Ginsberg (stefan.ginsberg@reactos.org)
|
2009-10-12 11:35:35 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
2023-04-05 05:38:32 +08:00
|
|
|
|
|
|
|
#ifdef KDBG
|
|
|
|
#include <kdbg/kdb.h>
|
|
|
|
#endif
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
|
|
|
|
2015-10-15 20:56:19 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2019-11-18 05:28:42 +08:00
|
|
|
KdpMoveMemory(
|
|
|
|
_In_ PVOID Destination,
|
|
|
|
_In_ PVOID Source,
|
|
|
|
_In_ SIZE_T Length)
|
2015-10-15 20:56:19 +08:00
|
|
|
{
|
|
|
|
PCHAR DestinationBytes, SourceBytes;
|
|
|
|
|
|
|
|
/* Copy the buffers 1 byte at a time */
|
|
|
|
DestinationBytes = Destination;
|
|
|
|
SourceBytes = Source;
|
|
|
|
while (Length--) *DestinationBytes++ = *SourceBytes++;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2019-11-18 05:28:42 +08:00
|
|
|
KdpZeroMemory(
|
|
|
|
_In_ PVOID Destination,
|
|
|
|
_In_ SIZE_T Length)
|
2015-10-15 20:56:19 +08:00
|
|
|
{
|
|
|
|
PCHAR DestinationBytes;
|
|
|
|
|
|
|
|
/* Zero the buffer 1 byte at a time */
|
|
|
|
DestinationBytes = Destination;
|
|
|
|
while (Length--) *DestinationBytes++ = 0;
|
|
|
|
}
|
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2019-11-18 05:28:42 +08:00
|
|
|
KdpCopyMemoryChunks(
|
|
|
|
_In_ ULONG64 Address,
|
|
|
|
_In_ PVOID Buffer,
|
|
|
|
_In_ ULONG TotalSize,
|
|
|
|
_In_ ULONG ChunkSize,
|
|
|
|
_In_ ULONG Flags,
|
|
|
|
_Out_opt_ PULONG ActualSize)
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2009-10-31 09:02:35 +08:00
|
|
|
ULONG RemainingLength, CopyChunk;
|
2009-10-14 03:45:40 +08:00
|
|
|
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Check if we didn't get a chunk size or if it is too big */
|
|
|
|
if (ChunkSize == 0)
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Default to 4 byte chunks */
|
|
|
|
ChunkSize = 4;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
2009-10-31 09:02:35 +08:00
|
|
|
else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
|
|
|
|
{
|
|
|
|
/* Normalize to maximum size */
|
|
|
|
ChunkSize = MMDBG_COPY_MAX_SIZE;
|
|
|
|
}
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Copy the whole range in aligned chunks */
|
2009-10-31 09:02:35 +08:00
|
|
|
RemainingLength = TotalSize;
|
|
|
|
CopyChunk = 1;
|
|
|
|
while (RemainingLength > 0)
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
/*
|
|
|
|
* Determine the best chunk size for this round.
|
2009-11-03 01:45:51 +08:00
|
|
|
* The ideal size is aligned, isn't larger than the
|
2009-10-31 09:02:35 +08:00
|
|
|
* the remaining length and respects the chunk limit.
|
|
|
|
*/
|
|
|
|
while (((CopyChunk * 2) <= RemainingLength) &&
|
|
|
|
(CopyChunk < ChunkSize) &&
|
|
|
|
((Address & ((CopyChunk * 2) - 1)) == 0))
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Increase it */
|
2009-11-03 01:45:51 +08:00
|
|
|
CopyChunk *= 2;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
|
|
|
|
2009-10-31 09:02:35 +08:00
|
|
|
/*
|
2019-11-04 06:32:56 +08:00
|
|
|
* The chunk size can be larger than the remaining size if this
|
|
|
|
* isn't the first round, so check if we need to shrink it back.
|
2009-10-31 09:02:35 +08:00
|
|
|
*/
|
|
|
|
while (CopyChunk > RemainingLength)
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Shrink it */
|
|
|
|
CopyChunk /= 2;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
2009-10-31 09:02:35 +08:00
|
|
|
|
|
|
|
/* Do the copy */
|
2019-11-18 05:28:42 +08:00
|
|
|
Status = MmDbgCopyMemory(Address, Buffer, CopyChunk, Flags);
|
2009-10-31 09:02:35 +08:00
|
|
|
if (!NT_SUCCESS(Status))
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Copy failed, break out */
|
|
|
|
break;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
|
|
|
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Update pointers and length for the next run */
|
|
|
|
Address = Address + CopyChunk;
|
|
|
|
Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
|
|
|
|
RemainingLength = RemainingLength - CopyChunk;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
|
|
|
|
2019-11-04 06:32:56 +08:00
|
|
|
/* We may have modified executable code, flush the instruction cache */
|
|
|
|
KeSweepICache((PVOID)(ULONG_PTR)Address, TotalSize);
|
2015-09-02 07:45:48 +08:00
|
|
|
|
2009-10-31 09:02:35 +08:00
|
|
|
/*
|
2019-11-04 06:32:56 +08:00
|
|
|
* Return the size we managed to copy and return
|
|
|
|
* success if we could copy the whole range.
|
2009-10-31 09:02:35 +08:00
|
|
|
*/
|
|
|
|
if (ActualSize) *ActualSize = TotalSize - RemainingLength;
|
|
|
|
return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
PDBGKD_QUERY_MEMORY Memory = &State->u.QueryMemory;
|
|
|
|
STRING Header;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Validate the address space */
|
|
|
|
if (Memory->AddressSpace == DBGKD_QUERY_MEMORY_VIRTUAL)
|
|
|
|
{
|
|
|
|
/* Check if this is process memory */
|
|
|
|
if ((PVOID)(ULONG_PTR)Memory->Address < MmHighestUserAddress)
|
|
|
|
{
|
|
|
|
/* It is */
|
|
|
|
Memory->AddressSpace = DBGKD_QUERY_MEMORY_PROCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-11-08 09:13:49 +08:00
|
|
|
/* Check if it's session space */
|
|
|
|
if (MmIsSessionAddress((PVOID)(ULONG_PTR)Memory->Address))
|
|
|
|
{
|
|
|
|
/* It is */
|
|
|
|
Memory->AddressSpace = DBGKD_QUERY_MEMORY_SESSION;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Not session space but some other kernel memory */
|
|
|
|
Memory->AddressSpace = DBGKD_QUERY_MEMORY_KERNEL;
|
|
|
|
}
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set flags */
|
|
|
|
Memory->Flags = DBGKD_QUERY_MEMORY_READ |
|
|
|
|
DBGKD_QUERY_MEMORY_WRITE |
|
|
|
|
DBGKD_QUERY_MEMORY_EXECUTE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid */
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return structure */
|
|
|
|
State->ReturnStatus = Status;
|
|
|
|
Memory->Reserved = 0;
|
|
|
|
|
|
|
|
/* Build header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpSearchMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
//PDBGKD_SEARCH_MEMORY SearchMemory = &State->u.SearchMemory;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Memory Search support is unimplemented!\n");
|
|
|
|
|
|
|
|
/* Send a failure packet */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpFillMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
//PDBGKD_FILL_MEMORY FillMemory = &State->u.FillMemory;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Memory Fill support is unimplemented!\n");
|
|
|
|
|
|
|
|
/* Send a failure packet */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
PDBGKD_WRITE_BREAKPOINT64 Breakpoint = &State->u.WriteBreakPoint;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Build header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Create the breakpoint */
|
|
|
|
Breakpoint->BreakPointHandle =
|
|
|
|
KdpAddBreakpoint((PVOID)(ULONG_PTR)Breakpoint->BreakPointAddress);
|
|
|
|
if (!Breakpoint->BreakPointHandle)
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Success! */
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Fill out the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Get the version block */
|
|
|
|
if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle))
|
|
|
|
{
|
|
|
|
/* We're all good */
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdpWriteBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
//PDBGKD_BREAKPOINTEX = &State->u.BreakPointEx;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Extended Breakpoint Write support is unimplemented!\n");
|
|
|
|
|
|
|
|
/* Send a failure packet */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
2009-10-12 11:35:35 +08:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpRestoreBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
//PDBGKD_BREAKPOINTEX = &State->u.BreakPointEx;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Extended Breakpoint Restore support is unimplemented!\n");
|
|
|
|
|
|
|
|
/* Send a failure packet */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
2015-09-28 22:08:54 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteCustomBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
//PDBGKD_WRITE_CUSTOM_BREAKPOINT = &State->u.WriteCustomBreakpoint;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Not supported */
|
|
|
|
KdpDprintf("Custom Breakpoint Write is unimplemented\n");
|
|
|
|
|
|
|
|
/* Send a failure packet */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DumpTraceData(IN PSTRING TraceData)
|
|
|
|
{
|
|
|
|
/* Update the buffer */
|
|
|
|
TraceDataBuffer[0] = TraceDataBufferPosition;
|
|
|
|
|
|
|
|
/* Setup the trace data */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
TraceData->Length = (USHORT)(TraceDataBufferPosition * sizeof(ULONG));
|
2009-10-12 11:35:35 +08:00
|
|
|
TraceData->Buffer = (PCHAR)TraceDataBuffer;
|
|
|
|
|
|
|
|
/* Reset the buffer location */
|
|
|
|
TraceDataBufferPosition = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpSetCommonState(IN ULONG NewState,
|
|
|
|
IN PCONTEXT Context,
|
2009-10-25 23:56:38 +08:00
|
|
|
IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
|
2009-10-12 11:35:35 +08:00
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
ULONG InstructionCount;
|
2009-10-12 11:35:35 +08:00
|
|
|
BOOLEAN HadBreakpoints;
|
|
|
|
|
|
|
|
/* Setup common stuff available for all CPU architectures */
|
|
|
|
WaitStateChange->NewState = NewState;
|
|
|
|
WaitStateChange->ProcessorLevel = KeProcessorLevel;
|
|
|
|
WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;
|
|
|
|
WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;
|
|
|
|
WaitStateChange->Thread = (ULONG64)(LONG_PTR)KeGetCurrentThread();
|
|
|
|
WaitStateChange->ProgramCounter = (ULONG64)(LONG_PTR)KeGetContextPc(Context);
|
|
|
|
|
2009-10-25 23:56:38 +08:00
|
|
|
/* Zero out the entire Control Report */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpZeroMemory(&WaitStateChange->AnyControlReport,
|
2009-10-25 23:56:38 +08:00
|
|
|
sizeof(DBGKD_ANY_CONTROL_REPORT));
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Now copy the instruction stream and set the count */
|
2009-10-31 09:02:35 +08:00
|
|
|
KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
|
|
|
|
&WaitStateChange->ControlReport.InstructionStream[0],
|
|
|
|
DBGKD_MAXSTREAM,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE,
|
|
|
|
&InstructionCount);
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
WaitStateChange->ControlReport.InstructionCount = (USHORT)InstructionCount;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Clear all the breakpoints in this region */
|
|
|
|
HadBreakpoints =
|
|
|
|
KdpDeleteBreakpointRange((PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
|
|
|
|
(PVOID)((ULONG_PTR)WaitStateChange->ProgramCounter +
|
|
|
|
WaitStateChange->ControlReport.InstructionCount - 1));
|
|
|
|
if (HadBreakpoints)
|
|
|
|
{
|
|
|
|
/* Copy the instruction stream again, this time without breakpoints */
|
2009-10-31 09:02:35 +08:00
|
|
|
KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
|
|
|
|
&WaitStateChange->ControlReport.InstructionStream[0],
|
|
|
|
InstructionCount,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE,
|
|
|
|
NULL);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
|
|
|
|
{
|
|
|
|
/* Copy the version block */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpMoveMemory(Version,
|
|
|
|
&KdVersionBlock,
|
|
|
|
sizeof(DBGKD_GET_VERSION64));
|
2009-11-03 01:45:51 +08:00
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpGetVersion(IN PDBGKD_MANIPULATE_STATE64 State)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Fill out the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Get the version block */
|
|
|
|
KdpSysGetVersion(&State->u.GetVersion64);
|
|
|
|
|
|
|
|
/* Fill out the state */
|
|
|
|
State->ApiNumber = DbgKdGetVersionApi;
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-10-14 03:45:40 +08:00
|
|
|
PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
|
2009-10-12 11:35:35 +08:00
|
|
|
STRING Header;
|
2009-10-14 03:45:40 +08:00
|
|
|
ULONG Length = ReadMemory->TransferCount;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Validate length */
|
|
|
|
if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
|
|
|
|
{
|
|
|
|
/* Overflow, set it to maximum possible */
|
|
|
|
Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
}
|
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
/* Do the read */
|
|
|
|
State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress,
|
|
|
|
Data->Buffer,
|
|
|
|
Length,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE,
|
|
|
|
&Length);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
/* Return the actual length read */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
ReadMemory->ActualBytesRead = Length;
|
|
|
|
Data->Length = (USHORT)Length;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-10-14 03:45:40 +08:00
|
|
|
PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Do the write */
|
|
|
|
State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress,
|
|
|
|
Data->Buffer,
|
|
|
|
Data->Length,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE |
|
|
|
|
MMDBG_COPY_WRITE,
|
|
|
|
&WriteMemory->ActualBytesWritten);
|
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2019-11-02 08:02:35 +08:00
|
|
|
KdpReadPhysicalMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
2009-10-12 11:35:35 +08:00
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-10-14 03:45:40 +08:00
|
|
|
PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
|
2009-10-12 11:35:35 +08:00
|
|
|
STRING Header;
|
2009-10-14 03:45:40 +08:00
|
|
|
ULONG Length = ReadMemory->TransferCount;
|
|
|
|
ULONG Flags, CacheFlags;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
/* Setup the header */
|
2009-10-12 11:35:35 +08:00
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
2009-10-14 03:45:40 +08:00
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Validate length */
|
|
|
|
if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
|
|
|
|
{
|
|
|
|
/* Overflow, set it to maximum possible */
|
|
|
|
Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
}
|
2009-10-12 11:35:35 +08:00
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
/* Start with the default flags */
|
|
|
|
Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_PHYSICAL;
|
|
|
|
|
|
|
|
/* Get the caching flags and check if a type is specified */
|
|
|
|
CacheFlags = ReadMemory->ActualBytesRead;
|
|
|
|
if (CacheFlags == DBGKD_CACHING_CACHED)
|
|
|
|
{
|
|
|
|
/* Cached */
|
|
|
|
Flags |= MMDBG_COPY_CACHED;
|
|
|
|
}
|
|
|
|
else if (CacheFlags == DBGKD_CACHING_UNCACHED)
|
|
|
|
{
|
|
|
|
/* Uncached */
|
|
|
|
Flags |= MMDBG_COPY_UNCACHED;
|
|
|
|
}
|
2009-11-05 06:40:18 +08:00
|
|
|
else if (CacheFlags == DBGKD_CACHING_WRITE_COMBINED)
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
|
|
|
/* Write Combined */
|
2009-11-05 06:40:18 +08:00
|
|
|
Flags |= MMDBG_COPY_WRITE_COMBINED;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Do the read */
|
|
|
|
State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress,
|
|
|
|
Data->Buffer,
|
|
|
|
Length,
|
|
|
|
0,
|
|
|
|
Flags,
|
|
|
|
&Length);
|
|
|
|
|
|
|
|
/* Return the actual length read */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
ReadMemory->ActualBytesRead = Length;
|
|
|
|
Data->Length = (USHORT)Length;
|
2009-10-14 03:45:40 +08:00
|
|
|
|
|
|
|
/* Send the packet */
|
2009-10-12 11:35:35 +08:00
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2019-11-02 08:02:35 +08:00
|
|
|
KdpWritePhysicalMemory(IN PDBGKD_MANIPULATE_STATE64 State,
|
2009-10-12 11:35:35 +08:00
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
2009-10-14 03:45:40 +08:00
|
|
|
PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
|
2009-10-12 11:35:35 +08:00
|
|
|
STRING Header;
|
2009-10-14 03:45:40 +08:00
|
|
|
ULONG Flags, CacheFlags;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
/* Setup the header */
|
2009-10-12 11:35:35 +08:00
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
2009-10-14 03:45:40 +08:00
|
|
|
/* Start with the default flags */
|
|
|
|
Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE | MMDBG_COPY_PHYSICAL;
|
|
|
|
|
|
|
|
/* Get the caching flags and check if a type is specified */
|
|
|
|
CacheFlags = WriteMemory->ActualBytesWritten;
|
|
|
|
if (CacheFlags == DBGKD_CACHING_CACHED)
|
|
|
|
{
|
|
|
|
/* Cached */
|
|
|
|
Flags |= MMDBG_COPY_CACHED;
|
|
|
|
}
|
|
|
|
else if (CacheFlags == DBGKD_CACHING_UNCACHED)
|
|
|
|
{
|
|
|
|
/* Uncached */
|
|
|
|
Flags |= MMDBG_COPY_UNCACHED;
|
|
|
|
}
|
2009-11-05 06:40:18 +08:00
|
|
|
else if (CacheFlags == DBGKD_CACHING_WRITE_COMBINED)
|
2009-10-14 03:45:40 +08:00
|
|
|
{
|
|
|
|
/* Write Combined */
|
2009-11-05 06:40:18 +08:00
|
|
|
Flags |= MMDBG_COPY_WRITE_COMBINED;
|
2009-10-14 03:45:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Do the write */
|
|
|
|
State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress,
|
|
|
|
Data->Buffer,
|
|
|
|
Data->Length,
|
|
|
|
0,
|
|
|
|
Flags,
|
|
|
|
&WriteMemory->ActualBytesWritten);
|
|
|
|
|
|
|
|
/* Send the packet */
|
2009-10-12 11:35:35 +08:00
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
2009-10-14 03:45:40 +08:00
|
|
|
NULL,
|
2009-10-12 11:35:35 +08:00
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
|
|
|
|
STRING Header;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Check the length requested */
|
|
|
|
Length = ReadMemory->TransferCount;
|
|
|
|
if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
|
|
|
|
{
|
|
|
|
/* Use maximum allowed */
|
|
|
|
Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysReadControlSpace(State->Processor,
|
|
|
|
ReadMemory->TargetBaseAddress,
|
|
|
|
Data->Buffer,
|
|
|
|
Length,
|
|
|
|
&Length);
|
|
|
|
|
|
|
|
/* Return the actual length read */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
ReadMemory->ActualBytesRead = Length;
|
|
|
|
Data->Length = (USHORT)Length;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysWriteControlSpace(State->Processor,
|
|
|
|
WriteMemory->TargetBaseAddress,
|
|
|
|
Data->Buffer,
|
|
|
|
Data->Length,
|
2009-10-14 03:45:40 +08:00
|
|
|
&WriteMemory->ActualBytesWritten);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
2009-11-03 01:45:51 +08:00
|
|
|
PCONTEXT TargetContext;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Make sure that this is a valid request */
|
|
|
|
if (State->Processor < KeNumberProcessors)
|
|
|
|
{
|
|
|
|
/* Check if the request is for this CPU */
|
|
|
|
if (State->Processor == KeGetCurrentPrcb()->Number)
|
|
|
|
{
|
|
|
|
/* We're just copying our own context */
|
2009-11-03 01:45:51 +08:00
|
|
|
TargetContext = Context;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Get the context from the PRCB array */
|
|
|
|
TargetContext = &KiProcessorBlock[State->Processor]->
|
|
|
|
ProcessorState.ContextFrame;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
2009-11-03 02:08:49 +08:00
|
|
|
/* Copy it over to the debugger */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpMoveMemory(Data->Buffer,
|
|
|
|
TargetContext,
|
|
|
|
sizeof(CONTEXT));
|
2009-10-12 11:35:35 +08:00
|
|
|
Data->Length = sizeof(CONTEXT);
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Let the debugger set the context now */
|
|
|
|
KdpContextSent = TRUE;
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
/* Finish up */
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid request */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
2009-11-03 01:45:51 +08:00
|
|
|
PCONTEXT TargetContext;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == sizeof(CONTEXT));
|
|
|
|
|
|
|
|
/* Make sure that this is a valid request */
|
2015-09-28 22:08:54 +08:00
|
|
|
if ((State->Processor < KeNumberProcessors) &&
|
|
|
|
(KdpContextSent))
|
2009-10-12 11:35:35 +08:00
|
|
|
{
|
|
|
|
/* Check if the request is for this CPU */
|
|
|
|
if (State->Processor == KeGetCurrentPrcb()->Number)
|
|
|
|
{
|
|
|
|
/* We're just copying our own context */
|
2009-11-03 01:45:51 +08:00
|
|
|
TargetContext = Context;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Get the context from the PRCB array */
|
|
|
|
TargetContext = &KiProcessorBlock[State->Processor]->
|
|
|
|
ProcessorState.ContextFrame;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
2009-11-03 02:08:49 +08:00
|
|
|
/* Copy the new context to it */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpMoveMemory(TargetContext,
|
|
|
|
Data->Buffer,
|
|
|
|
sizeof(CONTEXT));
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Finish up */
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid request */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
2009-10-29 05:49:58 +08:00
|
|
|
NULL,
|
2009-10-12 11:35:35 +08:00
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
2015-09-28 22:08:54 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpGetContextEx(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_CONTEXT_EX ContextEx;
|
|
|
|
PCONTEXT TargetContext;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Get our struct */
|
|
|
|
ContextEx = &State->u.ContextEx;
|
|
|
|
|
|
|
|
/* Set up the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Make sure that this is a valid request */
|
|
|
|
if ((State->Processor < KeNumberProcessors) &&
|
|
|
|
(ContextEx->Offset + ContextEx->ByteCount) <= sizeof(CONTEXT))
|
|
|
|
{
|
|
|
|
/* Check if the request is for this CPU */
|
|
|
|
if (State->Processor == KeGetCurrentPrcb()->Number)
|
|
|
|
{
|
|
|
|
/* We're just copying our own context */
|
|
|
|
TargetContext = Context;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the context from the PRCB array */
|
|
|
|
TargetContext = &KiProcessorBlock[State->Processor]->
|
|
|
|
ProcessorState.ContextFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy what is requested */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpMoveMemory(Data->Buffer,
|
2015-09-28 22:08:54 +08:00
|
|
|
(PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset),
|
|
|
|
ContextEx->ByteCount);
|
|
|
|
|
|
|
|
/* KD copies all */
|
|
|
|
Data->Length = ContextEx->BytesCopied = ContextEx->ByteCount;
|
|
|
|
|
|
|
|
/* Let the debugger set the context now */
|
|
|
|
KdpContextSent = TRUE;
|
|
|
|
|
|
|
|
/* Finish up */
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid request */
|
|
|
|
ContextEx->BytesCopied = 0;
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpSetContextEx(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_CONTEXT_EX ContextEx;
|
|
|
|
PCONTEXT TargetContext;
|
|
|
|
|
|
|
|
/* Get our struct */
|
|
|
|
ContextEx = &State->u.ContextEx;
|
|
|
|
ASSERT(Data->Length == ContextEx->ByteCount);
|
|
|
|
|
|
|
|
/* Set up the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Make sure that this is a valid request */
|
|
|
|
if ((State->Processor < KeNumberProcessors) &&
|
|
|
|
((ContextEx->Offset + ContextEx->ByteCount) <= sizeof(CONTEXT)) &&
|
|
|
|
(KdpContextSent))
|
|
|
|
{
|
|
|
|
/* Check if the request is for this CPU */
|
|
|
|
if (State->Processor == KeGetCurrentPrcb()->Number)
|
|
|
|
{
|
|
|
|
/* We're just copying our own context */
|
|
|
|
TargetContext = Context;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the context from the PRCB array */
|
|
|
|
TargetContext = &KiProcessorBlock[State->Processor]->
|
|
|
|
ProcessorState.ContextFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy what is requested */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpMoveMemory((PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset),
|
2015-09-28 22:08:54 +08:00
|
|
|
Data->Buffer,
|
|
|
|
ContextEx->ByteCount);
|
|
|
|
|
|
|
|
/* KD copies all */
|
|
|
|
ContextEx->BytesCopied = ContextEx->ByteCount;
|
|
|
|
|
|
|
|
/* Finish up */
|
|
|
|
State->ReturnStatus = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid request */
|
|
|
|
ContextEx->BytesCopied = 0;
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpCauseBugCheck(IN PDBGKD_MANIPULATE_STATE64 State)
|
|
|
|
{
|
|
|
|
/* Crash with the special code */
|
|
|
|
KeBugCheck(MANUALLY_INITIATED_CRASH);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_READ_WRITE_MSR ReadMsr = &State->u.ReadWriteMsr;
|
|
|
|
LARGE_INTEGER MsrValue;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr,
|
|
|
|
&MsrValue);
|
|
|
|
|
|
|
|
/* Return the data */
|
|
|
|
ReadMsr->DataValueLow = MsrValue.LowPart;
|
|
|
|
ReadMsr->DataValueHigh = MsrValue.HighPart;
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_READ_WRITE_MSR WriteMsr = &State->u.ReadWriteMsr;
|
|
|
|
LARGE_INTEGER MsrValue;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
MsrValue.LowPart = WriteMsr->DataValueLow;
|
|
|
|
MsrValue.HighPart = WriteMsr->DataValueHigh;
|
|
|
|
State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr,
|
|
|
|
&MsrValue);
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpGetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_GET_SET_BUS_DATA GetBusData = &State->u.GetSetBusData;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Check the length requested */
|
|
|
|
Length = GetBusData->Length;
|
|
|
|
if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
|
|
|
|
{
|
|
|
|
/* Use maximum allowed */
|
|
|
|
Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType,
|
|
|
|
GetBusData->BusNumber,
|
|
|
|
GetBusData->SlotNumber,
|
|
|
|
GetBusData->Offset,
|
2009-10-17 22:31:38 +08:00
|
|
|
Data->Buffer,
|
2009-10-12 11:35:35 +08:00
|
|
|
Length,
|
|
|
|
&Length);
|
|
|
|
|
|
|
|
/* Return the actual length read */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
GetBusData->Length = Length;
|
|
|
|
Data->Length = (USHORT)Length;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
Data,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_GET_SET_BUS_DATA SetBusData = &State->u.GetSetBusData;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType,
|
|
|
|
SetBusData->BusNumber,
|
|
|
|
SetBusData->SlotNumber,
|
|
|
|
SetBusData->Offset,
|
2009-10-17 22:31:38 +08:00
|
|
|
Data->Buffer,
|
2009-10-12 11:35:35 +08:00
|
|
|
SetBusData->Length,
|
|
|
|
&Length);
|
|
|
|
|
|
|
|
/* Return the actual length written */
|
|
|
|
SetBusData->Length = Length;
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
2009-10-29 05:49:58 +08:00
|
|
|
NULL,
|
2009-10-12 11:35:35 +08:00
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpReadIoSpace(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_READ_WRITE_IO64 ReadIo = &State->u.ReadWriteIo;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clear the value so 1 or 2 byte reads
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
* don't leave the higher bits unmodified
|
2009-10-12 11:35:35 +08:00
|
|
|
*/
|
|
|
|
ReadIo->DataValue = 0;
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysReadIoSpace(Isa,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
ReadIo->IoAddress,
|
|
|
|
&ReadIo->DataValue,
|
|
|
|
ReadIo->DataSize,
|
|
|
|
&ReadIo->DataSize);
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteIoSpace(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_READ_WRITE_IO64 WriteIo = &State->u.ReadWriteIo;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysWriteIoSpace(Isa,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
WriteIo->IoAddress,
|
|
|
|
&WriteIo->DataValue,
|
|
|
|
WriteIo->DataSize,
|
|
|
|
&WriteIo->DataSize);
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpReadIoSpaceExtended(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_READ_WRITE_IO_EXTENDED64 ReadIoExtended = &State->u.
|
|
|
|
ReadWriteIoExtended;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clear the value so 1 or 2 byte reads
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
* don't leave the higher bits unmodified
|
2009-10-12 11:35:35 +08:00
|
|
|
*/
|
|
|
|
ReadIoExtended->DataValue = 0;
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
|
|
|
State->ReturnStatus = KdpSysReadIoSpace(ReadIoExtended->InterfaceType,
|
|
|
|
ReadIoExtended->BusNumber,
|
|
|
|
ReadIoExtended->AddressSpace,
|
|
|
|
ReadIoExtended->IoAddress,
|
|
|
|
&ReadIoExtended->DataValue,
|
|
|
|
ReadIoExtended->DataSize,
|
|
|
|
&ReadIoExtended->DataSize);
|
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpWriteIoSpaceExtended(IN PDBGKD_MANIPULATE_STATE64 State,
|
|
|
|
IN PSTRING Data,
|
|
|
|
IN PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
PDBGKD_READ_WRITE_IO_EXTENDED64 WriteIoExtended = &State->u.
|
|
|
|
ReadWriteIoExtended;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
ASSERT(Data->Length == 0);
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
2017-03-20 18:21:11 +08:00
|
|
|
State->ReturnStatus = KdpSysWriteIoSpace(WriteIoExtended->InterfaceType,
|
2019-11-04 06:32:56 +08:00
|
|
|
WriteIoExtended->BusNumber,
|
|
|
|
WriteIoExtended->AddressSpace,
|
|
|
|
WriteIoExtended->IoAddress,
|
|
|
|
&WriteIoExtended->DataValue,
|
|
|
|
WriteIoExtended->DataSize,
|
|
|
|
&WriteIoExtended->DataSize);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Call the internal routine */
|
2009-10-14 03:45:40 +08:00
|
|
|
State->ReturnStatus = KdpSysCheckLowMemory(MMDBG_COPY_UNSAFE);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Send the reply */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpNotSupported(IN PDBGKD_MANIPULATE_STATE64 State)
|
|
|
|
{
|
|
|
|
STRING Header;
|
|
|
|
|
|
|
|
/* Set failure */
|
|
|
|
State->ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
/* Setup the packet */
|
|
|
|
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)State;
|
|
|
|
|
|
|
|
/* Send it */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
NULL,
|
|
|
|
&KdpContext);
|
|
|
|
}
|
|
|
|
|
2023-12-08 03:27:44 +08:00
|
|
|
static
|
|
|
|
KCONTINUE_STATUS
|
|
|
|
KdpSwitchProcessor(
|
|
|
|
_In_ USHORT ProcessorIndex)
|
|
|
|
{
|
|
|
|
/* Make sure that the processor index is valid */
|
|
|
|
if (ProcessorIndex >= KeNumberProcessors)
|
|
|
|
{
|
|
|
|
KdpDprintf("%u is not a valid processor number\n", ProcessorIndex);
|
|
|
|
return ContinueProcessorReselected;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the new processor is the current one, there is nothing to do */
|
|
|
|
if (ProcessorIndex == KeGetCurrentProcessorNumber())
|
|
|
|
{
|
|
|
|
return ContinueProcessorReselected;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the architecture specific Ke routine */
|
|
|
|
return KxSwitchKdProcessor(ProcessorIndex);
|
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
KCONTINUE_STATUS
|
|
|
|
NTAPI
|
|
|
|
KdpSendWaitContinue(IN ULONG PacketType,
|
|
|
|
IN PSTRING SendHeader,
|
|
|
|
IN PSTRING SendData OPTIONAL,
|
|
|
|
IN OUT PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Data, Header;
|
|
|
|
DBGKD_MANIPULATE_STATE64 ManipulateState;
|
|
|
|
ULONG Length;
|
|
|
|
KDSTATUS RecvCode;
|
|
|
|
|
|
|
|
/* Setup the Manipulate State structure */
|
|
|
|
Header.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64);
|
|
|
|
Header.Buffer = (PCHAR)&ManipulateState;
|
|
|
|
Data.MaximumLength = sizeof(KdpMessageBuffer);
|
|
|
|
Data.Buffer = KdpMessageBuffer;
|
2009-11-03 01:45:51 +08:00
|
|
|
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
/*
|
2009-11-03 01:45:51 +08:00
|
|
|
* Reset the context state to ensure the debugger has received
|
2019-11-04 06:32:56 +08:00
|
|
|
* the current context before it sets it.
|
2009-11-03 01:45:51 +08:00
|
|
|
*/
|
|
|
|
KdpContextSent = FALSE;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
SendPacket:
|
|
|
|
/* Send the Packet */
|
|
|
|
KdSendPacket(PacketType, SendHeader, SendData, &KdpContext);
|
|
|
|
|
|
|
|
/* If the debugger isn't present anymore, just return success */
|
|
|
|
if (KdDebuggerNotPresent) return ContinueSuccess;
|
|
|
|
|
|
|
|
/* Main processing Loop */
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
/* Receive Loop */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Wait to get a reply to our packet */
|
|
|
|
RecvCode = KdReceivePacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
&Data,
|
|
|
|
&Length,
|
|
|
|
&KdpContext);
|
|
|
|
|
|
|
|
/* If we got a resend request, do it */
|
|
|
|
if (RecvCode == KdPacketNeedsResend) goto SendPacket;
|
|
|
|
} while (RecvCode == KdPacketTimedOut);
|
|
|
|
|
|
|
|
/* Now check what API we got */
|
|
|
|
switch (ManipulateState.ApiNumber)
|
|
|
|
{
|
|
|
|
case DbgKdReadVirtualMemoryApi:
|
|
|
|
|
|
|
|
/* Read virtual memory */
|
|
|
|
KdpReadVirtualMemory(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteVirtualMemoryApi:
|
|
|
|
|
|
|
|
/* Write virtual memory */
|
|
|
|
KdpWriteVirtualMemory(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdGetContextApi:
|
|
|
|
|
|
|
|
/* Get the current context */
|
|
|
|
KdpGetContext(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSetContextApi:
|
|
|
|
|
|
|
|
/* Set a new context */
|
|
|
|
KdpSetContext(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteBreakPointApi:
|
|
|
|
|
|
|
|
/* Write the breakpoint */
|
|
|
|
KdpWriteBreakpoint(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdRestoreBreakPointApi:
|
|
|
|
|
|
|
|
/* Restore the breakpoint */
|
|
|
|
KdpRestoreBreakpoint(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdContinueApi:
|
|
|
|
|
|
|
|
/* Simply continue */
|
|
|
|
return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus);
|
|
|
|
|
|
|
|
case DbgKdReadControlSpaceApi:
|
|
|
|
|
|
|
|
/* Read control space */
|
|
|
|
KdpReadControlSpace(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteControlSpaceApi:
|
|
|
|
|
|
|
|
/* Write control space */
|
|
|
|
KdpWriteControlSpace(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdReadIoSpaceApi:
|
|
|
|
|
|
|
|
/* Read I/O Space */
|
|
|
|
KdpReadIoSpace(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteIoSpaceApi:
|
|
|
|
|
|
|
|
/* Write I/O Space */
|
|
|
|
KdpWriteIoSpace(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdRebootApi:
|
|
|
|
|
|
|
|
/* Reboot the system */
|
|
|
|
HalReturnToFirmware(HalRebootRoutine);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdContinueApi2:
|
|
|
|
|
|
|
|
/* Check if caller reports success */
|
|
|
|
if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus))
|
|
|
|
{
|
|
|
|
/* Update the state */
|
|
|
|
KdpGetStateChange(&ManipulateState, Context);
|
|
|
|
return ContinueSuccess;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Return an error */
|
|
|
|
return ContinueError;
|
|
|
|
}
|
|
|
|
|
|
|
|
case DbgKdReadPhysicalMemoryApi:
|
|
|
|
|
|
|
|
/* Read physical memory */
|
2019-11-02 08:02:35 +08:00
|
|
|
KdpReadPhysicalMemory(&ManipulateState, &Data, Context);
|
2009-10-12 11:35:35 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWritePhysicalMemoryApi:
|
|
|
|
|
|
|
|
/* Write physical memory */
|
2019-11-02 08:02:35 +08:00
|
|
|
KdpWritePhysicalMemory(&ManipulateState, &Data, Context);
|
2009-10-12 11:35:35 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdQuerySpecialCallsApi:
|
|
|
|
case DbgKdSetSpecialCallApi:
|
|
|
|
case DbgKdClearSpecialCallsApi:
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Special Call support is unimplemented!\n");
|
|
|
|
KdpNotSupported(&ManipulateState);
|
2009-10-12 11:35:35 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSetInternalBreakPointApi:
|
|
|
|
case DbgKdGetInternalBreakPointApi:
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Internal Breakpoint support is unimplemented!\n");
|
|
|
|
KdpNotSupported(&ManipulateState);
|
2009-10-12 11:35:35 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdReadIoSpaceExtendedApi:
|
|
|
|
|
|
|
|
/* Read I/O Space */
|
|
|
|
KdpReadIoSpaceExtended(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteIoSpaceExtendedApi:
|
|
|
|
|
|
|
|
/* Write I/O Space */
|
|
|
|
KdpWriteIoSpaceExtended(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdGetVersionApi:
|
|
|
|
|
|
|
|
/* Get version data */
|
|
|
|
KdpGetVersion(&ManipulateState);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteBreakPointExApi:
|
|
|
|
|
|
|
|
/* Write the breakpoint and check if it failed */
|
|
|
|
if (!NT_SUCCESS(KdpWriteBreakPointEx(&ManipulateState,
|
|
|
|
&Data,
|
|
|
|
Context)))
|
|
|
|
{
|
|
|
|
/* Return an error */
|
|
|
|
return ContinueError;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdRestoreBreakPointExApi:
|
|
|
|
|
|
|
|
/* Restore the breakpoint */
|
|
|
|
KdpRestoreBreakPointEx(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdCauseBugCheckApi:
|
|
|
|
|
|
|
|
/* Crash the system */
|
|
|
|
KdpCauseBugCheck(&ManipulateState);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSwitchProcessor:
|
|
|
|
|
2023-12-08 03:27:44 +08:00
|
|
|
/* Switch the processor and return */
|
|
|
|
return KdpSwitchProcessor(ManipulateState.Processor);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
case DbgKdPageInApi:
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Page-In support is unimplemented!\n");
|
|
|
|
KdpNotSupported(&ManipulateState);
|
2009-10-12 11:35:35 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdReadMachineSpecificRegister:
|
|
|
|
|
|
|
|
/* Read from the specified MSR */
|
|
|
|
KdpReadMachineSpecificRegister(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdWriteMachineSpecificRegister:
|
|
|
|
|
|
|
|
/* Write to the specified MSR */
|
|
|
|
KdpWriteMachineSpecificRegister(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSearchMemoryApi:
|
|
|
|
|
|
|
|
/* Search memory */
|
|
|
|
KdpSearchMemory(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdGetBusDataApi:
|
|
|
|
|
|
|
|
/* Read from the bus */
|
|
|
|
KdpGetBusData(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSetBusDataApi:
|
|
|
|
|
|
|
|
/* Write to the bus */
|
|
|
|
KdpSetBusData(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdCheckLowMemoryApi:
|
|
|
|
|
|
|
|
/* Check for memory corruption in the lower 4 GB */
|
|
|
|
KdpCheckLowMemory(&ManipulateState);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdClearAllInternalBreakpointsApi:
|
|
|
|
|
|
|
|
/* Just clear the counter */
|
|
|
|
KdpNumInternalBreakpoints = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdFillMemoryApi:
|
|
|
|
|
|
|
|
/* Fill memory */
|
|
|
|
KdpFillMemory(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdQueryMemoryApi:
|
|
|
|
|
|
|
|
/* Query memory */
|
|
|
|
KdpQueryMemory(&ManipulateState, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSwitchPartition:
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* TODO */
|
|
|
|
KdpDprintf("Partition Switch support is unimplemented!\n");
|
|
|
|
KdpNotSupported(&ManipulateState);
|
2009-10-12 11:35:35 +08:00
|
|
|
break;
|
|
|
|
|
2015-09-28 22:08:54 +08:00
|
|
|
case DbgKdWriteCustomBreakpointApi:
|
|
|
|
|
|
|
|
/* Write the customized breakpoint */
|
|
|
|
KdpWriteCustomBreakpoint(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdGetContextExApi:
|
2019-11-04 06:32:56 +08:00
|
|
|
|
2015-09-28 22:08:54 +08:00
|
|
|
/* Extended Context Get */
|
|
|
|
KdpGetContextEx(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DbgKdSetContextExApi:
|
|
|
|
|
|
|
|
/* Extended Context Set */
|
|
|
|
KdpSetContextEx(&ManipulateState, &Data, Context);
|
|
|
|
break;
|
|
|
|
|
2015-09-19 21:58:08 +08:00
|
|
|
/* Unsupported Messages */
|
|
|
|
default:
|
2014-02-08 22:57:11 +08:00
|
|
|
|
2015-09-19 21:58:08 +08:00
|
|
|
/* Send warning */
|
2015-09-28 22:08:54 +08:00
|
|
|
KdpDprintf("Received Unrecognized API 0x%lx\n", ManipulateState.ApiNumber);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Setup an empty message, with failure */
|
|
|
|
Data.Length = 0;
|
|
|
|
ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
/* Send it */
|
|
|
|
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
|
|
|
|
&Header,
|
|
|
|
&Data,
|
|
|
|
&KdpContext);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
VOID
|
2009-10-12 11:35:35 +08:00
|
|
|
NTAPI
|
|
|
|
KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
|
|
|
|
IN PKD_SYMBOLS_INFO SymbolInfo,
|
|
|
|
IN BOOLEAN Unload,
|
|
|
|
IN OUT PCONTEXT Context)
|
|
|
|
{
|
|
|
|
PSTRING ExtraData;
|
|
|
|
STRING Data, Header;
|
2009-10-25 23:56:38 +08:00
|
|
|
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
|
2009-10-31 09:02:35 +08:00
|
|
|
ULONG PathNameLength;
|
2009-10-12 11:35:35 +08:00
|
|
|
KCONTINUE_STATUS Status;
|
|
|
|
|
|
|
|
/* Start wait loop */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Build the architecture common parts of the message */
|
|
|
|
KdpSetCommonState(DbgKdLoadSymbolsStateChange,
|
|
|
|
Context,
|
|
|
|
&WaitStateChange);
|
|
|
|
|
|
|
|
/* Now finish creating the structure */
|
|
|
|
KdpSetContextState(&WaitStateChange, Context);
|
|
|
|
|
|
|
|
/* Fill out load data */
|
|
|
|
WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload;
|
|
|
|
WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG64)(LONG_PTR)SymbolInfo->BaseOfDll;
|
|
|
|
WaitStateChange.u.LoadSymbols.ProcessId = SymbolInfo->ProcessId;
|
|
|
|
WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
|
|
|
|
WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
|
|
|
|
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Check if we have a path name */
|
2009-10-12 11:35:35 +08:00
|
|
|
if (PathName)
|
|
|
|
{
|
2009-10-31 09:02:35 +08:00
|
|
|
/* Copy it to the path buffer */
|
|
|
|
KdpCopyMemoryChunks((ULONG_PTR)PathName->Buffer,
|
|
|
|
KdpPathBuffer,
|
|
|
|
PathName->Length,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE,
|
|
|
|
&PathNameLength);
|
|
|
|
|
|
|
|
/* Null terminate */
|
2009-11-03 01:45:51 +08:00
|
|
|
KdpPathBuffer[PathNameLength++] = ANSI_NULL;
|
2009-10-31 09:02:35 +08:00
|
|
|
|
|
|
|
/* Set the path length */
|
|
|
|
WaitStateChange.u.LoadSymbols.PathNameLength = PathNameLength;
|
|
|
|
|
|
|
|
/* Set up the data */
|
2009-10-12 11:35:35 +08:00
|
|
|
Data.Buffer = KdpPathBuffer;
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
Data.Length = (USHORT)PathNameLength;
|
2009-10-12 11:35:35 +08:00
|
|
|
ExtraData = &Data;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No name */
|
|
|
|
WaitStateChange.u.LoadSymbols.PathNameLength = 0;
|
|
|
|
ExtraData = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Setup the header */
|
2009-10-25 23:56:38 +08:00
|
|
|
Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
|
2009-10-12 11:35:35 +08:00
|
|
|
Header.Buffer = (PCHAR)&WaitStateChange;
|
|
|
|
|
|
|
|
/* Send the packet */
|
|
|
|
Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
|
|
|
|
&Header,
|
|
|
|
ExtraData,
|
|
|
|
Context);
|
|
|
|
} while (Status == ContinueProcessorReselected);
|
2009-11-03 01:45:51 +08:00
|
|
|
}
|
2009-10-12 11:35:35 +08:00
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpReportCommandStringStateChange(IN PSTRING NameString,
|
|
|
|
IN PSTRING CommandString,
|
|
|
|
IN OUT PCONTEXT Context)
|
|
|
|
{
|
|
|
|
STRING Header, Data;
|
|
|
|
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
|
|
|
|
ULONG Length, ActualLength, TotalLength;
|
|
|
|
KCONTINUE_STATUS Status;
|
|
|
|
|
|
|
|
/* Start wait loop */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Build the architecture common parts of the message */
|
|
|
|
KdpSetCommonState(DbgKdCommandStringStateChange,
|
|
|
|
Context,
|
|
|
|
&WaitStateChange);
|
|
|
|
|
|
|
|
/* Set the context */
|
|
|
|
KdpSetContextState(&WaitStateChange, Context);
|
|
|
|
|
|
|
|
/* Clear the command string structure */
|
2015-10-15 20:56:19 +08:00
|
|
|
KdpZeroMemory(&WaitStateChange.u.CommandString,
|
2009-11-03 01:45:51 +08:00
|
|
|
sizeof(DBGKD_COMMAND_STRING));
|
|
|
|
|
|
|
|
/* Normalize name string to max */
|
|
|
|
Length = min(128 - 1, NameString->Length);
|
|
|
|
|
|
|
|
/* Copy it to the message buffer */
|
|
|
|
KdpCopyMemoryChunks((ULONG_PTR)NameString->Buffer,
|
|
|
|
KdpMessageBuffer,
|
|
|
|
Length,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE,
|
|
|
|
&ActualLength);
|
|
|
|
|
|
|
|
/* Null terminate and calculate the total length */
|
|
|
|
TotalLength = ActualLength;
|
|
|
|
KdpMessageBuffer[TotalLength++] = ANSI_NULL;
|
|
|
|
|
|
|
|
/* Check if the command string is too long */
|
|
|
|
Length = CommandString->Length;
|
|
|
|
if (Length > (PACKET_MAX_SIZE -
|
|
|
|
sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) - TotalLength))
|
|
|
|
{
|
|
|
|
/* Use maximum possible size */
|
|
|
|
Length = (PACKET_MAX_SIZE -
|
|
|
|
sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) - TotalLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy it to the message buffer */
|
|
|
|
KdpCopyMemoryChunks((ULONG_PTR)CommandString->Buffer,
|
|
|
|
KdpMessageBuffer + TotalLength,
|
|
|
|
Length,
|
|
|
|
0,
|
|
|
|
MMDBG_COPY_UNSAFE,
|
|
|
|
&ActualLength);
|
|
|
|
|
|
|
|
/* Null terminate and calculate the total length */
|
|
|
|
TotalLength += ActualLength;
|
|
|
|
KdpMessageBuffer[TotalLength++] = ANSI_NULL;
|
|
|
|
|
|
|
|
/* Now set up the header and the data */
|
|
|
|
Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
|
|
|
|
Header.Buffer = (PCHAR)&WaitStateChange;
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 21:11:45 +08:00
|
|
|
Data.Length = (USHORT)TotalLength;
|
2009-11-03 01:45:51 +08:00
|
|
|
Data.Buffer = KdpMessageBuffer;
|
|
|
|
|
|
|
|
/* Send State Change packet and wait for a reply */
|
|
|
|
Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
|
|
|
|
&Header,
|
|
|
|
&Data,
|
|
|
|
Context);
|
|
|
|
} while (Status == ContinueProcessorReselected);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
|
|
|
|
IN OUT PCONTEXT Context,
|
|
|
|
IN BOOLEAN SecondChanceException)
|
|
|
|
{
|
|
|
|
STRING Header, Data;
|
2009-10-25 23:56:38 +08:00
|
|
|
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
|
2009-10-12 11:35:35 +08:00
|
|
|
KCONTINUE_STATUS Status;
|
|
|
|
|
|
|
|
/* Start report loop */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Build the architecture common parts of the message */
|
|
|
|
KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange);
|
|
|
|
|
2009-10-25 23:56:38 +08:00
|
|
|
#if !defined(_WIN64)
|
2015-10-15 20:56:19 +08:00
|
|
|
|
|
|
|
/* Convert it and copy it over */
|
2009-10-25 23:56:38 +08:00
|
|
|
ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord,
|
|
|
|
&WaitStateChange.u.Exception.ExceptionRecord);
|
2015-10-15 20:56:19 +08:00
|
|
|
|
2009-10-25 23:56:38 +08:00
|
|
|
#else
|
2015-10-15 20:56:19 +08:00
|
|
|
|
|
|
|
/* Just copy it directly, no need to convert */
|
|
|
|
KdpMoveMemory(&WaitStateChange.u.Exception.ExceptionRecord,
|
2009-10-25 23:56:38 +08:00
|
|
|
ExceptionRecord,
|
|
|
|
sizeof(EXCEPTION_RECORD));
|
2015-10-15 20:56:19 +08:00
|
|
|
|
2009-10-25 23:56:38 +08:00
|
|
|
#endif
|
2015-10-15 20:56:19 +08:00
|
|
|
|
|
|
|
/* Set the First Chance flag */
|
2009-10-12 11:35:35 +08:00
|
|
|
WaitStateChange.u.Exception.FirstChance = !SecondChanceException;
|
|
|
|
|
|
|
|
/* Now finish creating the structure */
|
|
|
|
KdpSetContextState(&WaitStateChange, Context);
|
|
|
|
|
|
|
|
/* Setup the actual header to send to KD */
|
2009-10-25 23:56:38 +08:00
|
|
|
Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
|
2009-10-12 11:35:35 +08:00
|
|
|
Header.Buffer = (PCHAR)&WaitStateChange;
|
|
|
|
|
|
|
|
/* Setup the trace data */
|
|
|
|
DumpTraceData(&Data);
|
|
|
|
|
|
|
|
/* Send State Change packet and wait for a reply */
|
|
|
|
Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
|
|
|
|
&Header,
|
|
|
|
&Data,
|
|
|
|
Context);
|
|
|
|
} while (Status == ContinueProcessorReselected);
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2023-12-08 03:27:44 +08:00
|
|
|
KCONTINUE_STATUS
|
|
|
|
NTAPI
|
|
|
|
KdReportProcessorChange(
|
|
|
|
VOID)
|
|
|
|
{
|
|
|
|
PKPRCB CurrentPrcb = KeGetCurrentPrcb();
|
|
|
|
PCONTEXT ContextRecord = &CurrentPrcb->ProcessorState.ContextFrame;
|
|
|
|
EXCEPTION_RECORD ExceptionRecord = {0};
|
|
|
|
KCONTINUE_STATUS Status;
|
|
|
|
|
|
|
|
/* Save the port data */
|
|
|
|
KdSave(FALSE);
|
|
|
|
|
|
|
|
ExceptionRecord.ExceptionAddress = (PVOID)KeGetContextPc(ContextRecord);
|
|
|
|
ExceptionRecord.ExceptionCode = STATUS_WAKE_SYSTEM_DEBUGGER;
|
|
|
|
|
|
|
|
/* Report the new state */
|
|
|
|
Status = KdpReportExceptionStateChange(&ExceptionRecord,
|
|
|
|
ContextRecord,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Restore the port data */
|
|
|
|
KdRestore(FALSE);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpTimeSlipDpcRoutine(IN PKDPC Dpc,
|
|
|
|
IN PVOID DeferredContext,
|
|
|
|
IN PVOID SystemArgument1,
|
|
|
|
IN PVOID SystemArgument2)
|
|
|
|
{
|
|
|
|
LONG OldSlip, NewSlip, PendingSlip;
|
|
|
|
|
|
|
|
/* Get the current pending slip */
|
|
|
|
PendingSlip = KdpTimeSlipPending;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Save the old value and either disable or enable it now. */
|
|
|
|
OldSlip = PendingSlip;
|
|
|
|
NewSlip = OldSlip > 1 ? 1 : 0;
|
|
|
|
|
|
|
|
/* Try to change the value */
|
|
|
|
} while (InterlockedCompareExchange(&KdpTimeSlipPending,
|
|
|
|
NewSlip,
|
|
|
|
OldSlip) != OldSlip);
|
|
|
|
|
|
|
|
/* If the New Slip value is 1, then do the Time Slipping */
|
|
|
|
if (NewSlip) ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdpTimeSlipWork(IN PVOID Context)
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
LARGE_INTEGER DueTime;
|
|
|
|
|
|
|
|
/* Update the System time from the CMOS */
|
|
|
|
ExAcquireTimeRefreshLock(FALSE);
|
|
|
|
ExUpdateSystemTimeFromCmos(FALSE, 0);
|
|
|
|
ExReleaseTimeRefreshLock();
|
|
|
|
|
|
|
|
/* Check if we have a registered Time Slip Event and signal it */
|
|
|
|
KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql);
|
|
|
|
if (KdpTimeSlipEvent) KeSetEvent(KdpTimeSlipEvent, 0, FALSE);
|
|
|
|
KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql);
|
|
|
|
|
|
|
|
/* Delay the DPC until it runs next time */
|
|
|
|
DueTime.QuadPart = -1800000000;
|
|
|
|
KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);
|
|
|
|
}
|
|
|
|
|
|
|
|
LARGE_INTEGER
|
|
|
|
NTAPI
|
|
|
|
KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
|
|
|
|
{
|
|
|
|
LARGE_INTEGER Null = {{0}};
|
|
|
|
|
|
|
|
/* Check if interrupts were disabled */
|
|
|
|
if (!KeGetTrapFrameInterruptState(TrapFrame))
|
|
|
|
{
|
|
|
|
/* Nothing to return */
|
|
|
|
return Null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, do the call */
|
|
|
|
return KeQueryPerformanceCounter(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
|
|
|
|
IN PKEXCEPTION_FRAME ExceptionFrame)
|
|
|
|
{
|
2009-11-08 09:13:49 +08:00
|
|
|
BOOLEAN Enable;
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Check if we have a trap frame */
|
|
|
|
if (TrapFrame)
|
|
|
|
{
|
|
|
|
/* Calculate the time difference for the enter */
|
|
|
|
KdTimerStop = KdpQueryPerformanceCounter(TrapFrame);
|
|
|
|
KdTimerDifference.QuadPart = KdTimerStop.QuadPart -
|
|
|
|
KdTimerStart.QuadPart;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No trap frame, so can't calculate */
|
|
|
|
KdTimerStop.QuadPart = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save the current IRQL */
|
|
|
|
KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();
|
|
|
|
|
2021-09-05 08:48:20 +08:00
|
|
|
/* Freeze all CPUs, raising also the IRQL to HIGH_LEVEL */
|
2009-11-08 09:13:49 +08:00
|
|
|
Enable = KeFreezeExecution(TrapFrame, ExceptionFrame);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Lock the port, save the state and set debugger entered */
|
|
|
|
KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock);
|
|
|
|
KdSave(FALSE);
|
|
|
|
KdEnteredDebugger = TRUE;
|
|
|
|
|
|
|
|
/* Check freeze flag */
|
|
|
|
if (KiFreezeFlag & 1)
|
|
|
|
{
|
|
|
|
/* Print out errror */
|
|
|
|
KdpDprintf("FreezeLock was jammed! Backup SpinLock was used!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check processor state */
|
|
|
|
if (KiFreezeFlag & 2)
|
|
|
|
{
|
|
|
|
/* Print out errror */
|
|
|
|
KdpDprintf("Some processors not frozen in debugger!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure we acquired the port */
|
|
|
|
if (!KdpPortLocked) KdpDprintf("Port lock was not acquired!\n");
|
|
|
|
|
2009-11-08 09:13:49 +08:00
|
|
|
/* Return if interrupts needs to be re-enabled */
|
|
|
|
return Enable;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2009-11-08 09:13:49 +08:00
|
|
|
KdExitDebugger(IN BOOLEAN Enable)
|
2009-10-12 11:35:35 +08:00
|
|
|
{
|
|
|
|
ULONG TimeSlip;
|
|
|
|
|
|
|
|
/* Restore the state and unlock the port */
|
|
|
|
KdRestore(FALSE);
|
|
|
|
if (KdpPortLocked) KdpPortUnlock();
|
|
|
|
|
2021-09-05 08:48:20 +08:00
|
|
|
/* Unfreeze the CPUs, restoring also the IRQL */
|
2009-11-08 09:13:49 +08:00
|
|
|
KeThawExecution(Enable);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
|
|
|
/* Compare time with the one from KdEnterDebugger */
|
|
|
|
if (!KdTimerStop.QuadPart)
|
|
|
|
{
|
|
|
|
/* We didn't get a trap frame earlier in so never got the time */
|
|
|
|
KdTimerStart = KdTimerStop;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Query the timer */
|
|
|
|
KdTimerStart = KeQueryPerformanceCounter(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if a Time Slip was on queue */
|
|
|
|
TimeSlip = InterlockedIncrement(&KdpTimeSlipPending);
|
|
|
|
if (TimeSlip == 1)
|
|
|
|
{
|
|
|
|
/* Queue a DPC for the time slip */
|
|
|
|
InterlockedIncrement(&KdpTimeSlipPending);
|
2014-02-08 22:57:11 +08:00
|
|
|
KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL); // FIXME: this can trigger context switches!
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
|
|
/* Make gcc happy */
|
|
|
|
OldIrql = PASSIVE_LEVEL;
|
|
|
|
#endif
|
|
|
|
|
2009-10-17 22:31:38 +08:00
|
|
|
/* Check if enabling the debugger is blocked */
|
|
|
|
if (KdBlockEnable)
|
|
|
|
{
|
|
|
|
/* It is, fail the enable */
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
/* Check if we need to acquire the lock */
|
|
|
|
if (NeedLock)
|
|
|
|
{
|
|
|
|
/* Lock the port */
|
|
|
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
|
|
|
KdpPortLock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we're not disabled */
|
|
|
|
if (!KdDisableCount)
|
|
|
|
{
|
|
|
|
/* Check if we had locked the port before */
|
|
|
|
if (NeedLock)
|
|
|
|
{
|
|
|
|
/* Do the unlock */
|
|
|
|
KdpPortUnlock();
|
2021-09-05 08:44:20 +08:00
|
|
|
KeLowerIrql(OldIrql);
|
2009-10-12 11:35:35 +08:00
|
|
|
|
2009-10-17 22:31:38 +08:00
|
|
|
/* Fail: We're already enabled */
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* This can only happen if we are called from a bugcheck
|
|
|
|
* and were never initialized, so initialize the debugger now.
|
|
|
|
*/
|
|
|
|
KdInitSystem(0, NULL);
|
|
|
|
|
|
|
|
/* Return success since we initialized */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Decrease the disable count */
|
|
|
|
if (!(--KdDisableCount))
|
|
|
|
{
|
|
|
|
/* We're now enabled again! Were we enabled before, too? */
|
|
|
|
if (KdPreviouslyEnabled)
|
|
|
|
{
|
|
|
|
/* Reinitialize the Debugger */
|
2016-10-07 03:01:33 +08:00
|
|
|
KdInitSystem(0, NULL);
|
2009-10-12 11:35:35 +08:00
|
|
|
KdpRestoreAllBreakpoints();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we had locked the port before */
|
|
|
|
if (NeedLock)
|
|
|
|
{
|
|
|
|
/* Yes, now unlock it */
|
|
|
|
KdpPortUnlock();
|
2021-09-05 08:44:20 +08:00
|
|
|
KeLowerIrql(OldIrql);
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We're done */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2009-10-17 22:31:38 +08:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdDisableDebuggerWithLock(IN BOOLEAN NeedLock)
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
|
|
/* Make gcc happy */
|
|
|
|
OldIrql = PASSIVE_LEVEL;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If enabling the debugger is blocked
|
|
|
|
* then there is nothing to disable (duh)
|
|
|
|
*/
|
|
|
|
if (KdBlockEnable)
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we need to acquire the lock */
|
|
|
|
if (NeedLock)
|
|
|
|
{
|
|
|
|
/* Lock the port */
|
|
|
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
|
|
|
KdpPortLock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we're not disabled */
|
|
|
|
if (!KdDisableCount)
|
|
|
|
{
|
|
|
|
/* Check if the debugger was never actually initialized */
|
|
|
|
if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
|
|
|
|
{
|
|
|
|
/* It wasn't, so don't re-enable it later */
|
|
|
|
KdPreviouslyEnabled = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* It was, so we will re-enable it later */
|
|
|
|
KdPreviouslyEnabled = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we were called from the exported API and are enabled */
|
|
|
|
if ((NeedLock) && (KdPreviouslyEnabled))
|
|
|
|
{
|
|
|
|
/* Check if it is safe to disable the debugger */
|
|
|
|
Status = KdpAllowDisable();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Release the lock and fail */
|
|
|
|
KdpPortUnlock();
|
2021-09-05 08:44:20 +08:00
|
|
|
KeLowerIrql(OldIrql);
|
2009-10-17 22:31:38 +08:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only disable the debugger if it is enabled */
|
|
|
|
if (KdDebuggerEnabled)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Disable the debugger; suspend breakpoints
|
|
|
|
* and reset the debug stub
|
|
|
|
*/
|
|
|
|
KdpSuspendAllBreakPoints();
|
|
|
|
KiDebugRoutine = KdpStub;
|
|
|
|
|
|
|
|
/* We are disabled now */
|
|
|
|
KdDebuggerEnabled = FALSE;
|
|
|
|
SharedUserData->KdDebuggerEnabled = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Increment the disable count */
|
|
|
|
KdDisableCount++;
|
|
|
|
|
|
|
|
/* Check if we had locked the port before */
|
|
|
|
if (NeedLock)
|
|
|
|
{
|
|
|
|
/* Yes, now unlock it */
|
|
|
|
KdpPortUnlock();
|
2021-09-05 08:44:20 +08:00
|
|
|
KeLowerIrql(OldIrql);
|
2009-10-17 22:31:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We're done */
|
|
|
|
return STATUS_SUCCESS;
|
2020-03-08 02:14:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* PUBLIC FUNCTIONS **********************************************************/
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdEnableDebugger(VOID)
|
|
|
|
{
|
|
|
|
/* Use the internal routine */
|
|
|
|
return KdEnableDebuggerWithLock(TRUE);
|
|
|
|
}
|
|
|
|
|
2009-10-17 22:31:38 +08:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdDisableDebugger(VOID)
|
|
|
|
{
|
|
|
|
/* Use the internal routine */
|
|
|
|
return KdDisableDebuggerWithLock(TRUE);
|
|
|
|
}
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2019-11-18 05:28:42 +08:00
|
|
|
KdSystemDebugControl(
|
|
|
|
_In_ SYSDBG_COMMAND Command,
|
|
|
|
_In_ PVOID InputBuffer,
|
|
|
|
_In_ ULONG InputBufferLength,
|
|
|
|
_Out_ PVOID OutputBuffer,
|
|
|
|
_In_ ULONG OutputBufferLength,
|
|
|
|
_Inout_ PULONG ReturnLength,
|
|
|
|
_In_ KPROCESSOR_MODE PreviousMode)
|
2009-10-12 11:35:35 +08:00
|
|
|
{
|
2019-11-18 05:28:42 +08:00
|
|
|
/* Handle some internal commands */
|
2020-03-20 18:32:40 +08:00
|
|
|
switch ((ULONG)Command)
|
2011-10-12 05:29:13 +08:00
|
|
|
{
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
#if DBG
|
|
|
|
case ' soR': /* ROS-INTERNAL */
|
2011-10-12 05:29:13 +08:00
|
|
|
{
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
switch ((ULONG_PTR)InputBuffer)
|
|
|
|
{
|
|
|
|
case 0x21: // DumpAllThreads:
|
|
|
|
PspDumpThreads(TRUE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x22: // DumpUserThreads:
|
|
|
|
PspDumpThreads(FALSE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x24: // KdSpare3:
|
|
|
|
MmDumpArmPfnDatabase(FALSE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
2011-10-12 05:29:13 +08:00
|
|
|
}
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
|
2020-03-08 02:14:09 +08:00
|
|
|
#if defined(_M_IX86) && !defined(_WINKD_) // See ke/i386/traphdlr.c
|
|
|
|
/* Register a debug callback */
|
|
|
|
case 'CsoR':
|
|
|
|
{
|
|
|
|
switch (InputBufferLength)
|
|
|
|
{
|
|
|
|
case ID_Win32PreServiceHook:
|
|
|
|
KeWin32PreServiceHook = InputBuffer;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_Win32PostServiceHook:
|
|
|
|
KeWin32PostServiceHook = InputBuffer;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
/* Special case for stack frame dumps */
|
|
|
|
case 'DsoR':
|
|
|
|
{
|
2019-11-18 08:33:06 +08:00
|
|
|
KeRosDumpStackFrames((PULONG_PTR)InputBuffer, InputBufferLength);
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
break;
|
|
|
|
}
|
2023-04-05 05:38:32 +08:00
|
|
|
#ifdef KDBG
|
2020-03-08 02:14:09 +08:00
|
|
|
/* Register KDBG CLI callback */
|
|
|
|
case 'RbdK':
|
|
|
|
{
|
|
|
|
return KdbRegisterCliCallback(InputBuffer, InputBufferLength);
|
|
|
|
}
|
2023-04-05 05:38:32 +08:00
|
|
|
#endif // KDBG
|
[NTOS:KD/KD64/KDBG] Share some code between our legacy KD/KDBG and KD64.
Our legacy KD module is slowly being phased out for the more recent KD64
Kernel Debugger that supports WinDbg, but at the same time we must retain
support for GCC debugging and the KDBG interface.
For the time being few #ifdef _WINKD_ have been introduced in KD64 so that
some of its code/data does not completely get shared yet with the legacy KD,
until the latter becomes phased out.
KD Modifications:
=================
- Remove the implementation of NtQueryDebugFilterState() /
NtSetDebugFilterState() that now comes entirely from KD64.
- Remove KD variables that are now shared with KD64.
- Share common code with KD64: KdpMoveMemory(), KdpZeroMemory(),
KdpCopyMemoryChunks(), KdpPrint(), KdpPrompt().
- KDBG: Remove the duplicated KdpCopyMemoryChunks() function.
- In KdpServiceDispatcher() and KdpEnterDebuggerException(), call the
KdpPrint() worker function that correctly probes and captures its arguments.
- Temporarily stub out KdEnterDebugger() and KdExitDebugger() that is used
by the shared code, until KD is removed and only the KD64 version of these
functions remain.
- Re-implement the KD/KDBG KdpPrompt() function using a custom KdpPromptString()
helper compatible with KD64, that is called by the KD64 implementation of
KdpPrompt(). This KdpPromptString() helper now issues the prompt on all
the KD loggers: e.g. if you use both at the same time COM-port and SCREEN
debugging, the prompt will appear on both. Before that the prompt was always
being displayed on COM port even if e.g. a SCREEN-only debug session was used...
- ppc_irq.c: Fix the prototype of KdpServiceDispatcher().
KD64 Fixes:
===========
- Initialize the MaximumLength member of the counted STRING variables
before using them elsewhere.
- Get rid of alloca() within SEH block in KdpPrint() (addendum to 7b95fcf9).
- Add the ROS-specific handy dump commands in KdSystemDebugControl().
2019-11-18 05:55:36 +08:00
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
break;
|
2011-10-12 05:29:13 +08:00
|
|
|
}
|
|
|
|
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Local kernel debugging is not yet supported */
|
|
|
|
DbgPrint("KdSystemDebugControl is unimplemented!\n");
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-11-03 01:45:51 +08:00
|
|
|
* @implemented
|
2009-10-12 11:35:35 +08:00
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdChangeOption(IN KD_OPTION Option,
|
|
|
|
IN ULONG InBufferBytes OPTIONAL,
|
|
|
|
IN PVOID InBuffer,
|
|
|
|
IN ULONG OutBufferBytes OPTIONAL,
|
|
|
|
OUT PVOID OutBuffer,
|
|
|
|
OUT PULONG OutBufferNeeded OPTIONAL)
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Fail if there is no debugger */
|
|
|
|
if (KdPitchDebugger)
|
|
|
|
{
|
|
|
|
/* No debugger, no options */
|
|
|
|
return STATUS_DEBUGGER_INACTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do we recognize this option? */
|
|
|
|
if (Option != KD_OPTION_SET_BLOCK_ENABLE)
|
|
|
|
{
|
|
|
|
/* We don't, clear the output length and fail */
|
|
|
|
if (OutBufferNeeded) *OutBufferNeeded = 0;
|
|
|
|
return STATUS_INVALID_INFO_CLASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify parameters */
|
|
|
|
if ((InBufferBytes != sizeof(BOOLEAN)) ||
|
|
|
|
(OutBufferBytes != 0) ||
|
|
|
|
(OutBuffer != NULL))
|
|
|
|
{
|
|
|
|
/* Invalid parameters for this option, fail */
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the high bit is set, meaning we don't
|
|
|
|
* allow the debugger to be enabled
|
|
|
|
*/
|
|
|
|
if (KdBlockEnable & 0x80)
|
|
|
|
{
|
|
|
|
/* Fail regardless of what state the caller tried to set */
|
|
|
|
return STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the new block enable state */
|
|
|
|
KdBlockEnable = *(PBOOLEAN)InBuffer;
|
|
|
|
|
|
|
|
/* No output buffer required for this option */
|
|
|
|
if (OutBufferNeeded) *OutBufferNeeded = 0;
|
|
|
|
|
|
|
|
/* We are done */
|
2009-10-12 11:35:35 +08:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-11-03 01:45:51 +08:00
|
|
|
* @implemented
|
2009-10-12 11:35:35 +08:00
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
KdPowerTransition(IN DEVICE_POWER_STATE NewState)
|
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Check what power state this is */
|
|
|
|
if (NewState == PowerDeviceD0)
|
|
|
|
{
|
|
|
|
/* Wake up the debug port */
|
|
|
|
KdD0Transition();
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else if ((NewState == PowerDeviceD1) ||
|
|
|
|
(NewState == PowerDeviceD2) ||
|
|
|
|
(NewState == PowerDeviceD3))
|
|
|
|
{
|
|
|
|
/* Power down the debug port */
|
|
|
|
KdD3Transition();
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid state! */
|
|
|
|
return STATUS_INVALID_PARAMETER_1;
|
|
|
|
}
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-11-03 01:45:51 +08:00
|
|
|
* @implemented
|
2009-10-12 11:35:35 +08:00
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
KdRefreshDebuggerNotPresent(VOID)
|
|
|
|
{
|
2009-11-08 09:13:49 +08:00
|
|
|
BOOLEAN Enable, DebuggerNotPresent;
|
2009-11-03 01:45:51 +08:00
|
|
|
|
|
|
|
/* Check if the debugger is completely disabled */
|
|
|
|
if (KdPitchDebugger)
|
|
|
|
{
|
2019-11-18 05:28:42 +08:00
|
|
|
/* Don't try to refresh then, fail early */
|
2009-11-03 01:45:51 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Enter the debugger */
|
2009-11-08 09:13:49 +08:00
|
|
|
Enable = KdEnterDebugger(NULL, NULL);
|
2009-11-03 01:45:51 +08:00
|
|
|
|
|
|
|
/*
|
2019-11-04 06:32:56 +08:00
|
|
|
* Attempt to send a string to the debugger
|
|
|
|
* to refresh the connection state.
|
2009-11-03 01:45:51 +08:00
|
|
|
*/
|
|
|
|
KdpDprintf("KDTARGET: Refreshing KD connection\n");
|
|
|
|
|
|
|
|
/* Save the state while we are holding the lock */
|
|
|
|
DebuggerNotPresent = KdDebuggerNotPresent;
|
|
|
|
|
|
|
|
/* Exit the debugger and return the state */
|
2009-11-08 09:13:49 +08:00
|
|
|
KdExitDebugger(Enable);
|
2009-11-03 01:45:51 +08:00
|
|
|
return DebuggerNotPresent;
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
2009-10-25 23:56:38 +08:00
|
|
|
/*
|
2009-11-03 01:45:51 +08:00
|
|
|
* @implemented
|
2009-10-25 23:56:38 +08:00
|
|
|
*/
|
2009-10-12 11:35:35 +08:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2019-11-18 00:16:55 +08:00
|
|
|
NtQueryDebugFilterState(
|
|
|
|
_In_ ULONG ComponentId,
|
|
|
|
_In_ ULONG Level)
|
2009-10-12 11:35:35 +08:00
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
PULONG Mask;
|
|
|
|
|
|
|
|
/* Check if the ID fits in the component table */
|
|
|
|
if (ComponentId < KdComponentTableSize)
|
|
|
|
{
|
|
|
|
/* It does, so get the mask from there */
|
|
|
|
Mask = KdComponentTable[ComponentId];
|
|
|
|
}
|
|
|
|
else if (ComponentId == MAXULONG)
|
|
|
|
{
|
|
|
|
/*
|
2019-11-04 06:32:56 +08:00
|
|
|
* This is the internal ID used for DbgPrint messages without ID
|
|
|
|
* and Level. Use the system-wide mask for those.
|
2009-11-03 01:45:51 +08:00
|
|
|
*/
|
|
|
|
Mask = &Kd_WIN2000_Mask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-18 00:16:55 +08:00
|
|
|
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
|
|
|
/* Use the default component ID */
|
|
|
|
Mask = &Kd_DEFAULT_Mask;
|
|
|
|
// Level = DPFLTR_INFO_LEVEL; // Override the Level.
|
|
|
|
#else
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Invalid ID, fail */
|
|
|
|
return STATUS_INVALID_PARAMETER_1;
|
2019-11-18 00:16:55 +08:00
|
|
|
#endif
|
2009-11-03 01:45:51 +08:00
|
|
|
}
|
|
|
|
|
2019-11-18 00:16:55 +08:00
|
|
|
/* Convert Level to bit field if required */
|
2009-11-03 01:45:51 +08:00
|
|
|
if (Level < 32) Level = 1 << Level;
|
2019-11-18 00:16:55 +08:00
|
|
|
Level &= ~DPFLTR_MASK;
|
2009-11-03 01:45:51 +08:00
|
|
|
|
|
|
|
/* Determine if this Level is filtered out */
|
2019-11-18 00:16:55 +08:00
|
|
|
if ((Kd_WIN2000_Mask & Level) || (*Mask & Level))
|
2009-11-03 01:45:51 +08:00
|
|
|
{
|
|
|
|
/* This mask will get through to the debugger */
|
|
|
|
return (NTSTATUS)TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* This mask is filtered out */
|
|
|
|
return (NTSTATUS)FALSE;
|
|
|
|
}
|
2009-10-12 11:35:35 +08:00
|
|
|
}
|
|
|
|
|
2009-10-25 23:56:38 +08:00
|
|
|
/*
|
2009-11-03 01:45:51 +08:00
|
|
|
* @implemented
|
2009-10-25 23:56:38 +08:00
|
|
|
*/
|
2009-10-12 11:35:35 +08:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2019-11-18 00:16:55 +08:00
|
|
|
NtSetDebugFilterState(
|
|
|
|
_In_ ULONG ComponentId,
|
|
|
|
_In_ ULONG Level,
|
|
|
|
_In_ BOOLEAN State)
|
2009-10-12 11:35:35 +08:00
|
|
|
{
|
2009-11-03 01:45:51 +08:00
|
|
|
PULONG Mask;
|
|
|
|
|
|
|
|
/* Modifying debug filters requires the debug privilege */
|
2019-11-18 00:16:55 +08:00
|
|
|
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, ExGetPreviousMode()))
|
2009-11-03 01:45:51 +08:00
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the ID fits in the component table */
|
|
|
|
if (ComponentId < KdComponentTableSize)
|
|
|
|
{
|
|
|
|
/* It does, so get the mask from there */
|
|
|
|
Mask = KdComponentTable[ComponentId];
|
|
|
|
}
|
|
|
|
else if (ComponentId == MAXULONG)
|
|
|
|
{
|
|
|
|
/*
|
2019-11-04 06:32:56 +08:00
|
|
|
* This is the internal ID used for DbgPrint messages without ID
|
|
|
|
* and Level. Use the system-wide mask for those.
|
2009-11-03 01:45:51 +08:00
|
|
|
*/
|
|
|
|
Mask = &Kd_WIN2000_Mask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-18 00:16:55 +08:00
|
|
|
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
|
|
|
/* Use the default component ID */
|
|
|
|
Mask = &Kd_DEFAULT_Mask;
|
|
|
|
#else
|
2009-11-03 01:45:51 +08:00
|
|
|
/* Invalid ID, fail */
|
|
|
|
return STATUS_INVALID_PARAMETER_1;
|
2019-11-18 00:16:55 +08:00
|
|
|
#endif
|
2009-11-03 01:45:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert Level to bit field if required */
|
|
|
|
if (Level < 32) Level = 1 << Level;
|
2019-11-18 00:16:55 +08:00
|
|
|
Level &= ~DPFLTR_MASK;
|
2009-11-03 01:45:51 +08:00
|
|
|
|
2019-11-18 00:16:55 +08:00
|
|
|
/* Set or remove the Level */
|
2009-11-03 01:45:51 +08:00
|
|
|
if (State)
|
|
|
|
*Mask |= Level;
|
|
|
|
else
|
|
|
|
*Mask &= ~Level;
|
|
|
|
|
2009-10-12 11:35:35 +08:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|