From f56c7ac5e668acd8633e8c91b438fec506162fc2 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 8 Oct 2023 15:35:54 +0300 Subject: YAMN: another bunch of services removed --- plugins/ExternalAPI/m_account.h | 1 - plugins/ExternalAPI/m_mails.h | 53 ---- plugins/ExternalAPI/m_protoplugin.h | 344 +++++++---------------- plugins/ExternalAPI/m_yamn.h | 34 --- protocols/YAMN/src/account.cpp | 274 ++++++++---------- protocols/YAMN/src/browser/mailbrowser.cpp | 36 +-- protocols/YAMN/src/mails/mails.cpp | 323 +++++++++------------- protocols/YAMN/src/main.cpp | 78 ++---- protocols/YAMN/src/proto/pop3/pop3comm.cpp | 429 +++++++++++++---------------- protocols/YAMN/src/proto/pop3/pop3opt.cpp | 21 +- protocols/YAMN/src/protoplugin.cpp | 85 ++---- protocols/YAMN/src/services.cpp | 71 +---- protocols/YAMN/src/stdafx.h | 83 +++--- protocols/YAMN/src/yamn.cpp | 46 +--- 14 files changed, 668 insertions(+), 1210 deletions(-) diff --git a/plugins/ExternalAPI/m_account.h b/plugins/ExternalAPI/m_account.h index c316923cd3..c735fe083b 100644 --- a/plugins/ExternalAPI/m_account.h +++ b/plugins/ExternalAPI/m_account.h @@ -235,7 +235,6 @@ struct SWriteGuard struct CAccount { #define YAMN_ACCOUNTFILEVERSION 2 //version of standard file format (YAMN book file format) - #define YAMN_ACCOUNTVERSION 3 // If changes are made in this structure, version is changed. // So then YAMN does not initialzie your structure, if version does not matches. diff --git a/plugins/ExternalAPI/m_mails.h b/plugins/ExternalAPI/m_mails.h index ea53511b72..28c796ff67 100644 --- a/plugins/ExternalAPI/m_mails.h +++ b/plugins/ExternalAPI/m_mails.h @@ -67,7 +67,6 @@ struct CMimeItem // this is plugin-independent typedef struct CMailData { - #define YAMN_MAILDATAVERSION 3 DWORD Size = 0; int CP = -1; @@ -78,7 +77,6 @@ typedef struct CMailData typedef struct CMimeMsgQueue { -#define YAMN_MAILVERSION 3 char *ID; //The ID of mail. This ID identifies every mail in the account, so plugin should set it DWORD Number; @@ -144,57 +142,6 @@ typedef struct CMimeMsgQueue } YAMNMAIL,*HYAMNMAIL; #define LoadedMailData(x) (x->MailData!=nullptr) -// -//================================== YAMN MAIL SERVICES ================================== -// - -//CreateAccountMail Service -//Your plugin should call this to create new mail for your plugin. -//WPARAM- (CAccount *) Account handle -//LPARAM- CMailData version (use YAMN_MAILVERSION definition) -//returns pointer to (HYAMNMAIL) or pointer to your structure returned from imported NewMailFcnPtr, if implemented -#define MS_YAMN_CREATEACCOUNTMAIL "YAMN/Service/CreateMail" -#define CreateAccountMail(x) (HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)x,(LPARAM)YAMN_MAILVERSION) - -//DeleteAccountMail Service -//Deletes plugin's mail from memory. You probably won't use this service, because it deletes only account -//without any synchronization. Use MS_YAMN_DELETEACCOUNT instead. Note that deleting mail is something like "this mail is -//not more in the account". -//WPARAM- (HYAMNPROTOPLUGIN) handle of plugin, which is going to delete mail -//LPARAM- (HYAMNMAIL) mail going to delete -//returns zero if failed, otherwise returns nonzero -#define MS_YAMN_DELETEACCOUNTMAIL "YAMN/Service/DeletePluginMail" -#define DeleteAccountMail(x,y) CallService(MS_YAMN_DELETEACCOUNTMAIL,(WPARAM)x,(LPARAM)y) - -//LoadMailData Service -//This service loads mail from standard YAMN storage (now it is 1 file, from which mails are loaded once at startup, but -//in the future it can be Miranda profile file or separate file (1 file per 1 mail). It depends on YAMN implementation... -//Use this function if you want to read or write to MailData member of mail structure. Please use synchronization obejcts -//before calling this service (so you must have read or write access to mails) -//WPARAM- (HYAMNMAIL) mail where to load data -//LPARAM- (DWORD) version of MAILDATA structure (use YAMN_MAILDATAVERSION definition) -//returns pointer to new allocated MailData structure (the same value as MailData member) -#define MS_YAMN_LOADMAILDATA "YAMN/Service/LoadMailData" -#define LoadMailData(x) (CMailData*)CallService(MS_YAMN_LOADMAILDATA,(WPARAM)x,(LPARAM)YAMN_MAILDATAVERSION) - -//UnloadMailData Service -//This service frees mail data from memory. It does not care if data were saved or not. So you should save mail before you -//release data from memory. -//WPARAM- (HYAMNMAIL) mail whose data are about to free -//LPARAM- nothing yet -//returns nonzero if success -#define MS_YAMN_UNLOADMAILDATA "YAMN/Service/UnloadMailData" -#define UnloadMailData(x) CallService(MS_YAMN_UNLOADMAILDATA,(WPARAM)x,0) - -//SaveMailData Service -//This service saves mail to standard YAMN storage (when using now 1 book file, it does nothing, because save is done when -//using MS_YAMN_WRITEACCOUNT service. In the future, mail can be saved to Miranda profile or to separate file...) -//WPARAM- (HYAMNMAIL) mail to save -//LPARAM- (DWORD) version of MAILDATA structure (use YAMN_MAILDATAVERSION definition) -//returns ZERO! if succes -#define MS_YAMN_SAVEMAILDATA "YAMN/Service/SaveMailData" -#define SaveMailData(x) CallService(MS_YAMN_SAVEMAILDATA,(WPARAM)x,(LPARAM)YAMN_MAILDATAVERSION) - // //================================== FUNCTIONS DEFINITIONS ======================================== // diff --git a/plugins/ExternalAPI/m_protoplugin.h b/plugins/ExternalAPI/m_protoplugin.h index c2085d25a0..633740b857 100644 --- a/plugins/ExternalAPI/m_protoplugin.h +++ b/plugins/ExternalAPI/m_protoplugin.h @@ -2,66 +2,66 @@ #define __M_PROTOPLUGIN_H #include -#include "m_account.h" //for account import functions -#include "m_mails.h" //for mail import functions +#include "m_account.h" // for account import functions +#include "m_mails.h" // for mail import functions -// -//================================== OTHER DEFINITIONS ======================================== -// +// +// ================================== OTHER DEFINITIONS ======================================== +// -//structure is used to give parameters to Check, Synchro or Timeout function +// structure is used to give parameters to Check, Synchro or Timeout function struct CheckParam { - //Your plugin should use this definition + // Your plugin should use this definition #define YAMN_CHECKVERSION 2 - //Version of this structure. Please verify your version in your plugin + // Version of this structure. Please verify your version in your plugin int Ver; - //Event that new Check thread must set to signal calling thread that "I've copied all parameters from stack" - //IMPORTANT!!!: Although version #defined in your plugin is not the same, your plugin MUST signal this event - //in any way. YAMN is waiting for this event. If you do not signal it, YAMN is blocked. + // Event that new Check thread must set to signal calling thread that "I've copied all parameters from stack" + // IMPORTANT!!!: Although version #defined in your plugin is not the same, your plugin MUST signal this event + // in any way. YAMN is waiting for this event. If you do not signal it, YAMN is blocked. HANDLE ThreadRunningEV; - //ActualAccount- the only parameter used in Check function and should contain all needed information I think :) + // ActualAccount- the only parameter used in Check function and should contain all needed information I think :) CAccount *AccountParam; - //I thought it, but this is needed, too + // I thought it, but this is needed, too #define YAMN_NORMALCHECK 0 #define YAMN_FORCECHECK 1 int Flags; - //YAMN writes here some informations that are needed to pass to mail browser function (or bad connection) + // YAMN writes here some informations that are needed to pass to mail browser function (or bad connection) void *BrowserParam; - //Calling thread (protocol plugin) can write here its own parameters. Usefull when protocol calls its own check function. YAMN always sets this parameter to NULL + // Calling thread (protocol plugin) can write here its own parameters. Usefull when protocol calls its own check function. YAMN always sets this parameter to NULL void *CustomParam; }; -//structure is used to give parameters to DeleteMails function +// structure is used to give parameters to DeleteMails function struct DeleteParam { - //Your plugin should use this definition + // Your plugin should use this definition #define YAMN_DELETEVERSION 1 - //Version of this structure. Please verify your version in your plugin + // Version of this structure. Please verify your version in your plugin DWORD Ver; - //Event that new Delete thread must set to signal calling thread that it copied all parameters from stack - //IMPORTANT!!!: Although version #defined in your plugin is not the same, your plugin MUST signal this event - //in any way. YAMN is waiting for this event. If you do not signal it, YAMN is blocked. + // Event that new Delete thread must set to signal calling thread that it copied all parameters from stack + // IMPORTANT!!!: Although version #defined in your plugin is not the same, your plugin MUST signal this event + // in any way. YAMN is waiting for this event. If you do not signal it, YAMN is blocked. HANDLE ThreadRunningEV; - //ActualAccount- which account to delete + // ActualAccount- which account to delete CAccount *AccountParam; - //YAMN writes here some informations that are needed to pass to mail browser function (or bad connection or no new mail) + // YAMN writes here some informations that are needed to pass to mail browser function (or bad connection or no new mail) void *BrowserParam; - //Calling thread can write here its own parameter. Usefull when protocol calls its own delete function. YAMN always sets this parameter to NULL + // Calling thread can write here its own parameter. Usefull when protocol calls its own delete function. YAMN always sets this parameter to NULL void *CustomParam; }; -// -//================================== IMPORTED FUNCTIONS ================================== -// +// +// ================================== IMPORTED FUNCTIONS ================================== +// #ifndef YAMN_STANDARDFCN typedef DWORD(WINAPI *YAMN_STANDARDFCN)(LPVOID); #endif typedef struct CYAMNVariables *(WINAPI *YAMN_GETVARIABLESFCN)(DWORD); -typedef CAccount *(WINAPI *YAMN_NEWACCOUNTFCN)(struct YAMN_PROTOPLUGIN *, DWORD); +typedef CAccount *(WINAPI *YAMN_NEWACCOUNTFCN)(struct YAMN_PROTOPLUGIN *); typedef void (WINAPI *YAMN_STOPACCOUNTFCN)(CAccount *); typedef void (WINAPI *YAMN_DELETEACCOUNTFCN)(CAccount *); typedef DWORD(WINAPI *YAMN_WRITEPLUGINOPTS)(HANDLE File, CAccount *); @@ -73,156 +73,146 @@ typedef char* (WINAPI *YAMN_GETERRORSTRINGAFCN)(DWORD); typedef void (WINAPI *YAMN_DELETEERRORSTRINGFCN)(LPVOID); typedef DWORD(WINAPI *YAMN_WRITEACCOUNTSFCN)(); -typedef struct CAccountImportFcn +struct YAMN_PROTOIMPORTFCN { - //If changes are made in this structure, version is changed. - //So then YAMN does not initialize your structure, if version does not match. -#define YAMN_PROTOIMPORTFCNVERSION 3 - - //Note: not all of these functions are needed to be implemented in your protocol plugin. Those - //functions, which are not implemented, you have to set to NULL. - - //Function is called to construct protocol defined account - //This is VERY IMPORTANT for YAMN and plugin to cooperate: - //Imagine following situation. YAMN wants to add new account (it is possible e.g. - //when loading accounts from file), so it has to call protocol constructor. - //It calls NewAccount function and plugin creates new account and returns - //its handle (pointer in fact). That means new account is created with plugin features - //(it is created inherited account, not base class). + // Note: not all of these functions are needed to be implemented in your protocol plugin. Those + // functions, which are not implemented, you have to set to NULL. + + // Function is called to construct protocol defined account + // This is VERY IMPORTANT for YAMN and plugin to cooperate: + // Imagine following situation. YAMN wants to add new account (it is possible e.g. + // when loading accounts from file), so it has to call protocol constructor. + // It calls NewAccount function and plugin creates new account and returns + // its handle (pointer in fact). That means new account is created with plugin features + // (it is created inherited account, not base class). YAMN_NEWACCOUNTFCN NewAccountFcnPtr; - //Function is called to delete protocol defined variables to inherited CAccount structure + // Function is called to delete protocol defined variables to inherited CAccount structure YAMN_DELETEACCOUNTFCN DeleteAccountFcnPtr; - //Function is called when user requests not tu run account longer. (E.g. when closing Miranda) + // Function is called when user requests not tu run account longer. (E.g. when closing Miranda) YAMN_STOPACCOUNTFCN StopAccountFcnPtr; - //Function is called when plugin should write its own info into book file + // Function is called when plugin should write its own info into book file YAMN_WRITEPLUGINOPTS WritePluginOptsFcnPtr; - //Function is called when plugin should read its own info from book file + // Function is called when plugin should read its own info from book file YAMN_READPLUGINOPTS ReadPluginOptsFcnPtr; - //Function is called to synchronise account (delete old mails and get the new ones) + // Function is called to synchronise account (delete old mails and get the new ones) YAMN_CHECKFCN SynchroFcnPtr; - //Function is called when timer timed out- it can be the same as SynchroFcnPtr + // Function is called when timer timed out- it can be the same as SynchroFcnPtr YAMN_CHECKFCN TimeoutFcnPtr; - //Function is called when forced checking- it can be the same as SynchroFcnPtr + // Function is called when forced checking- it can be the same as SynchroFcnPtr YAMN_CHECKFCN ForceCheckFcnPtr; - //Function is called when user wants to delete mails + // Function is called when user wants to delete mails YAMN_DELETEFCN DeleteMailsFcnPtr; - //Function is called when YAMN wants to get error description. Note the parameter given in - //this function is in fact the same as your CheckFcnPtr, DeleteMailsFcnPtr etc. returns to YAMN. - //If you want, you may return pointer to some structure, which includes more information about - //error than only one DWORD. And then, you can in your function create Unicode string containing - //all your error code. YAMN copies this string into its own buffer. Your error code and pointer - //can be deleted in DeleteErrorStringFcnPtr, which is called by YAMN + // Function is called when YAMN wants to get error description. Note the parameter given in + // this function is in fact the same as your CheckFcnPtr, DeleteMailsFcnPtr etc. returns to YAMN. + // If you want, you may return pointer to some structure, which includes more information about + // error than only one DWORD. And then, you can in your function create Unicode string containing + // all your error code. YAMN copies this string into its own buffer. Your error code and pointer + // can be deleted in DeleteErrorStringFcnPtr, which is called by YAMN YAMN_GETERRORSTRINGWFCN GetErrorStringWFcnPtr; - //This is the same as previous one, but plugin returns normal string (not Unicode). YAMN first - //looks, if your plugin has implemented GetErrorStringWFcnPtr. If not, it looks for this function - //So as you (of course) wait, you implemnt only one of these functions or no one of them. + // This is the same as previous one, but plugin returns normal string (not Unicode). YAMN first + // looks, if your plugin has implemented GetErrorStringWFcnPtr. If not, it looks for this function + // So as you (of course) wait, you implemnt only one of these functions or no one of them. YAMN_GETERRORSTRINGAFCN GetErrorStringAFcnPtr; - //Deletes error string that was allocated in your GetErrorStringXFcnPtr. Parameter to this fcn is - //Unicode or normal string. Therefore parameter is defined as LPVOID, but your plugin knows if it is - //Unicode or not... - //If NULL, YAMN does nothing with string + // Deletes error string that was allocated in your GetErrorStringXFcnPtr. Parameter to this fcn is + // Unicode or normal string. Therefore parameter is defined as LPVOID, but your plugin knows if it is + // Unicode or not... + // If NULL, YAMN does nothing with string YAMN_DELETEERRORSTRINGFCN DeleteErrorStringFcnPtr; - //Function is called to notify plugin, that it is quite good to store account status (and mails) + // Function is called to notify plugin, that it is quite good to store account status (and mails) YAMN_WRITEACCOUNTSFCN WriteAccountsFcnPtr; - //Function is called when user wants to view mails - //not used now, in the future + // Function is called when user wants to view mails + // not used now, in the future YAMN_STANDARDFCN ViewMailsFcnPtr; - //Function is called when application exits. Plugin should unload + // Function is called when application exits. Plugin should unload YAMN_STANDARDFCN UnLoadFcn; -} YAMN_PROTOIMPORTFCN, *PYAMN_PROTOIMPORTFCN; +}; -typedef HYAMNMAIL(WINAPI *YAMN_NEWMAILFCN)(CAccount *, DWORD); +typedef HYAMNMAIL(WINAPI *YAMN_NEWMAILFCN)(CAccount *); typedef void (WINAPI *YAMN_DELETEMAILFCN)(HYAMNMAIL); typedef DWORD(WINAPI *YAMN_WRITEMAILOPTS)(HANDLE File, HYAMNMAIL); typedef DWORD(WINAPI *YAMN_READMAILOPTS)(HYAMNMAIL, char **, char *); -typedef struct CMailImportFcn +struct YAMN_MAILIMPORTFCN { - //If changes are made in this structure, version is changed. - //So then YAMN does not initialize your structure, if version does not match. -#define YAMN_MAILIMPORTFCNVERSION 1 - - //Note: not all of these functions are needed to be implemented in your protocol plugin. Those - //functions, which are not implemented, you have to set to NULL. - - //Function is called to construct protocol defined account - //This is VERY IMPORTANT for YAMN and plugin to cooperate: - //Imagine following situation. YAMN wants to add new account (it is possible e.g. - //when loading accounts from file), so it has to call protocol constructor. - //It calls NewAccount function and plugin creates new account and returns - //its handle (pointer in fact). That means new account is created with plugin features - //(it is created inherited account, not base class). + // Note: not all of these functions are needed to be implemented in your protocol plugin. Those + // functions, which are not implemented, you have to set to NULL. + + // Function is called to construct protocol defined account + // This is VERY IMPORTANT for YAMN and plugin to cooperate: + // Imagine following situation. YAMN wants to add new account (it is possible e.g. + // when loading accounts from file), so it has to call protocol constructor. + // It calls NewAccount function and plugin creates new account and returns + // its handle (pointer in fact). That means new account is created with plugin features + // (it is created inherited account, not base class). YAMN_NEWMAILFCN NewMailFcnPtr; - //Function is called to delete protocol defined variables to inherited CAccount structure + // Function is called to delete protocol defined variables to inherited CAccount structure YAMN_DELETEMAILFCN DeleteMailFcnPtr; - //Function is called when plugin should write its own info into book file + // Function is called when plugin should write its own info into book file YAMN_WRITEMAILOPTS WriteMailOptsFcnPtr; - //Function is called when plugin should read its own info from book file + // Function is called when plugin should read its own info from book file YAMN_READMAILOPTS ReadMailOptsFcnPtr; -} YAMN_MAILIMPORTFCN, *PYAMN_MAILIMPORTFCN; +}; -// -//================================== PROTOCOL PLUGIN REGISTRATION STRUCTURES ================================== -// +// +// ================================== PROTOCOL PLUGIN REGISTRATION STRUCTURES ================================== +// -typedef struct CProtoPluginRegistration +struct YAMN_PROTOREGISTRATION { -#define YAMN_PROTOREGISTRATIONVERSION 1 - //Name of plugin - //this member CANNOT be NULL. Just write here description, i.e. "Yahoo Mail 1.2" + // Name of plugin + // this member CANNOT be NULL. Just write here description, i.e. "Yahoo Mail 1.2" char *Name; - //The version of plugin. CANNOT be NULL. + // The version of plugin. CANNOT be NULL. char *Ver; - //Plugin copyright - //Write here your copyright if you want (or NULL) + // Plugin copyright + // Write here your copyright if you want (or NULL) char *Copyright; - //Plugin description. Can be NULL. + // Plugin description. Can be NULL. char *Description; - //Your contact (email). Can be NULL. + // Your contact (email). Can be NULL. char *Email; - //The web page. Can be NULL. + // The web page. Can be NULL. char *WWW; - -} YAMN_PROTOREGISTRATION, *PYAMN_PROTOREGISTRATION; +}; struct YAMN_PROTOPLUGIN { // Pointer to first protocol plugin account - CAccount *FirstAccount; + CAccount *FirstAccount = 0; // We prevent browsing through accounts (chained list) from deleting or adding any account // If we want to delete or add, we must have "write" access to AccountBrowserSO // Note that accounts can be changed during AccountBrowser is in "read" mode, because we do not add or delete account. SWMRG AccountBrowserSO; - //All needed other info from plugin - PYAMN_PROTOREGISTRATION PluginInfo; + // All needed other info from plugin + YAMN_PROTOREGISTRATION *PluginInfo; - //Imported functions - PYAMN_PROTOIMPORTFCN Fcn; - PYAMN_MAILIMPORTFCN MailFcn; + // Imported functions + YAMN_PROTOIMPORTFCN *Fcn = 0; + YAMN_MAILIMPORTFCN *MailFcn = 0; }; struct YAMN_PROTOPLUGINQUEUE @@ -231,138 +221,4 @@ struct YAMN_PROTOPLUGINQUEUE YAMN_PROTOPLUGINQUEUE *Next; }; -// -//================================== YAMN SERVICES FOR PROTOCOL PLUGIN ================================== -// - -//RegisterProtoPlugin Service -//Your plugin can call this service to "connect to YAMN"- it means, that you -//give some parameters to YAMN and YAMN can then cooperate with your protocol plugins -//WPARAM- pointer to YAMN_PROTOREGISTRATION structure. Plugin must not delete this structure from memory. -//LPARAM- version of YAMN_PROTOREGISTRATION structure (use YAMN_PROTOREGISTRATIONVERSION definition) -//returns handle to plugin (HYAMNPROTOPLUGIN), if registration failed (plugin not registered) returns NULL -//Note, that your plugin should store returned plugin handle, because it will be usefull in next services. -//You need next to call SetProtocolPluginFcnImportFcn to have your plugin cooperated with YAMN. -#define MS_YAMN_REGISTERPROTOPLUGIN "YAMN/Service/RegisterProtocolPlugin" - -//UnregisterProtoPlugin Service -//Removes plugin from YAMN and deltes its structures -//WPARAM- (HYAMNPROTOPLUGIN) handle of protocol plugin -//LPARAM- any value -//returns nonzero if success -#define MS_YAMN_UNREGISTERPROTOPLUGIN "YAMN/Service/UnregisterProtocolPlugin" - -//CreateAccount Service -//Your plugin should call this to create new account for your plugin. -//WPARAM- (HYAMNPLUGIN) Plugin handle -//LPARAM- CAccount version (use YAMN_ACCOUNTVERSION definition) -//returns pointer to (CAccount *) or pointer to your structure returned from imported NewAccountFcnPtr, if implemented -#define MS_YAMN_CREATEPLUGINACCOUNT "YAMN/Service/CreateAccount" - -//DeletePluginAccount Service -//Deletes plugin's account from memory. You probably won't use this service, because it deletes only account -//without any synchronization. Use MS_YAMN_DELETEACCOUNT instead. -//WPARAM- (CAccount *) to delete -//LPARAM- any value -//returns zero if failed, otherwise returns nonzero -#define MS_YAMN_DELETEPLUGINACCOUNT "YAMN/Service/DeletePluginAccount" - -//FindAccountByName Service -//Searches accounts queue for first account that belongs to plugin -//WPARAM- (HYAMNPLUGIN) Plugin handle -//LPARAM- (TCHAR *)string, name of account to find -//returns found CAccount * handle or NULL if not found -#define MS_YAMN_FINDACCOUNTBYNAME "YAMN/Service/FindAccountByName" - -//GetNextFreeAccount Service -//Creates new account for plugin and adds it to plugin account queue. -//Note!!! you have to use AccountBrowserSO in your plugin before and after calling this service, because it is not synchronized -//So the normal way is like this: -// WaitToWriteSO(MyPlugin->AccountBrowserSO); -// CallService(MS_YAMN_GETNEXTFREEACCOUNT,MyPlugin,YAMN_ACCOUNTVERSION); -// WriteDoneSO(MyPlugin->AccountBrowserSO); -// -//WPARAM- (HYAMNPLUGIN) Plugin handle -//LPARAM- CAccount version (use YAMN_ACCOUNTVERSION definition) -//returns new CAccount * handle or NULL if not found -#define MS_YAMN_GETNEXTFREEACCOUNT "YAMN/Service/GetNextFreeAccount" - -//DeleteAccount Service -//Deletes account from plugin account queue. It also deletes it, but in background (when needed). -//This deleting is full synchronized and safe. It is recommended for plugins to use this service. -//WPARAM- (HYAMNPLUGIN) Plugin handle -//LPARAM- (CAccount *) Account to delete -#define MS_YAMN_DELETEACCOUNT "YAMN/Service/DeleteAccount" - -//ReadAccounts Service -//Reads standard accounts to file. Standard account means standard YAMN book format. -//WPARAM- (HYAMNPLUGIN) Plugin handle -//LPARAM- (TCHAR*)filename string. Put here your own desired filename. -//return value is one of the ones written in "account.h" file -#define MS_YAMN_READACCOUNTS "YAMN/Service/ReadAccounts" - -//WriteAccounts Service -//Writes standard accounts to file. Standard account means standard YAMN book format. It does not -//store special protocol features. It stores Account settings from CAccount struct and stores MIME mails -//from CMimeMsgQueue. If your Mails pointer does not point to CMimeMsgQueue structure, -//do not use this function. You are then forced to write your own function -//WPARAM- (HYAMNPLUGIN) Plugin handle -//LPARAM- (TCHAR*)filename string. Put here your own desired filename. -//return value is one of the ones written in "account.h" file -#define MS_YAMN_WRITEACCOUNTS "YAMN/Service/WriteAccounts" - -//GetFileName Service -//Function makes original filename, when you add your protocol string -//From "yahoo" makes "yamn-accounts.yahoo.xxxxx.book" filename -//It is good to use this fcn to have similar filenames... -//WPARAM- (TCHAR*) plugin string -//LPARAM- ignored -//returns NULL when failed, otherwise returns (TCHAR*)string (!!! not char *) to filename!!! -//You can use MS_YAMN_DELETEFILENAME service to release allocated filename from memory -#define MS_YAMN_GETFILENAME "YAMN/Service/GetFileName" - -//DeleteFileName Service -//deletes unicode string from memory -//WPARAM- (WCHAR *) pointer to unicode string -//LPARAM- any value -#define MS_YAMN_DELETEFILENAME "YAMN/Service/DeleteFileName" - -// -//================================== FUNCTIONS DEFINITIONS ======================================== -// - -typedef int (WINAPI *YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, DWORD YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, DWORD YAMNMailFcnVer); - -// -//================================== QUICK FUNCTION CALL DEFINITIONS ======================================== -// - -//These are defininitions for YAMN exported functions. Your plugin can use them. -//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions. -//It is something similar like pluginLink variable in Miranda plugin. If you use -//this name of variable, you have already defined these functions and you can use them. -//It's similar to Miranda's CreateService function. - -//How to use YAMN functions: -//Create a structure containing pointer to functions you want to use in your plugin -//This structure can look something like this: -// -// struct -// { -// YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN SetProtocolPluginFcnImportFcn; -// } *pYAMNFcn; -// -//then you have to fill this structure with pointers... -// -// pYAMNFcn->SetProtocolPluginFcnImportFcn=(YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETPROTOCOLPLUGINFCNIMPORTID,0); -// -//and in your plugin just simply use e.g.: -// -// SetProtocolPluginFcnImport(...); -// - -#define YAMN_SETPROTOCOLPLUGINFCNIMPORTID "YAMN/SetProtocolPluginFcnImport" - -#define SetProtocolPluginFcnImport(a,b,c,d,e) pYAMNFcn->SetProtocolPluginFcnImportFcn(a,b,c,d,e) - #endif diff --git a/plugins/ExternalAPI/m_yamn.h b/plugins/ExternalAPI/m_yamn.h index 77ea3cb676..0b4a9f306d 100644 --- a/plugins/ExternalAPI/m_yamn.h +++ b/plugins/ExternalAPI/m_yamn.h @@ -15,22 +15,6 @@ struct YAMN_VARIABLES int Shutdown; }; -// -//================================== EXPORTED FUNCTIONS STRUCT =============================== -// - -struct CExportedFunctions -{ - char* ID; - void *Ptr; -}; - -struct CExportedServices -{ - char* ID; - INT_PTR (* Ptr)(WPARAM,LPARAM); -}; - // //================================== YAMN EVENTS ================================== // @@ -50,24 +34,6 @@ struct CExportedServices //================================== YAMN SERVICES ================================== // -//GetFcnPtr Service -//Your plugin can co-operate with YAMN in 2 ways: with Miranda services and with YAMN exported functions -//Some commands are written in services, some are functions. The advantage of function calling instead of -//service calling is, that your code is more clear and it is faster than service calling (smaller, FASTER, -//easier- it is slogan of Miranda, isn't it ?). Miranda service has only 2 parameters, that can be -//disadvantage too. -//In every way, it is discutable which functions should be exported or if they should be implemented as -//services. And if YAMN should export some functions etc. Functions not used very often are now implemented -//as Miranda services. -// -//This service gets pointer to YAMN function. Then you can use function directly. In m_?????.h files you have -//definitions of some functions, with definitions of structure variable, so you can use functions very -//clearly, just look to header file. -//WPARAM- function ID. It is string representating function you need to get pointer (e.g. YAMN_WRITEWAITID) -//LPARAM- not used now, but set it to 0 -//returns pointer to YAMN function or NULL when functions does not exist -#define MS_YAMN_GETFCNPTR "YAMN/Service/GetFcn" - //ForceCheck Service //Check mail on accounts //WPARAM- not used diff --git a/protocols/YAMN/src/account.cpp b/protocols/YAMN/src/account.cpp index 55c9dbb9a9..d8ae8abc97 100644 --- a/protocols/YAMN/src/account.cpp +++ b/protocols/YAMN/src/account.cpp @@ -17,69 +17,46 @@ static mir_cs csAccountStatusCS; // When 2 threads want to write to file... static mir_cs csFileWritingCS; -struct CExportedServices AccountExportedSvc[] = -{ - {MS_YAMN_CREATEPLUGINACCOUNT, CreatePluginAccountSvc}, - {MS_YAMN_DELETEPLUGINACCOUNT, DeletePluginAccountSvc}, - {MS_YAMN_FINDACCOUNTBYNAME, FindAccountByNameSvc}, - {MS_YAMN_GETNEXTFREEACCOUNT, GetNextFreeAccountSvc}, - {MS_YAMN_DELETEACCOUNT, DeletePluginAccountSvc}, - {MS_YAMN_READACCOUNTS, AddAccountsFromFileSvc}, - {MS_YAMN_WRITEACCOUNTS, WriteAccountsToFileSvc}, -}; - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- - -INT_PTR CreatePluginAccountSvc(WPARAM wParam, LPARAM lParam) +///////////////////////////////////////////////////////////////////////////////////////// + +CAccount* CreatePluginAccount(YAMN_PROTOPLUGIN *Plugin) { - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN *)wParam; - uint32_t AccountVersion = (uint32_t)lParam; + if (Plugin == nullptr) + return nullptr; - //test if we are going to initialize members of suitable structure (structures of plugin and YAMN must match) - if (AccountVersion != YAMN_ACCOUNTVERSION) - return NULL; + CAccount *NewAccount; + if (Plugin->Fcn->NewAccountFcnPtr != nullptr) + // Let plugin create its own structure, which can be derived from CAccount structure + NewAccount = Plugin->Fcn->NewAccountFcnPtr(Plugin); + else + // We suggest plugin uses standard CAccount structure, so we create it + NewAccount = new CAccount(); - if (Plugin != nullptr) { - CAccount *NewAccount; - if (Plugin->Fcn->NewAccountFcnPtr != nullptr) - //Let plugin create its own structure, which can be derived from CAccount structure - NewAccount = Plugin->Fcn->NewAccountFcnPtr(Plugin, YAMN_ACCOUNTVERSION); - else - //We suggest plugin uses standard CAccount structure, so we create it - NewAccount = new CAccount(); - - //If not created successfully - if (NewAccount == nullptr) - return NULL; + // If not created successfully + if (NewAccount == nullptr) + return NULL; - NewAccount->Plugin = Plugin; - //Init every members of structure, used by YAMN - InitAccount(NewAccount); + NewAccount->Plugin = Plugin; - return (INT_PTR)NewAccount; - } - return NULL; + // Init every members of structure, used by YAMN + InitAccount(NewAccount); + return NewAccount; } -INT_PTR DeletePluginAccountSvc(WPARAM wParam, LPARAM) +void DeletePluginAccount(CAccount *OldAccount) { - CAccount *OldAccount = (CAccount *)wParam; - if (OldAccount->Plugin->Fcn != nullptr) { // Deinit every members and allocated fields of structure used by YAMN DeInitAccount(OldAccount); if (OldAccount->Plugin->Fcn->DeleteAccountFcnPtr != nullptr) { // Let plugin delete its own CAccount derived structure OldAccount->Plugin->Fcn->DeleteAccountFcnPtr(OldAccount); + return; } - else { - delete OldAccount; //consider account as standard YAMN CAccount *and use its own destructor - } - return 1; } - delete OldAccount; //consider account as standard YAMN CAccount *, not initialized before and use its own destructor - return 1; + + // consider account as standard YAMN CAccount *, not initialized before and use its own destructor + delete OldAccount; } int InitAccount(CAccount *Which) @@ -105,7 +82,7 @@ int InitAccount(CAccount *Which) void DeInitAccount(CAccount *Which) { - //delete YAMN allocated fields + // delete YAMN allocated fields if (Which->Name != nullptr) delete[] Which->Name; if (Which->Server != nullptr) { @@ -122,7 +99,7 @@ void DeInitAccount(CAccount *Which) } void StopSignalFcn(CAccount *Which) -//set event that we are going to delete account +// set event that we are going to delete account { Which->AbleToWork = FALSE; @@ -156,13 +133,13 @@ static uint32_t PostFileToMemory(HANDLE File, char **MemFile, char **End) return EACC_FILESIZE; } - //allocate space in memory, where we copy the whole file + // allocate space in memory, where we copy the whole file if (nullptr == (*MemFile = new char[FileSize])) { CloseHandle(File); return EACC_ALLOC; } - //copy file to memory + // copy file to memory if (!ReadFile(File, (LPVOID)*MemFile, FileSize, &ReadBytes, nullptr)) { CloseHandle(File); delete[] * MemFile; @@ -173,7 +150,7 @@ static uint32_t PostFileToMemory(HANDLE File, char **MemFile, char **End) return 0; } -uint32_t FileToMemory(wchar_t *FileName, char **MemFile, char **End) +uint32_t FileToMemory(const wchar_t *FileName, char **MemFile, char **End) { HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) @@ -185,8 +162,8 @@ uint32_t FileToMemory(wchar_t *FileName, char **MemFile, char **End) #if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES) uint32_t ReadStringFromMemory(char **Parser, wchar_t *End, char **StoreTo, wchar_t *DebugString) { - //This is the debug version of ReadStringFromMemory function. This version shows MessageBox where - //read string is displayed + // This is the debug version of ReadStringFromMemory function. This version shows MessageBox where + // read string is displayed wchar_t *Dest, *Finder; uint32_t Size; wchar_t Debug[65536]; @@ -236,8 +213,8 @@ uint32_t ReadStringFromMemory(char **Parser, char *End, char **StoreTo) #if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES) uint32_t ReadStringFromMemoryW(wchar_t **Parser, wchar_t *End, wchar_t **StoreTo, wchar_t *DebugString) { - //This is the debug version of ReadStringFromMemoryW function. This version shows MessageBox where - //read string is displayed + // This is the debug version of ReadStringFromMemoryW function. This version shows MessageBox where + // read string is displayed wchar_t *Dest, *Finder; uint32_t Size; wchar_t Debug[65536]; @@ -260,7 +237,7 @@ uint32_t ReadStringFromMemoryW(wchar_t **Parser, wchar_t *End, wchar_t **StoreTo } return 0; } -#endif //if defined(DEBUG...) +#endif // if defined(DEBUG...) uint32_t ReadStringFromMemoryW(wchar_t **Parser, wchar_t *End, wchar_t **StoreTo) { @@ -357,7 +334,7 @@ uint32_t ReadMessagesFromMemory(CAccount *Which, char **Parser, char *End) if (Finder >= End) return EACC_FILECOMPATIBILITY; if (Size = Finder - *Parser) { - if (Which->Mails == nullptr) //First message in queue + if (Which->Mails == nullptr) // First message in queue { if (nullptr == (Which->Mails = ActualMail = CreateAccountMail(Which))) return EACC_ALLOC; @@ -375,7 +352,7 @@ uint32_t ReadMessagesFromMemory(CAccount *Which, char **Parser, char *End) if (Stat = ReadStringFromMemory(Parser, End, &ActualMail->ID)) #endif return Stat; - // ActualMail->MailData=new MAILDATA; !!! mem leake !!! this is alloc by CreateAccountMail, no need for doubble alloc !!!! + // ActualMail->MailData=new MAILDATA; !!! mem leake !!! this is alloc by CreateAccountMail, no need for doubble alloc !!!! ActualMail->MailData->Size = *(uint32_t *)(*Parser); (*Parser) += sizeof(uint32_t); @@ -391,7 +368,7 @@ uint32_t ReadMessagesFromMemory(CAccount *Which, char **Parser, char *End) return EACC_FILECOMPATIBILITY; if ((nullptr != Which->Plugin->MailFcn) && (nullptr != Which->Plugin->MailFcn->ReadMailOptsFcnPtr)) - Which->Plugin->MailFcn->ReadMailOptsFcnPtr(ActualMail, Parser, End); //read plugin mail settings from file + Which->Plugin->MailFcn->ReadMailOptsFcnPtr(ActualMail, Parser, End); // read plugin mail settings from file do { #if defined(DEBUG_FILEREADMESSAGES) || defined(DEBUG_FILEREAD) @@ -430,7 +407,7 @@ uint32_t ReadMessagesFromMemory(CAccount *Which, char **Parser, char *End) } while (1); } else - break; //no next messages, new account! + break; // no next messages, new account! } while (1); (*Parser)++; @@ -443,7 +420,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) #ifdef DEBUG_FILEREAD wchar_t Debug[65536]; #endif - //Read name of account + // Read name of account #ifdef DEBUG_FILEREAD if (Stat = ReadStringFromMemory(Parser, End, &Which->Name, L"Name")) @@ -454,7 +431,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) if (Which->Name == nullptr) return EACC_FILECOMPATIBILITY; - //Read server parameters + // Read server parameters #ifdef DEBUG_FILEREAD if (Stat = ReadStringFromMemory(Parser, End, &Which->Server->Name, L"Server")) #else @@ -483,7 +460,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) return Stat; CodeDecodeString(Which->Server->Passwd, FALSE); - //Read account flags + // Read account flags Which->Flags = *(uint32_t *)(*Parser); (*Parser) += sizeof(uint32_t); if (*Parser >= End) @@ -505,9 +482,9 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) MessageBox(NULL, Debug, L"debug", MB_OK); #endif - //Read account miscellaneous parameters + // Read account miscellaneous parameters Which->Interval = *(uint16_t *)(*Parser); - Which->TimeLeft = Which->Interval; //check on loading + Which->TimeLeft = Which->Interval; // check on loading (*Parser) += sizeof(uint16_t); if (*Parser >= End) return EACC_FILECOMPATIBILITY; @@ -516,7 +493,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) MessageBox(NULL, Debug, L"debug", MB_OK); #endif - //Read notification parameters + // Read notification parameters if (Stat = ReadNotificationFromMemory(Parser, End, &Which->NewMailN)) return Stat; if (Stat = ReadNotificationFromMemory(Parser, End, &Which->NoNewMailN)) @@ -524,7 +501,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) if (Stat = ReadNotificationFromMemory(Parser, End, &Which->BadConnectN)) return Stat; - //Let plugin read its own data stored in file + // Let plugin read its own data stored in file if (Which->Plugin->Fcn != nullptr && Which->Plugin->Fcn->ReadPluginOptsFcnPtr != nullptr) if (Stat = Which->Plugin->Fcn->ReadPluginOptsFcnPtr(Which, Parser, End)) return Stat; @@ -554,7 +531,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) Which->LastMail = *(SYSTEMTIME *)(*Parser); (*Parser) += sizeof(SYSTEMTIME); - if (*Parser > End) //WARNING! There's only > at the end of testing + if (*Parser > End) // WARNING! There's only > at the end of testing return EACC_FILECOMPATIBILITY; if (*Parser == End) @@ -562,7 +539,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End) return 0; } -static INT_PTR PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, char *End) +static uint32_t PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, char *End) { // Retrieve info for account from memory char *Parser; @@ -578,7 +555,7 @@ static INT_PTR PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, ch Parser = MemFile + sizeof(Ver); { SWriteGuard swb(Plugin->AccountBrowserSO); - if (nullptr == (ActualAccount = (CAccount *)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)Plugin, (LPARAM)YAMN_ACCOUNTVERSION))) { + if (nullptr == (ActualAccount = GetNextFreeAccount(Plugin))) { delete[] MemFile; return EACC_ALLOC; } @@ -593,7 +570,7 @@ static INT_PTR PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, ch Stat = ReadAccountFromMemory(ActualAccount, &Parser, End); if (ActualAccount->StatusFlags & (YAMN_ACC_STARTA | YAMN_ACC_STARTS)) - ActualAccount->TimeLeft = 1; //check on loading + ActualAccount->TimeLeft = 1; // check on loading if (Stat && (Stat != EACC_ENDOFFILE)) { for (ActualAccount = FirstAllocatedAccount; ActualAccount != nullptr; ActualAccount = Temp) { @@ -608,7 +585,7 @@ static INT_PTR PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, ch } } - if ((Stat != EACC_ENDOFFILE) && (nullptr == (ActualAccount = (CAccount *)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)Plugin, (LPARAM)YAMN_ACCOUNTVERSION)))) { + if ((Stat != EACC_ENDOFFILE) && (nullptr == (ActualAccount = GetNextFreeAccount(Plugin)))) { for (ActualAccount = FirstAllocatedAccount; ActualAccount != nullptr; ActualAccount = Temp) { Temp = ActualAccount->Next; delete ActualAccount; @@ -626,14 +603,14 @@ static INT_PTR PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, ch } // Add accounts from file to memory -INT_PTR AddAccountsFromFileSvc(WPARAM wParam, LPARAM lParam) +uint32_t AddAccountsFromFile(YAMN_PROTOPLUGIN *Plugin, const wchar_t *pwszFilename) { char *MemFile, *End; - uint32_t Stat = FileToMemory((wchar_t *)lParam, &MemFile, &End); + uint32_t Stat = FileToMemory(pwszFilename, &MemFile, &End); if (Stat != NO_ERROR) - return (INT_PTR)Stat; + return Stat; - return PerformAccountReading((YAMN_PROTOPLUGIN *)wParam, MemFile, End); + return PerformAccountReading(Plugin, MemFile, End); } uint32_t WriteStringToFile(HANDLE File, char *Source) @@ -685,7 +662,7 @@ DWORD WriteMessagesToFile(HANDLE File, CAccount *Which) !WriteFile(File, (char *)&ActualMail->Number, sizeof(ActualMail->Number), &WrittenBytes, nullptr)) return EACC_SYSTEM; if ((nullptr != Which->Plugin->MailFcn) && (nullptr != Which->Plugin->MailFcn->WriteMailOptsFcnPtr)) - Which->Plugin->MailFcn->WriteMailOptsFcnPtr(File, ActualMail); //write plugin mail options to file + Which->Plugin->MailFcn->WriteMailOptsFcnPtr(File, ActualMail); // write plugin mail options to file for (items = ActualMail->MailData->TranslatedHeader; items != nullptr; items = items->Next) { if (Stat = WriteStringToFile(File, items->name)) return Stat; @@ -714,12 +691,12 @@ static INT_PTR PerformAccountWriting(YAMN_PROTOPLUGIN *Plugin, HANDLE File) try { for (ActualAccount = Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) { SReadGuard sra(ActualAccount->AccountAccessSO); - if (sra == WAIT_FINISH) { //account is about to delete + if (sra == WAIT_FINISH) { // account is about to delete ActualAccount = ActualAccount->Next; continue; } - if (sra == WAIT_FAILED) //account is deleted + if (sra == WAIT_FAILED) // account is deleted break; if ((ActualAccount->Name == nullptr) || (*ActualAccount->Name == (wchar_t)0)) @@ -788,7 +765,7 @@ static INT_PTR PerformAccountWriting(YAMN_PROTOPLUGIN *Plugin, HANDLE File) (Stat = WriteStringToFileW(File, ActualAccount->BadConnectN.AppParam))) throw (uint32_t)Stat; - //Let plugin write its own values into file + // Let plugin write its own values into file if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->WritePluginOptsFcnPtr != nullptr) if (Stat = ActualAccount->Plugin->Fcn->WritePluginOptsFcnPtr(File, ActualAccount)) throw (uint32_t)Stat; @@ -812,113 +789,102 @@ static INT_PTR PerformAccountWriting(YAMN_PROTOPLUGIN *Plugin, HANDLE File) } // Writes accounts to file -INT_PTR WriteAccountsToFileSvc(WPARAM wParam, LPARAM lParam) +uint32_t WriteAccountsToFile(YAMN_PROTOPLUGIN *Plugin, const wchar_t *pwszFilename) { - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam; - mir_cslock lck(csFileWritingCS); - HANDLE hFile = CreateFile((wchar_t *)lParam, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + HANDLE hFile = CreateFile(pwszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) return EACC_SYSTEM; return PerformAccountWriting(Plugin, hFile); } -INT_PTR FindAccountByNameSvc(WPARAM wParam, LPARAM lParam) +CAccount* FindAccountByName(YAMN_PROTOPLUGIN *Plugin, const char *SearchedAccount) { - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam; - char *SearchedAccount = (char *)lParam; - SReadGuard srb(Plugin->AccountBrowserSO); for (auto *Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next) if ((Finder->Name != nullptr) && (0 == mir_strcmp(SearchedAccount, Finder->Name))) - return (INT_PTR)Finder; + return Finder; - return 0; + return nullptr; } -INT_PTR GetNextFreeAccountSvc(WPARAM wParam, LPARAM lParam) +CAccount* GetNextFreeAccount(YAMN_PROTOPLUGIN *Plugin) { - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam; - CAccount *Finder; - if (Plugin->FirstAccount == nullptr) { - Plugin->FirstAccount = (CAccount *)CallService(MS_YAMN_CREATEPLUGINACCOUNT, wParam, lParam); - return (INT_PTR)Plugin->FirstAccount; + Plugin->FirstAccount = CreatePluginAccount(Plugin); + return Plugin->FirstAccount; } + + CAccount *Finder; for (Finder = Plugin->FirstAccount; Finder->Next != nullptr; Finder = Finder->Next); - Finder->Next = (CAccount *)CallService(MS_YAMN_CREATEPLUGINACCOUNT, wParam, lParam); - return (INT_PTR)Finder->Next; + Finder->Next = CreatePluginAccount(Plugin); + return Finder->Next; } -INT_PTR DeleteAccountSvc(WPARAM wParam, LPARAM lParam) -{ - //Deleting account works on these steps: - //1. set signal that account should stop activity (set event) - // setting this event we achieve, that any access to account is failed, - // so threads do not start any work with accounts (better saying threads of plugins should not start) - //2. wait to get write access to chained list of accounts - //3. we can write to chained list, so we change chain not to show to actual account - // now, any thread browsing list of accounts does not browse through actual account - // actual account seems to be hidden (it exists, but it is not in accounts chained list (chained list=queue)) - //Now, we should delete account from memory, BUT!!! - // Any thread can still be waked up and start asking account synchronizing object - // If account is deleted, asking about access to read account can throw memory exception (reading for - // a synchronizing object from memory, that was deleted) - //So, we cannot now delete account. We have to wait until we are sure no thread will be using account anymore - // (or to the end of Miranda, but problem is in allocated memory- it is allocated and Miranda is SMALLER, faster, easier, isn't it?) - // This deleting is achieved in 2 ways: - // We have event in UsingThreads synchronization objects. This event signals that no thread will use actual account - // 1. Any thread using account first increment UsingThread, so we know that account is used - // 2. If thread is about to close, it should decrement UsingThread - // 3. If thread creates another thread, that will use account, caller has to wait until the new thread does not - // increment UsingThreads (imagine that caller ends before the new thread set it: if no other thread is using - // account, account is automaticaly (decreasing UsingThreads) signaled as "not used" and we delete it. But then - // new thread is going to read account...). - //4. wait until UsingThread Event is signaled - //5. delete account from memory - - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam; - CAccount *Which = (CAccount *)lParam; - CAccount *Finder; - - //1. set stop signal +// Deleting account works on these steps: +// 1. set signal that account should stop activity (set event) +// setting this event we achieve, that any access to account is failed, +// so threads do not start any work with accounts (better saying threads of plugins should not start) +// 2. wait to get write access to chained list of accounts +// 3. we can write to chained list, so we change chain not to show to actual account +// now, any thread browsing list of accounts does not browse through actual account +// actual account seems to be hidden (it exists, but it is not in accounts chained list (chained list=queue)) +// Now, we should delete account from memory, BUT!!! +// Any thread can still be waked up and start asking account synchronizing object +// If account is deleted, asking about access to read account can throw memory exception (reading for +// a synchronizing object from memory, that was deleted) +// So, we cannot now delete account. We have to wait until we are sure no thread will be using account anymore +// (or to the end of Miranda, but problem is in allocated memory- it is allocated and Miranda is SMALLER, faster, easier, isn't it?) +// This deleting is achieved in 2 ways: +// We have event in UsingThreads synchronization objects. This event signals that no thread will use actual account +// 1. Any thread using account first increment UsingThread, so we know that account is used +// 2. If thread is about to close, it should decrement UsingThread +// 3. If thread creates another thread, that will use account, caller has to wait until the new thread does not +// increment UsingThreads (imagine that caller ends before the new thread set it: if no other thread is using +// account, account is automaticaly (decreasing UsingThreads) signaled as "not used" and we delete it. But then +// new thread is going to read account...). +// 4. wait until UsingThread Event is signaled +// 5. delete account from memory + +int DeleteAccount(YAMN_PROTOPLUGIN *Plugin, CAccount *Which) +{ + // 1. set stop signal StopSignalFcn(Which); WindowList_BroadcastAsync(YAMNVar.MessageWnds, WM_YAMN_STOPACCOUNT, (WPARAM)Which, 0); if (Plugin->Fcn->StopAccountFcnPtr != nullptr) Plugin->Fcn->StopAccountFcnPtr(Which); - { - // 2. wait to get write access + { // 2. wait to get write access SWriteGuard swb(Plugin->AccountBrowserSO); // 3. remove from queue (chained list) - if (Plugin->FirstAccount == nullptr) { + if (Plugin->FirstAccount == nullptr) return 0; - } + if (Plugin->FirstAccount == Which) { - Finder = Plugin->FirstAccount->Next; - Plugin->FirstAccount = Finder; + Plugin->FirstAccount = Plugin->FirstAccount->Next; } else { + CAccount *Finder; for (Finder = Plugin->FirstAccount; Which != Finder->Next; Finder = Finder->Next); Finder->Next = Finder->Next->Next; } } - //4. wait while event "UsingThread" is not signaled - // And what to do, if this event will be signaled in 1 hour? (Although it's paranoia, because we have sent "delete signal", so - // other threads do not start any new work with actual account) We will wait in blocked state? - // No, of course not. We will create new thread, that will wait and additionally remove our thread in background. - //5. So, the last point (deleting from memory) is performed in new DeleteAccountInBackground thread + // 4. wait while event "UsingThread" is not signaled + // And what to do, if this event will be signaled in 1 hour? (Although it's paranoia, because we have sent "delete signal", so + // other threads do not start any new work with actual account) We will wait in blocked state? + // No, of course not. We will create new thread, that will wait and additionally remove our thread in background. + // 5. So, the last point (deleting from memory) is performed in new DeleteAccountInBackground thread if ((Plugin->Fcn != nullptr) && (Plugin->Fcn->WriteAccountsFcnPtr != nullptr)) Plugin->Fcn->WriteAccountsFcnPtr(); CloseHandle(mir_forkthread(DeleteAccountInBackground, (void *)Which)); - //Now, plugin can consider account as deleted, but plugin really can achieve deleting this account from memory when using - //event UsingThreads. + // Now, plugin can consider account as deleted, but plugin really can achieve deleting this account from memory when using + // event UsingThreads. return 1; } @@ -926,41 +892,41 @@ void __cdecl DeleteAccountInBackground(void *Value) { CAccount *Which = (CAccount *)Value; WaitForSingleObject(Which->UsingThreads.GetEvent(), INFINITE); - CallService(MS_YAMN_DELETEPLUGINACCOUNT, (WPARAM)Which, 0); + DeletePluginAccount(Which); } int StopAccounts(YAMN_PROTOPLUGIN *Plugin) { CAccount *Finder; - //1. wait to get write access + // 1. wait to get write access SWriteGuard swb(Plugin->AccountBrowserSO); for (Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next) { - //2. set stop signal + // 2. set stop signal StopSignalFcn(Finder); WindowList_BroadcastAsync(YAMNVar.MessageWnds, WM_YAMN_STOPACCOUNT, (WPARAM)Finder, 0); if (Plugin->Fcn->StopAccountFcnPtr != nullptr) Plugin->Fcn->StopAccountFcnPtr(Finder); } - //Now, account is stopped. It can be removed from memory... + // Now, account is stopped. It can be removed from memory... return 1; } int WaitForAllAccounts(YAMN_PROTOPLUGIN *Plugin, BOOL GetAccountBrowserAccess) { if (GetAccountBrowserAccess) { - //1. wait to get write access + // 1. wait to get write access Plugin->AccountBrowserSO.WaitToWrite(); } for (CAccount *Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next) { - //2. wait for signal that account is not in use + // 2. wait for signal that account is not in use WaitForSingleObject(Finder->UsingThreads.GetEvent(), INFINITE); SetEvent(Finder->UsingThreads.GetEvent()); } if (GetAccountBrowserAccess) { - //leave write access + // leave write access Plugin->AccountBrowserSO.DoneWriting(); } @@ -975,13 +941,13 @@ int DeleteAccounts(YAMN_PROTOPLUGIN *Plugin) for (CAccount *Finder = Plugin->FirstAccount; Finder != nullptr;) { CAccount *Next = Finder->Next; - DeletePluginAccountSvc((WPARAM)Finder, 0); + DeletePluginAccount(Finder); Finder = Next; } return 1; } -void WINAPI GetStatusFcn(CAccount *Which, wchar_t *Value) +void GetStatusFcn(CAccount *Which, wchar_t *Value) { if (Which == nullptr) return; @@ -990,7 +956,7 @@ void WINAPI GetStatusFcn(CAccount *Which, wchar_t *Value) mir_wstrcpy(Value, Which->Status); } -void WINAPI SetStatusFcn(CAccount *Which, wchar_t *Value) +void SetStatusFcn(CAccount *Which, wchar_t *Value) { if (Which != nullptr) { mir_cslock lck(csAccountStatusCS); diff --git a/protocols/YAMN/src/browser/mailbrowser.cpp b/protocols/YAMN/src/browser/mailbrowser.cpp index 1a320322ec..beea20ea18 100644 --- a/protocols/YAMN/src/browser/mailbrowser.cpp +++ b/protocols/YAMN/src/browser/mailbrowser.cpp @@ -336,19 +336,14 @@ int UpdateMails(HWND hDlg, CAccount *ActualAccount, uint32_t nflags, uint32_t nn memset(&MN, 0, sizeof(MN)); for (HYAMNMAIL msgq = (HYAMNMAIL)ActualAccount->Mails; msgq != nullptr; msgq = msgq->Next) { - if (!LoadedMailData(msgq)) //check if mail is already in memory - { + if (!LoadedMailData(msgq)) { // check if mail is already in memory Loaded = false; - if (nullptr == LoadMailData(msgq)) //if we could not load mail to memory, consider this mail deleted and do not display it + if (nullptr == msgq->MailData) // if we could not load mail to memory, consider this mail deleted and do not display it continue; } - else - Loaded = true; + else Loaded = true; IncrementMailCounters(msgq, &MN); - - if (!Loaded) - UnloadMailData(msgq); //do not keep data for mail in memory } if (mwui != nullptr) @@ -497,7 +492,7 @@ int AddNewMailsToListView(HWND hListView, CAccount *ActualAccount, uint32_t nfla if (!LoadedMailData(msgq)) { // check if mail is already in memory Loaded = false; - if (nullptr == LoadMailData(msgq)) //if we could not load mail to memory, consider this mail deleted and do not display it + if (nullptr == msgq->MailData) //if we could not load mail to memory, consider this mail deleted and do not display it continue; } else Loaded = true; @@ -575,11 +570,6 @@ int AddNewMailsToListView(HWND hListView, CAccount *ActualAccount, uint32_t nfla DeleteHeaderContent(&UnicodeHeader); memset(&UnicodeHeader, 0, sizeof(UnicodeHeader)); } - - if (!Loaded) { - SaveMailData(msgq); - UnloadMailData(msgq); //do not keep data for mail in memory - } } return TRUE; @@ -765,12 +755,11 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa mir_forkthread(ShowEmailThread, MailParam); } else { - DBVARIANT dbv; - hContact = PUGetContact(hWnd); + DBVARIANT dbv; if (!g_plugin.getString(hContact, "Id", &dbv)) { - Account = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); + Account = FindAccountByName(POP3Plugin, dbv.pszVal); db_free(&dbv); } else Account = (CAccount *)hContact; //???? @@ -819,7 +808,7 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa MCONTACT hContact = PUGetContact(hWnd); if (!g_plugin.getString(hContact, "Id", &dbv)) { - ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); + ActualAccount = FindAccountByName(POP3Plugin, dbv.pszVal); db_free(&dbv); } else ActualAccount = (CAccount *)hContact; @@ -846,7 +835,7 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l DBVARIANT dbv; CAccount *ActualAccount; if (!g_plugin.getString(hContact, "Id", &dbv)) { - ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); + ActualAccount = FindAccountByName(POP3Plugin, dbv.pszVal); db_free(&dbv); } else ActualAccount = (CAccount *)hContact; @@ -895,11 +884,10 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l MCONTACT hContact = PUGetContact(hWnd); if (!g_plugin.getString(hContact, "Id", &dbv)) { - ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); + ActualAccount = FindAccountByName(POP3Plugin, dbv.pszVal); db_free(&dbv); } - else - ActualAccount = (CAccount *)hContact; + else ActualAccount = (CAccount *)hContact; if ((CAccount *)wParam != ActualAccount) break; @@ -1697,7 +1685,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR if ((Parser->Flags & YAMN_MSG_DELETED) && YAMN_MSG_SPAML(Parser->Flags, YAMN_MSG_SPAML3) && mwui->Seen) //if spaml3 was already deleted and user knows about it { DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails, Parser, 1); - CallService(MS_YAMN_DELETEACCOUNTMAIL, (WPARAM)ActualAccount->Plugin, (LPARAM)Parser); + DeleteAccountMail(ActualAccount->Plugin, Parser); } } @@ -1944,7 +1932,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR if ((ActualMail->Flags & YAMN_MSG_DELETED) && ((ActualMail->Flags & YAMN_MSG_USERDELETE))) //if selected mail was already deleted { DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails, ActualMail, 1); - CallService(MS_YAMN_DELETEACCOUNTMAIL, (WPARAM)ActualAccount->Plugin, (LPARAM)ActualMail); //delete it from memory + DeleteAccountMail(ActualAccount->Plugin, ActualMail); //delete it from memory continue; } } diff --git a/protocols/YAMN/src/mails/mails.cpp b/protocols/YAMN/src/mails/mails.cpp index 87a4faaf42..606a21ebbd 100644 --- a/protocols/YAMN/src/mails/mails.cpp +++ b/protocols/YAMN/src/mails/mails.cpp @@ -6,142 +6,40 @@ #include "../stdafx.h" - //-------------------------------------------------------------------------------------------------- - //-------------------------------------------------------------------------------------------------- +///////////////////////////////////////////////////////////////////////////////////////// +// Creates new mail for plugin (calling plugin's constructor, when plugin imported to YAMN) - // SMALL INTRO - // Mails are queued in a queue (chained list). Pointer to first mail is pointed from Account structure - // member called Mails. - // Mail queue is ended with NULL- pointered mail (NULL handle) - - //Creates new mail for plugin (calling plugin's constructor, when plugin imported to YAMN) -INT_PTR CreateAccountMailSvc(WPARAM wParam, LPARAM lParam); - -//Deletes mail for plugin (calling plugin's destructor, when plugin imported to YAMN) -INT_PTR DeleteAccountMailSvc(WPARAM wParam, LPARAM lParam); - -//Loads mail data from standard storage to memory -INT_PTR LoadMailDataSvc(WPARAM wParam, LPARAM lParam); - -//Deletes mail data from memory -INT_PTR UnloadMailDataSvc(WPARAM wParam, LPARAM); - -//Saves mail data from memory to standard storage -INT_PTR SaveMailDataSvc(WPARAM wParam, LPARAM lParam); - -//Appends second MIME mail queue to the first one -//Only finds the end of first queue and its Next memember repoints to second one -void WINAPI AppendQueueFcn(HYAMNMAIL first, HYAMNMAIL second); - -//Synchronizes two accounts -//Function finds, if there were some mails deleted from mailbox and deletes (depends on RemovedOld param) them from OldQueue -//Next finds, if there are new mails. Mails that are still on mailbox are deleted (depends on RemovedNew param) from NewQueue -//After this, OldQueue is pointer to mails that are on mailbox, but not new mails -//and NewQueue contains new mails in account -//New accounts can be then appended to account mails queue, but they have set the New flag -// -//Two mails equals if they have the same ID -// -// hPlugin- handle of plugin going to delete mails -// OldQueue- queue of mails that we found on mailbox last time, after function finishes queue contains all mails except new ones -// RemovedOld- queue of mails where to store removed mails from OldQueue, if NULL deletes mails from OldQueue -// NewQueue- queue of mails that we found on mailbox (all mails), after function finishes queue contains only new mails -// RemovedNew- queue of mails where to store removed mails from NewQueue, if NULL deletes mails from NewQueue -//So function works like: -//1. delete (or move to RemovedOld queue if RemovedOld is not NULL) all mails from OldQueue not found in NewQueue -//2. delete (or move to RemovedNew queue if RemovedNew is not NULL) all mails from NewQueue found in OldQueue -void WINAPI SynchroMessagesFcn(CAccount *Account, HYAMNMAIL *OldQueue, HYAMNMAIL *RemovedOld, HYAMNMAIL *NewQueue, HYAMNMAIL *RemovedNew); - -//Deletes messages from mail From to the end -// Account- account who owns mails -// From- first mail in queue, which is going to delete -void WINAPI DeleteMessagesToEndFcn(CAccount *Account, HYAMNMAIL From); - -//Removes message from queue, does not delete from memory -// From- queue pointer -// Which- mail to delete -// mode- nonzero if you want to decrement numbers in messages that are bigger than the one in Which mail, 0 if not -void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode); - -//Finds message in queue that has the same ID number -// From- message queue -// ID- pointer to ID -// returns pointer to found message, NULL if not found -HYAMNMAIL WINAPI FindMessageByIDFcn(HYAMNMAIL From, char *ID); - -//Translate header from text to queue of CMimeItem structures -//This means that new queue will contain all info about headers -// stream- pointer to text containing header (can be ended with zero) -// len- length of stream -// head- function fills this pointer to first header item in queue -void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head); - -//Creates new mail queue, copying only these mails, that have set flag for deleting -// From- message queue, whose mail with given flag are duplicated -// returns new mail queue (or NULL when no mail with flag is in From queue) -//Function does not copy the whole mails, it copies only ID string. And ID is copied as string, so -//you can use this fcn only if you have your ID as pointer to char string ended with zero character -HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From); - -//Sets/removes flags from specific mails -// From- pointer to first message -// FlagsSet- mail must have set these flags... -// FlagsNotSet- ...and must not have set these flags... -// FlagsToSetRemove- ...to set/remove these flags (see mode) -// mode- nonzero to set, else remove -void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From, uint32_t FlagsSet, uint32_t FlagsNotSet, uint32_t FlagsToSetRemove, int mode); - -struct CExportedServices MailExportedSvc[] = -{ - {MS_YAMN_CREATEACCOUNTMAIL, CreateAccountMailSvc}, - {MS_YAMN_DELETEACCOUNTMAIL, DeleteAccountMailSvc}, - {MS_YAMN_LOADMAILDATA, LoadMailDataSvc}, - {MS_YAMN_UNLOADMAILDATA, UnloadMailDataSvc}, - {MS_YAMN_SAVEMAILDATA, SaveMailDataSvc}, -}; - - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- - -INT_PTR CreateAccountMailSvc(WPARAM wParam, LPARAM lParam) +HYAMNMAIL CreateAccountMail(CAccount *Account) { - CAccount *Account = (CAccount *)wParam; - uint32_t MailVersion = (uint32_t)lParam; HYAMNMAIL NewMail; - //test if we are going to initialize members of suitable structure (structures of plugin and YAMN must match) - if (MailVersion != YAMN_MAILVERSION) + if (Account->Plugin == nullptr) return NULL; - if (Account->Plugin != nullptr) { - if (Account->Plugin->MailFcn->NewMailFcnPtr != nullptr) { - //Let plugin create its own structure, which can be derived from CAccount structure - if (nullptr == (NewMail = Account->Plugin->MailFcn->NewMailFcnPtr(Account, YAMN_MAILVERSION))) - return NULL; - } - else { - //We suggest plugin uses standard CAccount structure, so we create it - if (nullptr == (NewMail = new YAMNMAIL)) - //If not created successfully - return NULL; - NewMail->MailData = nullptr; - } - //Init every members of structure, used by YAMN - return (INT_PTR)NewMail; + if (Account->Plugin->MailFcn->NewMailFcnPtr != nullptr) { + // Let plugin create its own structure, which can be derived from CAccount structure + if (nullptr == (NewMail = Account->Plugin->MailFcn->NewMailFcnPtr(Account))) + return NULL; } - return NULL; + else { + // We suggest plugin uses standard CAccount structure, so we create it + NewMail = new YAMNMAIL(); + NewMail->MailData = nullptr; + } + // Init every members of structure, used by YAMN + return NewMail; } -INT_PTR DeleteAccountMailSvc(WPARAM wParam, LPARAM lParam) +///////////////////////////////////////////////////////////////////////////////////////// +// Deletes mail for plugin (calling plugin's destructor, when plugin imported to YAMN) + +int DeleteAccountMail(YAMN_PROTOPLUGIN *Plugin, HYAMNMAIL OldMail) { - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam; - HYAMNMAIL OldMail = (HYAMNMAIL)lParam; struct CMimeItem *TH; if (Plugin->MailFcn != nullptr) { if (Plugin->MailFcn->DeleteMailFcnPtr != nullptr) { - //Let plugin delete its own CMimeMsgQueue derived structure + // Let plugin delete its own CMimeMsgQueue derived structure Plugin->MailFcn->DeleteMailFcnPtr(OldMail); return 1; } @@ -164,10 +62,13 @@ INT_PTR DeleteAccountMailSvc(WPARAM wParam, LPARAM lParam) if (OldMail->ID != nullptr) delete[] OldMail->ID; - delete OldMail; //consider mail as standard HYAMNMAIL, not initialized before and use its own destructor + delete OldMail; // consider mail as standard HYAMNMAIL, not initialized before and use its own destructor return 1; } +///////////////////////////////////////////////////////////////////////////////////////// +// Appends second MIME mail queue to the first one +// Only finds the end of first queue and its Next memember repoints to second one void WINAPI AppendQueueFcn(HYAMNMAIL first, HYAMNMAIL second) { @@ -176,39 +77,31 @@ void WINAPI AppendQueueFcn(HYAMNMAIL first, HYAMNMAIL second) Finder->Next = second; } -INT_PTR LoadMailDataSvc(WPARAM wParam, LPARAM lParam) -{ - HYAMNMAIL Mail = (HYAMNMAIL)wParam; - uint32_t MailVersion = (uint32_t)lParam; - - if (MailVersion != YAMN_MAILDATAVERSION) - return NULL; - - // now we have all data to memory persisting, so no loading is needed - return (INT_PTR)Mail->MailData; -} - -INT_PTR UnloadMailDataSvc(WPARAM, LPARAM) -{ - return 1; -} - -INT_PTR SaveMailDataSvc(WPARAM, LPARAM lParam) -{ - uint32_t MailVersion = (uint32_t)lParam; - - if (MailVersion != YAMN_MAILDATAVERSION) - return (INT_PTR)-1; - - // now we have all data to memory persisting, so no saving is needed - return (INT_PTR)0; -} +///////////////////////////////////////////////////////////////////////////////////////// +// Synchronizes two accounts +// +// Function finds, if there were some mails deleted from mailbox and deletes (depends on RemovedOld param) them from OldQueue +// Next finds, if there are new mails. Mails that are still on mailbox are deleted (depends on RemovedNew param) from NewQueue +// After this, OldQueue is pointer to mails that are on mailbox, but not new mails +// and NewQueue contains new mails in account +// New accounts can be then appended to account mails queue, but they have set the New flag +// +// Two mails equals if they have the same ID +// +// hPlugin- handle of plugin going to delete mails +// OldQueue- queue of mails that we found on mailbox last time, after function finishes queue contains all mails except new ones +// RemovedOld- queue of mails where to store removed mails from OldQueue, if NULL deletes mails from OldQueue +// NewQueue- queue of mails that we found on mailbox (all mails), after function finishes queue contains only new mails +// RemovedNew- queue of mails where to store removed mails from NewQueue, if NULL deletes mails from NewQueue +// So function works like: +// 1. delete (or move to RemovedOld queue if RemovedOld is not NULL) all mails from OldQueue not found in NewQueue +// 2. delete (or move to RemovedNew queue if RemovedNew is not NULL) all mails from NewQueue found in OldQueue void WINAPI SynchroMessagesFcn(CAccount *Account, HYAMNMAIL *OldQueue, HYAMNMAIL *RemovedOld, HYAMNMAIL *NewQueue, HYAMNMAIL *RemovedNew) -//deletes messages from new queue, if they are old -//it also deletes messages from old queue, if they are not in mailbox anymore -//"YAMN_MSG_DELETED" messages in old queue remain in old queue (are never removed, although they are not in new queue) -//"YAMN_MSG_DELETED" messages in new queue remain in new queue (are never removed, although they can be in old queue) +// deletes messages from new queue, if they are old +// it also deletes messages from old queue, if they are not in mailbox anymore +// "YAMN_MSG_DELETED" messages in old queue remain in old queue (are never removed, although they are not in new queue) +// "YAMN_MSG_DELETED" messages in new queue remain in new queue (are never removed, although they can be in old queue) { HYAMNMAIL Finder, FinderPrev; HYAMNMAIL Parser, ParserPrev; @@ -218,73 +111,70 @@ void WINAPI SynchroMessagesFcn(CAccount *Account, HYAMNMAIL *OldQueue, HYAMNMAIL if (RemovedNew != nullptr) *RemovedNew = nullptr; for (FinderPrev = nullptr, Finder = *OldQueue; Finder != nullptr;) { - if (Finder->Flags & YAMN_MSG_DELETED) //if old queue contains deleted mail + if (Finder->Flags & YAMN_MSG_DELETED) // if old queue contains deleted mail { FinderPrev = Finder; - Finder = Finder->Next; //get next message in old queue for testing + Finder = Finder->Next; // get next message in old queue for testing continue; } for (ParserPrev = nullptr, Parser = *NewQueue; Parser != nullptr; ParserPrev = Parser, Parser = Parser->Next) { if (Parser->Flags & YAMN_MSG_DELETED) continue; - if (Parser->ID == nullptr) //simply ignore the message, that has not filled its ID + if (Parser->ID == nullptr) // simply ignore the message, that has not filled its ID continue; - if (0 == mir_strcmp(Parser->ID, Finder->ID)) //search for equal message in new queue + if (0 == mir_strcmp(Parser->ID, Finder->ID)) // search for equal message in new queue break; } - if (Parser != nullptr) //found equal message in new queue - { + + if (Parser != nullptr) { // found equal message in new queue if (Parser == *NewQueue) *NewQueue = (*NewQueue)->Next; else ParserPrev->Next = Parser->Next; - Finder->Number = Parser->Number; //rewrite the number of current message in old queue - - if (RemovedNew == nullptr) //delete from new queue - DeleteAccountMailSvc((WPARAM)Account->Plugin, (LPARAM)Parser); - else //or move to RemovedNew - { - if (RemovedNewParser == nullptr) //if it is first mail removed from NewQueue - *RemovedNew = Parser; //set RemovedNew queue to point to first message in removed queue + Finder->Number = Parser->Number; // rewrite the number of current message in old queue + + if (RemovedNew == nullptr) // delete from new queue + DeleteAccountMail(Account->Plugin, Parser); + else { // or move to RemovedNew + if (RemovedNewParser == nullptr) // if it is first mail removed from NewQueue + *RemovedNew = Parser; // set RemovedNew queue to point to first message in removed queue else - RemovedNewParser->Next = Parser; //else don't forget to show to next message in RemovedNew queue - RemovedNewParser = Parser; //follow RemovedNew queue + RemovedNewParser->Next = Parser; // else don't forget to show to next message in RemovedNew queue + RemovedNewParser = Parser; // follow RemovedNew queue RemovedNewParser->Next = nullptr; } FinderPrev = Finder; - Finder = Finder->Next; //get next message in old queue for testing + Finder = Finder->Next; // get next message in old queue for testing } - else //a message was already deleted from mailbox - { - if (Finder == *OldQueue) //if we are at the first item in OldQueue - { - *OldQueue = (*OldQueue)->Next; //set OldQueue to next item - if (RemovedOld == nullptr) //delete from old queue - DeleteAccountMailSvc((WPARAM)Account->Plugin, (LPARAM)Finder); - else //or move to RemovedOld - { - if (RemovedOldParser == nullptr) //if it is first mail removed from OldQueue - *RemovedOld = Finder; //set RemovedOld queue to point to first message in removed queue + else { // a message was already deleted from mailbox + if (Finder == *OldQueue) { // if we are at the first item in OldQueue + *OldQueue = (*OldQueue)->Next; // set OldQueue to next item + if (RemovedOld == nullptr) // delete from old queue + DeleteAccountMail(Account->Plugin, Finder); + else { // or move to RemovedOld + if (RemovedOldParser == nullptr) // if it is first mail removed from OldQueue + *RemovedOld = Finder; // set RemovedOld queue to point to first message in removed queue else - RemovedOldParser->Next = Finder; //else don't forget to show to next message in RemovedNew queue - RemovedOldParser = Finder; //follow RemovedOld queue + RemovedOldParser->Next = Finder; // else don't forget to show to next message in RemovedNew queue + RemovedOldParser = Finder; // follow RemovedOld queue RemovedOldParser->Next = nullptr; } Finder = *OldQueue; } else { FinderPrev->Next = Finder->Next; - if (RemovedOld == nullptr) //delete from old queue - DeleteAccountMailSvc((WPARAM)Account->Plugin, (LPARAM)Finder); - else //or move to RemovedOld - { - if (RemovedOldParser == nullptr) //if it is first mail removed from OldQueue - *RemovedOld = Finder; //set RemovedOld queue to point to first message in removed queue + // delete from old queue + if (RemovedOld == nullptr) + DeleteAccountMail(Account->Plugin, Finder); + // or move to RemovedOld + else { + if (RemovedOldParser == nullptr) // if it is first mail removed from OldQueue + *RemovedOld = Finder; // set RemovedOld queue to point to first message in removed queue else - RemovedOldParser->Next = Finder; //else don't forget to show to next message in RemovedNew queue - RemovedOldParser = Finder; //follow RemovedOld queue + RemovedOldParser->Next = Finder; // else don't forget to show to next message in RemovedNew queue + RemovedOldParser = Finder; // follow RemovedOld queue RemovedOldParser->Next = nullptr; } Finder = FinderPrev->Next; @@ -293,16 +183,27 @@ void WINAPI SynchroMessagesFcn(CAccount *Account, HYAMNMAIL *OldQueue, HYAMNMAIL } } +///////////////////////////////////////////////////////////////////////////////////////// +// Deletes messages from mail From to the end +// Account- account who owns mails +// From- first mail in queue, which is going to delete + void WINAPI DeleteMessagesToEndFcn(CAccount *Account, HYAMNMAIL From) { HYAMNMAIL Temp; while (From != nullptr) { Temp = From; From = From->Next; - DeleteAccountMailSvc((WPARAM)Account->Plugin, (LPARAM)Temp); + DeleteAccountMail(Account->Plugin, Temp); } } +///////////////////////////////////////////////////////////////////////////////////////// +// Removes message from queue, does not delete from memory +// From- queue pointer +// Which- mail to delete +// mode- nonzero if you want to decrement numbers in messages that are bigger than the one in Which mail, 0 if not + void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode) { uint32_t Number = Which->Number; @@ -332,6 +233,12 @@ void DeleteMessagesFromQueue(HYAMNMAIL *From, HYAMNMAIL Which, int mode = 0) DeleteMessageFromQueueFcn(From, Parser, mode); } +///////////////////////////////////////////////////////////////////////////////////////// +// Finds message in queue that has the same ID number +// From- message queue +// ID- pointer to ID +// returns pointer to found message, NULL if not found + HYAMNMAIL WINAPI FindMessageByIDFcn(HYAMNMAIL From, char *ID) { HYAMNMAIL Browser; @@ -342,6 +249,13 @@ HYAMNMAIL WINAPI FindMessageByIDFcn(HYAMNMAIL From, char *ID) return Browser; } +///////////////////////////////////////////////////////////////////////////////////////// +// Translate header from text to queue of CMimeItem structures +// This means that new queue will contain all info about headers +// stream- pointer to text containing header (can be ended with zero) +// len- length of stream +// head- function fills this pointer to first header item in queue + void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head) { try { @@ -352,8 +266,8 @@ void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head) while (finder <= (stream + len)) { while (ENDLINEWS(finder)) finder++; - //at the start of line - if (DOTLINE(finder + 1)) //at the end of stream + // at the start of line + if (DOTLINE(finder + 1)) // at the end of stream break; prev1 = finder; @@ -371,7 +285,7 @@ void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head) break; do { - if (ENDLINEWS(finder)) finder += 2; //after endline information continues + if (ENDLINEWS(finder)) finder += 2; // after endline information continues while (!ENDLINE(finder) && !EOS(finder)) finder++; } while (ENDLINEWS(finder)); @@ -407,7 +321,7 @@ void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head) if (prev2 > prev1) { // yes, we have body Item->Next = new CMimeItem(); Item = Item->Next; - Item->Next = nullptr;//just in case; + Item->Next = nullptr;// just in case; Item->name = new char[5]; strncpy(Item->name, "Body", 5); Item->value = new char[prev2 - prev1]; mir_strncpy(Item->value, prev1, prev2 - prev1 - 1); @@ -422,6 +336,13 @@ void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head) } } +///////////////////////////////////////////////////////////////////////////////////////// +// Creates new mail queue, copying only these mails, that have set flag for deleting +// From- message queue, whose mail with given flag are duplicated +// returns new mail queue (or NULL when no mail with flag is in From queue) +// Function does not copy the whole mails, it copies only ID string. And ID is copied as string, so +// you can use this fcn only if you have your ID as pointer to char string ended with zero character + HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From) { HYAMNMAIL FirstMail, Browser = nullptr; @@ -446,6 +367,14 @@ HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From) return FirstMail; } +///////////////////////////////////////////////////////////////////////////////////////// +// Sets/removes flags from specific mails +// From- pointer to first message +// FlagsSet- mail must have set these flags... +// FlagsNotSet- ...and must not have set these flags... +// FlagsToSetRemove- ...to set/remove these flags (see mode) +// mode- nonzero to set, else remove + void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From, uint32_t FlagsSet, uint32_t FlagsNotSet, uint32_t FlagsToSetRemove, int mode) { HYAMNMAIL msgq; diff --git a/protocols/YAMN/src/main.cpp b/protocols/YAMN/src/main.cpp index 3094e2a283..3d370d9a44 100644 --- a/protocols/YAMN/src/main.cpp +++ b/protocols/YAMN/src/main.cpp @@ -15,16 +15,13 @@ wchar_t ProfileName[MAX_PATH]; wchar_t UserDirectory[MAX_PATH]; -wchar_t szMirandaDir[MAX_PATH]; -wchar_t szProfileDir[MAX_PATH]; +wchar_t szMirandaDir[MAX_PATH]; +wchar_t szProfileDir[MAX_PATH]; BOOL UninstallPlugins; HANDLE hAccountFolder; -HINSTANCE *hDllPlugins; -static int iDllPlugins = 0; - YAMN_VARIABLES YAMNVar; CMPlugin g_plugin; @@ -37,32 +34,9 @@ UINT SecTimer; #define FIXED_TAB_SIZE 100 // default value for fixed width tabs -static void GetProfileDirectory(wchar_t *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 -{ - wchar_t tszOldPath[MAX_PATH]; - Profile_GetPathW(_countof(tszOldPath), tszOldPath); - mir_wstrcat(tszOldPath, L"\\*.book"); - - VARSW ptszNewPath(L"%miranda_userdata%"); - - SHFILEOPSTRUCT file_op = { - nullptr, - FO_MOVE, - tszOldPath, - ptszNewPath, - FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT, - false, - nullptr, - L""}; - SHFileOperation(&file_op); - - wcsncpy(szPath, ptszNewPath, cbPath); -} - ///////////////////////////////////////////////////////////////////////////////////////// -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST }; ///////////////////////////////////////////////////////////////////////////////////////// @@ -76,7 +50,7 @@ PLUGININFOEX pluginInfoEx = { __AUTHORWEB, UNICODE_AWARE, // {B047A7E5-027A-4CFC-8B18-EDA8345D2790} - {0xb047a7e5, 0x27a, 0x4cfc, {0x8b, 0x18, 0xed, 0xa8, 0x34, 0x5d, 0x27, 0x90}} + { 0xb047a7e5, 0x27a, 0x4cfc, { 0x8b, 0x18, 0xed, 0xa8, 0x34, 0x5d, 0x27, 0x90 } } }; CMPlugin::CMPlugin() : @@ -99,18 +73,19 @@ BOOL CALLBACK EnumSystemCodePagesProc(LPTSTR cpStr) // Get Code Page name CPINFOEX info; if (GetCPInfoEx(cp, 0, &info)) { - for (int i = 1; i < CPLENALL; i++) if (CodePageNamesAll[i].CP == cp) { - CodePageNamesAll[i].isValid = TRUE; - CPLENSUPP++; - break; - } + for (int i = 1; i < CPLENALL; i++) + if (CodePageNamesAll[i].CP == cp) { + CodePageNamesAll[i].isValid = TRUE; + CPLENSUPP++; + break; + } } return TRUE; } int SystemModulesLoaded(WPARAM, LPARAM) { - //Insert "Check mail (YAMN)" item to Miranda's menu + // Insert "Check mail (YAMN)" item to Miranda's menu CMenuItem mi(&g_plugin); SET_UID(mi, 0xa01ff3d9, 0x53cb, 0x4406, 0x85, 0xd9, 0xf1, 0x90, 0x3a, 0x94, 0xed, 0xf4); @@ -142,10 +117,10 @@ int SystemModulesLoaded(WPARAM, LPARAM) static IconItem iconList[] = { - {LPGEN("Check mail"), "YAMN_Check", IDI_CHECKMAIL}, - {LPGEN("Launch application"), "YAMN_Launch", IDI_LAUNCHAPP}, - {LPGEN("New Mail"), "YAMN_NewMail", IDI_NEWMAIL}, - {LPGEN("Connect Fail"), "YAMN_ConnectFail", IDI_BADCONNECT}, + { LPGEN("Check mail"), "YAMN_Check", IDI_CHECKMAIL }, + { LPGEN("Launch application"), "YAMN_Launch", IDI_LAUNCHAPP }, + { LPGEN("New Mail"), "YAMN_NewMail", IDI_NEWMAIL }, + { LPGEN("Connect Fail"), "YAMN_ConnectFail", IDI_BADCONNECT }, }; void LoadIcons() @@ -160,11 +135,11 @@ int CMPlugin::Load() // retrieve the current profile name Profile_GetNameW(_countof(ProfileName), ProfileName); - wchar_t *fc = wcsrchr(ProfileName, '.'); - if (fc != nullptr) *fc = 0; + if (wchar_t *fc = wcsrchr(ProfileName, '.')) + *fc = 0; // we get the user path where our yamn-account.book.ini is stored from mirandaboot.ini file - GetProfileDirectory(UserDirectory, _countof(UserDirectory)); + mir_wstrncpy(UserDirectory, VARSW(L"%miranda_userdata%"), _countof(UserDirectory)); // Enumerate all the code pages available for the System Locale EnumSystemCodePages(EnumSystemCodePagesProc, CP_INSTALLED); @@ -233,21 +208,6 @@ int CMPlugin::Load() ///////////////////////////////////////////////////////////////////////////////////////// -static void UnloadPlugins() -{ - if (hDllPlugins == nullptr) - return; - - for (int i = iDllPlugins - 1; i >= 0; i--) { - if (FreeLibrary(hDllPlugins[i])) { - hDllPlugins[i] = nullptr; //for safety - iDllPlugins--; - } - } - free((void *)hDllPlugins); - hDllPlugins = nullptr; -} - int CMPlugin::Unload() { #ifdef _DEBUG @@ -264,8 +224,6 @@ int CMPlugin::Unload() CloseHandle(WriteToFileEV); CloseHandle(ExitEV); - UnloadPlugins(); - delete[] CodePageNamesSupp; return 0; } diff --git a/protocols/YAMN/src/proto/pop3/pop3comm.cpp b/protocols/YAMN/src/proto/pop3/pop3comm.cpp index 9d65132475..c27b27b9bd 100644 --- a/protocols/YAMN/src/proto/pop3/pop3comm.cpp +++ b/protocols/YAMN/src/proto/pop3/pop3comm.cpp @@ -12,76 +12,72 @@ #include "../../stdafx.h" -#define ERRORSTR_MAXLEN 1024 //in wide-chars - -int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer); - - //-------------------------------------------------------------------------------------------------- +#define ERRORSTR_MAXLEN 1024 // in wide-chars HANDLE hNetLib = nullptr; SCOUNTER CPOP3Account::AccountWriterSO; -//Creates new CPOP3Account structure -CAccount *WINAPI CreatePOP3Account(YAMN_PROTOPLUGIN *Plugin, DWORD CAccountVersion); +// Creates new CPOP3Account structure +CAccount *WINAPI CreatePOP3Account(YAMN_PROTOPLUGIN *Plugin); -//Deletes CPOP3Account structure +// Deletes CPOP3Account structure void WINAPI DeletePOP3Account(CAccount *Which); -//Sets stop flag to account +// Sets stop flag to account void WINAPI StopPOP3Account(CAccount *Which); -//Function registers standard functions for YAMN +// Function registers standard functions for YAMN int RegisterPOP3Plugin(WPARAM, LPARAM); -//Unloads all variables created on heap (delete[]) +// Unloads all variables created on heap (delete[]) DWORD WINAPI UnLoadPOP3(void *); -//Function writes POP3 accounts using YAMN exported functions +// Function writes POP3 accounts using YAMN exported functions DWORD WINAPI WritePOP3Accounts(); -//Function stores plugin's data for account to file +// Function stores plugin's data for account to file DWORD WINAPI WritePOP3Options(HANDLE, CAccount *); -//Function reads plugin's data for account from file +// Function reads plugin's data for account from file DWORD WINAPI ReadPOP3Options(CAccount *, char **, char *); -//Creates new mail for an account -HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account, DWORD CMimeMailVersion); +// Creates new mail for an account +HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account); -//Function does all needed work when connection failed or any error occured -//Creates structure containing error code, closes internet session, runs "bad connect" function +// Function does all needed work when connection failed or any error occured +// Creates structure containing error code, closes internet session, runs "bad connect" function static void PostErrorProc(CPOP3Account *ActualAccount, void *ParamToBadConnect, uint32_t POP3PluginParam, BOOL UseSSL); -//Checks POP3 account and stores all info to account. It deletes old mails=> synchro +// Checks POP3 account and stores all info to account. It deletes old mails=> synchro // WhichTemp- pointer to strucure containing needed information -DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp); +DWORD WINAPI SynchroPOP3(CheckParam *WhichTemp); -//Deletes mails from POP3 server +// Deletes mails from POP3 server // WhichTemp- structure containing needed information (queued messages to delete) -//Function deletes from memory queue in WhichTemp structure +// Function deletes from memory queue in WhichTemp structure void __cdecl DeleteMailsPOP3(void *param); -//Function makes readable message about error. It sends it back to YAMN, so YAMN then -//can show it to the message window +// Function makes readable message about error. It sends it back to YAMN, so YAMN then +// can show it to the message window wchar_t *WINAPI GetErrorString(DWORD Code); -//Function deletes string allocated in GetErrorString +// Function deletes string allocated in GetErrorString void WINAPI DeleteErrorString(LPVOID String); -//Extracts info from result of POP3's STAT command +// Extracts info from result of POP3's STAT command // stream- source string // len- length of source string // mboxsize- adreess to integer, that receives size of mailbox // mails- adreess to integer, that receives number of mails void ExtractStat(char *stream, int *mboxsize, int *mails); -//Extracts mail ID on mailbox +// Extracts mail ID on mailbox // stream- source string // len- length of source string // queue- address of first message, where first ID will be stored void ExtractUIDL(char *stream, int len, HYAMNMAIL queue); -//Extracts mail size on mailbox +// Extracts mail size on mailbox // stream- source string // len- length of source string // queue- address of first message, where size of message #1 will be stored @@ -127,12 +123,12 @@ YAMN_PROTOREGISTRATION POP3ProtocolRegistration = __AUTHORWEB, }; -static wchar_t *FileName = nullptr; +static CMStringW wszFileName; HANDLE RegisterNLClient(char *name); -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------- CPOP3Account::CPOP3Account() { @@ -150,31 +146,31 @@ CPOP3Account::~CPOP3Account() CloseHandle(UseInternetFree); } -CAccount* WINAPI CreatePOP3Account(YAMN_PROTOPLUGIN*, DWORD) +CAccount *WINAPI CreatePOP3Account(YAMN_PROTOPLUGIN *) { - //First, we should check whether CAccountVersion matches. - //But this is internal plugin, so YAMN's CAccount structure and our CAccount structure are - //the same, so we do not need to test version. Otherwise, if CAccount version does not match - //in your plugin, you should return NULL, like this: - // if (CAccountVersion != YAMN_ACCOUNTVERSION) return NULL; + // First, we should check whether CAccountVersion matches. + // But this is internal plugin, so YAMN's CAccount structure and our CAccount structure are + // the same, so we do not need to test version. Otherwise, if CAccount version does not match + // in your plugin, you should return NULL, like this: + // if (CAccountVersion != YAMN_ACCOUNTVERSION) return NULL; - //Now it is needed to construct our POP3 account and return its handle + // Now it is needed to construct our POP3 account and return its handle return new CPOP3Account(); } void WINAPI DeletePOP3Account(CAccount *Which) { - delete (CPOP3Account*)Which; + delete (CPOP3Account *)Which; } void WINAPI StopPOP3Account(CAccount *Which) { - ((CPOP3Account*)Which)->Client.Stopped = TRUE; - if (((CPOP3Account*)Which)->Client.NetClient != nullptr) //we should inform also network client. Usefull only when network client implements this feature - ((CPOP3Account*)Which)->Client.NetClient->Stopped = TRUE; + ((CPOP3Account *)Which)->Client.Stopped = TRUE; + if (((CPOP3Account *)Which)->Client.NetClient != nullptr) // we should inform also network client. Usefull only when network client implements this feature + ((CPOP3Account *)Which)->Client.NetClient->Stopped = TRUE; } -//This function is like main function for POP3 internal protocol +// This function is like main function for POP3 internal protocol int RegisterPOP3Plugin(WPARAM, LPARAM) { // Register new pop3 user in netlib @@ -187,42 +183,37 @@ int RegisterPOP3Plugin(WPARAM, LPARAM) // it is quite impossible this function returns zero (failure) as YAMN and internal plugin structre versions are the same POP3ProtocolRegistration.Name = Translate("POP3 protocol (internal)"); POP3ProtocolRegistration.Description = Translate(__DESCRIPTION); - if (nullptr == (POP3Plugin = (YAMN_PROTOPLUGIN*)CallService(MS_YAMN_REGISTERPROTOPLUGIN, (WPARAM)&POP3ProtocolRegistration, (LPARAM)YAMN_PROTOREGISTRATIONVERSION))) + if (nullptr == (POP3Plugin = RegisterProtocolPlugin(&POP3ProtocolRegistration))) return 0; - //Next we set our imported functions for YAMN - if (!SetProtocolPluginFcnImportFcn(POP3Plugin, &POP3ProtocolFunctions, YAMN_PROTOIMPORTFCNVERSION, &POP3MailFunctions, YAMN_MAILIMPORTFCNVERSION)) + // Next we set our imported functions for YAMN + if (!SetProtocolPluginFcnImportFcn(POP3Plugin, &POP3ProtocolFunctions, &POP3MailFunctions)) return 0; - //Then, we read all mails for accounts. - //You must first register account, before using this function as YAMN must use CreatePOP3Account function to add new accounts - //But if CreatePOP3Account is not implemented (equals to NULL), YAMN creates account as YAMN's standard CAccount * - if (FileName) CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); //shoud not happen (only for secure) - FileName = (wchar_t *)CallService(MS_YAMN_GETFILENAME, (WPARAM)L"pop3", 0); + // Then, we read all mails for accounts. + // You must first register account, before using this function as YAMN must use CreatePOP3Account function to add new accounts + // But if CreatePOP3Account is not implemented (equals to NULL), YAMN creates account as YAMN's standard CAccount * + wszFileName = GetFileName(L"pop3"); - switch (CallService(MS_YAMN_READACCOUNTS, (WPARAM)POP3Plugin, (LPARAM)FileName)) { + switch (AddAccountsFromFile(POP3Plugin, wszFileName)) { case EACC_FILEVERSION: MessageBox(nullptr, TranslateT("Found new version of account book, not compatible with this version of YAMN."), TranslateT("YAMN (internal POP3) read error"), MB_OK); - CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); - FileName = nullptr; + wszFileName.Empty(); return 0; case EACC_FILECOMPATIBILITY: MessageBox(nullptr, TranslateT("Error reading account file. Account file corrupted."), TranslateT("YAMN (internal POP3) read error"), MB_OK); - CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); - FileName = nullptr; + wszFileName.Empty(); return 0; case EACC_ALLOC: MessageBox(nullptr, TranslateT("Memory allocation error while data reading"), TranslateT("YAMN (internal POP3) read error"), MB_OK); - CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); - FileName = nullptr; + wszFileName.Empty(); return 0; case EACC_SYSTEM: if (ERROR_FILE_NOT_FOUND != GetLastError()) { - wchar_t temp[1024] = {0}; - mir_snwprintf(temp, L"%s\n%s", TranslateT("Reading file error. File already in use?"), FileName); + wchar_t temp[1024] = { 0 }; + mir_snwprintf(temp, L"%s\n%s", TranslateT("Reading file error. File already in use?"), wszFileName.c_str()); MessageBox(nullptr, temp, TranslateT("YAMN (internal POP3) read error"), MB_OK); - CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); - FileName = nullptr; + wszFileName.Empty(); return 0; } break; @@ -262,22 +253,16 @@ int RegisterPOP3Plugin(WPARAM, LPARAM) DWORD WINAPI UnLoadPOP3(void *) { - if (hNetLib) { - Netlib_CloseHandle(hNetLib); hNetLib = nullptr; - } - if (FileName) { - CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); FileName = nullptr; - } - + Netlib_CloseHandle(hNetLib); hNetLib = nullptr; return 1; } -DWORD WINAPI WritePOP3Accounts() +DWORD WritePOP3Accounts() { - uint32_t ReturnValue = CallService(MS_YAMN_WRITEACCOUNTS, (WPARAM)POP3Plugin, (LPARAM)FileName); + uint32_t ReturnValue = WriteAccountsToFile(POP3Plugin, wszFileName); if (ReturnValue == EACC_SYSTEM) { - wchar_t temp[1024] = {0}; - mir_snwprintf(temp, L"%s\n%s", TranslateT("Error while copying data to disk occurred. Is file in use?"), FileName); + wchar_t temp[1024] = { 0 }; + mir_snwprintf(temp, L"%s\n%s", TranslateT("Error while copying data to disk occurred. Is file in use?"), wszFileName.c_str()); MessageBox(nullptr, temp, TranslateT("POP3 plugin - write file error"), MB_OK); } @@ -290,7 +275,7 @@ DWORD WINAPI WritePOP3Options(HANDLE File, CAccount *Which) uint32_t Ver = POP3_FILEVERSION; if ((!WriteFile(File, (char *)&Ver, sizeof(uint32_t), &WrittenBytes, nullptr)) || - (!WriteFile(File, (char *)&((CPOP3Account*)Which)->CP, sizeof(uint16_t), &WrittenBytes, nullptr))) + (!WriteFile(File, (char *)&((CPOP3Account *)Which)->CP, sizeof(uint16_t), &WrittenBytes, nullptr))) return EACC_SYSTEM; return 0; } @@ -308,27 +293,27 @@ DWORD WINAPI ReadPOP3Options(CAccount *Which, char **Parser, char *End) if (Ver != POP3_FILEVERSION) return EACC_FILECOMPATIBILITY; - ((CPOP3Account*)Which)->CP = *(uint16_t *)(*Parser); + ((CPOP3Account *)Which)->CP = *(uint16_t *)(*Parser); (*Parser) += sizeof(uint16_t); if (*Parser >= End) return EACC_FILECOMPATIBILITY; #ifdef DEBUG_FILEREAD - mir_snwprintf(Debug, L"CodePage: %d, remaining %d chars", ((CPOP3Account*)Which)->CP, End - *Parser); + mir_snwprintf(Debug, L"CodePage: %d, remaining %d chars", ((CPOP3Account *)Which)->CP, End - *Parser); MessageBox(NULL, Debug, L"debug", MB_OK); #endif return 0; } -HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account, DWORD) +HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account) { HYAMNMAIL NewMail; - //First, we should check whether MAILDATA matches. - //But this is internal plugin, so YAMN's MAILDATA structure and our MAILDATA structure are - //the same, so we do not need to test version. Otherwise, if MAILDATA version does not match - //in your plugin, you should return NULL, like this: - // if (MailDataVersion != YAMN_MAILDATAVERSION) return NULL; + // First, we should check whether MAILDATA matches. + // But this is internal plugin, so YAMN's MAILDATA structure and our MAILDATA structure are + // the same, so we do not need to test version. Otherwise, if MAILDATA version does not match + // in your plugin, you should return NULL, like this: + // if (MailDataVersion != YAMN_MAILDATAVERSION) return NULL; - //Now it is needed to construct our POP3 account and return its handle + // Now it is needed to construct our POP3 account and return its handle if (nullptr == (NewMail = new YAMNMAIL)) return nullptr; @@ -336,7 +321,7 @@ HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account, DWORD) delete NewMail; return nullptr; } - NewMail->MailData->CP = ((CPOP3Account*)Account)->CP; + NewMail->MailData->CP = ((CPOP3Account *)Account)->CP; return (HYAMNMAIL)NewMail; } @@ -346,16 +331,16 @@ static void SetContactStatus(CAccount *account, int status) g_plugin.setWord(account->hContact, "Status", status); } -static void PostErrorProc(CPOP3Account* ActualAccount, void *ParamToBadConnection, uint32_t POP3PluginParam, BOOL UseSSL) +static void PostErrorProc(CPOP3Account *ActualAccount, void *ParamToBadConnection, uint32_t POP3PluginParam, BOOL UseSSL) { char *DataRX; - //We create new structure, that we pass to bad connection dialog procedure. This procedure next calls YAMN imported fuction - //from POP3 protocol to determine the description of error. We can describe error from our error code structure, because later, - //when YAMN calls our function, it passes us our error code. This is pointer to structure for POP3 protocol in fact. + // We create new structure, that we pass to bad connection dialog procedure. This procedure next calls YAMN imported fuction + // from POP3 protocol to determine the description of error. We can describe error from our error code structure, because later, + // when YAMN calls our function, it passes us our error code. This is pointer to structure for POP3 protocol in fact. PPOP3_ERRORCODE ErrorCode; - //We store status before we do Quit(), because quit can destroy our errorcode status + // We store status before we do Quit(), because quit can destroy our errorcode status if (nullptr != (ErrorCode = new POP3_ERRORCODE)) { ErrorCode->SSL = UseSSL; ErrorCode->AppError = ActualAccount->SystemError; @@ -364,8 +349,7 @@ static void PostErrorProc(CPOP3Account* ActualAccount, void *ParamToBadConnectio ErrorCode->SystemError = ActualAccount->Client.NetClient->SystemError; } - if (POP3PluginParam == (uint32_t)NULL) //if it was normal YAMN call (force check or so on) - { + if (POP3PluginParam == (uint32_t)NULL) { // if it was normal YAMN call (force check or so on) try { DataRX = ActualAccount->Client.Quit(); if (DataRX != nullptr) @@ -373,7 +357,7 @@ static void PostErrorProc(CPOP3Account* ActualAccount, void *ParamToBadConnectio } catch (...) { } - //We always close connection if error occured + // We always close connection if error occured try { ActualAccount->Client.NetClient->Disconnect(); } @@ -382,7 +366,7 @@ static void PostErrorProc(CPOP3Account* ActualAccount, void *ParamToBadConnectio SetStatusFcn(ActualAccount, TranslateT("Disconnected")); - //If we cannot allocate memory, do nothing + // If we cannot allocate memory, do nothing if (ErrorCode == nullptr) { SetEvent(ActualAccount->UseInternetFree); return; @@ -395,14 +379,14 @@ static void PostErrorProc(CPOP3Account* ActualAccount, void *ParamToBadConnectio if ((ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) || (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) || (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP)) RunBadConnection(ActualAccount, (UINT_PTR)ErrorCode, ParamToBadConnection); - if (POP3PluginParam == (uint32_t)NULL) //if it was normal YAMN call + if (POP3PluginParam == (uint32_t)NULL) // if it was normal YAMN call SetEvent(ActualAccount->UseInternetFree); } -//Checks POP3 account and synchronizes it -DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) +// Checks POP3 account and synchronizes it +DWORD WINAPI SynchroPOP3(CheckParam *WhichTemp) { - CPOP3Account* ActualAccount; + CPOP3Account *ActualAccount; CPop3Client *MyClient; HYAMNMAIL NewMails = nullptr, MsgQueuePtr = nullptr; char *DataRX = nullptr; @@ -422,23 +406,12 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) uint32_t NNFlags; } ActualCopied; - //First, we should compare our version of CheckParam structure, but here it is not needed, because YAMN and internal plugin - //have the same version. But your plugin should do that in this way: - // if (((struct CheckParam *)WhichTemp)->Ver != YAMN_CHECKVERSION) - // { - // SetEvent(((struct CheckParam *)WhichTemp)->ThreadRunningEV); //don't forget to unblock YAMN - // return (uint32_t)-1; //ok, but we should return value. - // //When our plugin returns e.g. 0xFFFFFFFF (=-1, this is only our plugin value, YAMN does nothing with return value, - // //but only tests if it is nonzero. If yes, it calls GetErrorStringFcn. We know problem occured in YAMN incompatibility - // //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN". - // } - - ActualAccount = (CPOP3Account*)WhichTemp->AccountParam; //copy address of structure from calling thread to stack of this thread + ActualAccount = (CPOP3Account *)WhichTemp->AccountParam; // copy address of structure from calling thread to stack of this thread YAMNParam = WhichTemp->BrowserParam; CheckFlags = WhichTemp->Flags; SCGuard sc(ActualAccount->UsingThreads); - //Unblock YAMN, signal that we have copied all parameters from YAMN thread stack + // Unblock YAMN, signal that we have copied all parameters from YAMN thread stack if (INVALID_HANDLE_VALUE != WhichTemp->ThreadRunningEV) SetEvent(WhichTemp->ThreadRunningEV); @@ -447,7 +420,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) return 0; MyClient = &ActualAccount->Client; - //Now, copy all needed information about account to local variables, so ActualAccount is not blocked in read mode during all connection process, which can last for several minutes. + // Now, copy all needed information about account to local variables, so ActualAccount is not blocked in read mode during all connection process, which can last for several minutes. ActualCopied.ServerName = _strdup(ActualAccount->Server->Name); ActualCopied.ServerPort = ActualAccount->Server->Port; ActualCopied.Flags = ActualAccount->Flags; @@ -460,9 +433,9 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) SCGuard scq(ActualAccount->InternetQueries); // increment counter, that there is one more thread waiting for connection WaitForSingleObject(ActualAccount->UseInternetFree, INFINITE); // wait until we can use connection } - //OK, we enter the "use internet" section. But after we start communication, we can test if we did not enter the "use internet" section only for the reason, - //that previous thread release the internet section because this account has stop signal (we stop account and there are 2 threads: one communicating, - //the second one waiting for network access- the first one ends because we want to stop account, this one is released, but should be stopped as well). + // OK, we enter the "use internet" section. But after we start communication, we can test if we did not enter the "use internet" section only for the reason, + // that previous thread release the internet section because this account has stop signal (we stop account and there are 2 threads: one communicating, + // the second one waiting for network access- the first one ends because we want to stop account, this one is released, but should be stopped as well). if (!ActualAccount->AbleToWork) { SetEvent(ActualAccount->UseInternetFree); return 0; @@ -470,12 +443,12 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) UsingInternet = TRUE; GetLocalTime(&now); - ActualAccount->SystemError = 0; //now we can use internet for this socket. First, clear errorcode. + ActualAccount->SystemError = 0; // now we can use internet for this socket. First, clear errorcode. try { SetContactStatus(ActualAccount, ID_STATUS_OCCUPIED); - // if we are already connected, we have open session (another thread left us open session), so we don't need to login - // note that connected state without logging cannot occur, because if we close session, we always close socket too (we must close socket is the right word :)) + // if we are already connected, we have open session (another thread left us open session), so we don't need to login + // note that connected state without logging cannot occur, because if we close session, we always close socket too (we must close socket is the right word :)) if ((MyClient->NetClient == nullptr) || !MyClient->NetClient->Connected()) { SetStatusFcn(ActualAccount, TranslateT("Connecting to server")); @@ -528,9 +501,9 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) DataRX = nullptr; for (i = 0; i < msgs; i++) { if (!i) - MsgQueuePtr = NewMails = (HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL, (WPARAM)ActualAccount, (LPARAM)YAMN_MAILVERSION); + MsgQueuePtr = NewMails = CreateAccountMail(ActualAccount); else { - MsgQueuePtr->Next = (HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL, (WPARAM)ActualAccount, (LPARAM)YAMN_MAILVERSION); + MsgQueuePtr->Next = CreateAccountMail(ActualAccount); MsgQueuePtr = MsgQueuePtr->Next; } if (MsgQueuePtr == nullptr) { @@ -604,9 +577,9 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) } } - SynchroMessagesFcn(ActualAccount, (HYAMNMAIL *)&ActualAccount->Mails, nullptr, (HYAMNMAIL *)&NewMails, nullptr); //we get only new mails on server! + SynchroMessagesFcn(ActualAccount, (HYAMNMAIL *)&ActualAccount->Mails, nullptr, (HYAMNMAIL *)&NewMails, nullptr); // we get only new mails on server! } - + for (MsgQueuePtr = (HYAMNMAIL)ActualAccount->Mails; MsgQueuePtr != nullptr; MsgQueuePtr = MsgQueuePtr->Next) { if ((MsgQueuePtr->Flags & YAMN_MSG_BODYREQUESTED) && (MsgQueuePtr->Flags & YAMN_MSG_BODYRECEIVED)) { MsgQueuePtr->Flags &= ~YAMN_MSG_BODYREQUESTED; @@ -615,7 +588,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) } } - for (msgs = 0, MsgQueuePtr = NewMails; MsgQueuePtr != nullptr; MsgQueuePtr = MsgQueuePtr->Next, msgs++); //get number of new mails + for (msgs = 0, MsgQueuePtr = NewMails; MsgQueuePtr != nullptr; MsgQueuePtr = MsgQueuePtr->Next, msgs++); // get number of new mails try { wchar_t accstatus[512]; @@ -628,7 +601,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) if (DataRX == nullptr) continue; - + char *Temp = DataRX; while ((Temp < DataRX + MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++; @@ -651,13 +624,14 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) free(DataRX); DataRX = nullptr; - //MsgQueuePtr->MailData->Body=MyClient->Retr(MsgQueuePtr->Number); + // MsgQueuePtr->MailData->Body=MyClient->Retr(MsgQueuePtr->Number); MsgQueuePtr = MsgQueuePtr->Next; } - - { SWriteGuard swm(ActualAccount->MessagesAccessSO); + + { + SWriteGuard swm(ActualAccount->MessagesAccessSO); if (!swm.Succeeded()) throw (uint32_t)ActualAccount->SystemError == EACC_STOPPED; @@ -669,16 +643,16 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) } } - // we are going to delete mails having SPAM flag level3 and 4 (see m_mails.h) set + // we are going to delete mails having SPAM flag level3 and 4 (see m_mails.h) set { - struct DeleteParam ParamToDeleteMails = {YAMN_DELETEVERSION, INVALID_HANDLE_VALUE, ActualAccount, YAMNParam, (void *)POP3_DELETEFROMCHECK}; + struct DeleteParam ParamToDeleteMails = { YAMN_DELETEVERSION, INVALID_HANDLE_VALUE, ActualAccount, YAMNParam, (void *)POP3_DELETEFROMCHECK }; - // Delete mails from server. Here we should not be in write access for account's mails + // Delete mails from server. Here we should not be in write access for account's mails DeleteMailsPOP3(&ParamToDeleteMails); } - // if there is no waiting thread for internet connection close it - // else leave connection open + // if there is no waiting thread for internet connection close it + // else leave connection open if (0 == ActualAccount->InternetQueries.GetNumber()) { DataRX = MyClient->Quit(); if (DataRX != nullptr) @@ -696,10 +670,10 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) ActualAccount->LastSynchronised = ActualAccount->LastChecked; } catch (...) { - throw; //go to the main exception handling + throw; // go to the main exception handling } - YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualCopied.NFlags, ActualCopied.NNFlags, YAMNParam}; + YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualCopied.NFlags, ActualCopied.NNFlags, YAMNParam }; if (CheckFlags & YAMN_FORCECHECK) Param.nnflags |= YAMN_ACC_POP; // if force check, show popup anyway and if mailbrowser was opened, do not close Param.nnflags |= YAMN_ACC_MSGP; // do not close browser if already open @@ -735,14 +709,14 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) ActualAccount->Client.NetClient->Disconnect(); break; default: - PostErrorProc(ActualAccount, YAMNParam, (uint32_t)NULL, MyClient->SSL); //it closes internet connection too - } + PostErrorProc(ActualAccount, YAMNParam, (uint32_t)NULL, MyClient->SSL); // it closes internet connection too + } - if (UsingInternet) //if our thread still uses internet + if (UsingInternet) // if our thread still uses internet SetEvent(ActualAccount->UseInternetFree); SetContactStatus(ActualAccount, ID_STATUS_NA); - } +} free(ActualCopied.ServerName); free(ActualCopied.ServerLogin); free(ActualCopied.ServerPasswd); @@ -750,7 +724,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp) DebugLog(CommFile, "\n"); #endif - // WriteAccounts(); + // WriteAccounts(); return 0; } @@ -774,26 +748,27 @@ void __cdecl DeleteMailsPOP3(void *param) uint32_t NNFlags; } ActualCopied; - //First, we should compare our version of DeleteParam structure, but here it is not needed, because YAMN and internal plugin - //have the same version. But your plugin should do that in this way: - // if (((struct DeleteParam *)WhichTemp)->Ver != YAMN_DELETEVERSION) - // { - // SetEvent(((struct DeleteParam *)WhichTemp)->ThreadRunningEV); //don't forget to unblock YAMN - // return (uint32_t)-1; //ok, but we should return value. - // //When our plugin returns e.g. 0xFFFFFFFF (this is only our plugin value, YAMN does nothing with return value, - // //but only tests if it is nonzero. If yes, it calls GetErrorStringFcn), we know problem occured in YAMN incompatibility - // //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN". - // } - - CPOP3Account* ActualAccount = (CPOP3Account*)WhichTemp->AccountParam; //copy address of structure from calling thread to stack of this thread + // First, we should compare our version of DeleteParam structure, but here it is not needed, because YAMN and internal plugin + // have the same version. But your plugin should do that in this way: + // if (((struct DeleteParam *)WhichTemp)->Ver != YAMN_DELETEVERSION) + // { + // SetEvent(((struct DeleteParam *)WhichTemp)->ThreadRunningEV); // don't forget to unblock YAMN + // return (uint32_t)-1; // ok, but we should return value. + // // When our plugin returns e.g. 0xFFFFFFFF (this is only our plugin value, YAMN does nothing with return value, + // // but only tests if it is nonzero. If yes, it calls GetErrorStringFcn), we know problem occured in YAMN incompatibility + // // and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN". + // } + + CPOP3Account *ActualAccount = (CPOP3Account *)WhichTemp->AccountParam; // copy address of structure from calling thread to stack of this thread LPVOID YAMNParam = WhichTemp->BrowserParam; UINT_PTR POP3PluginParam = (UINT_PTR)((struct DeleteParam *)WhichTemp)->CustomParam; SCGuard sc(ActualAccount->UsingThreads); if (INVALID_HANDLE_VALUE != WhichTemp->ThreadRunningEV) SetEvent(WhichTemp->ThreadRunningEV); - - { SReadGuard sra(ActualAccount->AccountAccessSO); + + { + SReadGuard sra(ActualAccount->AccountAccessSO); if (!sra.Succeeded()) return; @@ -801,7 +776,7 @@ void __cdecl DeleteMailsPOP3(void *param) if (nullptr == (DeleteMails = CreateNewDeleteQueueFcn((HYAMNMAIL)ActualAccount->Mails))) { // We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked if (POP3_DELETEFROMCHECK != POP3PluginParam) { - YAMN_MAILBROWSERPARAM Param = { ActualAccount, YAMN_ACC_MSGP, YAMN_ACC_MSGP, YAMNParam }; //Just update the window + YAMN_MAILBROWSERPARAM Param = { ActualAccount, YAMN_ACC_MSGP, YAMN_ACC_MSGP, YAMNParam }; // Just update the window CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, YAMN_MAILBROWSERVERSION); } return; @@ -818,7 +793,7 @@ void __cdecl DeleteMailsPOP3(void *param) ActualCopied.NFlags = ActualAccount->NewMailN.Flags; ActualCopied.NNFlags = ActualAccount->NoNewMailN.Flags; } - + { SCGuard scq(ActualAccount->InternetQueries); // This is POP3-internal SCOUNTER, we set another thread wait for this account to be connected to inet if (POP3_DELETEFROMCHECK != POP3PluginParam) // We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked @@ -847,11 +822,11 @@ void __cdecl DeleteMailsPOP3(void *param) timestamp = new char[sz]; memcpy(timestamp, lpos, sz - 1); timestamp[sz - 1] = '\0'; - } } + } free(DataRX); DataRX = nullptr; - } + } SetStatusFcn(ActualAccount, TranslateT("Entering POP3 account")); if (ActualAccount->Flags & YAMN_ACC_APOP) { @@ -871,12 +846,12 @@ void __cdecl DeleteMailsPOP3(void *param) free(DataRX); DataRX = nullptr; } - } + } #ifdef DEBUG_DECODE DebugLog(DecodeFile, "<--------Deleting requested mails-------->\n"); #endif - if (POP3_DELETEFROMCHECK != POP3PluginParam) //We do not need to get mails on server as we have already it from check function + if (POP3_DELETEFROMCHECK != POP3PluginParam) // We do not need to get mails on server as we have already it from check function { SetStatusFcn(ActualAccount, TranslateT("Deleting requested mails")); @@ -896,16 +871,16 @@ void __cdecl DeleteMailsPOP3(void *param) DataRX = nullptr; for (i = 0; i < msgs; i++) { if (!i) - MsgQueuePtr = NewMails = (HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL, (WPARAM)ActualAccount, (LPARAM)YAMN_MAILVERSION); + MsgQueuePtr = NewMails = CreateAccountMail(ActualAccount); else { - MsgQueuePtr->Next = (HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL, (WPARAM)ActualAccount, (LPARAM)YAMN_MAILVERSION); + MsgQueuePtr->Next = CreateAccountMail(ActualAccount); MsgQueuePtr = MsgQueuePtr->Next; } if (MsgQueuePtr == nullptr) { ActualAccount->SystemError = EPOP3_QUEUEALLOC; throw (uint32_t)ActualAccount->SystemError; } - } + } if (msgs) { #ifdef DEBUG_DECODE @@ -919,38 +894,33 @@ void __cdecl DeleteMailsPOP3(void *param) if (DataRX != nullptr) free(DataRX); DataRX = nullptr; - // we get "new mails" on server (NewMails will contain all mails on server not found in DeleteMails) - // but also in DeleteMails we get only those, which are still on server with their responsable numbers + // we get "new mails" on server (NewMails will contain all mails on server not found in DeleteMails) + // but also in DeleteMails we get only those, which are still on server with their responsable numbers SynchroMessagesFcn(ActualAccount, (HYAMNMAIL *)&DeleteMails, nullptr, (HYAMNMAIL *)&NewMails, nullptr); } - } + } else SetStatusFcn(ActualAccount, TranslateT("Deleting spam")); - { SWriteGuard swm(ActualAccount->MessagesAccessSO); + { + SWriteGuard swm(ActualAccount->MessagesAccessSO); if (!swm.Succeeded()) throw (uint32_t)EACC_STOPPED; if (msgs || POP3_DELETEFROMCHECK == POP3PluginParam) { - HYAMNMAIL Temp; - for (i = 0, MsgQueuePtr = DeleteMails; MsgQueuePtr != nullptr; i++) { - if (!(MsgQueuePtr->Flags & YAMN_MSG_VIRTUAL)) //of course we can only delete real mails, not virtual - { + if (!(MsgQueuePtr->Flags & YAMN_MSG_VIRTUAL)) { // of course we can only delete real mails, not virtual DataRX = MyClient->Dele(MsgQueuePtr->Number); - Temp = MsgQueuePtr->Next; - if (POP3_FOK == MyClient->AckFlag) //if server answers that mail was deleted - { + HYAMNMAIL Temp = MsgQueuePtr->Next; + if (POP3_FOK == MyClient->AckFlag) { // if server answers that mail was deleted DeleteMessageFromQueueFcn((HYAMNMAIL *)&DeleteMails, MsgQueuePtr); HYAMNMAIL DeletedMail = FindMessageByIDFcn((HYAMNMAIL)ActualAccount->Mails, MsgQueuePtr->ID); - if ((MsgQueuePtr->Flags & YAMN_MSG_MEMDELETE)) //if mail should be deleted from memory (or disk) - { - DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails, DeletedMail); //remove from queue - CallService(MS_YAMN_DELETEACCOUNTMAIL, (WPARAM)POP3Plugin, (LPARAM)DeletedMail); + if ((MsgQueuePtr->Flags & YAMN_MSG_MEMDELETE)) { // if mail should be deleted from memory (or disk) + DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails, DeletedMail); // remove from queue + DeleteAccountMail(POP3Plugin, DeletedMail); } - else //else mark it only as "deleted mail" - { + else { // else mark it only as "deleted mail" DeletedMail->Flags |= (YAMN_MSG_VIRTUAL | YAMN_MSG_DELETED); - DeletedMail->Flags &= ~(YAMN_MSG_NEW | YAMN_MSG_USERDELETE | YAMN_MSG_AUTODELETE); //clear "new mail" + DeletedMail->Flags &= ~(YAMN_MSG_NEW | YAMN_MSG_USERDELETE | YAMN_MSG_AUTODELETE); // clear "new mail" } delete MsgQueuePtr->MailData; delete[] MsgQueuePtr->ID; @@ -962,19 +932,18 @@ void __cdecl DeleteMailsPOP3(void *param) free(DataRX); DataRX = nullptr; } - else - MsgQueuePtr = MsgQueuePtr->Next; + else MsgQueuePtr = MsgQueuePtr->Next; } if (NewMails != nullptr) - // in ActualAccount->Mails we have all mails stored before calling this function - // in NewMails we have all mails not found in DeleteMails (in other words: we performed new ID checking and we - // stored all mails found on server, then we deleted the ones we wanted to delete in this function - // and NewMails queue now contains actual state of mails on server). But we will not use NewMails as actual state, because NewMails does not contain header data (subject, from...) - // We perform deleting from ActualAccount->Mails: we remove from original queue (ActualAccount->Mails) all deleted mails + // in ActualAccount->Mails we have all mails stored before calling this function + // in NewMails we have all mails not found in DeleteMails (in other words: we performed new ID checking and we + // stored all mails found on server, then we deleted the ones we wanted to delete in this function + // and NewMails queue now contains actual state of mails on server). But we will not use NewMails as actual state, because NewMails does not contain header data (subject, from...) + // We perform deleting from ActualAccount->Mails: we remove from original queue (ActualAccount->Mails) all deleted mails SynchroMessagesFcn(ActualAccount, (HYAMNMAIL *)&ActualAccount->Mails, nullptr, (HYAMNMAIL *)&NewMails, nullptr); - // Now ActualAccount->Mails contains all mails when calling this function except the ones, we wanted to delete (these are in DeleteMails) - // And in NewMails we have new mails (if any) + // Now ActualAccount->Mails contains all mails when calling this function except the ones, we wanted to delete (these are in DeleteMails) + // And in NewMails we have new mails (if any) else if (POP3_DELETEFROMCHECK != POP3PluginParam) { DeleteMessagesToEndFcn(ActualAccount, (HYAMNMAIL)ActualAccount->Mails); ActualAccount->Mails = nullptr; @@ -984,20 +953,20 @@ void __cdecl DeleteMailsPOP3(void *param) DeleteMessagesToEndFcn(ActualAccount, (HYAMNMAIL)ActualAccount->Mails); ActualAccount->Mails = nullptr; } - } - +} + #ifdef DEBUG_DECODE DebugLog(DecodeFile, "\n"); #endif - // TODO: now, we have in NewMails new mails. If NewMails is not NULL, we found some new mails, so Checking for new mail should be performed - // now, we do not call CheckPOP3 + // TODO: now, we have in NewMails new mails. If NewMails is not NULL, we found some new mails, so Checking for new mail should be performed + // now, we do not call CheckPOP3 - // if there is no waiting thread for internet connection close it - // else leave connection open - // if this functin was called from SynchroPOP3, then do not try to disconnect + // if there is no waiting thread for internet connection close it + // else leave connection open + // if this functin was called from SynchroPOP3, then do not try to disconnect if (POP3_DELETEFROMCHECK != POP3PluginParam) { - YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualCopied.NFlags, YAMN_ACC_MSGP, YAMNParam}; + YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualCopied.NFlags, YAMN_ACC_MSGP, YAMNParam }; CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, YAMN_MAILBROWSERVERSION); if (0 == ActualAccount->InternetQueries.GetNumber()) { @@ -1008,7 +977,7 @@ void __cdecl DeleteMailsPOP3(void *param) MyClient->NetClient->Disconnect(); SetStatusFcn(ActualAccount, TranslateT("Disconnected")); - } + } UsingInternet = FALSE; SetEvent(ActualAccount->UseInternetFree); @@ -1034,10 +1003,10 @@ void __cdecl DeleteMailsPOP3(void *param) ActualAccount->Client.NetClient->Disconnect(); break; default: - PostErrorProc(ActualAccount, YAMNParam, POP3PluginParam, MyClient->SSL); //it closes internet connection too + PostErrorProc(ActualAccount, YAMNParam, POP3PluginParam, MyClient->SSL); // it closes internet connection too } - if (UsingInternet && (POP3_DELETEFROMCHECK != POP3PluginParam)) //if our thread still uses internet and it is needed to release internet + if (UsingInternet && (POP3_DELETEFROMCHECK != POP3PluginParam)) // if our thread still uses internet and it is needed to release internet SetEvent(ActualAccount->UseInternetFree); } @@ -1052,7 +1021,7 @@ void __cdecl DeleteMailsPOP3(void *param) DebugLog(CommFile, "\n"); #endif - // WriteAccounts(); + // WriteAccounts(); return; } @@ -1063,7 +1032,7 @@ void ExtractStat(char *stream, int *mboxsize, int *mails) if (ACKLINE(finder)) { while (!WS(finder)) finder++; while (WS(finder)) finder++; - } +} if (1 != sscanf(finder, "%d", mails)) throw (uint32_t)EPOP3_STAT; while (!WS(finder)) finder++; @@ -1080,31 +1049,31 @@ void ExtractMail(char *stream, int len, HYAMNMAIL queue) while (WS(finder) || ENDLINE(finder)) finder++; while (!ACKLINE(finder)) finder++; - while (!ENDLINE(finder)) finder++; //now we at the end of first ack line + while (!ENDLINE(finder)) finder++; // now we at the end of first ack line while (finder <= (stream + len)) { - while (ENDLINE(finder)) finder++; //go to the new line - if (DOTLINE(finder + 1)) //at the end of stream + while (ENDLINE(finder)) finder++; // go to the new line + if (DOTLINE(finder + 1)) // at the end of stream break; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "\n"); #endif - while (WS(finder)) finder++; //jump whitespace + while (WS(finder)) finder++; // jump whitespace if (1 != sscanf(finder, "%d", &msgnr)) throw (uint32_t)EPOP3_UIDL; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "%d\n", msgnr); #endif - // for (i=1,queueptr=queue;(queueptr->Next != NULL) && (iNext,i++); - // if (i != msgnr) - // throw (uint32_t)EPOP3_UIDL; - while (!WS(finder)) finder++; //jump characters - while (WS(finder)) finder++; //jump whitespace + // for (i=1,queueptr=queue;(queueptr->Next != NULL) && (iNext,i++); + // if (i != msgnr) + // throw (uint32_t)EPOP3_UIDL; + while (!WS(finder)) finder++; // jump characters + while (WS(finder)) finder++; // jump whitespace finderend = finder + 1; while (!WS(finderend) && !ENDLINE(finderend)) finderend++; queueptr->ID = new char[finderend - finder + 1]; for (i = 0; finder != finderend; finder++, i++) queueptr->MailData->Body[i] = *finder; - queueptr->MailData->Body[i] = 0; //ends string + queueptr->MailData->Body[i] = 0; // ends string queueptr->Number = msgnr; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "%s\n", queueptr->MailData->Body); @@ -1124,31 +1093,31 @@ void ExtractUIDL(char *stream, int len, HYAMNMAIL queue) while (WS(finder) || ENDLINE(finder)) finder++; while (!ACKLINE(finder)) finder++; - while (!ENDLINE(finder)) finder++; //now we at the end of first ack line + while (!ENDLINE(finder)) finder++; // now we at the end of first ack line while (finder <= (stream + len)) { - while (ENDLINE(finder)) finder++; //go to the new line - if (DOTLINE(finder + 1)) //at the end of stream + while (ENDLINE(finder)) finder++; // go to the new line + if (DOTLINE(finder + 1)) // at the end of stream break; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "\n"); #endif - while (WS(finder)) finder++; //jump whitespace + while (WS(finder)) finder++; // jump whitespace if (1 != sscanf(finder, "%d", &msgnr)) throw (uint32_t)EPOP3_UIDL; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "%d\n", msgnr); #endif - // for (i=1,queueptr=queue;(queueptr->Next != NULL) && (iNext,i++); - // if (i != msgnr) - // throw (uint32_t)EPOP3_UIDL; - while (!WS(finder)) finder++; //jump characters - while (WS(finder)) finder++; //jump whitespace + // for (i=1,queueptr=queue;(queueptr->Next != NULL) && (iNext,i++); + // if (i != msgnr) + // throw (uint32_t)EPOP3_UIDL; + while (!WS(finder)) finder++; // jump characters + while (WS(finder)) finder++; // jump whitespace finderend = finder + 1; while (!WS(finderend) && !ENDLINE(finderend)) finderend++; queueptr->ID = new char[finderend - finder + 1]; for (i = 0; finder != finderend; finder++, i++) queueptr->ID[i] = *finder; - queueptr->ID[i] = 0; //ends string + queueptr->ID[i] = 0; // ends string queueptr->Number = msgnr; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "%s\n", queueptr->ID); @@ -1168,16 +1137,16 @@ void ExtractList(char *stream, int len, HYAMNMAIL queue) while (WS(finder) || ENDLINE(finder)) finder++; while (!ACKLINE(finder)) finder++; - while (!ENDLINE(finder)) finder++; //now we at the end of first ack line + while (!ENDLINE(finder)) finder++; // now we at the end of first ack line while (finder <= (stream + len)) { - while (ENDLINE(finder)) finder++; //go to the new line - if (DOTLINE(finder + 1)) //at the end of stream + while (ENDLINE(finder)) finder++; // go to the new line + if (DOTLINE(finder + 1)) // at the end of stream break; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "\n", NULL, 0); #endif - while (WS(finder)) finder++; //jump whitespace - if (1 != sscanf(finder, "%d", &msgnr)) //message nr. + while (WS(finder)) finder++; // jump whitespace + if (1 != sscanf(finder, "%d", &msgnr)) // message nr. throw (uint32_t)EPOP3_LIST; #ifdef DEBUG_DECODE DebugLog(DecodeFile, "%d\n", msgnr); @@ -1186,8 +1155,8 @@ void ExtractList(char *stream, int len, HYAMNMAIL queue) for (i = 1, queueptr = queue; (queueptr->Next != nullptr) && (i < msgnr); queueptr = queueptr->Next, i++); if (i != msgnr) throw (uint32_t)EPOP3_LIST; - while (!WS(finder)) finder++; //jump characters - while (WS(finder)) finder++; //jump whitespace + while (!WS(finder)) finder++; // jump characters + while (WS(finder)) finder++; // jump whitespace finderend = finder + 1; if (1 != sscanf(finder, "%u", &queueptr->MailData->Size)) throw (uint32_t)EPOP3_LIST; @@ -1202,8 +1171,8 @@ wchar_t *WINAPI GetErrorString(DWORD Code) { static wchar_t *POP3Errors[] = { - LPGENW("Memory allocation error."), //memory allocation - LPGENW("Account is about to be stopped."), //stop account + LPGENW("Memory allocation error."), // memory allocation + LPGENW("Account is about to be stopped."), // stop account LPGENW("Cannot connect to POP3 server."), LPGENW("Cannot allocate memory for received data."), LPGENW("Cannot login to POP3 server."), diff --git a/protocols/YAMN/src/proto/pop3/pop3opt.cpp b/protocols/YAMN/src/proto/pop3/pop3opt.cpp index 25937acbbb..5966cc84cf 100644 --- a/protocols/YAMN/src/proto/pop3/pop3opt.cpp +++ b/protocols/YAMN/src/proto/pop3/pop3opt.cpp @@ -199,10 +199,11 @@ static BOOL DlgShowAccountStatus(HWND hDlg, CPOP3Account* ActualAccount) static INT_PTR CALLBACK DlgProcPOP3AccStatusOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM) { - static CPOP3Account* ActualAccount; + static CPOP3Account *ActualAccount; + switch (msg) { case WM_INITDIALOG: - ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput); + ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, DlgInput); if (ActualAccount != nullptr) { DlgShowAccountStatus(hDlg, ActualAccount); for (auto &it : g_iStatusControls) @@ -400,7 +401,7 @@ public: void onKillFocus_Account(CCtrlCombo *) { GetDlgItemTextA(m_hwnd, IDC_COMBOACCOUNT, DlgInput, _countof(DlgInput)); - if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))) { + if (nullptr == (ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, DlgInput))) { DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr); EnableWindow(GetDlgItem(m_hwnd, IDC_BTNDEL), FALSE); DlgEnableAccount(mir_strlen(DlgInput) > 0); @@ -417,7 +418,7 @@ public: if (CB_ERR != (Result = cmbAccount.GetCurSel())) SendDlgItemMessageA(m_hwnd, IDC_COMBOACCOUNT, CB_GETLBTEXT, (WPARAM)Result, (LPARAM)DlgInput); - if ((Result == CB_ERR) || (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) { + if ((Result == CB_ERR) || (nullptr == (ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, DlgInput)))) { DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr); EnableWindow(GetDlgItem(m_hwnd, IDC_BTNDEL), FALSE); } @@ -509,7 +510,7 @@ public: GetDlgItemTextA(m_hwnd, IDC_COMBOACCOUNT, DlgInput, _countof(DlgInput)); EnableWindow(GetDlgItem(m_hwnd, IDC_BTNDEL), FALSE); if ((CB_ERR == (Result = SendDlgItemMessage(m_hwnd, IDC_COMBOACCOUNT, CB_GETCURSEL, 0, 0))) - || (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) + || (nullptr == (ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, DlgInput)))) return; if (IDOK != MessageBox(m_hwnd, TranslateT("Do you really want to delete this account?"), TranslateT("Delete account confirmation"), MB_OKCANCEL | MB_ICONWARNING)) @@ -520,7 +521,7 @@ public: if (ActualAccount->hContact != NULL) db_delete_contact(ActualAccount->hContact, true); - CallService(MS_YAMN_DELETEACCOUNT, (WPARAM)POP3Plugin, (LPARAM)ActualAccount); + DeleteAccount(POP3Plugin, ActualAccount); // We can consider our account as deleted. SendDlgItemMessage(m_hwnd, IDC_COMBOACCOUNT, CB_DELETESTRING, Result, 0); @@ -595,10 +596,10 @@ public: DlgSetItemTextW(m_hwnd, IDC_STTIMELEFT, TranslateT("Please wait while no account is in use.")); - if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)Text))) { + if (nullptr == (ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, Text))) { NewAcc = TRUE; SWriteGuard swb(POP3Plugin->AccountBrowserSO); - if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)POP3Plugin, (LPARAM)YAMN_ACCOUNTVERSION))) { + if (nullptr == (ActualAccount = (CPOP3Account*)GetNextFreeAccount(POP3Plugin))) { swb.Uninit(); MessageBox(m_hwnd, TranslateT("Cannot allocate memory space for new account"), TranslateT("Memory error"), MB_OK); return false; @@ -867,7 +868,7 @@ public: void onKillFocus_Account(CCtrlCombo *) { GetDlgItemTextA(m_hwnd, IDC_COMBOACCOUNT, DlgInput, _countof(DlgInput)); - if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))) { + if (nullptr == (ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, DlgInput))) { DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr); if (mir_strlen(DlgInput)) DlgEnableAccountPopup(true); @@ -886,7 +887,7 @@ public: int Result = cmbAccount.GetCurSel(); if (CB_ERR != Result) SendDlgItemMessageA(m_hwnd, IDC_COMBOACCOUNT, CB_GETLBTEXT, (WPARAM)Result, (LPARAM)DlgInput); - if ((Result == CB_ERR) || (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) { + if ((Result == CB_ERR) || (nullptr == (ActualAccount = (CPOP3Account*)FindAccountByName(POP3Plugin, DlgInput)))) { DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr); } else { diff --git a/protocols/YAMN/src/protoplugin.cpp b/protocols/YAMN/src/protoplugin.cpp index 7732640fcb..26479e292e 100644 --- a/protocols/YAMN/src/protoplugin.cpp +++ b/protocols/YAMN/src/protoplugin.cpp @@ -10,62 +10,30 @@ YAMN_PROTOPLUGINQUEUE *FirstProtoPlugin = nullptr; -INT_PTR RegisterProtocolPluginSvc(WPARAM, LPARAM); - -//Removes plugin from queue and deletes registration structures -INT_PTR UnregisterProtocolPlugin(YAMN_PROTOPLUGIN *Plugin); - -INT_PTR UnregisterProtocolPluginSvc(WPARAM, LPARAM); - -//Removes plugins from queue and deletes registration structures +// Removes plugins from queue and deletes registration structures INT_PTR UnregisterProtoPlugins(); -//Sets imported functions for an plugin and therefore it starts plugin to be registered and running -// Plugin- plugin, which wants to set its functions -// YAMNFcn- pointer to imported functions with accounts -// YAMNFcnVer- version of YAMN_PROTOIMPORTFCN, use YAMN_PROTOIMPORTFCNVERSION -// YAMNMailFcn- pointer to imported functions with mails -// YAMNMailFcnVer- version of YAMN_MAILIMPORTFCN, use YAMN_MAILIMPORTFCNVERSION -// returns nonzero if success -int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer); - -struct CExportedServices ProtoPluginExportedSvc[] = -{ - {MS_YAMN_REGISTERPROTOPLUGIN, RegisterProtocolPluginSvc}, - {MS_YAMN_UNREGISTERPROTOPLUGIN, UnregisterProtocolPluginSvc}, - {MS_YAMN_GETFILENAME, GetFileNameSvc}, - {MS_YAMN_DELETEFILENAME, DeleteFileNameSvc}, -}; - //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- -INT_PTR RegisterProtocolPluginSvc(WPARAM wParam, LPARAM lParam) +YAMN_PROTOPLUGIN* RegisterProtocolPlugin(YAMN_PROTOREGISTRATION *Registration) { - PYAMN_PROTOREGISTRATION Registration = (PYAMN_PROTOREGISTRATION)wParam; - YAMN_PROTOPLUGIN *Plugin; - - if (lParam != YAMN_PROTOREGISTRATIONVERSION) - return 0; if ((Registration->Name == nullptr) || (Registration->Ver == nullptr)) return (INT_PTR)NULL; - if (nullptr == (Plugin = new YAMN_PROTOPLUGIN)) - return (INT_PTR)NULL; + auto *Plugin = new YAMN_PROTOPLUGIN(); Plugin->PluginInfo = Registration; - Plugin->FirstAccount = nullptr; - Plugin->Fcn = nullptr; - Plugin->MailFcn = nullptr; - - return (INT_PTR)Plugin; + return Plugin; } -int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer) +// Sets imported functions for an plugin and therefore it starts plugin to be registered and running +// Plugin- plugin, which wants to set its functions +// YAMNFcn- pointer to imported functions with accounts +// YAMNMailFcn- pointer to imported functions with mails +// returns nonzero if success + +int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, YAMN_PROTOIMPORTFCN *YAMNFcn, YAMN_MAILIMPORTFCN *YAMNMailFcn) { - if (YAMNFcnVer != YAMN_PROTOIMPORTFCNVERSION) - return 0; - if (YAMNMailFcnVer != YAMN_MAILIMPORTFCNVERSION) - return 0; if (YAMNFcn == nullptr) return 0; if (YAMNMailFcn == nullptr) @@ -93,10 +61,11 @@ int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIM return 1; } -INT_PTR UnregisterProtocolPlugin(YAMN_PROTOPLUGIN *Plugin) +int UnregisterProtocolPlugin(YAMN_PROTOPLUGIN *Plugin) { - YAMN_PROTOPLUGINQUEUE *Parser, *Found; + mir_cslock lck(PluginRegCS); + YAMN_PROTOPLUGINQUEUE *Parser, *Found; if (FirstProtoPlugin->Plugin == Plugin) { Found = FirstProtoPlugin; FirstProtoPlugin = FirstProtoPlugin->Next; @@ -124,15 +93,6 @@ INT_PTR UnregisterProtocolPlugin(YAMN_PROTOPLUGIN *Plugin) return 0; } -INT_PTR UnregisterProtocolPluginSvc(WPARAM wParam, LPARAM) -{ - YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam; - - mir_cslock lck(PluginRegCS); - UnregisterProtocolPlugin(Plugin); - return 1; -} - INT_PTR UnregisterProtoPlugins() { mir_cslock lck(PluginRegCS); @@ -142,20 +102,7 @@ INT_PTR UnregisterProtoPlugins() return 1; } -INT_PTR GetFileNameSvc(WPARAM wParam, LPARAM) +CMStringW GetFileName(wchar_t *pwszPlugin) { - wchar_t *FileName = new wchar_t[MAX_PATH]; - if (FileName == nullptr) - return NULL; - - mir_snwprintf(FileName, MAX_PATH, L"%s\\yamn-accounts.%s.%s.book", UserDirectory, (wchar_t *)wParam, ProfileName); - return (INT_PTR)FileName; -} - -INT_PTR DeleteFileNameSvc(WPARAM wParam, LPARAM) -{ - if ((wchar_t *)wParam != nullptr) - delete[](wchar_t *) wParam; - - return 0; + return CMStringW(FORMAT, L"%s\\yamn-accounts.%s.%s.book", UserDirectory, pwszPlugin, ProfileName); } diff --git a/protocols/YAMN/src/services.cpp b/protocols/YAMN/src/services.cpp index d1ce51c96a..3ada411646 100644 --- a/protocols/YAMN/src/services.cpp +++ b/protocols/YAMN/src/services.cpp @@ -53,9 +53,9 @@ static INT_PTR ContactApplication(WPARAM wParam, LPARAM) if (g_plugin.getString(wParam, "Id", &dbv)) return 0; - CAccount *ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); + CAccount *ActualAccount = FindAccountByName(POP3Plugin, dbv.pszVal); if (ActualAccount != nullptr) { - STARTUPINFOW si = {0}; + STARTUPINFOW si = { 0 }; si.cb = sizeof(si); SReadGuard sra(ActualAccount->AccountAccessSO); @@ -85,10 +85,9 @@ static INT_PTR ContactApplication(WPARAM wParam, LPARAM) return 0; } -uint32_t WINAPI SWMRGWaitToRead(SWMRG *pSWMRG, uint32_t dwTimeout); static INT_PTR AccountMailCheck(WPARAM wParam, LPARAM lParam) { - //This service will check/sincronize the account pointed by wParam + // This service will check/sincronize the account pointed by wParam CAccount *ActualAccount = (CAccount *)wParam; // copy/paste make mistakes if (ActualAccount != nullptr) { @@ -104,7 +103,7 @@ static INT_PTR AccountMailCheck(WPARAM wParam, LPARAM lParam) SReadGuard sra(ActualAccount->AccountAccessSO, 0); if (sra.Succeeded()) { if ((ActualAccount->Flags & YAMN_ACC_ENA) && ActualAccount->Plugin->Fcn->SynchroFcnPtr) { - CheckParam ParamToPlugin = {YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, lParam != 0 ? YAMN_FORCECHECK : YAMN_NORMALCHECK, nullptr, nullptr}; + CheckParam ParamToPlugin = { YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, lParam != 0 ? YAMN_FORCECHECK : YAMN_NORMALCHECK, nullptr, nullptr }; ActualAccount->TimeLeft = ActualAccount->Interval; DWORD tid; @@ -130,23 +129,23 @@ static INT_PTR ContactMailCheck(WPARAM hContact, LPARAM) if (g_plugin.getString(hContact, "Id", &dbv)) return 0; - CAccount *ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); - if (ActualAccount != nullptr) { - //we use event to signal, that running thread has all needed stack parameters copied + if (CAccount *ActualAccount = FindAccountByName(POP3Plugin, dbv.pszVal)) { + // we use event to signal, that running thread has all needed stack parameters copied HANDLE ThreadRunningEV; if (nullptr == (ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr))) return 0; - //if we want to close miranda, we get event and do not run pop3 checking anymore + + // 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; - + mir_cslock lck(PluginRegCS); SReadGuard sra(ActualAccount->AccountAccessSO); if (sra.Succeeded()) { - if ((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) //account cannot be forced to check - { + // account cannot be forced to check + if ((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) { DWORD tid; - struct CheckParam ParamToPlugin = {YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, YAMN_FORCECHECK, (void *)nullptr, nullptr}; + CheckParam ParamToPlugin = { YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, YAMN_FORCECHECK, (void *)nullptr, nullptr }; if (CreateThread(nullptr, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr, &ParamToPlugin, 0, &tid)) WaitForSingleObject(ThreadRunningEV, INFINITE); } @@ -167,11 +166,10 @@ static INT_PTR ContactMailCheck(WPARAM hContact, LPARAM) if (g_plugin.getString(wParam, "Id", &dbv)) return; - CAccount *ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal); - if (ActualAccount != nullptr) { + if (CAccount *ActualAccount = FindAccountByName(POP3Plugin, dbv.pszVal)) { SReadGuard sra(ActualAccount->AccountAccessSO); if (sra.Succeeded()) { - YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualAccount->NewMailN.Flags, ActualAccount->NoNewMailN.Flags, nullptr}; + YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualAccount->NewMailN.Flags, ActualAccount->NoNewMailN.Flags, nullptr }; Param.nnflags = Param.nnflags | YAMN_ACC_MSG; //show mails in account even no new mail in account Param.nnflags = Param.nnflags & ~YAMN_ACC_POP; @@ -194,7 +192,7 @@ HBITMAP LoadBmpFromIcon(HICON hIcon) HBRUSH hBkgBrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); - BITMAPINFOHEADER bih = {0}; + BITMAPINFOHEADER bih = {}; bih.biSize = sizeof(bih); bih.biBitCount = 24; bih.biPlanes = 1; @@ -275,51 +273,12 @@ void CreateServiceFunctions(void) CreateServiceFunction(YAMN_DBMODULE PS_GETNAME, Service_GetName); CreateServiceFunction(YAMN_DBMODULE PS_LOADICON, Service_LoadIcon); - // Function with which protocol plugin can register - CreateServiceFunction(MS_YAMN_REGISTERPROTOPLUGIN, RegisterProtocolPluginSvc); - - // Function with which protocol plugin can unregister - CreateServiceFunction(MS_YAMN_UNREGISTERPROTOPLUGIN, UnregisterProtocolPluginSvc); - - // Function creates an account for plugin - CreateServiceFunction(MS_YAMN_CREATEPLUGINACCOUNT, CreatePluginAccountSvc); - - // Function deletes plugin account - CreateServiceFunction(MS_YAMN_DELETEPLUGINACCOUNT, DeletePluginAccountSvc); - - // Finds account for plugin by name - CreateServiceFunction(MS_YAMN_FINDACCOUNTBYNAME, FindAccountByNameSvc); - - // Creates next account for plugin - CreateServiceFunction(MS_YAMN_GETNEXTFREEACCOUNT, GetNextFreeAccountSvc); - - // Function removes account from YAMN queue. Does not delete it from memory - CreateServiceFunction(MS_YAMN_DELETEACCOUNT, DeleteAccountSvc); - - // Function finds accounts for specified plugin - CreateServiceFunction(MS_YAMN_READACCOUNTS, AddAccountsFromFileSvc); - - // Function that stores all plugin mails to one file - CreateServiceFunction(MS_YAMN_WRITEACCOUNTS, WriteAccountsToFileSvc); - - // Function that returns user's filename - CreateServiceFunction(MS_YAMN_GETFILENAME, GetFileNameSvc); - - // Releases unicode string from memory - CreateServiceFunction(MS_YAMN_DELETEFILENAME, DeleteFileNameSvc); - // Checks mail CreateServiceFunction(MS_YAMN_FORCECHECK, ForceCheckSvc); // Runs YAMN's mail browser CreateServiceFunction(MS_YAMN_MAILBROWSER, RunMailBrowserSvc); - // Function creates new mail for plugin - CreateServiceFunction(MS_YAMN_CREATEACCOUNTMAIL, CreateAccountMailSvc); - - // Function deletes plugin account - CreateServiceFunction(MS_YAMN_DELETEACCOUNTMAIL, DeleteAccountMailSvc); - // Function contact list double click CreateServiceFunction(MS_YAMN_CLISTDBLCLICK, ClistContactDoubleclicked); diff --git a/protocols/YAMN/src/stdafx.h b/protocols/YAMN/src/stdafx.h index 0cfd60cda2..9369f2a418 100644 --- a/protocols/YAMN/src/stdafx.h +++ b/protocols/YAMN/src/stdafx.h @@ -67,60 +67,49 @@ void UnInitDebug(); #endif // From yamn.cpp -INT_PTR GetFcnPtrSvc(WPARAM wParam, LPARAM lParam); +// Function every seconds decrements account counter of seconds and checks if they are 0 +// If yes, creates a POP3 thread to check account void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD); + +// Function called to check all accounts immidialtelly +// no params INT_PTR ForceCheckSvc(WPARAM, LPARAM); // From account.cpp -INT_PTR CreatePluginAccountSvc(WPARAM wParam, LPARAM lParam); -INT_PTR DeletePluginAccountSvc(WPARAM wParam, LPARAM); int InitAccount(CAccount *Which); void DeInitAccount(CAccount *Which); void StopSignalFcn(CAccount *Which); void CodeDecodeString(char *Dest, BOOL Encrypt); uint32_t FileToMemory(wchar_t *FileName, char **MemFile, char **End); -#if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES) -uint32_t ReadStringFromMemory(char **Parser,char *End,char **StoreTo,char *DebugString); -#endif +uint32_t AddAccountsFromFile(YAMN_PROTOPLUGIN *Plugin, const wchar_t *pwszFilename); +CAccount* CreatePluginAccount(YAMN_PROTOPLUGIN *Plugin); +int DeleteAccount(YAMN_PROTOPLUGIN *Plugin, CAccount *Which); +void DeletePluginAccount(CAccount *OldAccount); +CAccount* FindAccountByName(YAMN_PROTOPLUGIN *Plugin, const char *SearchedAccount); +CAccount* GetNextFreeAccount(YAMN_PROTOPLUGIN *Plugin); +uint32_t WriteAccountsToFile(YAMN_PROTOPLUGIN *Plugin, const wchar_t *pwszFilename); + + uint32_t ReadStringFromMemory(char **Parser, char *End, char **StoreTo); uint32_t ReadMessagesFromMemory(CAccount *Which, char **Parser, char *End); -uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, wchar_t *End); -INT_PTR AddAccountsFromFileSvc(WPARAM wParam, LPARAM lParam); uint32_t WriteStringToFile(HANDLE File, char *Source); uint32_t WriteStringToFileW(HANDLE File, wchar_t *Source); - DWORD WriteMessagesToFile(HANDLE File, CAccount *Which); -DWORD WINAPI WritePOP3Accounts(); -INT_PTR WriteAccountsToFileSvc(WPARAM wParam, LPARAM lParam); -INT_PTR FindAccountByNameSvc(WPARAM wParam, LPARAM lParam); -INT_PTR GetNextFreeAccountSvc(WPARAM wParam, LPARAM lParam); +DWORD WritePOP3Accounts(); -INT_PTR DeleteAccountSvc(WPARAM wParam, LPARAM); void __cdecl DeleteAccountInBackground(void *Which); int StopAccounts(YAMN_PROTOPLUGIN *Plugin); int WaitForAllAccounts(YAMN_PROTOPLUGIN *Plugin, BOOL GetAccountBrowserAccess = FALSE); int DeleteAccounts(YAMN_PROTOPLUGIN *Plugin); -void WINAPI GetStatusFcn(CAccount *Which, wchar_t *Value); -void WINAPI SetStatusFcn(CAccount *Which, wchar_t *Value); +void GetStatusFcn(CAccount *Which, wchar_t *Value); +void SetStatusFcn(CAccount *Which, wchar_t *Value); INT_PTR UnregisterProtoPlugins(); -INT_PTR RegisterProtocolPluginSvc(WPARAM, LPARAM); -INT_PTR UnregisterProtocolPluginSvc(WPARAM, LPARAM); -INT_PTR GetFileNameSvc(WPARAM, LPARAM); -INT_PTR DeleteFileNameSvc(WPARAM, LPARAM); - -// From mails.cpp (MIME) -// struct CExportedFunctions MailExported[]; -INT_PTR CreateAccountMailSvc(WPARAM wParam, LPARAM lParam); -INT_PTR DeleteAccountMailSvc(WPARAM wParam, LPARAM lParam); -INT_PTR LoadMailDataSvc(WPARAM wParam, LPARAM lParam); -INT_PTR UnloadMailDataSvc(WPARAM wParam, LPARAM); -INT_PTR SaveMailDataSvc(WPARAM wParam, LPARAM lParam); // From mime.cpp // void WINAPI ExtractHeaderFcn(char *,int,uint16_t,HYAMNMAIL); //already in MailExported @@ -168,18 +157,20 @@ extern HCURSOR hCurSplitNS, hCurSplitWE; extern UINT SecTimer; // From synchro.cpp -void WINAPI DeleteMessagesToEndFcn(CAccount *Account, HYAMNMAIL From); +void DeleteMessagesToEndFcn(CAccount *Account, HYAMNMAIL From); // From mails.cpp -void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode); -void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From, uint32_t FlagsSet, uint32_t FlagsNotSet, uint32_t FlagsToSet, int mode); - -void WINAPI AppendQueueFcn(HYAMNMAIL first, HYAMNMAIL second); -HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From); -void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode = 0); -HYAMNMAIL WINAPI FindMessageByIDFcn(HYAMNMAIL From, char *ID); -void WINAPI SynchroMessagesFcn(CAccount *Account, HYAMNMAIL *OldQueue, HYAMNMAIL *RemovedOld, HYAMNMAIL *NewQueue, HYAMNMAIL *RemovedNew); -void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head); +void DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode); +void SetRemoveFlagsInQueueFcn(HYAMNMAIL From, uint32_t FlagsSet, uint32_t FlagsNotSet, uint32_t FlagsToSet, int mode); + +void AppendQueueFcn(HYAMNMAIL first, HYAMNMAIL second); +HYAMNMAIL CreateAccountMail(CAccount *Account); +HYAMNMAIL CreateNewDeleteQueueFcn(HYAMNMAIL From); +int DeleteAccountMail(YAMN_PROTOPLUGIN *Plugin, HYAMNMAIL OldMail); +void DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode = 0); +HYAMNMAIL FindMessageByIDFcn(HYAMNMAIL From, char *ID); +void SynchroMessagesFcn(CAccount *Account, HYAMNMAIL *OldQueue, HYAMNMAIL *RemovedOld, HYAMNMAIL *NewQueue, HYAMNMAIL *RemovedNew); +void TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head); // From mime.cpp void ExtractHeader(struct CMimeItem *items, int &CP, struct CHeader *head); @@ -189,9 +180,7 @@ void DeleteShortHeaderContent(struct CShortHeader *head); char *ExtractFromContentType(char *ContentType, char *value); wchar_t *ParseMultipartBody(char *src, char *bond); -//From account.cpp -void WINAPI GetStatusFcn(CAccount *Which, wchar_t *Value); - +// From account.cpp extern YAMN_PROTOPLUGIN *POP3Plugin; //from decode.cpp @@ -205,13 +194,19 @@ extern char *iconDescs[]; extern char *iconNames[]; extern HIMAGELIST CSImages; -extern void __stdcall SSL_DebugLog(const char *fmt, ...); +int SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, YAMN_PROTOIMPORTFCN *YAMNFcn, YAMN_MAILIMPORTFCN *YAMNMailFcn); + +void __stdcall SSL_DebugLog(const char *fmt, ...); extern struct WndHandles *MessageWnd; -extern int GetCharsetFromString(char *input, size_t size); -extern void ConvertCodedStringToUnicode(char *stream, wchar_t **storeto, uint32_t cp, int mode); +YAMN_PROTOPLUGIN* RegisterProtocolPlugin(YAMN_PROTOREGISTRATION *Registration); + +int GetCharsetFromString(char *input, size_t size); +void ConvertCodedStringToUnicode(char *stream, wchar_t **storeto, uint32_t cp, int mode); extern PVOID TLSCtx; extern PVOID SSLCtx; +CMStringW GetFileName(wchar_t *pwszPlugin); + #endif diff --git a/protocols/YAMN/src/yamn.cpp b/protocols/YAMN/src/yamn.cpp index 753f269d3a..e4ad646694 100644 --- a/protocols/YAMN/src/yamn.cpp +++ b/protocols/YAMN/src/yamn.cpp @@ -26,34 +26,13 @@ HANDLE ExitEV; //If this is signaled, write accounts to file is performed. Set this event if you want to actualize your accounts and messages HANDLE WriteToFileEV; -// Function every seconds decrements account counter of seconds and checks if they are 0 -// If yes, creates a POP3 thread to check account -void CALLBACK TimerProc(HWND, UINT, UINT, uint32_t); - -// Function called to check all accounts immidialtelly -// no params -INT_PTR ForceCheckSvc(WPARAM, LPARAM); - -//thread is running all the time -//waits for WriteToFileEV and then writes all accounts to file -//uint32_t WINAPI FileWritingThread(PVOID); - // Function is called when Miranda notifies plugin that it is about to exit // Ensures succesfull end of POP3 checking, sets event that no next checking should be performed // If there's no writer to account (POP3 thread), saves the results to the file -//not used now, perhaps in the future - - -//int ExitProc(WPARAM wParam, LPARAM lParam); - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- +// not used now, perhaps in the future void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) { - CAccount *ActualAccount; - DWORD Status, tid; - // we use event to signal, that running thread has all needed stack parameters copied HANDLE ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (ThreadRunningEV == nullptr) @@ -64,7 +43,7 @@ void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) return; // Get actual status of current user in Miranda - Status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0); + DWORD Status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0); mir_cslock lck(PluginRegCS); for (YAMN_PROTOPLUGINQUEUE *ActualPlugin = FirstProtoPlugin; ActualPlugin != nullptr; ActualPlugin = ActualPlugin->Next) { @@ -72,7 +51,7 @@ void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) if (!srb.Succeeded()) return; - for (ActualAccount = ActualPlugin->Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) { + for (auto *ActualAccount = ActualPlugin->Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) { if (ActualAccount->Plugin == nullptr || ActualAccount->Plugin->Fcn == nullptr) //account not inited continue; @@ -104,6 +83,8 @@ void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) struct CheckParam ParamToPlugin = {YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, YAMN_NORMALCHECK, (void *)nullptr, nullptr}; ActualAccount->TimeLeft = ActualAccount->Interval; + + DWORD tid; HANDLE NewThread = CreateThread(nullptr, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->TimeoutFcnPtr, &ParamToPlugin, 0, &tid); if (NewThread == nullptr) continue; @@ -116,13 +97,12 @@ void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) ChangeIsCountingStatusLabel: if (((ActualAccount->isCounting) != 0) != isAccountCounting) { ActualAccount->isCounting = isAccountCounting; + uint16_t cStatus = g_plugin.getWord(ActualAccount->hContact, "Status"); switch (cStatus) { case ID_STATUS_ONLINE: case ID_STATUS_OFFLINE: g_plugin.setWord(ActualAccount->hContact, "Status", isAccountCounting ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE); - default: - break; } } } @@ -132,14 +112,12 @@ ChangeIsCountingStatusLabel: INT_PTR ForceCheckSvc(WPARAM, LPARAM) { - CAccount *ActualAccount; - DWORD tid; - - //we use event to signal, that running thread has all needed stack parameters copied + // we use event to signal, that running thread has all needed stack parameters copied HANDLE ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (ThreadRunningEV == nullptr) return 0; - //if we want to close miranda, we get event and do not run pop3 checking anymore + + // 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; @@ -147,7 +125,7 @@ INT_PTR ForceCheckSvc(WPARAM, LPARAM) for (YAMN_PROTOPLUGINQUEUE *ActualPlugin = FirstProtoPlugin; ActualPlugin != nullptr; ActualPlugin = ActualPlugin->Next) { SReadGuard srb(ActualPlugin->Plugin->AccountBrowserSO); - for (ActualAccount = ActualPlugin->Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) { + for (auto *ActualAccount = ActualPlugin->Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) { if (ActualAccount->Plugin->Fcn == nullptr) //account not inited continue; @@ -159,8 +137,8 @@ INT_PTR ForceCheckSvc(WPARAM, LPARAM) if (ActualAccount->Plugin->Fcn->ForceCheckFcnPtr == nullptr) continue; - struct CheckParam ParamToPlugin = { YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, YAMN_FORCECHECK, (void *)nullptr, nullptr }; - + DWORD tid; + CheckParam ParamToPlugin = { YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, YAMN_FORCECHECK, (void *)nullptr, nullptr }; if (nullptr == CreateThread(nullptr, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr, &ParamToPlugin, 0, &tid)) continue; -- cgit v1.2.3