/* * YAMN plugin main file * Miranda homepage: http://miranda-icq.sourceforge.net/ * YAMN homepage: http://www.majvan.host.sk/Projekty/YAMN * * initializes all variables for further work * * (c) majvan 2002-2004 */ #include "main.h" #include "yamn.h" #include "resources/resource.h" #include //- imported --------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- //CRITICAL_SECTION MWCS; //CRITICAL_SECTION ASCS; //CRITICAL_SECTION PRCS; extern LPCRITICAL_SECTION PluginRegCS; extern HANDLE ExitEV; extern HANDLE WriteToFileEV; extern int PosX,PosY,SizeX,SizeY; extern int HeadPosX,HeadPosY,HeadSizeX,HeadSizeY,HeadSplitPos; //From account.cpp extern LPCRITICAL_SECTION AccountStatusCS; extern LPCRITICAL_SECTION FileWritingCS; //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- WCHAR *ProfileName = NULL; //e.g. "majvan" WCHAR *UserDirectory = NULL; //e.g. "F:\WINNT\Profiles\UserXYZ" char *ProtoName = YAMN_DBMODULE; //char *AltProtoName; char *szMirandaDir = NULL; char *szProfileDir = NULL; INT_PTR YAMN_STATUS; BOOL UninstallPlugins; HANDLE hAccountFolder; HINSTANCE *hDllPlugins; static int iDllPlugins=0; PLUGINLINK *pluginLink; YAMN_VARIABLES YAMNVar; int hLangpack; struct MM_INTERFACE mmi; static const MUUID interfaces[] = {MUUID_YAMN_FORCECHECK, MIID_LAST}; PLUGININFOEX pluginInfo={ sizeof(PLUGININFOEX), YAMN_SHORTNAME, YAMN_VERSION, "Mail notifier and browser for Miranda IM. Included POP3 protocol. Mod for Mataes Pack.", "y_b tweety (majvan)", "francois.mean@skynet.be", "© (2002-2004 majvan) 2005-2007 tweety y_b Miranda community", "http://www.miranda-im.org/download/details.php?action=viewfile&id=3411", //"http://www.majvan.host.sk/Projekty/YAMN?fm=soft", UNICODE_AWARE, 0, //doesn't replace anything built-in { 0xb047a7e5, 0x27a, 0x4cfc, { 0x8b, 0x18, 0xed, 0xa8, 0x34, 0x5d, 0x27, 0x90 } } // {B047A7E5-027A-4cfc-8B18-EDA8345D2790} }; SKINSOUNDDESC NewMailSound={ sizeof(SKINSOUNDDESC), YAMN_NEWMAILSOUND, //name to refer to sound when playing and in db YAMN_NEWMAILSNDDESC, //description for options dialog "", //default sound file to use, without path }; SKINSOUNDDESC ConnectFailureSound={ sizeof(SKINSOUNDDESC), YAMN_CONNECTFAILSOUND, //name to refer to sound when playing and in db YAMN_CONNECTFAILSNDDESC,//description for options dialog "", //default sound file to use, without path }; HANDLE hNewMailHook; //HANDLE hUninstallPluginsHook; HANDLE NoWriterEV; HANDLE hTTButton; //TopToolBar button DWORD HotKeyThreadID; UINT SecTimer; BOOL bIcolibEmbededInCore = FALSE; HICON hYamnIcons[ICONSNUMBER]; char *iconDescs[ICONSNUMBER]={ICONSDESCS}; char *iconNames[ICONSNUMBER]={ICONSNAMES}; int iconIndexes[ICONSNUMBER]={ICONSINDS}; HANDLE hMenuItemMain = 0; HANDLE hMenuItemCont = 0; HANDLE hMenuItemContApp = 0; BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD) = 0; HMODULE hUxTheme = 0; // function pointers, use typedefs for casting to shut up the compiler when using GetProcAddress() typedef BOOL (WINAPI *PITA)(); typedef HANDLE (WINAPI *POTD)(HWND, LPCWSTR); typedef UINT (WINAPI *PDTB)(HANDLE, HDC, int, int, RECT *, RECT *); typedef UINT (WINAPI *PCTD)(HANDLE); typedef UINT (WINAPI *PDTT)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, RECT *); PITA pfnIsThemeActive = 0; POTD pfnOpenThemeData = 0; PDTB pfnDrawThemeBackground = 0; PCTD pfnCloseThemeData = 0; PDTT pfnDrawThemeText = 0; #define FIXED_TAB_SIZE 100 // default value for fixed width tabs /* * visual styles support (XP+) * returns 0 on failure */ int InitVSApi() { if((hUxTheme = LoadLibraryA("uxtheme.dll")) == 0) return 0; pfnIsThemeActive = (PITA)GetProcAddress(hUxTheme, "IsThemeActive"); pfnOpenThemeData = (POTD)GetProcAddress(hUxTheme, "OpenThemeData"); pfnDrawThemeBackground = (PDTB)GetProcAddress(hUxTheme, "DrawThemeBackground"); pfnCloseThemeData = (PCTD)GetProcAddress(hUxTheme, "CloseThemeData"); pfnDrawThemeText = (PDTT)GetProcAddress(hUxTheme, "DrawThemeText"); MyEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture"); if(pfnIsThemeActive != 0 && pfnOpenThemeData != 0 && pfnDrawThemeBackground != 0 && pfnCloseThemeData != 0 && pfnDrawThemeText != 0) { return 1; } return 0; } /* * unload uxtheme.dll */ int FreeVSApi() { if(hUxTheme != 0) FreeLibrary(hUxTheme); return 0; } //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- static void GetProfileDirectory(char *szPath,int cbPath) //This is copied from Miranda's sources. In 0.2.1.0 it is needed, in newer vesions of Miranda use MS_DB_GETPROFILEPATH service { szProfileDir=new char[MAX_PATH]; if (ServiceExists(MS_DB_GETPROFILEPATH)){ if (!CallService(MS_DB_GETPROFILEPATH,(WPARAM)cbPath,(LPARAM)szPath)) { lstrcpy(szProfileDir,szPath); return; //success } } char szMirandaIni[MAX_PATH],szExpandedProfileDir[MAX_PATH]; DWORD dwAttributes; lstrcpy(szMirandaIni,szMirandaDir); lstrcat(szMirandaIni,"\\mirandaboot.ini"); GetPrivateProfileString("Database","ProfileDir",".",szProfileDir,sizeof(szProfileDir),szMirandaIni); ExpandEnvironmentStrings(szProfileDir,szExpandedProfileDir,sizeof(szExpandedProfileDir)); _chdir(szMirandaDir); if(!_fullpath(szPath,szExpandedProfileDir,cbPath)) lstrcpyn(szPath,szMirandaDir,cbPath); if(szPath[lstrlen(szPath)-1]=='\\') szPath[lstrlen(szPath)-1]='\0'; if((dwAttributes=GetFileAttributes(szPath))!=0xffffffff&&dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return; CreateDirectory(szPath,NULL); } void SetDefaultProtocolIcons() { char szFileName[MAX_PATH+1]; char oldname[] = YAMN_DBMODULE"4007_"; // the deprecated one char dllname[] = "plugins\\"YAMN_DBMODULE".dll,-xxxxx"; // determine whether external icon file exists lstrcpy(szFileName, szMirandaDir); lstrcat(szFileName, "\\icons\\proto_"YAMN_DBMODULE".dll"); BOOL isDllPresent = (_access(szFileName, 0) == 0); WORD statuses[4] = {ID_STATUS_OFFLINE,ID_STATUS_ONLINE,ID_STATUS_NA,ID_STATUS_OCCUPIED}; BYTE indices[4] = {7, 0, 3, 4}; //From skinicons.c skinIconStatusToIdStatus[] BYTE protoStatusInd[4] = {0,1,4,5}; for (int i=0;i<4;i++){ oldname[sizeof(oldname)-2]=protoStatusInd[i]+'1'; // "Out for lunch will not work here" if (isDllPresent){ // use the icons in proto_YAMN.dll and delete any user settings DBDeleteContactSetting(NULL, "Icons", oldname); } else { DBVARIANT dbv; if(!DBGetContactSetting(NULL,"SkinIcons",iconNames[indices[i]],&dbv)) {// user won't be able to set status icons different from those in YAMN section DBWriteContactSettingString(NULL, "Icons", oldname, (char *)dbv.pszVal); DBFreeVariant(&dbv); } else { _snprintf(&dllname[sizeof(dllname)-6],5,"%d",iconIndexes[indices[i]]); DBWriteContactSettingString(NULL, "Icons", oldname, dllname); } } } } extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { YAMNVar.hInst=hinstDLL; if(fdwReason==DLL_PROCESS_ATTACH) { if(NULL==(UserDirectory=new WCHAR[MAX_PATH])) return FALSE; } return TRUE; } extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) { if (mirandaVersion >= PLUGIN_MAKE_VERSION(0, 7, 0, 3)) bIcolibEmbededInCore = TRUE; pluginInfo.cbSize = sizeof(PLUGININFO);//Miranda pre-0.7.0.17 does not load the plugin if cbSize does not match. return (PLUGININFO *) &pluginInfo; } extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { if (mirandaVersion >= PLUGIN_MAKE_VERSION(0, 7, 0, 3)) bIcolibEmbededInCore = TRUE; pluginInfo.cbSize = sizeof(PLUGININFOEX);//Make sure cbSize is correct; return &pluginInfo; } extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) { return interfaces; } #ifdef YAMN_DEBUG static char unknownCP[1500]={0}; #endif // The callback function BOOL CALLBACK EnumSystemCodePagesProc(LPTSTR cpStr) { //Convert code page string to number UINT cp = _ttoi(cpStr); if (!IsValidCodePage(cp)) return TRUE; //Get Code Page name CPINFOEX info; if(GetCPInfoEx(cp,0,&info)){ #ifdef YAMN_DEBUG BOOLEAN found = FALSE; #endif for (int i=1;iYAMN tweety win9x "; #else update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=2165"; update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=2165"; update.pbVersionPrefix = (BYTE *)"YAMN tweety "; #endif*/ update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=3411"; update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=3411"; update.pbVersionPrefix = (BYTE *)"YAMN 2in1 "; wsprintf(szUrl,"http://www.miranda-fr.net/tweety/yamn/%s.zip",YAMN_FILENAME); update.szBetaUpdateURL = szUrl; update.szBetaVersionURL = "http://www.miranda-fr.net/tweety/yamn/yamn_beta.html"; update.pbBetaVersionPrefix = (BYTE *)"YAMN version "; update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix); update.cpbBetaVersionPrefix = (int)strlen((char *)update.pbBetaVersionPrefix); CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); } if (ServiceExists(MS_FOLDERS_GET_PATH)){ //char AccountFolder[MAX_PATH]; //CallService(MS_DB_GETPROFILEPATH, (WPARAM) MAX_PATH, (LPARAM)AccountFolder); //sprintf(AccountFolder,"%s\\%s",AccountFolder,ProtoName); hAccountFolder = FoldersRegisterCustomPathW(ProtoName,YAMN_DBMODULE" Account Folder", UserDirectory); FoldersGetCustomPathW(hAccountFolder, UserDirectory, MAX_PATH, UserDirectory); //MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,AccountFolder,-1,UserDirectory,strlen(AccountFolder)+1); } RegisterPOP3Plugin(0,0); return 0; } //int IcoLibIconsChanged(WPARAM wParam, LPARAM lParam); // implemented in services.cpp extern HCURSOR hCurSplitNS, hCurSplitWE; extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) { UINT mod,vk; char pn[MAX_PATH+1]; char *fc; int i,k; pluginLink=link; mir_getLP(&pluginInfo); mir_getMMI(&mmi); YAMN_STATUS = ID_STATUS_OFFLINE; // we get the Miranda Root Path szMirandaDir=new char[MAX_PATH]; if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)){ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)".",(LPARAM)szMirandaDir); } else { char *str2; GetModuleFileName(GetModuleHandle(NULL),szMirandaDir,MAX_PATH); str2=strrchr(szMirandaDir,'\\'); if(str2!=NULL) *str2=0; } // we get the user path where our yamn-account.book.ini is stored from mirandaboot.ini file char szProfileDir[MAX_PATH+1]; GetProfileDirectory(szProfileDir,sizeof(szProfileDir)); MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,szProfileDir,-1,UserDirectory,(int)strlen(szProfileDir)+1); // Enumerate all the code pages available for the System Locale EnumSystemCodePages(EnumSystemCodePagesProc, CP_INSTALLED); CodePageNamesSupp = new _tcptable[CPLENSUPP]; for (i=0,k=0;ipszDocsPath,DocFiles); if(ppup->bDoDeleteSettings) PUIRemoveDbModule("YAMN"); return 0; } int Shutdown(WPARAM,LPARAM) { DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSX,HeadPosX); DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSY,HeadPosY); DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEX,HeadSizeX); DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEY,HeadSizeY); DBWriteContactSettingWord(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSSPLIT,HeadSplitPos); YAMNVar.Shutdown=TRUE; // CallService(MS_TTB_REMOVEBUTTON,(WPARAM)hTTButton,0); //this often leads to deadlock in Miranda (bug in Miranda) KillTimer(NULL,SecTimer); UnregisterProtoPlugins(); UnregisterFilterPlugins(); return 0; } //We undo all things from Load() extern "C" int __declspec(dllexport) Unload(void) { #ifdef YAMN_DEBUG UnInitDebug(); #endif DestroyCursor(hCurSplitNS); DestroyCursor(hCurSplitWE); CloseHandle(NoWriterEV); CloseHandle(WriteToFileEV); CloseHandle(ExitEV); FreeVSApi(); DeleteCriticalSection(AccountStatusCS); delete AccountStatusCS; DeleteCriticalSection(FileWritingCS); delete FileWritingCS; DeleteCriticalSection(PluginRegCS); delete PluginRegCS; UnhookEvents(); DestroyServiceFunctions(); UnloadPlugins(); delete [] CodePageNamesSupp; delete [] szMirandaDir; delete [] UserDirectory; delete [] szProfileDir; delete [] ProfileName; return 0; } void LoadPlugins() { HANDLE hFind; WIN32_FIND_DATA fd; char szSearchPath[MAX_PATH]; char szPluginPath[MAX_PATH]; lstrcpy(szSearchPath,szMirandaDir); lstrcat(szSearchPath,"\\Plugins\\YAMN\\*.dll"); typedef INT_PTR (*LOADFILTERFCN)(MIRANDASERVICE GetYAMNFcn); hDllPlugins=NULL; if(INVALID_HANDLE_VALUE!=(hFind=FindFirstFile(szSearchPath,&fd))) { do { //rewritten from Miranda sources... Needed because Win32 API has a bug in FindFirstFile, search is done for *.dlllllll... too char *dot=strrchr(fd.cFileName,'.'); if(dot) { // we have a dot int len=(int)strlen(fd.cFileName); // find the length of the string char* end=fd.cFileName+len; // get a pointer to the NULL int safe=(end-dot)-1; // figure out how many chars after the dot are "safe", not including NULL if((safe!=3) || (lstrcmpi(dot+1,"dll")!=0)) //not bound, however the "dll" string should mean only 3 chars are compared continue; } else continue; HINSTANCE hDll; LOADFILTERFCN LoadFilter; lstrcpy(szPluginPath,szMirandaDir); lstrcat(szPluginPath,"\\Plugins\\YAMN\\"); lstrcat(szPluginPath,fd.cFileName); if((hDll=LoadLibrary(szPluginPath))==NULL) continue; LoadFilter=(LOADFILTERFCN)GetProcAddress(hDll,"LoadFilter"); if(NULL==LoadFilter) { FreeLibrary(hDll); hDll=NULL; continue; } if(!(*LoadFilter)(GetFcnPtrSvc)) { FreeLibrary(hDll); hDll=NULL; } if(hDll!=NULL) { hDllPlugins=(HINSTANCE *)realloc((void *)hDllPlugins,(iDllPlugins+1)*sizeof(HINSTANCE)); hDllPlugins[iDllPlugins++]=hDll; } } while(FindNextFile(hFind,&fd)); FindClose(hFind); } } void UnloadPlugins() { for(int i=iDllPlugins-1;i>=0;i--) { if(FreeLibrary(hDllPlugins[i])){ hDllPlugins[i]=NULL; //for safety iDllPlugins --; } } if(hDllPlugins){ free((void *)hDllPlugins); hDllPlugins = NULL; } } void GetIconSize(HICON hIcon, int* sizeX, int* sizeY) { ICONINFO ii; BITMAP bm; GetIconInfo(hIcon, &ii); GetObject(ii.hbmColor, sizeof(bm), &bm); if (sizeX != NULL) *sizeX = bm.bmWidth; if (sizeY != NULL) *sizeY = bm.bmHeight; DeleteObject(ii.hbmMask); DeleteObject(ii.hbmColor); } HBITMAP LoadBmpFromIcon(HICON hIcon) { HBITMAP hBmp, hoBmp; HDC hdc, hdcMem; HBRUSH hBkgBrush; int IconSizeX = 16; int IconSizeY = 16; //GetIconSize(hIcon, &IconSizeX, &IconSizeY); //DebugLog(SynchroFile,"Icon size %i %i\n",IconSizeX,IconSizeY); if ((IconSizeX == 0) || (IconSizeY == 0)) { IconSizeX = 16; IconSizeY = 16; } RECT rc; BITMAPINFOHEADER bih = {0}; int widthBytes; hBkgBrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); bih.biSize = sizeof(bih); bih.biBitCount = 24; bih.biPlanes = 1; bih.biCompression = BI_RGB; bih.biHeight = IconSizeY; bih.biWidth = IconSizeX; widthBytes = ((bih.biWidth*bih.biBitCount + 31) >> 5) * 4; rc.top = rc.left = 0; rc.right = bih.biWidth; rc.bottom = bih.biHeight; hdc = GetDC(NULL); hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight); hdcMem = CreateCompatibleDC(hdc); hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); FillRect(hdcMem, &rc, hBkgBrush); DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, NULL, DI_NORMAL); SelectObject(hdcMem, hoBmp); return hBmp; } int AddTopToolbarIcon(WPARAM,LPARAM) { TTBButton Button= { sizeof(TTBButton), NULL, NULL, NULL, MS_YAMN_FORCECHECK, TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP, // | TTBBF_DRAWBORDER, 0,0,0,0, NULL }; if(!DBGetContactSettingByte(NULL,YAMN_DBMODULE,YAMN_TTBFCHECK,1)) return 1; Button.name=Translate("Check mail"); Button.hbBitmapUp = LoadBmpFromIcon(hYamnIcons[5]); Button.hbBitmapDown = LoadBmpFromIcon(hYamnIcons[6]); //LoadBitmap(YAMNVar.hInst,MAKEINTRESOURCE(IDB_BMTTB)); if((HANDLE)-1==(hTTButton=(HANDLE)CallService(MS_TTB_ADDBUTTON,(WPARAM)&Button,(LPARAM)0))) return 1; CallService(MS_TTB_SETBUTTONOPTIONS,MAKEWPARAM((WORD)TTBO_TIPNAME,(WORD)hTTButton),(LPARAM)Translate("Check mail")); return 0; } int UninstallQuestionSvc(WPARAM wParam,LPARAM) { // if(strcmp((char *)wParam,Translate("Yet Another Mail Notifier"))) // return 0; switch(MessageBoxA(NULL,Translate("Do you also want to remove native YAMN plugins settings?"),Translate("YAMN uninstalling"),MB_YESNOCANCEL|MB_ICONQUESTION)) { case IDYES: UninstallPlugins=TRUE; break; case IDNO: UninstallPlugins=FALSE; break; case IDCANCEL: return 1; } return 0; }