You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
403 lines
13 KiB
403 lines
13 KiB
//----------------------------------------------------------------------------
|
|
//
|
|
// KD hard-line communication support.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1999-2002.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#ifndef __DBGKDTRANS_HPP__
|
|
#define __DBGKDTRANS_HPP__
|
|
|
|
#define MAX_MANIP_TRANSFER (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))
|
|
|
|
#define PACKET_MAX_MANIP_SIZE \
|
|
(PACKET_MAX_SIZE + sizeof(DBGKD_MANIPULATE_STATE64) - \
|
|
sizeof(DBGKD_MANIPULATE_STATE32) + sizeof(KD_PACKET))
|
|
|
|
enum
|
|
{
|
|
DBGKD_WRITE_PACKET,
|
|
DBGKD_WRITE_RESEND,
|
|
};
|
|
|
|
enum
|
|
{
|
|
DBGKD_WAIT_PACKET,
|
|
DBGKD_WAIT_ACK,
|
|
DBGKD_WAIT_RESYNC,
|
|
DBGKD_WAIT_FAILED,
|
|
DBGKD_WAIT_RESEND,
|
|
DBGKD_WAIT_AGAIN,
|
|
DBGKD_WAIT_INTERRUPTED
|
|
};
|
|
|
|
enum
|
|
{
|
|
DBGKD_TRANSPORT_COM,
|
|
DBGKD_TRANSPORT_1394,
|
|
DBGKD_TRANSPORT_COUNT
|
|
};
|
|
|
|
#define DBGKD_OUTPUT_READS 0x00000001
|
|
#define DBGKD_OUTPUT_WRITES 0x00000002
|
|
|
|
#define KD_FILE_SIGNATURE 'lFdK'
|
|
|
|
struct KD_FILE
|
|
{
|
|
LIST_ENTRY List;
|
|
HANDLE Handle;
|
|
ULONG Signature;
|
|
};
|
|
|
|
PCSTR g_DbgKdTransportNames[];
|
|
|
|
class DbgKdTransport : public ParameterStringParser
|
|
{
|
|
public:
|
|
DbgKdTransport(ConnLiveKernelTargetInfo* Target);
|
|
virtual ~DbgKdTransport(void);
|
|
|
|
// ParameterStringParser.
|
|
virtual ULONG GetNumberParameters(void);
|
|
virtual void GetParameter(ULONG Index,
|
|
PSTR Name, ULONG NameSize,
|
|
PSTR Value, ULONG ValueSize);
|
|
|
|
virtual void ResetParameters(void);
|
|
virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
|
|
|
|
//
|
|
// DbgKdTransport.
|
|
//
|
|
|
|
void Restart(void);
|
|
|
|
// Base implementation displays general information and
|
|
// packets/bytes read/written. It should be invoked
|
|
// before derived operations.
|
|
virtual void OutputInfo(void);
|
|
|
|
// Base implementation creates events for overlapped operations.
|
|
virtual HRESULT Initialize(void);
|
|
|
|
virtual BOOL Read(IN PVOID Buffer,
|
|
IN ULONG SizeOfBuffer,
|
|
IN PULONG BytesRead) = 0;
|
|
virtual BOOL Write(IN PVOID Buffer,
|
|
IN ULONG SizeOfBuffer,
|
|
IN PULONG BytesWritten) = 0;
|
|
|
|
// Base implementation does nothing.
|
|
virtual void CycleSpeed(void);
|
|
|
|
virtual HRESULT ReadTargetPhysicalMemory(IN ULONG64 MemoryOffset,
|
|
IN PVOID Buffer,
|
|
IN ULONG SizeofBuffer,
|
|
IN PULONG BytesRead);
|
|
|
|
// This routine keeps on sending reset packet to target until reset packet
|
|
// is acknowledged by a reset packet from target.
|
|
//
|
|
// N.B. This routine is intended to be used by kernel debugger at startup
|
|
// time (ONLY) to get packet control variables on both target and host
|
|
// back in synchronization. Also, reset request will cause kernel to
|
|
// reset its control variables AND resend us its previous packet (with
|
|
// the new packet id).
|
|
virtual VOID Synchronize(VOID) = 0;
|
|
|
|
virtual ULONG ReadPacketContents(IN USHORT PacketType) = 0;
|
|
virtual ULONG WritePacketContents(IN KD_PACKET* Packet,
|
|
IN PVOID PacketData,
|
|
IN USHORT PacketDataLength,
|
|
IN PVOID MorePacketData OPTIONAL,
|
|
IN USHORT MorePacketDataLength OPTIONAL,
|
|
IN BOOL NoAck) = 0;
|
|
|
|
ULONG HandleDebugIo(PDBGKD_DEBUG_IO Packet);
|
|
ULONG HandleTraceIo(PDBGKD_TRACE_IO Packet);
|
|
ULONG HandleControlRequest(PDBGKD_CONTROL_REQUEST Packet);
|
|
ULONG HandleFileIo(PDBGKD_FILE_IO Packet);
|
|
|
|
ULONG WaitForPacket(IN USHORT PacketType,
|
|
OUT PVOID Packet);
|
|
|
|
VOID WriteBreakInPacket(VOID);
|
|
VOID WriteControlPacket(IN USHORT PacketType,
|
|
IN ULONG PacketId OPTIONAL);
|
|
VOID WriteDataPacket(IN PVOID PacketData,
|
|
IN USHORT PacketDataLength,
|
|
IN USHORT PacketType,
|
|
IN PVOID MorePacketData OPTIONAL,
|
|
IN USHORT MorePacketDataLength OPTIONAL,
|
|
IN BOOL NoAck);
|
|
|
|
inline VOID WritePacket(IN PVOID PacketData,
|
|
IN USHORT PacketDataLength,
|
|
IN USHORT PacketType,
|
|
IN PVOID MorePacketData OPTIONAL,
|
|
IN USHORT MorePacketDataLength OPTIONAL)
|
|
{
|
|
WriteDataPacket(PacketData, PacketDataLength, PacketType,
|
|
MorePacketData, MorePacketDataLength, FALSE);
|
|
}
|
|
inline VOID WriteAsyncPacket(IN PVOID PacketData,
|
|
IN USHORT PacketDataLength,
|
|
IN USHORT PacketType,
|
|
IN PVOID MorePacketData OPTIONAL,
|
|
IN USHORT MorePacketDataLength OPTIONAL)
|
|
{
|
|
WriteDataPacket(PacketData, PacketDataLength, PacketType,
|
|
MorePacketData, MorePacketDataLength, TRUE);
|
|
}
|
|
|
|
ULONG ComputeChecksum(IN PUCHAR Buffer,
|
|
IN ULONG Length);
|
|
|
|
// This save/restore isn't particularly elegant
|
|
// but we need something like it. We receive a state change
|
|
// without knowing what kind of machine we're talking to.
|
|
// We have to send/receive a GetVersion packet to get that
|
|
// information, but we need to keep the original packet
|
|
// information around while we do so.
|
|
void SaveReadPacket(void)
|
|
{
|
|
memcpy(s_SavedPacket, s_Packet, sizeof(s_Packet));
|
|
s_SavedPacketHeader = s_PacketHeader;
|
|
}
|
|
void RestoreReadPacket(void)
|
|
{
|
|
memcpy(s_Packet, s_SavedPacket, sizeof(s_Packet));
|
|
s_PacketHeader = s_SavedPacketHeader;
|
|
}
|
|
|
|
void HandlePrint(IN ULONG Processor,
|
|
IN PCSTR String,
|
|
IN USHORT StringLength,
|
|
IN ULONG Mask);
|
|
void HandlePromptString(IN PDBGKD_DEBUG_IO IoMessage);
|
|
void HandlePrintTrace(IN ULONG Processor,
|
|
IN PUCHAR Data,
|
|
IN USHORT DataLength,
|
|
IN ULONG Mask);
|
|
|
|
void ClearKdFileAssoc(void);
|
|
HRESULT LoadKdFileAssoc(PSTR FileName);
|
|
void InitKdFileAssoc(void);
|
|
void ParseKdFileAssoc(void);
|
|
NTSTATUS CreateKdFile(PWSTR FileName,
|
|
ULONG DesiredAccess, ULONG FileAttributes,
|
|
ULONG ShareAccess, ULONG CreateDisposition,
|
|
ULONG CreateOptions,
|
|
KD_FILE** FileEntry, PULONG64 Length);
|
|
void CloseKdFile(KD_FILE* File);
|
|
KD_FILE* TranslateKdFileHandle(ULONG64 Handle);
|
|
|
|
void Ref(void)
|
|
{
|
|
m_Refs++;
|
|
}
|
|
void Release(void)
|
|
{
|
|
if (--m_Refs == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
ULONG m_Refs;
|
|
ConnLiveKernelTargetInfo* m_Target;
|
|
ULONG m_Index;
|
|
HANDLE m_Handle;
|
|
BOOL m_DirectPhysicalMemory;
|
|
ULONG m_InvPacketRetryLimit;
|
|
BOOL m_AckWrites;
|
|
ULONG m_OutputIo;
|
|
|
|
//
|
|
// This overlapped structure will be used for all serial read
|
|
// operations. We only need one structure since the code is
|
|
// designed so that no more than one serial read operation is
|
|
// outstanding at any one time.
|
|
//
|
|
OVERLAPPED m_ReadOverlapped;
|
|
|
|
//
|
|
// This overlapped structure will be used for all serial write
|
|
// operations. We only need one structure since the code is
|
|
// designed so that no more than one serial write operation is
|
|
// outstanding at any one time.
|
|
//
|
|
OVERLAPPED m_WriteOverlapped;
|
|
|
|
ULONG m_PacketsRead;
|
|
ULONG64 m_BytesRead;
|
|
ULONG m_PacketsWritten;
|
|
ULONG64 m_BytesWritten;
|
|
|
|
// ID for expected incoming packet.
|
|
ULONG m_PacketExpected;
|
|
// ID for Next packet to send.
|
|
ULONG m_NextPacketToSend;
|
|
|
|
// Thread ID for thread in WaitStateChange. Normally
|
|
// multithreaded access to the transport is prevented by
|
|
// the engine lock, but the engine lock is suspended
|
|
// while WaitStateChange is doing its WaitPacketForever.
|
|
// During that time other threads must be forcibly
|
|
// prevented from using the kernel connection.
|
|
ULONG m_WaitingThread;
|
|
|
|
BOOL m_AllowInitialBreak;
|
|
BOOL m_Resync;
|
|
BOOL m_BreakIn;
|
|
BOOL m_SyncBreakIn;
|
|
BOOL m_ValidUnaccessedPacket;
|
|
|
|
LIST_ENTRY m_KdFiles;
|
|
char m_KdFileAssocSource[MAX_PATH];
|
|
LIST_ENTRY m_KdFileAssoc;
|
|
|
|
static UCHAR s_BreakinPacket[1];
|
|
static UCHAR s_PacketTrailingByte[1];
|
|
static UCHAR s_PacketLeader[4];
|
|
|
|
static UCHAR s_Packet[PACKET_MAX_MANIP_SIZE];
|
|
static KD_PACKET s_PacketHeader;
|
|
|
|
static UCHAR s_SavedPacket[PACKET_MAX_MANIP_SIZE];
|
|
static KD_PACKET s_SavedPacketHeader;
|
|
|
|
private:
|
|
struct KD_FILE_ASSOC* FindKdFileAssoc(PWSTR From);
|
|
};
|
|
|
|
class DbgKdComTransport : public DbgKdTransport
|
|
{
|
|
public:
|
|
DbgKdComTransport(ConnLiveKernelTargetInfo* Target);
|
|
virtual ~DbgKdComTransport(void);
|
|
|
|
// ParameterStringParser.
|
|
virtual ULONG GetNumberParameters(void);
|
|
virtual void GetParameter(ULONG Index,
|
|
PSTR Name, ULONG NameSize,
|
|
PSTR Value, ULONG ValueSize);
|
|
|
|
virtual void ResetParameters(void);
|
|
virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
|
|
|
|
// DbgKdTransport.
|
|
virtual HRESULT Initialize(void);
|
|
|
|
virtual BOOL Read(IN PVOID Buffer,
|
|
IN ULONG SizeOfBuffer,
|
|
IN PULONG BytesRead);
|
|
virtual BOOL Write(IN PVOID Buffer,
|
|
IN ULONG SizeOfBuffer,
|
|
IN PULONG BytesWritten);
|
|
virtual void CycleSpeed(void);
|
|
|
|
virtual VOID Synchronize(VOID);
|
|
|
|
virtual ULONG ReadPacketContents(IN USHORT PacketType);
|
|
virtual ULONG WritePacketContents(IN KD_PACKET* Packet,
|
|
IN PVOID PacketData,
|
|
IN USHORT PacketDataLength,
|
|
IN PVOID MorePacketData OPTIONAL,
|
|
IN USHORT MorePacketDataLength OPTIONAL,
|
|
IN BOOL NoAck);
|
|
|
|
//
|
|
// DbgKdComTransport.
|
|
//
|
|
|
|
ULONG ReadPacketLeader(IN ULONG PacketType,
|
|
OUT PULONG PacketLeader);
|
|
void CheckComStatus(void);
|
|
DWORD SelectNewBaudRate(DWORD NewRate);
|
|
|
|
char m_PortName[MAX_PARAM_VALUE + 8];
|
|
ULONG m_BaudRate;
|
|
COM_PORT_TYPE m_PortType;
|
|
ULONG m_Timeout;
|
|
ULONG m_CurTimeout;
|
|
ULONG m_MaxSyncResets;
|
|
ULONG m_IpPort;
|
|
|
|
// Used to carrier detection.
|
|
DWORD m_ComEvent;
|
|
|
|
//
|
|
// This overlapped structure will be used for all event operations.
|
|
// We only need one structure since the code is designed so that no more
|
|
// than one serial event operation is outstanding at any one time.
|
|
//
|
|
OVERLAPPED m_EventOverlapped;
|
|
};
|
|
|
|
enum
|
|
{
|
|
DBGKD_1394_OPERATION_MODE_DEBUG,
|
|
DBGKD_1394_OPERATION_RAW_MEMORY_ACCESS
|
|
};
|
|
|
|
class DbgKd1394Transport : public DbgKdTransport
|
|
{
|
|
public:
|
|
DbgKd1394Transport(ConnLiveKernelTargetInfo* Target);
|
|
virtual ~DbgKd1394Transport(void);
|
|
|
|
// ParameterStringParser.
|
|
virtual ULONG GetNumberParameters(void);
|
|
virtual void GetParameter(ULONG Index,
|
|
PSTR Name, ULONG NameSize,
|
|
PSTR Value, ULONG ValueSize);
|
|
|
|
virtual void ResetParameters(void);
|
|
virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
|
|
|
|
// DbgKdTransport.
|
|
virtual HRESULT Initialize(void);
|
|
|
|
virtual BOOL Read(IN PVOID Buffer,
|
|
IN ULONG SizeOfBuffer,
|
|
IN PULONG BytesRead);
|
|
virtual BOOL Write(IN PVOID Buffer,
|
|
IN ULONG SizeOfBuffer,
|
|
IN PULONG BytesWritten);
|
|
|
|
virtual HRESULT ReadTargetPhysicalMemory(IN ULONG64 MemoryOffset,
|
|
IN PVOID Buffer,
|
|
IN ULONG SizeofBuffer,
|
|
IN PULONG BytesRead);
|
|
|
|
virtual VOID Synchronize(VOID);
|
|
|
|
virtual ULONG ReadPacketContents(IN USHORT PacketType);
|
|
virtual ULONG WritePacketContents(IN KD_PACKET* Packet,
|
|
IN PVOID PacketData,
|
|
IN USHORT PacketDataLength,
|
|
IN PVOID MorePacketData OPTIONAL,
|
|
IN USHORT MorePacketDataLength OPTIONAL,
|
|
IN BOOL NoAck);
|
|
|
|
// DbgKd1394Transport.
|
|
|
|
BOOL SwitchVirtualDebuggerDriverMode(IN ULONG NewMode);
|
|
void CloseSecond(BOOL MakeFirst);
|
|
|
|
ULONG m_Channel;
|
|
char m_Symlink[MAX_PARAM_VALUE];
|
|
ULONG m_OperationMode;
|
|
BOOL m_SymlinkSpecified;
|
|
char m_Symlink2[MAX_PARAM_VALUE];
|
|
|
|
HANDLE m_Handle2;
|
|
OVERLAPPED m_ReadOverlapped2;
|
|
|
|
UCHAR m_TxPacket[PACKET_MAX_MANIP_SIZE];
|
|
};
|
|
|
|
#endif // #ifndef __DBGKDTRANS_HPP__
|