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

📄 exdsptch.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                    memcpy(OriginalContext, ContextRecord, sizeof(CONTEXT));
                    return Handled;

                    // The disposition is to continue execution.
                    // If the exception is not continuable, then raise the
                    // exception STATUS_NONCONTINUABLE_EXCEPTION. Otherwise
                    // return exception handled.
                case ExceptionContinueExecution :
                    DEBUGMSG(ZONE_SEH, (TEXT("Continuing execution ...\r\n")));
                    if ((ExceptionFlags & EXCEPTION_NONCONTINUABLE) != 0)
                        RAISE_EXCEPTION(STATUS_NONCONTINUABLE_EXCEPTION, ExceptionRecord);
                    KPlpvTls = pth->tlsPtr = tlsSave;
                    UpdateASID(pth, pprcSave, akySave);

                    memcpy(OriginalContext, ContextRecord, sizeof(CONTEXT));
                    return TRUE;

                    // The disposition is to continue the search.
                    // Get next frame address and continue the search.
                case ExceptionContinueSearch :
                    break;

                    // The disposition is nested exception.
                    // Set the nested context frame to the establisher frame
                    // address and set the nested exception flag in the
                    // exception flags.
                case ExceptionNestedException :
                    DEBUGMSG(ZONE_SEH, (TEXT("Nested exception: frame=%8.8lx\r\n"), 
                            DispatcherContext.EstablisherFrame));
                    ExceptionFlags |= EXCEPTION_NESTED_CALL;
                    if (DispatcherContext.EstablisherFrame > NestedFrame)
                        NestedFrame = DispatcherContext.EstablisherFrame;
                    break;

                    // All other disposition values are invalid.
                    // Raise invalid disposition exception.
                default :
                    RETAILMSG(1, (TEXT("NKDispatchException: invalid dispositon (%d)\r\n"),
                            Disposition));
                    RAISE_EXCEPTION(STATUS_INVALID_DISPOSITION, ExceptionRecord);
                }
            } else {
                if (NextPc != ControlPc)
                    PrevSp = 0; // don't terminate loop because sp didn't change.
            }
                    
        } else {
            // Set point at which control left the previous routine.
            NextPc = (ULONG) ContextRecord1.IntRa - INST_SIZE;
            PrevSp = 0; // don't terminate loop because sp didn't change.

            // If the next control PC is the same as the old control PC, then
            // the function table is not correctly formed.
            if (NextPc == ControlPc)
                break;
        }

        // Set point at which control left the previous routine.
        ControlPc = NextPc;
        if (((ControlPc == SYSCALL_RETURN)
                || (ControlPc+INST_SIZE == SYSCALL_RETURN)
                || (ControlPc == DIRECT_RETURN)
                || (ControlPc+INST_SIZE == (DWORD) MD_CBRtn)
                || (ControlPc == (DWORD) MD_CBRtn)
                || (ControlPc+INST_SIZE == DIRECT_RETURN))) {
        
            PPROCESS pProc; 
            PEXCEPTION_ROUTINE pEH; 

            if (!pcstk) {
                RETAILMSG(1, (TEXT("NKDispatchException: no CALLSTACK object to continue...\r\n")));
                KPlpvTls = pth->tlsPtr = tlsSave;
                UpdateASID(pth, pprcSave, akySave);
                return FALSE;
            }

            // Server IPC return. If the server process has registered an
            // exception handler, the call that handler before unwinding
            // in the calling process.
            pProc = pcstk->pprcLast;
            pEH = KPSLExceptionRoutine;

            if (TargetCStk == 0 && pcstk->akyLast && ((pcstk->dwPrcInfo & CST_IN_KERNEL) || (pEH = pCurProc->pfnEH) != 0)) {
                TargetCStk = pcstk;
                DEBUGMSG(ZONE_SEH, (TEXT("NKDispatchException: Invoke Handler, dwPrevSP = %8.8lx, dwPrcInfo = %8.8lx\r\n"), 
                    pcstk->dwPrevSP, pcstk->dwPrcInfo));
                FunctionEntry = &TempFunctionEntry;
                FunctionEntry->ExceptionHandler = pEH;
                FunctionEntry->BeginAddress = 0;
                FunctionEntry->EndAddress = 0;
                FunctionEntry->HandlerData = 0;
                EstablisherFrame = 0;
                goto invokeHandler;
            }

            // returning from callback  (ASSUMING ALL PSL HAS A HANDLER)
            // If the following debugchk occurs, the PSL doesn't have
            // a default handler and should provide it.
            DEBUGCHK (pcstk->dwPrcInfo & CST_CALLBACK);
            if (pcstk->dwPrevSP) {
                DEBUGMSG(ZONE_SEH, (TEXT("NKDispatchException: switch to secure stack\r\n")));
                ContextRecord1.IntSp   = EstablisherFrame = pcstk->dwPrevSP + CALLEE_SAVED_REGS;
                MDRestoreCalleeSavedRegisters (pcstk, &ContextRecord1);
                KPlpvTls = pth->tlsPtr = pth->tlsSecure;
                NKGetStackLimits(pth, &LowLimit, &HighLimit);
                PrevSp = 0;
            }

            // Update the return address and process context
            // information from the thread's call stack list.
            ContextRecord1.IntRa = (ULONG)pcstk->retAddr;
            RESTORE_EXTRA_INFO(&ContextRecord1, pcstk->extra);
            SetContextMode(&ContextRecord1, (pcstk->dwPrcInfo & CST_MODE_FROM_USER)? USER_MODE : KERNEL_MODE);
            UpdateASID(pth, pProc, pcstk->akyLast ? pcstk->akyLast : pth->aky);
            ControlPc = (ULONG) ContextRecord1.IntRa - INST_SIZE;
            DEBUGMSG(ZONE_SEH, (TEXT("NKDispatchException: callback ret=%8.8lx\r\n"),
                    ContextRecord1.IntRa));
            pcstk = pcstk->pcstkNext;
        }
    } while ((ULONG) ContextRecord1.IntSp < HighLimit && (ULONG) ContextRecord1.IntSp > PrevSp);

    // Set final exception flags and return exception not handled.
    DEBUGMSG(1, (TEXT("NKDispatchException: returning failure. Flags=%x\r\n"),
            ExceptionFlags));
    KPlpvTls = pth->tlsPtr = tlsSave;
    UpdateASID(pth, pprcSave, akySave);
    ExceptionRecord->ExceptionFlags = ExceptionFlags;

    memcpy(OriginalContext, ContextRecord, sizeof(CONTEXT));
    return FALSE;
}


