#include "yamn.h" #include "main.h" // External icon var for icolib support //Plugin registration CS //Used if we add (register) plugin to YAMN plugins and when we browse through registered plugins extern CRITICAL_SECTION PluginRegCS; //AccountWriterCS //We want to store number of writers of Accounts (number of Accounts used for writing) //If we want to read all accounts (for saving to file) immidiatelly, we have to wait until no account is changing (no thread writing to account) extern SCOUNTER *AccountWriterSO; //NoExitEV //Event that is signaled when there's a request to exit, so no new pop3 check should be performed extern HANDLE ExitEV; //WriteToFileEV //If this is signaled, write accounts to file is performed. Set this event if you want to actualize your accounts and messages extern HANDLE WriteToFileEV; //extern HICON hYamnIconsOrg[]; extern HICON hYamnIcons[]; extern char *iconDescs[]; extern char *iconNames[]; extern HIMAGELIST CSImages; extern void __stdcall SSL_DebugLog( const char *fmt, ... ); extern char *ProtoName; extern INT_PTR YAMN_STATUS; extern PYAMN_VARIABLES pYAMNVar; extern HYAMNPROTOPLUGIN POP3Plugin; static INT_PTR Service_GetCaps(WPARAM wParam, LPARAM lParam) { if (wParam==PFLAGNUM_4) return PF4_NOCUSTOMAUTH; if (wParam==PFLAG_UNIQUEIDTEXT) return (INT_PTR) Translate("Nick"); if (wParam==PFLAG_MAXLENOFMESSAGE) return 400; if (wParam==PFLAG_UNIQUEIDSETTING) return (INT_PTR) "Id"; if (wParam==PFLAGNUM_2) return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND; if (wParam==PFLAGNUM_5) if (DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWASPROTO, 1)) return PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND; else return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND; return 0; } static INT_PTR Service_GetStatus(WPARAM wParam, LPARAM lParam) { return YAMN_STATUS; } static INT_PTR Service_SetStatus(WPARAM wParam,LPARAM lParam) { INT_PTR newstatus = (wParam!=ID_STATUS_OFFLINE)?ID_STATUS_ONLINE:ID_STATUS_OFFLINE; if (newstatus != YAMN_STATUS){ INT_PTR oldstatus = YAMN_STATUS; YAMN_STATUS=newstatus; ProtoBroadcastAck(ProtoName,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)oldstatus,newstatus); } return 0; } static INT_PTR Service_GetName(WPARAM wParam, LPARAM lParam) { lstrcpynA((char *) lParam, ProtoName, wParam);; return 0; } static INT_PTR Service_LoadIcon(WPARAM wParam,LPARAM lParam) { if ( LOWORD( wParam ) == PLI_PROTOCOL ) return (INT_PTR)CopyIcon(hYamnIcons[0]); // noone cares about other than PLI_PROTOCOL return (INT_PTR)(HICON)NULL; } /*static*/ INT_PTR ClistContactDoubleclicked(WPARAM wParam, LPARAM lParam) { ContactDoubleclicked(((CLISTEVENT*)lParam)->lParam, lParam); return 0; } static int Service_ContactDoubleclicked(WPARAM wParam, LPARAM lParam) { ContactDoubleclicked(wParam, lParam); return 0; } static INT_PTR ContactApplication(WPARAM wParam, LPARAM lParam) { DBVARIANT dbv; char *szProto; HACCOUNT ActualAccount; szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); if (szProto != NULL && strcmp(szProto, ProtoName)==0) { if (!DBGetContactSetting((HANDLE) wParam,ProtoName,"Id",&dbv)) { ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal); if (ActualAccount != NULL) { PROCESS_INFORMATION pi; STARTUPINFOW si; ZeroMemory(&si,sizeof(si)); si.cb=sizeof(si); #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ContactApplication:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO)) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ContactApplication:ualAccountSO-read enter\n"); #endif if (ActualAccount->NewMailN.App!=NULL) { WCHAR *Command; if (ActualAccount->NewMailN.AppParam!=NULL) Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+wcslen(ActualAccount->NewMailN.AppParam)+6]; else Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+6]; if (Command!=NULL) { lstrcpyW(Command,L"\""); lstrcatW(Command,ActualAccount->NewMailN.App); lstrcatW(Command,L"\" "); if (ActualAccount->NewMailN.AppParam!=NULL) lstrcatW(Command,ActualAccount->NewMailN.AppParam); CreateProcessW(NULL,Command,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); delete[] Command; } } #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ContactApplication:ActualAccountSO-read done\n"); #endif ReadDoneFcn(ActualAccount->AccountAccessSO); } #ifdef DEBUG_SYNCHRO else DebugLog(SynchroFile,"ContactApplication:ActualAccountSO-read enter failed\n"); #endif } DBFreeVariant(&dbv); } } return 0; } DWORD WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, DWORD dwTimeout); static INT_PTR AccountMailCheck(WPARAM wParam, LPARAM lParam){ //This service will check/sincronize the account pointed by wParam HACCOUNT ActualAccount = (HACCOUNT)wParam; HANDLE ThreadRunningEV; DWORD tid; // copy/paste make mistakes if (ActualAccount != NULL) { //we use event to signal, that running thread has all needed stack parameters copied if (NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL))) return 0; //if we want to close miranda, we get event and do not run pop3 checking anymore if (WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0)) return 0; EnterCriticalSection(&PluginRegCS); #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"AccountCheck:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0!=SWMRGWaitToRead(ActualAccount->AccountAccessSO,0)) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait failed\n"); #endif } else { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read enter\n"); #endif if ((ActualAccount->Flags & YAMN_ACC_ENA) && ActualAccount->Plugin->Fcn->SynchroFcnPtr) { struct CheckParam ParamToPlugin={YAMN_CHECKVERSION,ThreadRunningEV,ActualAccount,lParam?YAMN_FORCECHECK:YAMN_NORMALCHECK,(void *)0,NULL}; HANDLE NewThread; ActualAccount->TimeLeft=ActualAccount->Interval; if (NewThread=CreateThread(NULL,0,(YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->SynchroFcnPtr,&ParamToPlugin,0,&tid)) { WaitForSingleObject(ThreadRunningEV,INFINITE); CloseHandle(NewThread); } else { //ReadDoneFcn(ActualAccount->AccountAccessSO); } } ReadDoneFcn(ActualAccount->AccountAccessSO); } LeaveCriticalSection(&PluginRegCS); CloseHandle(ThreadRunningEV); } return 0; } static INT_PTR ContactMailCheck(WPARAM wParam, LPARAM lParam) { DBVARIANT dbv; char *szProto; HACCOUNT ActualAccount; HANDLE ThreadRunningEV; DWORD tid; szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); if (szProto != NULL && strcmp(szProto, ProtoName)==0) { if (!DBGetContactSetting((HANDLE) wParam,ProtoName,"Id",&dbv)) { ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal); if (ActualAccount != NULL) { //we use event to signal, that running thread has all needed stack parameters copied if (NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL))) return 0; //if we want to close miranda, we get event and do not run pop3 checking anymore if (WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0)) return 0; EnterCriticalSection(&PluginRegCS); #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO)) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait failed\n"); #endif } else { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read enter\n"); #endif if ((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) //account cannot be forced to check { if (ActualAccount->Plugin->Fcn->ForceCheckFcnPtr==NULL) { ReadDoneFcn(ActualAccount->AccountAccessSO); } struct CheckParam ParamToPlugin={YAMN_CHECKVERSION,ThreadRunningEV,ActualAccount,YAMN_FORCECHECK,(void *)0,NULL}; if (NULL==CreateThread(NULL,0,(YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr,&ParamToPlugin,0,&tid)) { ReadDoneFcn(ActualAccount->AccountAccessSO); } else WaitForSingleObject(ThreadRunningEV,INFINITE); } ReadDoneFcn(ActualAccount->AccountAccessSO); } LeaveCriticalSection(&PluginRegCS); CloseHandle(ThreadRunningEV); } DBFreeVariant(&dbv); } } return 0; } void MainMenuAccountClicked(WPARAM wParam, LPARAM lParam) { } /*static*/ void ContactDoubleclicked(WPARAM wParam, LPARAM lParam) { DBVARIANT dbv; char *szProto; HACCOUNT ActualAccount; szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); if (szProto != NULL && strcmp(szProto, ProtoName)==0) { if (!DBGetContactSetting((HANDLE) wParam,ProtoName,"Id",&dbv)) { ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal); if (ActualAccount != NULL) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO)) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read enter\n"); #endif YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualAccount->NewMailN.Flags,ActualAccount->NoNewMailN.Flags,0}; Param.nnflags=Param.nnflags | YAMN_ACC_MSG; //show mails in account even no new mail in account Param.nnflags=Param.nnflags & ~YAMN_ACC_POP; Param.nflags=Param.nflags | YAMN_ACC_MSG; //show mails in account even no new mail in account Param.nflags=Param.nflags & ~YAMN_ACC_POP; RunMailBrowserSvc((WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION); #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read done\n"); #endif ReadDoneFcn(ActualAccount->AccountAccessSO); } #ifdef DEBUG_SYNCHRO else DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read enter failed\n"); #endif } DBFreeVariant(&dbv); } } } int IcoLibIconsChanged(WPARAM wParam, LPARAM lParam) { HICON temp; for (int i=0;iFirstAccount;Finder!=NULL;Finder=Finder->Next) { if (Finder->hContact != NULL) { if ((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT)) { DBDeleteContactSetting(Finder->hContact, "CList", "Hidden"); } else { DBWriteContactSettingByte(Finder->hContact, "CList", "Hidden", 1); } } else { if ((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT)) { Finder->hContact =(HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)Finder->hContact,(LPARAM)ProtoName); DBWriteContactSettingString(Finder->hContact,ProtoName,"Id",Finder->Name); DBWriteContactSettingString(Finder->hContact,ProtoName,"Nick",Finder->Name); DBWriteContactSettingString(Finder->hContact,"Protocol","p",ProtoName); DBWriteContactSettingWord(Finder->hContact, ProtoName, "Status", ID_STATUS_ONLINE); DBWriteContactSettingString(Finder->hContact, "CList", "StatusMsg", Translate("No new mail message")); } } } }