bool Plugin::Load() { if (WorkFlags.Check(PIWF_DONTLOADAGAIN)) return false; if (!WorkFlags.Check(PIWF_DATALOADED)&&!LoadData()) return false; if (WorkFlags.Check(PIWF_LOADED)) return true; WorkFlags.Set(PIWF_LOADED); bool Inited = false; if (CheckMinFarVersion()) { PluginStartupInfo info; FarStandardFunctions fsf; CreatePluginStartupInfo(this, &info, &fsf); Inited = SetStartupInfo(&info); } if (!Inited) { if (!bPendingRemove) { Unload(); } //чтоб не пытаться загрузить опять а то ошибка будет постоянно показываться. WorkFlags.Set(PIWF_DONTLOADAGAIN); return false; } SaveToCache(); return true; }
static DWORD WINAPI _xfilter(LPVOID dummy=nullptr) { ProcessException=TRUE; DWORD Result = EXCEPTION_EXECUTE_HANDLER; BOOL Res=FALSE; // if(From == EXCEPT_KERNEL) // CriticalInternalError=TRUE; if (!Is_STACK_OVERFLOW && Opt.ExceptUsed) { if (!Opt.strExceptEventSvc.IsEmpty()) { HMODULE m = LoadLibrary(Opt.strExceptEventSvc); if (m) { typedef BOOL (WINAPI *ExceptionProc_t)(EXCEPTION_POINTERS *xp, const PLUGINRECORD *Module, const PluginStartupInfo *LocalStartupInfo, LPDWORD Result); ExceptionProc_t p = (ExceptionProc_t)GetProcAddress(m,"ExceptionProc"); if (p) { static PluginStartupInfo LocalStartupInfo; ClearStruct(LocalStartupInfo); static FarStandardFunctions LocalStandardFunctions; ClearStruct(LocalStandardFunctions); CreatePluginStartupInfo(nullptr, &LocalStartupInfo, &LocalStandardFunctions); LocalStartupInfo.ModuleName = Opt.strExceptEventSvc; static PLUGINRECORD PlugRec; if (Module) { ClearStruct(PlugRec); PlugRec.TypeRec=RTYPE_PLUGIN; PlugRec.SizeRec=sizeof(PLUGINRECORD); PlugRec.ModuleName=Module->GetModuleName(); PlugRec.WorkFlags=Module->GetWorkFlags(); PlugRec.CallFlags=Module->GetFuncFlags(); PlugRec.FuncFlags=0; PlugRec.FuncFlags|=Module->HasGetGlobalInfo()?PICFF_GETGLOBALINFO:0; PlugRec.FuncFlags|=Module->HasSetStartupInfo()?PICFF_SETSTARTUPINFO:0; PlugRec.FuncFlags|=Module->HasOpenPanel()?PICFF_OPENPANEL:0; PlugRec.FuncFlags|=Module->HasAnalyse()?PICFF_ANALYSE:0; PlugRec.FuncFlags|=Module->HasClosePanel()?PICFF_CLOSEPANEL:0; PlugRec.FuncFlags|=Module->HasGetPluginInfo()?PICFF_GETPLUGININFO:0; PlugRec.FuncFlags|=Module->HasGetOpenPanelInfo()?PICFF_GETOPENPANELINFO:0; PlugRec.FuncFlags|=Module->HasGetFindData()?PICFF_GETFINDDATA:0; PlugRec.FuncFlags|=Module->HasFreeFindData()?PICFF_FREEFINDDATA:0; PlugRec.FuncFlags|=Module->HasGetVirtualFindData()?PICFF_GETVIRTUALFINDDATA:0; PlugRec.FuncFlags|=Module->HasFreeVirtualFindData()?PICFF_FREEVIRTUALFINDDATA:0; PlugRec.FuncFlags|=Module->HasSetDirectory()?PICFF_SETDIRECTORY:0; PlugRec.FuncFlags|=Module->HasGetFiles()?PICFF_GETFILES:0; PlugRec.FuncFlags|=Module->HasPutFiles()?PICFF_PUTFILES:0; PlugRec.FuncFlags|=Module->HasDeleteFiles()?PICFF_DELETEFILES:0; PlugRec.FuncFlags|=Module->HasMakeDirectory()?PICFF_MAKEDIRECTORY:0; PlugRec.FuncFlags|=Module->HasProcessHostFile()?PICFF_PROCESSHOSTFILE:0; PlugRec.FuncFlags|=Module->HasSetFindList()?PICFF_SETFINDLIST:0; PlugRec.FuncFlags|=Module->HasConfigure()?PICFF_CONFIGURE:0; PlugRec.FuncFlags|=Module->HasExitFAR()?PICFF_EXITFAR:0; PlugRec.FuncFlags|=Module->HasProcessPanelInput()?PICFF_PROCESSPANELINPUT:0; PlugRec.FuncFlags|=Module->HasProcessPanelEvent()?PICFF_PROCESSPANELEVENT:0; PlugRec.FuncFlags|=Module->HasProcessEditorEvent()?PICFF_PROCESSEDITOREVENT:0; PlugRec.FuncFlags|=Module->HasCompare()?PICFF_COMPARE:0; PlugRec.FuncFlags|=Module->HasProcessEditorInput()?PICFF_PROCESSEDITORINPUT:0; PlugRec.FuncFlags|=Module->HasMinFarVersion()?PICFF_MINFARVERSION:0; PlugRec.FuncFlags|=Module->HasProcessViewerEvent()?PICFF_PROCESSVIEWEREVENT:0; PlugRec.FuncFlags|=Module->HasProcessDialogEvent()?PICFF_PROCESSDIALOGEVENT:0; PlugRec.FuncFlags|=Module->HasProcessSynchroEvent()?PICFF_PROCESSSYNCHROEVENT:0; #if defined(MANTIS_0000466) PlugRec.FuncFlags|=Module->HasProcessMacro()?PICFF_PROCESSMACRO:0; #endif #if defined(MANTIS_0001687) PlugRec.FuncFlags|=Module->HasProcessConsoleInput()?PICFF_PROCESSCONSOLEINPUT:0; #endif } Res=p(xp,(Module?&PlugRec:nullptr),&LocalStartupInfo,&Result); } FreeLibrary(m); } } } if (Res) { if (From == EXCEPT_KERNEL) { CriticalInternalError=TRUE; } return Result; } struct __ECODE { NTSTATUS Code; // код исключения LNGID IdMsg; // ID сообщения из LNG-файла DWORD RetCode; // Что вернем? } ECode[]= { {EXCEPTION_ACCESS_VIOLATION, MExcRAccess, EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_ARRAY_BOUNDS_EXCEEDED, MExcOutOfBounds, EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_INT_DIVIDE_BY_ZERO,MExcDivideByZero, EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_STACK_OVERFLOW,MExcStackOverflow, EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_BREAKPOINT,MExcBreakPoint, EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_FLT_DIVIDE_BY_ZERO,MExcFloatDivideByZero,EXCEPTION_EXECUTE_HANDLER}, // BUGBUG: Floating-point exceptions (VC) are disabled by default. See http://msdn2.microsoft.com/en-us/library/aa289157(vs.71).aspx#floapoint_topic8 {EXCEPTION_FLT_OVERFLOW,MExcFloatOverflow,EXCEPTION_EXECUTE_HANDLER}, // BUGBUG: ^^^ {EXCEPTION_FLT_STACK_CHECK,MExcFloatStackOverflow,EXCEPTION_EXECUTE_HANDLER}, // BUGBUG: ^^^ {EXCEPTION_FLT_UNDERFLOW,MExcFloatUnderflow,EXCEPTION_EXECUTE_HANDLER}, // BUGBUG: ^^^ {EXCEPTION_ILLEGAL_INSTRUCTION,MExcBadInstruction,EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_PRIV_INSTRUCTION,MExcBadInstruction,EXCEPTION_EXECUTE_HANDLER}, {EXCEPTION_DATATYPE_MISALIGNMENT, MExcDatatypeMisalignment, EXCEPTION_EXECUTE_HANDLER}, // сюды добавляем. }; // EXCEPTION_CONTINUE_EXECUTION ?????? DWORD rc; string strBuf1, strBuf2, strBuf3; LangString strBuf; string strFileName; BOOL ShowMessages=FALSE; // получим запись исключения EXCEPTION_RECORD *xr = xp->ExceptionRecord; // выведим дамп перед выдачей сообщений WriteEvent(FLOG_ALL,xp,Module,nullptr,0); // CONTEXT можно использовать для отображения или записи в лог // содержимого регистров... // CONTEXT *xc = xp->ContextRecord; rc = Result;// EXCEPTION_EXECUTE_HANDLER; /*$ 23.01.2001 skv Неизвестное исключение не стоит игнорировать. */ if (From == EXCEPT_KERNEL || !Module) strFileName=g_strFarModuleName; else strFileName = Module->GetModuleName(); LPCWSTR Exception=nullptr; // просмотрим "знакомые" FAR`у исключения и обработаем... for (size_t I=0; I < ARRAYSIZE(ECode); ++I) { if (ECode[I].Code == static_cast<NTSTATUS>(xr->ExceptionCode)) { Exception=MSG(ECode[I].IdMsg); rc=ECode[I].RetCode; if (xr->ExceptionCode == static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION)) { int Offset = 0; // вот только не надо здесь неочевидных оптимизаций вида // if ( xr->ExceptionInformation[0] == 8 ) Offset = 2 else Offset = xr->ExceptionInformation[0], // а то M$ порадует нас как-нибудь xr->ExceptionInformation[0] == 4 и все будет в полной жопе. switch (xr->ExceptionInformation[0]) { case 0: Offset = 0; break; case 1: Offset = 1; break; case 8: Offset = 2; break; } strBuf2.Format(L"0x%p", xr->ExceptionInformation[1]+10); strBuf = MExcRAccess+Offset; strBuf << strBuf2; Exception=strBuf; } break; } } if (!Exception) { strBuf2.Format(L"%s (0x%X)", MSG(MExcUnknown), xr->ExceptionCode); Exception = strBuf2; } int MsgCode=0; if (FrameManager && !FrameManager->ManagerIsDown()) { MsgCode=ExcDialog(strFileName,Exception,xr->ExceptionAddress); ShowMessages=TRUE; } if (ShowMessages && (Is_STACK_OVERFLOW || From == EXCEPT_KERNEL)) { CriticalInternalError=TRUE; } if(MsgCode==1) { SetErrorMode(ErrorMode&~SEM_NOGPFAULTERRORBOX); rc=EXCEPTION_CONTINUE_SEARCH; UseExternalHandler=true; } else { rc = EXCEPTION_EXECUTE_HANDLER; } //return UnhandledExceptionFilter(xp); return rc; }