⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdapi.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++

Module Name:

    kdapi.c

Abstract:

    Implementation of Kernel Debugger portable remote APIs.

--*/

#include "kdp.h"

DWORD NkCEProcessorType; // Temp change [GH]: was CEProcessorType

union
{
    DBGKD_COMMAND Kd;
    OSAXS_COMMAND OsAxs;
} g_dbgCmdPacket;

#define g_dbgkdCmdPacket g_dbgCmdPacket.Kd
#define g_dbgOsAxsCmdPacket g_dbgCmdPacket.OsAxs


DWORD g_dwOsAxsProtocolVersion = OSAXS_PROTOCOL_LATEST_VERSION;


BOOL KDIoControl (DWORD dwIoControlCode, LPVOID lpBuf, DWORD nBufSize)
{
    BOOL fRet = FALSE;
    if (g_kdKernData.pKDIoControl)
    {
#if defined(x86)
        fRet = KCall (g_kdKernData.pKDIoControl, dwIoControlCode, lpBuf, nBufSize);
        KDEnableInt (FALSE, NULL); // Re-Disable interupts (KCall restored them)
#else
        fRet = g_kdKernData.pKDIoControl (dwIoControlCode, lpBuf, nBufSize);
#endif
    }
    return fRet;
}


static void KdpCallOsAccess (OSAXS_COMMAND *, PSTRING);


void KdpResetBps (void)
{
    if (g_kdKernData.pKDIoControl)
    {
        KDIoControl (KD_IOCTL_INIT, NULL, 0);
    }
    KdpDeleteAllBreakpoints();
}


void
KdpSendKdApiCmdPacket (
    IN STRING *MessageHeader,
    IN OPTIONAL STRING *MessageData
    )
{
    KdpSendPacket
    (
        PACKET_TYPE_KD_CMD,
        GUID_KDDBGCLIENT_KDSTUB,
        MessageHeader,
        MessageData
    );
}


/*++

Routine Description:

    This function sends a packet, and then handles debugger commands until
    a "continue" (resume execution) command.
    BreakIns received while waiting will always cause a resend of the
    packet originally sent out.  While waiting, manipulate messages
    will be serviced.

    A resend always resends the original event sent to the debugger,
    not the last response to some debugger command.

Arguments:

    OutPacketType - Supplies the type of packet to send.

    OutMessageHeader - Supplies a pointer to a string descriptor that describes
        the message information.

    OutMessageData - Supplies a pointer to a string descriptor that describes
        the optional message data.

Return Value:

    A value of TRUE is returned if the continue message indicates
    success, Otherwise, a value of FALSE is returned.

--*/

