void RemoveDetour(DWORD address) { CAutoLock Lock(&gDetourCS); DebugSpew("RemoveDetour(%X)",address); OurDetours *detour = ourdetours; while (detour) { if (detour->addr==address) { if (detour->pfDetour) { DetourRemove(detour->pfTrampoline, detour->pfDetour); } if (detour->pLast) detour->pLast->pNext=detour->pNext; else ourdetours=detour->pNext; if (detour->pNext) detour->pNext->pLast=detour->pLast; delete detour; DebugSpew("Detour removed."); return; } detour=detour->pNext; } DebugSpew("Detour not found in RemoveDetour()"); }
VOID ClickMouseLoc(PCHAR szMouseLoc, PCHAR szButton) { CHAR szArg1[MAX_STRING] = {0}; CHAR szArg2[MAX_STRING] = {0}; int ClickX; //actual location to click, calculated from ButtonX int ClickY; //actual location to click, calculated from ButtonY // determine mouse location - x and y given if ((szMouseLoc[0]=='+') || (szMouseLoc[0]=='-') || ((szMouseLoc[0]>='0') && (szMouseLoc[0]<='9'))) { // x and y were given so lets convert them and move mouse GetArg(szArg1,szMouseLoc,1); GetArg(szArg2,szMouseLoc,2); ClickX = atoi(szArg1); ClickY = atoi(szArg2); if ((szArg1[0]=='+') || (szArg1[0]=='-') || (szArg2[0]=='+') || (szArg2[0]=='-')) { // relative location was passed so offset from current ClickX += EQADDR_MOUSE->X; ClickY += EQADDR_MOUSE->Y; DebugSpew("Clicking mouse by relative offset"); } else { DebugSpew("Clicking mouse at absolute position"); } MouseButtonUp(ClickX,ClickY,szButton); } else { MacroError("'%s' mouse click is either invalid or should be done using /notify",szMouseLoc); } }
BOOL AddDetour(DWORD address, PBYTE pfDetour, PBYTE pfTrampoline, DWORD Count, PCHAR Name) { CAutoLock Lock(&gDetourCS); CHAR szName[MAX_STRING] = { 0 }; if (Name && Name[0] != '\0') { strcpy_s(szName, Name); } else { strcpy_s(szName, "Unknown"); } BOOL Ret = TRUE; DebugSpew("AddDetour(%s, 0x%X,0x%X,0x%X,0x%X)", szName, address, pfDetour, pfTrampoline, Count); if (FindDetour(address)) { DebugSpew("Address for %s (0x%x) already detoured.", szName, address); return FALSE; } OurDetours *detour = new OurDetours; strcpy_s(detour->Name, szName); detour->addr = address; detour->count = Count; memcpy(detour->array, (char *)address, Count); detour->pNext = ourdetours; if (ourdetours) ourdetours->pLast = detour; detour->pLast = 0; if (pfTrampoline) { // its an indirect jump, likely due to incremental linking. The actual // function body is at the other end of the jump. We need to follow it. if (pfTrampoline[0] == 0xe9) { pfTrampoline = pfTrampoline + *(DWORD*)&pfTrampoline[1] + 5; } if (pfTrampoline[0] && pfTrampoline[1]) { DWORD oldperm = 0, tmp; VirtualProtectEx(GetCurrentProcess(), (LPVOID)pfTrampoline, 2, PAGE_EXECUTE_READWRITE, &oldperm); pfTrampoline[0] = 0x90; pfTrampoline[1] = 0x90; VirtualProtectEx(GetCurrentProcess(), (LPVOID)pfTrampoline, 2, oldperm, &tmp); } } if (pfDetour && !DetourFunctionWithEmptyTrampoline(pfTrampoline, (PBYTE)address, pfDetour)) { detour->pfDetour = 0; detour->pfTrampoline = 0; Ret = FALSE; DebugSpew("Detour of %s failed.", szName); } else { detour->pfDetour = pfDetour; detour->pfTrampoline = pfTrampoline; DebugSpew("Detour of %s was successful.", szName); } ourdetours = detour; return Ret; }
int WndNotification(CXWnd *pWnd, unsigned int Message, void *unknown) { if (pWnd == (CXWnd*)InputBox) { if (Message == XWM_HITENTER) { char szBuffer[2048]; GetCXStr((PCXSTR)InputBox->InputText, szBuffer, 2047); if (szBuffer[0]) { OutputBox->AppendSTML(szBuffer); SetCXStr(&InputBox->InputText, ""); pISInterface->ExecuteCommand(szBuffer); } ((CXWnd*)InputBox)->ClrFocus(); } else { DebugSpew("InputBox message %Xh, value: %Xh",Message,unknown); } } else if (pWnd == (CXWnd*)OutputBox) { if (Message == XWM_NEWVALUE) { SaveChatToXML((PCSIDLWND)MQChatWnd); } else { DebugSpew("OutputBox message %Xh, value: %Xh", Message, unknown); } } else if (pWnd == 0) { if (Message == XWM_CLOSE) { dShow = 1; return 1; } } else if (Message == XWM_LINK) { class CChatWindow *p = (class CChatWindow *)this; if (OutputBox != (CStmlWnd *)pWnd) { CStmlWnd *tmp; int ret; DebugSpew("MQ2ChatWnd: 0x%X, Msg: 0x%X, value: %Xh", pWnd, Message, unknown); DebugSpew("MQ2ChatWnd: pWnd 0x%x != OutputBox 0x%x\n", pWnd, OutputBox); tmp = OutputBox; OutputBox = (CStmlWnd *)pWnd; ret = p->WndNotification(pWnd, Message, unknown); OutputBox = tmp; return ret; } return p->WndNotification(pWnd, Message, unknown); } else { //DebugSpew("MQ2ChatWnd: 0x%X, Msg: 0x%X, value: %Xh",pWnd,Message,unknown); } return CSidlScreenWnd::WndNotification(pWnd,Message,unknown); };
PLUGIN_API VOID SetGameState(DWORD GameState) { DebugSpew("MQ2ChatWnd::SetGameState()"); if (GameState==GAMESTATE_CHARSELECT) { if (bNoCharSelect) { // destroy chatwnd at charselect if NoCharSelect=on DestroyChatWnd(); } else { AddMQ2KeyBind("MQ2CSCHAT",DoMQ2ChatBind); KeyCombo Combo; ParseKeyCombo("/",Combo); SetMQ2KeyBind("MQ2CSCHAT",FALSE,Combo); } } else { if (GameState!=GAMESTATE_CHARCREATE) RemoveMQ2KeyBind("MQ2CSCHAT"); if (GameState==GAMESTATE_INGAME && !MQChatWnd) { // we entered the game, set up shop DebugTry(CreateChatWindow()); } } }
BOOL RemoveCommand(PCHAR Command) { PMQCOMMAND pCommand=pCommands; while(pCommand) { int Pos=strnicmp(Command,pCommand->Command,63); if (Pos<0) { DebugSpew("RemoveCommand: Command not found '%s'",Command); return 0; } if (Pos==0) { if (pCommand->pNext) pCommand->pNext->pLast=pCommand->pLast; if (pCommand->pLast) pCommand->pLast->pNext=pCommand->pNext; else pCommands=pCommand->pNext; delete pCommand; return 1; } pCommand=pCommand->pNext; } return 0; }
// CMD_EQModKey int CMD_EQModKey(int argc, char *argv[]) { CHAR chCommand[2048] = {0}; bool KeyboardFlags[4] = {false,false,false,false}; if (argc<1) { WriteChatf("Usage: %s <command>", argv[0]); return 0; } pISInterface->GetArgs(1,argc,argv,chCommand,sizeof(chCommand)); *(DWORD*)&KeyboardFlags=*(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags; if (!stricmp(argv[0],"nomodkey")) *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=0; else if (!stricmp(argv[0],"shift")) ((PCXWNDMGR)pWndMgr)->KeyboardFlags[0]=1; else if (!stricmp(argv[0],"ctrl")) ((PCXWNDMGR)pWndMgr)->KeyboardFlags[1]=1; else if (!stricmp(argv[0],"alt")) ((PCXWNDMGR)pWndMgr)->KeyboardFlags[2]=1; DebugSpew("CMD_EQModKey Executing %s", chCommand); pISInterface->ExecuteCommand(chCommand); *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=*(DWORD*)&KeyboardFlags; return 0; }
// *************************************************************************** // Function: ParseMouseLoc // Description: Parses mouseloc for /click and /mouseto // *************************************************************************** //Function used by ParseLocationXML to extract parameter // ExtractValue - gets value between specified start and end markers // - Parameters: // szFile - pointer to string to look in // szStart - pointer to string to mark start of value // szEnd - pointer to string to mark end of value // szValue - pointer to string to contain the value found // - Return Value: // if successful, return TRUE, szValue contains the value between the start and end markers // if unsuccessful, return FALSE BOOL ExtractValue(PCHAR szFile, PCHAR szStart, PCHAR szEnd, PCHAR szValue) { // verify we have legal pointers passed to us if (!szValue) return FALSE; if (!szFile || !szStart || !szEnd) { szValue[0] = 0; return FALSE; } PCHAR sub,sub2,fence; DWORD lenStart = strlen(szStart); fence = strstr(szFile,"ScreenID"); // needed to make sure we don't start into another element sub = strstr(szFile, szStart); sub2 = strstr(szFile, szEnd); if (!sub || !sub2 || (fence && (sub > fence))) { szValue[0] = 0; return FALSE; } memcpy(szValue,sub + lenStart, (sub2-sub) - lenStart); szValue[(sub2-sub) - lenStart] = 0; DebugSpew("Value extracted for %s was %s",szStart,szValue); return TRUE; }
BOOL UnloadMQ2Plugin(const PCHAR pszFilename) { DebugSpew("UnloadMQ2Plugin"); CHAR Filename[MAX_PATH]={0}; strcpy_s(Filename,pszFilename); _strlwr_s(Filename); PCHAR Temp=strstr(Filename,".dll"); if (Temp) Temp[0]=0; // find plugin in list CAutoLock Lock(&gPluginCS); //work in progress, move on, nothing to see here need to test this, but they keep patching on me... //well after messing with this for a while, I realized I couldn't bypass it by just deleting the registry key //need to check if we can just bypass the GetprocAddress hook and call the nt version which isnt hooked by the shim engine... /*if (pLdrGetProcedureAddress = (fLdrGetProcedureAddress)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrGetProcedureAddress")) { if (HMODULE h = GetModuleHandle("Kernel32.dll")) { CHAR szFreeLib[32] = { 0 }; strcpy_s(szFreeLib, "FreeLibrary"); FAKEGPSTRING as = { 0 }; as.Buffer = szFreeLib; as.Length = 11; as.MaximumLength = 11; DWORD addr = 0; BOOL ret = pLdrGetProcedureAddress(h, &as, NULL, (PVOID)&pFreeLibrary); Sleep(0); //pFreeLibrary = (fFreeLibrary)addr; } }*/ PMQPLUGIN pPlugin=pPlugins; while(pPlugin) { if (!_stricmp(Filename,pPlugin->szFilename)) { if (pPlugin->pLast) pPlugin->pLast->pNext=pPlugin->pNext; else pPlugins=pPlugin->pNext; if (pPlugin->pNext) pPlugin->pNext->pLast=pPlugin->pLast; if (pPlugin->CleanUI) pPlugin->CleanUI(); if (pPlugin->Shutdown) pPlugin->Shutdown(); //DeleteLayers(pPlugin); if (pFreeLibrary) pFreeLibrary(pPlugin->hModule); else FreeLibrary(pPlugin->hModule); delete pPlugin; return 1; } pPlugin=pPlugin->pNext; } return 0; }
void AddDetourf(DWORD address, ...) { va_list marker; int i = 0; va_start(marker, address); DWORD Parameters[4] = { 0 }; DWORD nParameters = 0; while (i != -1) { if (nParameters<4) { Parameters[nParameters] = i; nParameters++; } else { //we can break out now... break; } i = va_arg(marker, int); } va_end(marker); if (nParameters == 4) { AddDetour(address, (PBYTE)Parameters[1], (PBYTE)Parameters[2], 20,(PCHAR)Parameters[3]); } else { DebugSpew("Illegal AddDetourf call"); } }
void AddDetourf(DWORD address, ...) { va_list marker; int i=0; va_start(marker, address); DWORD Parameters[3]; DWORD nParameters=0; while (i!=-1) { if (nParameters<3) { Parameters[nParameters]=i; nParameters++; } i = va_arg(marker,int); } va_end(marker); if (nParameters==3) { AddDetour(address,(PBYTE)Parameters[1],(PBYTE)Parameters[2],20); } else { DebugSpew("Illegal AddDetourf call"); } }
VOID WriteChatColor(PCHAR Line, DWORD Color, DWORD Filter) { if (!bPluginCS) return; if (gFilterMQ) return; PluginDebug("Begin WriteChatColor()"); EnterMQ2Benchmark(bmWriteChatColor); if(size_t len = strlen(Line)) { if(char *PlainText = (char*)LocalAlloc(LPTR,len+1)) { StripMQChat(Line,PlainText); CheckChatForEvent(PlainText); LocalFree(PlainText); } DebugSpew("WriteChatColor(%s)",Line); } CAutoLock Lock(&gPluginCS); PMQPLUGIN pPlugin=pPlugins; while(pPlugin) { if (pPlugin->WriteChatColor) { pPlugin->WriteChatColor(Line,Color,Filter); } pPlugin=pPlugin->pNext; } ExitMQ2Benchmark(bmWriteChatColor); }
void AddAlias(PCHAR ShortCommand, PCHAR LongCommand) { std::string sName = ShortCommand; std::transform(sName.begin(), sName.end(), sName.begin(), tolower); DebugSpew("AddAlias(%s,%s)",sName.c_str(),LongCommand); mAliases[sName] = LongCommand; }
int is_3dON_Detour() { if(!this) { DebugSpew("MQ2EQBugFix::Crash avoided!"); return 0; } return is_3dON_Trampoline(); }
void InitializeMQ2Pulse() { DebugSpew("Initializing Pulse"); InitializeCriticalSection(&gPulseCS); EzDetour(ProcessGameEvents, Detour_ProcessGameEvents, Trampoline_ProcessGameEvents); EzDetour(CEverQuest__EnterZone, &CEverQuestHook::EnterZone_Detour, &CEverQuestHook::EnterZone_Trampoline); EzDetour(CEverQuest__SetGameState, &CEverQuestHook::SetGameState_Detour, &CEverQuestHook::SetGameState_Trampoline); }
VOID UnloadMQ2Plugins() { CAutoLock Lock(&gPluginCS); while(pPlugins) { DebugSpew("%s->Unload()",pPlugins->szFilename); UnloadMQ2Plugin(pPlugins->szFilename); } }
void RemoveOurDetours() { CAutoLock Lock(&gDetourCS); DebugSpew("RemoveOurDetours()"); if (!ourdetours) return; while (ourdetours) { if (ourdetours->pfDetour) { DebugSpew("RemoveOurDetours() -- Removing %s (%X)", ourdetours->Name, ourdetours->addr); DetourRemove(ourdetours->pfTrampoline, ourdetours->pfDetour); } OurDetours *pNext = ourdetours->pNext; delete ourdetours; ourdetours = pNext; } }
void InitializeMQ2Pulse() { DebugSpew("Initializing Pulse"); if (!ghLockDelayCommand) ghLockDelayCommand = CreateMutex(NULL, FALSE, NULL); InitializeCriticalSection(&gPulseCS); EzDetourwName(ProcessGameEvents, Detour_ProcessGameEvents, Trampoline_ProcessGameEvents,"ProcessGameEvents"); EzDetourwName(CEverQuest__EnterZone, &CEverQuestHook::EnterZone_Detour, &CEverQuestHook::EnterZone_Trampoline,"CEverQuest__EnterZone"); EzDetourwName(CEverQuest__SetGameState, &CEverQuestHook::SetGameState_Detour, &CEverQuestHook::SetGameState_Trampoline,"CEverQuest__SetGameState"); EzDetourwName(CTargetWnd__RefreshTargetBuffs, &CEverQuestHook::CTargetWnd__RefreshTargetBuffs_Detour, &CEverQuestHook::CTargetWnd__RefreshTargetBuffs_Trampoline,"CTargetWnd__RefreshTargetBuffs"); }
double DoMul(double op1, double op2) { char szResult[32]; CalcInterface cp; cp<<op1<<"*"<<op2<<"="; cp.Execute(szResult); DebugSpew("DoAdd %f * %f = %s", op1, op2, szResult); return atof(szResult); }
VOID PluginsAddGroundItem(PGROUNDITEM pNewGroundItem) { if (!pNewGroundItem) { DebugSpew("PluginsAddGroundItem was NULL"); return; } PluginDebug("PluginsAddGroundItem()"); if (!bPluginCS) return; CAutoLock Lock(&gPluginCS); PMQPLUGIN pPlugin=pPlugins; DebugSpew("PluginsAddGroundItem(%s) %.1f,%.1f,%.1f",pNewGroundItem->Name,pNewGroundItem->X,pNewGroundItem->Y,pNewGroundItem->Z); while(pPlugin) { if (pPlugin->AddGroundItem) { pPlugin->AddGroundItem(pNewGroundItem); } pPlugin=pPlugin->pNext; } }
VOID InitializeMQ2Plugins() { DebugSpew("Initializing plugins"); bmWriteChatColor=AddMQ2Benchmark("WriteChatColor"); bmPluginsIncomingChat=AddMQ2Benchmark("PluginsIncomingChat"); bmPluginsPulse=AddMQ2Benchmark("PluginsPulse"); bmPluginsOnZoned=AddMQ2Benchmark("PluginsOnZoned"); bmPluginsCleanUI=AddMQ2Benchmark("PluginsCleanUI"); bmPluginsReloadUI=AddMQ2Benchmark("PluginsReloadUI"); bmPluginsDrawHUD=AddMQ2Benchmark("PluginsDrawHUD"); bmPluginsSetGameState=AddMQ2Benchmark("PluginsSetGameState"); bmCalculate=AddMQ2Benchmark("Calculate"); bmBeginZone=AddMQ2Benchmark("BeginZone"); bmEndZone=AddMQ2Benchmark("EndZone"); bPluginCS=1; CHAR PluginList[MAX_STRING*10] = {0}; CHAR szBuffer[MAX_STRING] = {0}; CHAR MainINI[MAX_STRING] = {0}; sprintf_s(MainINI,"%s\\macroquest.ini",gszINIPath); GetPrivateProfileString("Plugins",NULL,"",PluginList,MAX_STRING*10,MainINI); PCHAR pPluginList = PluginList; BOOL loadvalue = 0; while (pPluginList[0]!=0) { GetPrivateProfileString("Plugins",pPluginList,"",szBuffer,MAX_STRING,MainINI); if (IsNumber(szBuffer)) { loadvalue=atoi(szBuffer); szBuffer[0] = '\0'; } if(loadvalue==1 || szBuffer[0]!=0) { LoadMQ2Plugin(pPluginList); } pPluginList+=strlen(pPluginList)+1; } //ok now check if user has a CustomPlugin.ini and load those as well... sprintf_s(MainINI,"%s\\CustomPlugins.ini",gszINIPath); GetPrivateProfileString("Plugins",NULL,"",PluginList,MAX_STRING*10,MainINI); pPluginList = PluginList; while (pPluginList[0]!=0) { GetPrivateProfileString("Plugins",pPluginList,"",szBuffer,MAX_STRING,MainINI); if (IsNumber(szBuffer)) { loadvalue=atoi(szBuffer); szBuffer[0] = '\0'; } if(loadvalue==1 || szBuffer[0]!=0) { LoadMQ2Plugin(pPluginList,1); } pPluginList+=strlen(pPluginList)+1; } }
void CreateChatWindow() { DebugSpew("MQ2ChatWnd::CreateChatWindow()"); if (MQChatWnd) { return; } MQChatWnd = new CMQChatWnd(); if (!MQChatWnd) { return; } LoadChatFromXML((PCSIDLWND)MQChatWnd); // SaveChatToXML((PCSIDLWND)MQChatWnd); // A) we're masochists, B) this creates the file if its not there.. }
void AddAlias(PCHAR ShortCommand, PCHAR LongCommand) { DebugSpew("AddAlias(%s,%s)",ShortCommand,LongCommand); // perform insertion sort if (!pAliases) { PALIAS pAlias=new ALIAS; memset(pAlias,0,sizeof(ALIAS)); strcpy(pAlias->szName,ShortCommand); strcpy(pAlias->szCommand,LongCommand); pAliases=pAlias; return; } PALIAS pInsert=pAliases; PALIAS pLast=0; while(pInsert) { int Pos=stricmp(ShortCommand,pInsert->szName); if (Pos<0) { // insert here. PALIAS pAlias=new ALIAS; memset(pAlias,0,sizeof(ALIAS)); strcpy(pAlias->szName,ShortCommand); strcpy(pAlias->szCommand,LongCommand); if (pLast) pLast->pNext=pAlias; else pAliases=pAlias; pAlias->pLast=pLast; pInsert->pLast=pAlias; pAlias->pNext=pInsert; return; } if (Pos==0) { strcpy(pInsert->szName,ShortCommand); strcpy(pInsert->szCommand,LongCommand); return; } pLast=pInsert; pInsert=pInsert->pNext; } // End of list PALIAS pAlias=new ALIAS; memset(pAlias,0,sizeof(ALIAS)); strcpy(pAlias->szName,ShortCommand); strcpy(pAlias->szCommand,LongCommand); pLast->pNext=pAlias; pAlias->pLast=pLast; }
void AddSubstitute(PCHAR Original, PCHAR Substitution) { DebugSpew("AddSubstitute(%s,%s)",Original,Substitution); // perform insertion sort if (!pSubs) { PSUB pSub=new SUB; memset(pSub,0,sizeof(SUB)); strcpy(pSub->szOrig,Original); strcpy(pSub->szSub,Substitution); pSubs=pSub; return; } PSUB pInsert=pSubs; PSUB pLast=0; while(pInsert) { int Pos=stricmp(Original,pInsert->szOrig); if (Pos<0) { // insert here. PSUB pSub=new SUB; memset(pSub,0,sizeof(SUB)); strcpy(pSub->szOrig,Original); strcpy(pSub->szSub,Substitution); if (pLast) pLast->pNext=pSub; else pSubs=pSub; pSub->pLast=pLast; pInsert->pLast=pSub; pSub->pNext=pInsert; return; } if (Pos==0) { strcpy(pInsert->szOrig,Original); strcpy(pInsert->szSub,Substitution); return; } pLast=pInsert; pInsert=pInsert->pNext; } // End of list PSUB pSub=new SUB; memset(pSub,0,sizeof(SUB)); strcpy(pSub->szOrig,Original); strcpy(pSub->szSub,Substitution); pLast->pNext=pSub; pSub->pLast=pLast; }
void RemoveDetour(DWORD address) { CAutoLock Lock(&gDetourCS); OurDetours *detour = ourdetours; while (detour) { if (detour->addr == address) { if (detour->pfDetour) { DebugSpew("DetourRemove %s (%X)", detour->Name, ((DWORD)GetModuleHandle(NULL) - address + 0x400000)); DetourRemove(detour->pfTrampoline, detour->pfDetour); //sometimes its useful to add and then remove a detour and then add it again... and so on... //the following 2 lines fixes a detours "bug" //I don't know if this was MS intention //but if we don't set these to nop //we cant detour the same function more than once. -eqmule //so dont remove these. DWORD oldperm = 0,tmp; VirtualProtectEx(GetCurrentProcess(), (LPVOID)detour->pfTrampoline, 2, PAGE_EXECUTE_READWRITE, &oldperm); detour->pfTrampoline[0] = 0x90; detour->pfTrampoline[1] = 0x90; VirtualProtectEx(GetCurrentProcess(), (LPVOID)detour->pfTrampoline, 2, oldperm, &tmp); } if (detour->pLast) detour->pLast->pNext = detour->pNext; else ourdetours = detour->pNext; if (detour->pNext) detour->pNext->pLast = detour->pLast; delete detour; return; } detour = detour->pNext; } DebugSpew("Detour for %x not found in RemoveDetour()",((DWORD)GetModuleHandle(NULL) - address + 0x400000)); }
VOID ShutdownMQ2Plugins() { bPluginCS=0; { CAutoLock Lock(&gPluginCS); while(pPlugins) { DebugSpew("%s->Unload()",pPlugins->szFilename); UnloadMQ2Plugin(pPlugins->szFilename); } } Sleep(50); // fixes crash on Windows 7 (Vista too?) in RtlpWaitOnCriticalSection DeleteCriticalSection(&gPluginCS); }
void DeleteDetour(DWORD address) { CAutoLock Lock(&gDetourCS); OurDetours *detour = ourdetours; while (detour) { if (detour->addr == address) { DebugSpew("Deleted %s (%X)", detour->Name, ((DWORD)GetModuleHandle(NULL) - address + 0x400000)); if (detour->pLast) detour->pLast->pNext = detour->pNext; else ourdetours = detour->pNext; if (detour->pNext) detour->pNext->pLast = detour->pLast; delete detour; return; } detour = detour->pNext; } DebugSpew("Failed Deleting (%X)", ((DWORD)GetModuleHandle(NULL) - address + 0x400000)); }
BOOL AddDetour(DWORD address, PBYTE pfDetour, PBYTE pfTrampoline, DWORD Count) { CAutoLock Lock(&gDetourCS); BOOL Ret=TRUE; DebugSpew("AddDetour(0x%X,0x%X,0x%X,0x%X)",address,pfDetour,pfTrampoline,Count); if (FindDetour(address)) { DebugSpew("Address 0x%x already detoured.",address); return FALSE; } OurDetours *detour = new OurDetours; detour->addr=address; detour->count=Count; memcpy(detour->array,(char *)address, Count); detour->pNext=ourdetours; if (ourdetours) ourdetours->pLast=detour; detour->pLast=0; if (pfDetour && !DetourFunctionWithEmptyTrampoline(pfTrampoline, (PBYTE)address, pfDetour)) { detour->pfDetour=0; detour->pfTrampoline=0; Ret=FALSE; DebugSpew("Detour failed."); } else { detour->pfDetour=pfDetour; detour->pfTrampoline=pfTrampoline; DebugSpew("Detour success."); } ourdetours=detour; return Ret; }
VOID CreateChatWindow() { DebugSpew("MQ2ChatWnd::CreateChatWindow()"); if (MQChatWnd) { return; } class CXStr ChatWnd("ChatWindow"); MQChatWnd = new CMQChatWnd(&ChatWnd); if (!MQChatWnd) { return; } LoadChatFromINI((PCSIDLWND)MQChatWnd); SaveChatToINI((PCSIDLWND)MQChatWnd); // A) we're masochists, B) this creates the file if its not there.. }
VOID PluginsReloadUI() { PluginDebug("PluginsReloadUI()"); if (!bPluginCS) return; CAutoLock Lock(&gPluginCS); PMQPLUGIN pPlugin=pPlugins; while(pPlugin) { if (pPlugin->ReloadUI) { DebugSpew("%s->ReloadUI()",pPlugin->szFilename); pPlugin->ReloadUI(); } pPlugin=pPlugin->pNext; } }