#if defined(COMPRESSED_PDATA)


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PRUNTIME_FUNCTION
NKLookupFunctionEntry(
    IN PPROCESS pProc,
    IN ULONG ControlPc,
    OUT PRUNTIME_FUNCTION prf
    )
/*++
Routine Description:
    This function searches the currently active function tables for an entry
    that corresponds to the specified PC value.

Arguments:
    pProc - process context for ControlPC

    ControlPc - Supplies the address of an instruction within the specified
        function.

    prf - ptr to RUNTIME_FUNCTION structure to be filled in & returned.

Return Value:
    If there is no entry in the function table for the specified PC, then
    NULL is returned. Otherwise, the address of the function table entry
    that corresponds to the specified PC is returned.
--*/
{
    PPDATA table;
    PPDATA entry;
    PPDATA_EH peh;
    ULONG SizeOfExceptionTable;
    ULONG InstSize;
    LONG High;
    LONG Low;
    LONG Middle;

    __try {
        // Search for the image that includes the specified PC value and locate
        // its function table.
        table = PDataFromPC(ControlPc, pProc, &SizeOfExceptionTable);

        // If a function table is located, then search the function table
        // for a function table entry for the specified PC.
        if (table != NULL) {
            // Initialize search indicies.
            Low = 0;
            High = (SizeOfExceptionTable / sizeof(PDATA)) - 1;

            // Perform binary search on the function table for a function table
            // entry that subsumes the specified PC.
            while (High >= Low) {
                // Compute next probe index and test entry. If the specified PC
                // is greater than of equal to the beginning address and less
                // than the ending address of the function table entry, then
                // return the address of the function table entry. Otherwise,
                // continue the search.
                Middle = (Low + High) >> 1;
                entry = &table[Middle];
                if (ControlPc < entry->pFuncStart) {
                    High = Middle - 1;

                } else if (Middle != High && ControlPc >= (entry+1)->pFuncStart) {
                    Low = Middle + 1;

                } else {
                    // The ControlPc is between the middle entry and the middle+1 entry
                    // or this is the last entry that will be examined. Check ControlPc
                    // against the function length.
                    InstSize = entry->ThirtyTwoBits ? 4 : 2;
                    prf->BeginAddress = entry->pFuncStart;
                    prf->EndAddress = entry->pFuncStart + entry->FuncLen*InstSize;
                    prf->PrologEndAddress = entry->pFuncStart + entry->PrologLen*InstSize;
                    if (ControlPc >= prf->EndAddress)
                        break;  // Not a match, stop searching

                    // Fill in the remaining fields in the RUNTIME_FUNCTION structure.
                    if (entry->ExceptionFlag) {
                        peh = (PPDATA_EH) MapPtrProc ((entry->pFuncStart & ~(InstSize-1)), pProc) - 1;
                        prf->ExceptionHandler = peh->pHandler;
                        prf->HandlerData = peh->pHandlerData;
                    } else {
                        prf->ExceptionHandler = 0;
                        prf->HandlerData = 0;
                    }

                    return prf;
                }
            }
        }
    } __except (EXCEPTION_EXECUTE_HANDLER) {
    }

    // A function table entry for the specified PC was not found.
    return NULL;
}
#endif // COMPRESSED_PDATA