BOOLEAN KdpSendNotifAndDoCmdLoop (
    IN PSTRING OutMessageHeader,
    IN PSTRING OutMessageData OPTIONAL
    )
{
    ULONG Length;
    STRING MessageData;
    STRING MessageHeader;
    USHORT ReturnCode;
    PUCHAR pucDummy;
    BOOLEAN fHandled = FALSE;
    BOOLEAN fExit = FALSE;

    if (!g_fKdbgRegistered)
    { // We never registered KDBG service
        // JIT Debugging
        EnableHDNotifs (TRUE);
        g_fKdbgRegistered = g_kdKernData.pKITLIoCtl(IOCTL_EDBG_REGISTER_DFLT_CLIENT, &pucDummy, KITL_SVC_KDBG, &pucDummy, 0, NULL);
    }

    if (!g_fKdbgRegistered) return FALSE;

    // Loop servicing command message until a continue message is received.
    
    MessageHeader.MaximumLength = sizeof (g_dbgCmdPacket);
    MessageHeader.Buffer = (PCHAR) &g_dbgCmdPacket;
    MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE;
    MessageData.Buffer = (PCHAR) g_abMessageBuffer;

ResendPacket:

    // Send event notification packet to debugger on host.  Come back
    // here any time we see a breakin sequence.
    KdpSendPacket (PACKET_TYPE_KD_NOTIF, GUID_KDDBGCLIENT_KDSTUB, OutMessageHeader, OutMessageData);

    while (!fExit)
    {
        GUID guidClient;

        // Make sure these two MaximumLength members never change while in break state
        KD_ASSERT (sizeof (g_dbgCmdPacket) == MessageHeader.MaximumLength);
        KD_ASSERT (KDP_MESSAGE_BUFFER_SIZE == MessageData.MaximumLength);

        ReturnCode = KdpReceiveCmdPacket(
                        &MessageHeader,
                        &MessageData,
                        &Length,
                        &guidClient
                        );
        if (ReturnCode == (USHORT) KDP_PACKET_RESEND)
        { // This means the host disconnected and reconnected
            DEBUGGERMSG(KDZONE_TRAP, (L"++KdpSendNotifAndDoCmdLoop: RESENDING NOTIFICATION\r\n"));
            KdpResetBps ();
            goto ResendPacket;
        }

        if (!memcmp (&guidClient, &GUID_KDDBGCLIENT_KDSTUB, sizeof (GUID)))
        {
            // Insert here flags of supported feature based on host version
            if (g_dbgkdCmdPacket.dwSubVersionId >= KDAPI_PROTOCOL_VERSION)
            {
                // Switch on the return message API number.
                DEBUGGERMSG(KDZONE_API, (L"Got Api %8.8lx\r\n", g_dbgkdCmdPacket.dwApiNumber));

                switch (g_dbgkdCmdPacket.dwApiNumber)
                {
                    case DbgKdReadVirtualMemoryApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdReadVirtualMemoryApi\r\n"));
                        KdpReadVirtualMemory (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    case DbgKdWriteVirtualMemoryApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteVirtualMemoryApi\r\n"));
                        KdpWriteVirtualMemory (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    case DbgKdReadPhysicalMemoryApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdReadPhysicalMemoryApi\r\n"));
                        KdpReadPhysicalMemory (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    case DbgKdWritePhysicalMemoryApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdWritePhysicalMemoryApi\r\n"));
                        KdpWritePhysicalMemory (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    case DbgKdSetContextApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdSetContextApi\r\n"));
                        KdpSetContext(&g_dbgkdCmdPacket,&MessageData);
                        break;
                    case DbgKdReadControlSpaceApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdReadControlSpaceApi\r\n"));
                        KdpReadControlSpace (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    case DbgKdWriteControlSpaceApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteControlSpaceApi\r\n"));
                        KdpWriteControlSpace (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    case DbgKdReadIoSpaceApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdReadIoSpaceApi\r\n"));
                        KdpReadIoSpace (&g_dbgkdCmdPacket, &MessageData, TRUE);
                        break;
                    case DbgKdWriteIoSpaceApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteIoSpaceApi\r\n"));
                        KdpWriteIoSpace (&g_dbgkdCmdPacket, &MessageData, TRUE);
                        break;
                    case DbgKdContinueApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdContinueApi\r\n"));
                        DEBUGGERMSG(KDZONE_API, (L"Continuing target system %i\r\n", g_dbgkdCmdPacket.u.Continue.dwContinueStatus));
                        fHandled = (BOOLEAN) (g_dbgkdCmdPacket.u.Continue.dwContinueStatus == DBG_CONTINUE);
                        fExit = TRUE;
                        break;
                    case DbgKdTerminateApi:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdTerminateApi\r\n"));
                        KdpResetBps ();
                        if (g_fKdbgRegistered)
                        {
                            EnableHDNotifs (FALSE);
                            g_kdKernData.pKITLIoCtl (IOCTL_EDBG_DEREGISTER_CLIENT, NULL, KITL_SVC_KDBG, NULL, 0, NULL);
                            g_fKdbgRegistered = FALSE;
                        }
                        // Disconnect from hdstub
                        Hdstub.pfnUnregisterClient (&g_KdstubClient);
                        // Kernel specific clean ups...
                        KdCleanup();
                        g_fDbgConnected = FALSE; // tell KdpTrap to shutdown
                        fHandled = TRUE;
                        fExit = TRUE;
                        break;
                    case DbgKdManipulateBreakpoint:
                        DEBUGGERMSG( KDZONE_API, (L"DbgKdManipulateBreakpoint\r\n"));
                        KdpManipulateBreakPoint (&g_dbgkdCmdPacket, &MessageData);
                        break;
                    default: // Invalid message.
                        DEBUGGERMSG( KDZONE_ALERT, (L"  KdpSendNotifAndDoCmdLoop: Unknown API??\r\n"));
                        MessageData.Length = 0;
                        g_dbgkdCmdPacket.dwReturnStatus = STATUS_UNSUCCESSFUL;
                        KdpSendKdApiCmdPacket (&MessageHeader, &MessageData);
                        break;
                }
            }
            else
            {
                DEBUGGERMSG( KDZONE_ALERT, (L"  KdpSendNotifAndDoCmdLoop: protocol Version not supported\r\n"));
                MessageData.Length = 0;
                g_dbgkdCmdPacket.dwReturnStatus = STATUS_UNSUCCESSFUL;
                KdpSendKdApiCmdPacket (&MessageHeader, &MessageData);
            }
        }
        else if (!memcmp (&guidClient, &GUID_KDDBGCLIENT_OSAXS, sizeof (GUID)))
        {
            DEBUGGERMSG (KDZONE_API, (L"Calling OsAccess\r\n"));
            KdpCallOsAccess (&g_dbgOsAxsCmdPacket, &MessageData);
        }
    }
    return fHandled;
}

static void KdpCallOsAccess (OSAXS_COMMAND *pOsAxsCmd, PSTRING AdditionalData)
{
    HRESULT hr;
    STRING ResponseHeader;

    DEBUGGERMSG (KDZONE_API, (L"++KdpCallOsAccess\r\n"));
    
    ResponseHeader.Length = sizeof (*pOsAxsCmd);
    ResponseHeader.Buffer = (BYTE *) pOsAxsCmd;
HandleRequest:
    if (pOsAxsCmd->dwVersion == g_dwOsAxsProtocolVersion)
    {
        switch (pOsAxsCmd->dwApi)
        {
            case OSAXS_API_GET_FLEXIPTMINFO:
                {
                    // Use tempory DWORD for IOCTL call, since AdditionalData->Length is a USHORT.
                    DWORD dwSize = AdditionalData->MaximumLength;

                    DEBUGGERMSG(KDZONE_API, (L"  KdpCallOsAccess -> GetFPTMI\r\n"));
                    // OsAccess requires an output buffer.  Need to report the
                    // size of the buffer to the API call so it won't overflow
                    hr = Hdstub.pfnCallClientIoctl (OSAXST0_NAME, OSAXST0_IOCTL_GET_FLEXIPTMINFO, (DWORD) &pOsAxsCmd->u.FlexiReq,
                            (DWORD) &dwSize, (DWORD) AdditionalData->Buffer, 0);

                    if (SUCCEEDED (hr))
                    {
                        AdditionalData->Length = (USHORT) dwSize;
                    }
                    else
                    {
                        DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdpCallOsAccess: Failed to get FlexiPTMI info from OsAxsT0, hr = 0x%08X\r\n"),hr));
                    }
                       
                }
                break;
            
            case OSAXS_API_GET_STRUCT:
                {
                    // Use tempory DWORD for IOCTL call, since AdditionalData->Length is a USHORT.
                    DWORD dwSize = AdditionalData->MaximumLength;
                    DEBUGGERMSG(KDZONE_API, (L"  KdpCallOsAccess -> GetStruct @0x%08x\r\n", pOsAxsCmd->u.Struct.StructAddr));

                    hr = Hdstub.pfnCallClientIoctl (OSAXST1_NAME, OSAXST1_IOCTL_GET_OSSTRUCT, (DWORD) &pOsAxsCmd->u.Struct,
                            (DWORD) AdditionalData->Buffer, (DWORD) &dwSize, 0);
                    if (SUCCEEDED (hr))
                    {
                        AdditionalData->Length = (USHORT) dwSize;
                    }
                    else
                    {
                        DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdpCallOsAccess: Failed to get OsStruct info from OsAxsT1, hr = 0x%08X\r\n"),hr));
                    }
                }
                break;
            case OSAXS_API_GET_THREADCTX:
                {
                    // Use tempory DWORD for IOCTL call, since AdditionalData->Length is a USHORT.
                    DWORD dwSize = AdditionalData->MaximumLength;

                    hr = Hdstub.pfnCallClientIoctl (OSAXST1_NAME, OSAXST1_IOCTL_GET_THREADCTX, (DWORD) pOsAxsCmd->u.Addr,
                            (DWORD) &AdditionalData->Buffer, (DWORD) &dwSize, 0);
                    if (SUCCEEDED (hr))
                    {
                        AdditionalData->Length = (USHORT) dwSize;
                    }
                    else
                    {
                        DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdpCallOsAccess: Failed to get ThreadCtx info from OsAxsT1, hr = 0x%08X\r\n"),hr));
                    }
                }
                break;
            case OSAXS_API_SET_THREADCTX:
                {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -