/********************************************************************* * __CxxRegisterExceptionObject (MSVCRT.@) */ BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_RECORD **rec, cxx_frame_info *frame_info) { thread_data_t *data = msvcrt_get_thread_data(); TRACE("(%p, %p)\n", rec, frame_info); if (!rec || !*rec) { frame_info->rec = (void*)-1; frame_info->unk = (void*)-1; return TRUE; } frame_info->rec = data->exc_record; frame_info->unk = 0; data->exc_record = *rec; _CreateFrameInfo(&frame_info->frame_info, (void*)(*rec)->ExceptionInformation[1]); return TRUE; }
void *CallCatchBlock( EHExceptionRecord *pExcept, EHRegistrationNode *pRN, // Dynamic info of function with catch void *pContext, // ignored DispatcherContext *pDC, // Context within subject frame FuncInfo *pFuncInfo, // Static info of function with catch void *handlerAddress, // Code address of handler int CatchDepth, // How deeply nested in catch blocks are we? unsigned int *pSp ) { FRAMEINFO frameinfo; PFRAMEINFO pframeinfo; EHExceptionRecord *pExceptTmp; unsigned char *pRetAddr; _CreateFrameInfo(&frameinfo, pDC, pContext); frameinfo.pExitContext = (void *)GetSP(); if (pDC->pftinfo == _pftinfo) { // okay we are throw and catch in the same code fragment _pftinfo->pFrameInfo = _pFrameInfoChain; } else { // we are not throw and catch in the same code fragment // we need to chain the _pFrameInfoChain after the pDC->pftinof->pFrameInfo // we should have got all the Frames saved so far, no matter how many code fragments we have been through if (pDC->pftinfo->pFrameInfo != NULL) { // not chain if the case where CRT Is a DLL for everyone if ( pDC->pftinfo->pFrameInfo != _pFrameInfoChain->pNext) { _pFrameInfoChain->pNext = (PFRAMEINFO)(pDC->pftinfo->pFrameInfo); } } } //call the handler pRetAddr = (unsigned char *)_CallSettingFrame(handlerAddress, pRN); *pSp = (unsigned int)GetR4(); //destructing the object if (pExcept && (*(unsigned int *)pExcept != 0xffffffff)) { DestructExceptionObject(pExcept, TRUE, pContext); } if (_pFrameInfoChain) { // don't forget to clear out the frame info the handler we are about // to remove since most if not all off them are stack elements _ASSERTE(_pFrameInfoChain->pftinfo != NULL); _ASSERTE(_pFrameInfoChain->pftinfo->pFrameInfo != NULL); pframeinfo = (PFRAMEINFO)_pFrameInfoChain->pftinfo->pFrameInfo; if (pframeinfo) _pFrameInfoChain->pftinfo->pFrameInfo = pframeinfo->pNext; _pFrameInfoChain = _pFrameInfoChain->pNext; //remove current handler from the chain cNested--; _pftinfo->pFrameInfo = _pFrameInfoChain; } pframeinfo = _pFrameInfoChain; pExceptTmp = pExcept; while (pframeinfo && (pframeinfo->pSp <= (PPMSTACK)pRN)) { // we should destruct any exception objects before this handler's frame if ((EHExceptionRecord *)(pframeinfo->pExcept) != pExceptTmp) { // this is not a re-throw, do destroy DestructExceptionObject((EHExceptionRecord *)pframeinfo->pExcept, TRUE, (void *)pframeinfo->dwRTOC); pExceptTmp = (EHExceptionRecord *)(pframeinfo->pExcept); *(unsigned int *)(pframeinfo->pExcept) = 0xffffffff; pframeinfo->pExcept = NULL; //??? } pframeinfo = pframeinfo->pNext; _pFrameInfoChain = pframeinfo; //remove handler frame from the list cNested--; _pftinfo->pFrameInfo = _pFrameInfoChain; } return (void *)pRetAddr; }