#if defined(COMBINED_PDATA)


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PRUNTIME_FUNCTION
NKLookupFunctionEntry(
    IN PPROCESS pProc,
    IN ULONG ControlPc,
    OUT PRUNTIME_FUNCTION prf
    )
/*++
Routine Description:
    This function searches the currently active function tables for an entry
    that corresponds to the specified PC value.

Arguments:
    pProc - process context for ControlPC

    ControlPc - Supplies the address of an instruction within the specified
        function.

Return Value:
    If there is no entry in the function table for the specified PC, then
    NULL is returned. Otherwise, the address of the function table entry
    that corresponds to the specified PC is returned.
--*/
{
    PCOMBINED_HEADER Header;
    PRUNTIME_FUNCTION OldEntry;
    PRUNTIME_FUNCTION OldTable;
    PPDATA NewEntry;
    PPDATA NewTable;
    PPDATA_EH NewEH;
    ULONG TotalSize;
    ULONG EndAddress;
    LONG NewHigh;
    LONG OldHigh;
    LONG Low;
    LONG Middle;
    UINT InstrShift;

    __try {
        // Search for the image that includes the specified PC value and locate
        // its function table.
        Header = PDataFromPC(ControlPc, pProc, &TotalSize);

        // If the exception table doesn't exist or the size is invalid, just return
        if (Header == NULL || TotalSize < sizeof (COMBINED_HEADER)) {
            return NULL;
        }

        // If the PDATA is all old style then the header will actually be the
        // first uncompressed entry and the zero fields will be non-zero
        if (Header->zero1 || Header->zero2) {
            OldTable = (PRUNTIME_FUNCTION)Header;
            OldHigh = (TotalSize / sizeof(RUNTIME_FUNCTION)) - 1;
            NewTable = NULL;
        } else {
            OldTable = (PRUNTIME_FUNCTION)(Header+1);
            OldHigh  = Header->Uncompressed - 1;
            NewTable = (PPDATA)(&OldTable[Header->Uncompressed]);
            NewHigh  = Header->Compressed - 1;
        }

        // Initialize search indicies.
        Low = 0;
                    
        // Perform binary search on the function table for a function table
        // entry that subsumes the specified PC.
        while (OldHigh >= Low) {

            // Compute next probe index and test entry. If the specified PC
            // is greater than of equal to the beginning address and less
            // than the ending address of the function table entry, then
            // return the address of the function table entry. Otherwise,
            // continue the search.
            Middle = (Low + OldHigh) >> 1;
            OldEntry = &OldTable[Middle];

⌨️ 快捷键说明

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