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

📄 kdctrl.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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:

    kdctrl.c

Abstract:

    This module implements CPU specific remote debug APIs.

Environment:

    WinCE

--*/

#include "kdp.h"

#if defined(x86)
int             __cdecl _inp(unsigned short);
int             __cdecl _outp(unsigned short, int);
unsigned short  __cdecl _inpw(unsigned short);
unsigned short  __cdecl _outpw(unsigned short, unsigned short);
unsigned long   __cdecl _inpd(unsigned short);
unsigned long   __cdecl _outpd(unsigned short, unsigned long);

PVOID __inline GetRegistrationHead(void)
{
    __asm mov eax, dword ptr fs:[0];
}

#pragma intrinsic(_inp, _inpw, _inpd, _outp, _outpw, _outpd)
#endif


BOOL fThreadWalk;

DWORD ReloadAllSymbols(LPBYTE lpBuffer, BOOL fDoCopy);
static NTSTATUS GetModuleRefCount(HMODULE hDll, LPVOID pBuffer, USHORT *pnLength);


BOOL CheckIfPThreadExists (PTHREAD pThreadToValidate)

{
    DWORD dwProcessIdx;
    PTHREAD pThread;

    for (dwProcessIdx = 0; dwProcessIdx < MAX_PROCESSES; dwProcessIdx++)
    { // For each process:
        if (kdProcArray [dwProcessIdx].dwVMBase)
        { // Only if VM Base Addr of process is valid (not null):
            for (pThread = kdProcArray [dwProcessIdx].pTh; // Get process main thread
                 pThread;
                 pThread = pThread->pNextInProc) // Next thread
            { // walk list of threads attached to process (until we reach the end of the list or we found the matching pThread)
                if (pThreadToValidate == pThread) return TRUE;
            }
        }
    }
    return FALSE;
}

VOID
KdpReadControlSpace (
    IN DBGKD_COMMAND *pdbgkdCmdPacket,
    IN PSTRING AdditionalData
    )

/*++

Routine Description:

    This function is called in response of a read control space command
    message.  Its function is to read implementation
    specific system data.

Arguments:

    pdbgkdCmdPacket - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

Return Value:

    None.

--*/

