#include "Mra.h" MRA_SETTINGS masMraSettings; int hLangpack; PLUGININFOEX pluginInfoEx={ sizeof(PLUGININFOEX), PROTOCOL_DISPLAY_NAME_ORIGA, PLUGIN_VERSION_DWORD, "Provides support for Mail.ru agent Instant Messenger protocol ("__DATE__" "__TIME__")", "Rozhuk Ivan", "Rozhuk_I@mail.ru", "� 2006-2011 Rozhuk Ivan", "http://miranda-ng.org/", UNICODE_AWARE, // {E7C48BAB-8ACE-4CB3-8446-D4B73481F497} { 0xe7c48bab, 0x8ace, 0x4cb3, { 0x84, 0x46, 0xd4, 0xb7, 0x34, 0x81, 0xf4, 0x97 } } }; int OnModulesLoaded (WPARAM wParam,LPARAM lParam); int OnPreShutdown (WPARAM wParam,LPARAM lParam); void VersionConversions (); BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID Reserved) { switch(dwReason){ case DLL_PROCESS_ATTACH: bzero(&masMraSettings,sizeof(masMraSettings)); masMraSettings.hInstance=hInstance; masMraSettings.hHeap=HeapCreate(0,0,0);//GetProcessHeap(); masMraSettings.bLoggedIn=FALSE; masMraSettings.dwStatusMode=ID_STATUS_OFFLINE; masMraSettings.dwDesiredStatusMode=ID_STATUS_OFFLINE; DisableThreadLibraryCalls((HMODULE)hInstance); break; case DLL_PROCESS_DETACH: HeapDestroy(masMraSettings.hHeap); masMraSettings.hHeap=NULL; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return(TRUE); } extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL,MIID_LAST}; extern "C" MRA_API PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { return(&pluginInfoEx); } extern "C" MRA_API int Load(void) { SIZE_T dwBuffLen; WCHAR szBuff[MAX_FILEPATH]; LPSTR lpszFullFileName=(LPSTR)szBuff; LPWSTR lpwszFileName; PROTOCOLDESCRIPTOR pd={0}; mir_getLP(&pluginInfoEx); // Get module name from DLL file name if (GetModuleFileName(masMraSettings.hInstance,szBuff,MAX_FILEPATH)) { WCHAR sztmBuff[MAX_FILEPATH]; if ((dwBuffLen=GetFullPathName(szBuff,MAX_FILEPATH,sztmBuff,&lpwszFileName))) { dwBuffLen=(lstrlenW(lpwszFileName)-4); //lpwszFileName=L"MRA.dll"; //dwBuffLen=3; masMraSettings.dwModuleNameLen=(dwBuffLen<MAXMODULELABELLENGTH)? dwBuffLen:(MAXMODULELABELLENGTH-1); memmove(masMraSettings.wszModuleName,lpwszFileName,(masMraSettings.dwModuleNameLen*sizeof(WCHAR))); CharUpperBuff(masMraSettings.wszModuleName,masMraSettings.dwModuleNameLen); masMraSettings.wszModuleName[masMraSettings.dwModuleNameLen]=0; WideCharToMultiByte(MRA_CODE_PAGE,0,masMraSettings.wszModuleName,(masMraSettings.dwModuleNameLen+1),masMraSettings.szModuleName,MAXMODULELABELLENGTH,NULL,NULL); if (DB_Mra_GetByte(NULL,"UseDisplayModuleName",TRUE)) { masMraSettings.dwDisplayModuleNameLen=mir_sntprintf(masMraSettings.wszDisplayModuleName,SIZEOF(masMraSettings.wszDisplayModuleName),L"%s: %S",PROTOCOL_NAMEW,PROTOCOL_DISPLAY_NAME_ORIGA); }else{ memmove(masMraSettings.wszDisplayModuleName,masMraSettings.wszModuleName,(masMraSettings.dwModuleNameLen*sizeof(WCHAR))); masMraSettings.dwDisplayModuleNameLen=masMraSettings.dwModuleNameLen; masMraSettings.szDisplayModuleName[masMraSettings.dwDisplayModuleNameLen]=0; } WideCharToMultiByte(MRA_CODE_PAGE,0,masMraSettings.wszDisplayModuleName,(masMraSettings.dwDisplayModuleNameLen+1),masMraSettings.szDisplayModuleName,MAX_PATH,NULL,NULL); } } // load libs if (GetModuleFileName(NULL,szBuff,MAX_FILEPATH)) {// DWORD dwErrorCode; masMraSettings.dwMirWorkDirPathLen=GetFullPathName(szBuff,MAX_FILEPATH,masMraSettings.szMirWorkDirPath,&lpwszFileName); if (masMraSettings.dwMirWorkDirPathLen) { masMraSettings.dwMirWorkDirPathLen-=lstrlenW(lpwszFileName); masMraSettings.szMirWorkDirPath[masMraSettings.dwMirWorkDirPathLen]=0; // load xstatus icons lib dwErrorCode=FindFile(masMraSettings.szMirWorkDirPath,masMraSettings.dwMirWorkDirPathLen,L"xstatus_MRA.dll",-1,szBuff,SIZEOF(szBuff),(DWORD*)&dwBuffLen); if (dwErrorCode==NO_ERROR) { masMraSettings.hDLLXStatusIcons=LoadLibraryEx(szBuff,NULL,/*LOAD_LIBRARY_AS_DATAFILE*/0); if (masMraSettings.hDLLXStatusIcons) { if ((dwBuffLen=LoadStringW(masMraSettings.hDLLXStatusIcons,IDS_IDENTIFY,szBuff,MAX_FILEPATH))==0 || CompareStringW(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,L"# Custom Status Icons #",23,szBuff,dwBuffLen)!=CSTR_EQUAL) { FreeLibrary(masMraSettings.hDLLXStatusIcons); masMraSettings.hDLLXStatusIcons=NULL; } } } // load zlib dwErrorCode=FindFile(masMraSettings.szMirWorkDirPath,masMraSettings.dwMirWorkDirPathLen,L"zlib.dll",-1,szBuff,SIZEOF(szBuff),(DWORD*)&dwBuffLen); if (dwErrorCode!=NO_ERROR) dwErrorCode=FindFile(masMraSettings.szMirWorkDirPath,masMraSettings.dwMirWorkDirPathLen,L"zlib1.dll",-1,szBuff,SIZEOF(szBuff),(DWORD*)&dwBuffLen); if (dwErrorCode==NO_ERROR) {// load xstatus icons lib masMraSettings.hDLLZLib=LoadLibraryEx(szBuff,NULL,0); if (masMraSettings.hDLLZLib) { masMraSettings.lpfnCompress2=(HANDLE)GetProcAddress(masMraSettings.hDLLZLib,"compress2"); masMraSettings.lpfnUncompress=(HANDLE)GetProcAddress(masMraSettings.hDLLZLib,"uncompress"); } } } } InitializeCriticalSectionAndSpinCount(&masMraSettings.csCriticalSectionSend,0); MraSendQueueInitialize(0,&masMraSettings.hSendQueueHandle); MraFilesQueueInitialize(0,&masMraSettings.hFilesQueueHandle); MraMPopSessionQueueInitialize(&masMraSettings.hMPopSessionQueue); FifoMTInitialize(&masMraSettings.ffmtAPCQueue,0); masMraSettings.hWaitEventThreadAPCHandle=CreateEvent(NULL,FALSE,FALSE,NULL); InterlockedExchange((volatile LONG*)&masMraSettings.dwAPCThreadRunning,TRUE); masMraSettings.hThreadAPC=(HANDLE)mir_forkthread((pThreadFunc)MraUserAPCThreadProc,NULL); if (masMraSettings.hThreadAPC==NULL) { MraAPCQueueDestroy(&masMraSettings.ffmtAPCQueue); CloseHandle(masMraSettings.hWaitEventThreadAPCHandle); masMraSettings.hWaitEventThreadAPCHandle=NULL; DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&masMraSettings.hThreadAPC,THREAD_SET_CONTEXT,FALSE,0); DebugPrintCRLFW(L"Fail on create event APC thread, using miranda main thread"); MessageBoxW(NULL,L"Fail on create event APC thread, using miranda main thread",PROTOCOL_DISPLAY_NAMEW,(MB_OK|MB_ICONINFORMATION)); }//*/ masMraSettings.hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,OnModulesLoaded); masMraSettings.hHookPreShutdown=HookEvent(ME_SYSTEM_PRESHUTDOWN,OnPreShutdown); LoadServices(); //pd.cbSize=sizeof(pd); pd.cbSize=PROTOCOLDESCRIPTOR_V3_SIZE; pd.szName=PROTOCOL_NAMEA; pd.type=PROTOTYPE_PROTOCOL; CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); DebugPrintCRLFW(L"Load - DONE"); return(0); } extern "C" MRA_API int Unload(void) { UnloadServices(); //if (hHookOnUserInfoInit) UnhookEvent(hHookOnUserInfoInit); if (masMraSettings.hHookPreShutdown) {UnhookEvent(masMraSettings.hHookPreShutdown); masMraSettings.hHookPreShutdown=NULL;} if (masMraSettings.hHookModulesLoaded) {UnhookEvent(masMraSettings.hHookModulesLoaded); masMraSettings.hHookModulesLoaded=NULL;} Netlib_CloseHandle(masMraSettings.hNetlibUser); masMraSettings.hNetlibUser=NULL; MraMPopSessionQueueDestroy(masMraSettings.hMPopSessionQueue); masMraSettings.hMPopSessionQueue=NULL; MraFilesQueueDestroy(masMraSettings.hFilesQueueHandle); masMraSettings.hFilesQueueHandle=NULL; MraSendQueueDestroy(masMraSettings.hSendQueueHandle); masMraSettings.hSendQueueHandle=NULL; DeleteCriticalSection(&masMraSettings.csCriticalSectionSend); SecureZeroMemory(&masMraSettings.csCriticalSectionSend,sizeof(CRITICAL_SECTION)); if (masMraSettings.hDLLXStatusIcons) { FreeLibrary(masMraSettings.hDLLXStatusIcons); masMraSettings.hDLLXStatusIcons=NULL; } if (masMraSettings.hDLLZLib) { FreeLibrary(masMraSettings.hDLLZLib); masMraSettings.hDLLZLib=NULL; masMraSettings.lpfnCompress2=NULL; masMraSettings.lpfnUncompress=NULL; } DebugPrintCRLFW(L"Unload - DONE"); return(0); } static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) { WCHAR szBuffer[MAX_PATH]; NETLIBUSER nlu={0}; mir_sntprintf(szBuffer,SIZEOF(szBuffer),L"%s %s",PROTOCOL_NAMEW,TranslateW(L"plugin connections")); nlu.cbSize=sizeof(nlu); nlu.flags=(NUF_INCOMING|NUF_OUTGOING|NUF_HTTPCONNS|NUF_UNICODE); nlu.szSettingsModule=PROTOCOL_NAMEA; nlu.ptszDescriptiveName=szBuffer; masMraSettings.hNetlibUser=(HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu); #ifdef _DEBUG // ���� � offline // �� unsaved values ����������� �� ����� ���������������� for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) {// ������� ���� ��������� �������������� �������� � MRA SetContactBasicInfoW(hContact,SCBIFSI_LOCK_CHANGES_EVENTS,(SCBIF_ID|SCBIF_GROUP_ID|SCBIF_SERVER_FLAG|SCBIF_STATUS),-1,-1,0,0,ID_STATUS_OFFLINE,NULL,0,NULL,0,NULL,0); } #else // unsaved values DB_Mra_CreateResidentSetting("Status");// NOTE: XStatus cannot be temporary DB_Mra_CreateResidentSetting("LogonTS"); DB_Mra_CreateResidentSetting("ContactID"); DB_Mra_CreateResidentSetting("GroupID"); DB_Mra_CreateResidentSetting("ContactFlags"); DB_Mra_CreateResidentSetting("ContactSeverFlags"); DB_Mra_CreateResidentSetting("HooksLocked"); DB_Mra_CreateResidentSetting(DBSETTING_CAPABILITIES); DB_Mra_CreateResidentSetting(DBSETTING_XSTATUSNAME); DB_Mra_CreateResidentSetting(DBSETTING_XSTATUSMSG); DB_Mra_CreateResidentSetting(DBSETTING_BLOGSTATUSTIME); DB_Mra_CreateResidentSetting(DBSETTING_BLOGSTATUSID); DB_Mra_CreateResidentSetting(DBSETTING_BLOGSTATUS); DB_Mra_CreateResidentSetting(DBSETTING_BLOGSTATUSMUSIC); // ���� � offline // �� unsaved values ����������� �� ����� ���������������� for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) {// ������� ���� ��������� �������������� �������� � MRA SetContactBasicInfoW(hContact,SCBIFSI_LOCK_CHANGES_EVENTS,(SCBIF_ID|SCBIF_GROUP_ID|SCBIF_SERVER_FLAG|SCBIF_STATUS),-1,-1,0,0,ID_STATUS_OFFLINE,NULL,0,NULL,0,NULL,0); } #endif MraAvatarsQueueInitialize(&masMraSettings.hAvatarsQueueHandle); VersionConversions(); MraAntiSpamLoadBadWordsW(); LoadModules(); InterlockedExchange((volatile LONG*)&masMraSettings.dwGlobalPluginRunning,TRUE); DebugPrintCRLFW(L"OnModulesLoaded - DONE"); return(0); } int OnPreShutdown(WPARAM wParam,LPARAM lParam) { InterlockedExchange((volatile LONG*)&masMraSettings.dwGlobalPluginRunning,FALSE); MraSetStatus(ID_STATUS_OFFLINE,0); MraAvatarsQueueDestroy(masMraSettings.hAvatarsQueueHandle); masMraSettings.hAvatarsQueueHandle=NULL; if (masMraSettings.hThreadWorker) { if (IsThreadAlive(masMraSettings.hThreadWorker)) WaitForSingleObjectEx(masMraSettings.hThreadWorker,(WAIT_FOR_THREAD_TIMEOUT*1000),FALSE); masMraSettings.hThreadWorker=NULL; } InterlockedExchange((volatile LONG*)&masMraSettings.dwAPCThreadRunning,FALSE); if (masMraSettings.hWaitEventThreadAPCHandle) if (IsThreadAlive(masMraSettings.hThreadAPC)) { SetEvent(masMraSettings.hWaitEventThreadAPCHandle); }else{ CloseHandle(masMraSettings.hWaitEventThreadAPCHandle); //WaitForSingleObjectEx(masMraSettings.hThreadAPC,(WAIT_FOR_THREAD_TIMEOUT*1000),FALSE); // no wait - dead lock. masMraSettings.hWaitEventThreadAPCHandle=NULL; masMraSettings.hThreadAPC=NULL; } UnloadModules(); MraAntiSpamFreeBadWords(); DebugPrintCRLFW(L"OnPreShutdown - DONE"); return(0); } void VersionConversions() { /*switch(DB_Mra_GetDword(NULL,"LastPluginVersion",PLUGIN_MAKE_VERSION(0,0,0,0))) { default: case PLUGIN_MAKE_VERSION(1,14,0,0): case PLUGIN_MAKE_VERSION(1,14,0,1): case PLUGIN_MAKE_VERSION(1,14,0,2): DB_Mra_DeleteValue(NULL,"MirVer"); DB_Mra_DeleteValue(NULL,"MessagesCountSend"); DB_Mra_DeleteValue(NULL,"MRAClient"); DB_Mra_DeleteValue(NULL,"MRAClientVer"); DB_Mra_DeleteValue(NULL,"MRAClientCapabilities"); DB_Mra_DeleteValue(NULL,"Status"); DB_Mra_DeleteValue(NULL,"ContactID"); DB_Mra_DeleteValue(NULL,"GroupID"); DB_Mra_DeleteValue(NULL,"ContactSeverFlags"); DB_Mra_DeleteValue(NULL,"HooksLocked"); for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) { DB_Mra_DeleteValue(hContact,"MessagesCountSend"); DB_Mra_DeleteValue(hContact,"MRAClient"); DB_Mra_DeleteValue(hContact,"MRAClientVer"); DB_Mra_DeleteValue(hContact,"MRAClientCapabilities"); DB_Mra_DeleteValue(hContact,"Status"); DB_Mra_DeleteValue(hContact,"ContactID"); DB_Mra_DeleteValue(hContact,"GroupID"); DB_Mra_DeleteValue(hContact,"ContactSeverFlags"); DB_Mra_DeleteValue(hContact,"HooksLocked"); } case PLUGIN_MAKE_VERSION(1,14,0,3): case PLUGIN_MAKE_VERSION(1,14,0,4): case PLUGIN_MAKE_VERSION(1,14,0,5): case PLUGIN_MAKE_VERSION(1,14,0,6): case PLUGIN_MAKE_VERSION(1,14,0,7): //case PLUGIN_MAKE_VERSION(1,14,1,0): DB_Mra_SetByte(NULL,DBSETTING_XSTATUSID,(BYTE)DB_Mra_GetDword(NULL,DBSETTING_XSTATUSID,MRA_MIR_XSTATUS_NONE)); for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) { if (IsContactMra(hContact)) DB_Mra_SetByte(hContact,DBSETTING_XSTATUSID,(BYTE)DB_Mra_GetDword(hContact,DBSETTING_XSTATUSID,MRA_MIR_XSTATUS_NONE)); } case PLUGIN_MAKE_VERSION(1,16,0,2): DB_Mra_DeleteValue(NULL,"CvtSmilesToTags"); case PLUGIN_MAKE_VERSION(1,16,0,3): for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) { if (IsContactMra(hContact)==FALSE) DB_Mra_DeleteValue(hContact,DBSETTING_XSTATUSID); } case PLUGIN_MAKE_VERSION(0,0,0,0):// no previos version MraAntiSpamResetBadWordsList(); case PLUGIN_VERSION_DWORD:// current version break; }*/ DB_Mra_SetDword(NULL,"LastPluginVersion",PLUGIN_VERSION_DWORD); {// pass conv char szPass[MAX_PATH]; SIZE_T dwPassSize; if(DB_Mra_GetStaticStringA(NULL,"Password",(LPSTR)szPass,SIZEOF(szPass),&dwPassSize)) {//bit of a security hole here, since it's easy to extract a password from an edit box CallService(MS_DB_CRYPT_DECODESTRING,(dwPassSize+1),(LPARAM)szPass); SetPassDB(szPass,dwPassSize); SecureZeroMemory(szPass,sizeof(szPass)); DB_Mra_DeleteValue(NULL,"Password"); } } }