From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/YAMN/main.cpp | 824 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 824 insertions(+) create mode 100644 plugins/YAMN/main.cpp (limited to 'plugins/YAMN/main.cpp') diff --git a/plugins/YAMN/main.cpp b/plugins/YAMN/main.cpp new file mode 100644 index 0000000000..05b7fd5eb4 --- /dev/null +++ b/plugins/YAMN/main.cpp @@ -0,0 +1,824 @@ +/* + * 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; +} -- cgit v1.2.3