{

    DBGKD_READ_MEMORY *a = &pdbgkdCmdPacket->u.ReadMemory;
    STRING MessageHeader;
    ULONG NextOffset;
    DWORD dwReturnAddr;
    DWORD dwFramePtr = 0;
    DWORD dwStackPtr = 0;
    DWORD dwProcHandle = 0;


    MessageHeader.Length = sizeof(*pdbgkdCmdPacket);
    MessageHeader.Buffer = (PCHAR)pdbgkdCmdPacket;

    pdbgkdCmdPacket->dwReturnStatus = STATUS_UNSUCCESSFUL; // By default (shorter and safer)

    //
    // qwTgtAddress field is being used as the ControlSpace request id
    //
    switch (a->qwTgtAddress)
    {

        case HANDLE_PROCESS_THREAD_INFO_REQ: // Replacing HANDLE_PROCESS_INFO_REQUEST

            GetProcessAndThreadInfo (AdditionalData);
            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS; // the return status is in the message itself
            break;

        case HANDLE_GET_NEXT_OFFSET_REQUEST:

            if (AdditionalData->Length != sizeof(ULONG)) {
                AdditionalData->Length = 0;
                break; // Unsucessful
            }

            memcpy((PVOID)&NextOffset, (PVOID)AdditionalData->Buffer, sizeof(ULONG));

            if (!TranslateAddress(&NextOffset, g_pctxException)) {
                AdditionalData->Length = 0;
                break; // Unsucessful
            }

            memcpy((PVOID)AdditionalData->Buffer, (PVOID)&NextOffset, sizeof(ULONG));


            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            AdditionalData->Length = sizeof(ULONG);

            break;

        case HANDLE_STACKWALK_REQUEST:

            //
            // Translate a stack frame address
            //

            DEBUGGERMSG(KDZONE_STACKW, (L"++ReadCtrl HANDLE_STACKWALK_REQUEST\r\n"));

            if ((sizeof(DWORD) != AdditionalData->Length) &&
                (2*sizeof(DWORD) != AdditionalData->Length) &&
                (3*sizeof(DWORD) != AdditionalData->Length))
            {
                // Invalid argument
                DEBUGGERMSG (KDZONE_ALERT, (L"  ReadCtrl Bad AdditionalData Length (%i)\r\n", AdditionalData->Length));

                AdditionalData->Length = 0;
            }
            else
            {
                memcpy((VOID*)&dwReturnAddr, (PVOID)AdditionalData->Buffer, sizeof(DWORD));
                if (2*sizeof(DWORD) <= AdditionalData->Length)
                {
                    memcpy((PVOID)&dwFramePtr, (PVOID)(AdditionalData->Buffer + sizeof(DWORD)), sizeof(DWORD));

                    DEBUGGERMSG (KDZONE_STACKW, (L"  ReadCtrl dwFramePtr=%8.8lX\r\n", dwFramePtr));
                }
                else
                {
                    dwFramePtr = 0;
                }

                DEBUGGERMSG (KDZONE_STACKW, (L"  ReadCtrl Old RetAddr=%8.8lX\r\n", dwReturnAddr));

                if (!TranslateRA (&dwReturnAddr, &dwStackPtr, dwFramePtr, &dwProcHandle))
                {
                    DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl TranslateRA FAILED\r\n"));

                    AdditionalData->Length = 0;
                }
                else
                {
                    DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl: New RetAddr=%8.8lX\r\n", dwReturnAddr));
                    if (dwStackPtr)
                    {
                        DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl: New dwStackPtr=%8.8lX\r\n", dwStackPtr));
                    }
                    DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl: New dwProcHandle=%8.8lX\r\n", dwProcHandle));

                    memcpy((PVOID)AdditionalData->Buffer, (PVOID)&dwReturnAddr, sizeof(DWORD));
                    AdditionalData->Length = sizeof(DWORD);

                    // Pass Previous SP
                    memcpy ((PVOID) (AdditionalData->Buffer + AdditionalData->Length), (PVOID)&dwStackPtr, sizeof(DWORD));
                    AdditionalData->Length += sizeof(DWORD);

                    memcpy ((PVOID) (AdditionalData->Buffer + AdditionalData->Length), (PVOID)&dwProcHandle, sizeof(DWORD));
                    AdditionalData->Length += sizeof(DWORD);

                    pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
                }
            }

            DEBUGGERMSG(KDZONE_STACKW, (L"--ReadCtrl HANDLE_STACKWALK_REQUEST\r\n"));
            break;

        case HANDLE_THREADSTACK_REQUEST:

            //
            // Set up a (thread-specific) stackwalk
            //

            DEBUGGERMSG(KDZONE_STACKW, (L"++ReadCtrl HANDLE_THREADSTACK_REQUEST\r\n"));

            pWalkThread = (PTHREAD)Kdstrtoul(AdditionalData->Buffer, 0x10);

            // Ensure pWalkThread is valid
            if (!CheckIfPThreadExists(pWalkThread))
            {
                DEBUGGERMSG (KDZONE_ALERT, (L"  ReadCtrl pWalkThread is invalid (%8.8lX)\r\n", (DWORD)pWalkThread));

                AdditionalData->Length = 0;
            }
            else
            {
                fThreadWalk = TRUE;
                g_fTopFrame = TRUE;

                pStk = pWalkThread->pcstkTop;
                pLastProc = pWalkThread->pProc;

                DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl pWalkThread=%8.8lX pLastProc=%8.8lX pStk=%8.8lX\r\n", pWalkThread, pLastProc, pStk));

                //
                // The thread's context will be returned in AdditionalData->Buffer
                //

                AdditionalData->Length = sizeof(CONTEXT);
                if (pWalkThread == pCurThread)
                {
                    memcpy(AdditionalData->Buffer, g_pctxException, sizeof(CONTEXT));
                }
                else
                {
                    CpuContextToContext((CONTEXT*)AdditionalData->Buffer, &pWalkThread->ctx);
                }

                DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl Context copied\r\n"));

                //
                // Slotize the PC if not in the kernel or a DLL
                //

                if (pLastProc)
                {
                    if ((ZeroPtr(CONTEXT_TO_PROGRAM_COUNTER((PCONTEXT)AdditionalData->Buffer)) > (1 << VA_SECTION)) ||
                        (ZeroPtr(CONTEXT_TO_PROGRAM_COUNTER((PCONTEXT)AdditionalData->Buffer)) < (DWORD)DllLoadBase))
                         CONTEXT_TO_PROGRAM_COUNTER((PCONTEXT)AdditionalData->Buffer) =
                           (UINT)MapPtrProc(CONTEXT_TO_PROGRAM_COUNTER((PCONTEXT)AdditionalData->Buffer), pLastProc);
                }
                else
                {
                    DEBUGGERMSG(KDZONE_STACKW, (L"  ReadCtrl *** ERROR pLastProc is NULL\r\n"));
                }

                pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            }

            DEBUGGERMSG(KDZONE_STACKW, (L"--ReadCtrl HANDLE_THREADSTACK_REQUEST\r\n"));

            break;

        case HANDLE_THREADSTACK_TERMINATE:

            //
            // Terminate a (thread-specific) stackwalk
            //

            DEBUGGERMSG(KDZONE_STACKW, (L"++ReadCtrl HANDLE_THREADSTACK_TERMINATE\r\n"));

            fThreadWalk = FALSE;

            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;

            DEBUGGERMSG(KDZONE_STACKW, (L"--ReadCtrl HANDLE_THREADSTACK_TERMINATE\r\n"));

            break;
        case HANDLE_RELOAD_MODULES_REQUEST:
            AdditionalData->Length = (WORD)ReloadAllSymbols( AdditionalData->Buffer, FALSE);
            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            break;

        case HANDLE_RELOAD_MODULES_INFO:
            AdditionalData->Length = (WORD)ReloadAllSymbols( AdditionalData->Buffer, TRUE);
            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            break;

        case HANDLE_GETCURPROCTHREAD:
            memcpy( AdditionalData->Buffer, &pCurProc, sizeof(DWORD));
            memcpy( AdditionalData->Buffer+(sizeof(DWORD)), &pCurThread, sizeof(DWORD));
            memcpy( AdditionalData->Buffer+(sizeof(DWORD)*2), &hCurProc, sizeof(DWORD));
            memcpy( AdditionalData->Buffer+(sizeof(DWORD)*3), &hCurThread, sizeof(DWORD));
            memcpy( AdditionalData->Buffer+(sizeof(DWORD)*4), &(pCurThread->pOwnerProc), sizeof(DWORD));
            memcpy( AdditionalData->Buffer+(sizeof(DWORD)*5), &((PROCESS *)(pCurThread->pOwnerProc)->hProc), sizeof(DWORD));
            AdditionalData->Length = sizeof(DWORD)*6;
            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            break;

        case HANDLE_GET_EXCEPTION_REGISTRATION:
#if defined(x86)
            DEBUGGERMSG(KDZONE_CTRL, (L"++ReadCtrl HANDLE_GET_EXCEPTION_REGISTRATION\r\n"));
            // This is only valid for x86 platforms!!!  It is used
            // by the kernel debugger for unwinding through exception
            // handlers
            if (AdditionalData->Length == 2*sizeof(VOID*))
            {
                CALLSTACK* pStack;
                VOID* pRegistration;
                VOID* pvCallStack = AdditionalData->Buffer+sizeof(VOID*);

                memcpy(&pStack, pvCallStack, sizeof(VOID*));
                if (pStack)
                {
                    // we are at a PSL boundary and need to look up the next registration
                    // pointer -- don't trust the pointer we got from the host
                    pRegistration = (VOID*)pStack->extra;
                    pStack = pStack->pcstkNext;
                }
                else
                {
                    // request for the registration head pointer
                    pRegistration = GetRegistrationHead();
                    pStack = pCurThread->pcstkTop;
                }

                memcpy(AdditionalData->Buffer, &pRegistration, sizeof(VOID*));
                memcpy(pvCallStack, &pStack, sizeof(VOID*));
                DEBUGGERMSG(KDZONE_CTRL, (L"  ReadCtrl HANDLE_GET_EXCEPTION_REGISTRATION: Registration Ptr: %8.8lx pCallStack: %8.8lx\r\n", (DWORD)pRegistration, (DWORD)pStack));
                // AdditionalData->Length stays the same (2*sizeof(VOID*))
                pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;

            }
            else
            { // ERROR case!!!
                DEBUGGERMSG (KDZONE_ALERT, (L"  ReadCtrl HANDLE_GET_EXCEPTION_REGISTRATION: Invalid parameter.\r\n"));
            }
#else
            DEBUGGERMSG (KDZONE_ALERT, (L"  ReadCtrl HANDLE_GET_EXCEPTION_REGISTRATION: Registration Head request not supported on this platform.\r\n"));
            AdditionalData->Length = 0;
#endif
            DEBUGGERMSG (KDZONE_CTRL, (L"--ReadCtrl HANDLE_GET_EXCEPTION_REGISTRATION\r\n"));

            break;
        case HANDLE_MODULE_REFCOUNT_REQUEST:
            DEBUGGERMSG(KDZONE_CTRL, (L"++ReadCtrl HANDLE_MODULE_REFCOUNT_REQUEST\r\n"));

            /* Sanity check... */
            if (AdditionalData->Length != sizeof(HMODULE))
            {
                DEBUGGERMSG(KDZONE_CTRL, (L"--ReadCtrl HANDLE_MODULE_REFCOUNT_REQUEST\r\n"));
                pdbgkdCmdPacket->dwReturnStatus = STATUS_INVALID_PARAMETER;
                AdditionalData->Length = 0;
                break;
            }

            pdbgkdCmdPacket->dwReturnStatus = GetModuleRefCount(*((HMODULE *) AdditionalData->Buffer), AdditionalData->Buffer, &AdditionalData->Length);
            DEBUGGERMSG(KDZONE_CTRL, (L"--ReadCtrl HANDLE_MODULE_REFCOUNT_REQUEST\r\n"));
            break;
        case HANDLE_DESC_HANDLE_DATA:
            pdbgkdCmdPacket->dwReturnStatus = KdQueryHandleFields((PDBGKD_HANDLE_DESC_DATA) AdditionalData->Buffer, AdditionalData->Length);
            break;
        case HANDLE_GET_HANDLE_DATA:
            pdbgkdCmdPacket->dwReturnStatus = KdQueryHandleList((PDBGKD_HANDLE_GET_DATA) AdditionalData->Buffer, AdditionalData->Length);
            break;
        default:
            pdbgkdCmdPacket->dwReturnStatus = STATUS_NOT_IMPLEMENTED;
            AdditionalData->Length = 0;
            break; // Unsuccessful
    }

    if (AdditionalData->Length > a->dwTransferCount) {
        AdditionalData->Length = (USHORT)a->dwTransferCount;
    }

    a->dwActualBytesRead = AdditionalData->Length;

    KdpSendKdApiCmdPacket (&MessageHeader, AdditionalData);
}

VOID
KdpWriteControlSpace (
    IN DBGKD_COMMAND *pdbgkdCmdPacket,
    IN PSTRING AdditionalData
    )

/*++

Routine Description:

    This function is called in response of a write control space command
    message.  Its function is to write implementation
    specific system data.

Arguments:

    pdbgkdCmdPacket - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

Return Value:

    None.

--*/

{
    DBGKD_WRITE_MEMORY *a = &pdbgkdCmdPacket->u.WriteMemory;
    STRING MessageHeader;
    LPSTR Params;
    HANDLE hProcessFocus;

    MessageHeader.Length = sizeof(*pdbgkdCmdPacket);
    MessageHeader.Buffer = (PCHAR)pdbgkdCmdPacket;

    pdbgkdCmdPacket->dwReturnStatus = STATUS_UNSUCCESSFUL; // By default (shorter and safer)

    //
    // None of these commands actually write anything directly to memory
    //

    a->dwActualBytesWritten = 0;

    DEBUGGERMSG(KDZONE_CTRL, (L"++KdpWriteControlSpace\r\n"));
    switch (a->qwTgtAddress)
    {
        case HANDLE_PROCESS_SWITCH_REQUEST:

            Params = AdditionalData->Buffer;
            DEBUGGERMSG(KDZONE_CTRL, (L"  KdpWriteControlSpace HANDLE_PROCESS_SWITCH_REQUEST %a\r\n", Params));
            hProcessFocus = (HANDLE) Kdstrtoul(Params, 16); // we are getting hProc as a param
            g_pFocusProcOverride = HandleToProc (hProcessFocus);
            if (g_pFocusProcOverride)
            {
                pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            }
            DEBUGGERMSG(KDZONE_CTRL, (L"  KdpWriteControlSpace g_pFocusProcOverride=0x%08X\r\n", g_pFocusProcOverride));
            break;

        case HANDLE_THREAD_SWITCH_REQUEST:

            // Unsupported in CE
            /*
            Params = AdditionalData->Buffer;
            Thread = Kdstrtoul(Params, 16);

            if (!SwitchToThread((PTHREAD)Thread)) {
                break; // Unsuccessful
            }

            pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
            */
            break;

        case HANDLE_STACKWALK_REQUEST:

⌨️ 快捷键说明

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