summaryrefslogtreecommitdiff
path: root/protocols/YAMN
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-10-06 14:03:42 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-10-06 14:03:42 +0300
commit4f7cb79f7c8d1b46260f135e3ab7ba615cf8ea29 (patch)
tree70bab49f49e7f4989445ba9a8bff94c90e1acf60 /protocols/YAMN
parent4549087d4f7044dbf51a75d1af605ac93f6fbd6b (diff)
fixes #3704 (YAMN: Миранда зависает если изменить настройки YAMN во время прилёта письма)
Diffstat (limited to 'protocols/YAMN')
-rw-r--r--protocols/YAMN/src/account.cpp208
-rw-r--r--protocols/YAMN/src/browser/badconnect.cpp140
-rw-r--r--protocols/YAMN/src/browser/browser.h23
-rw-r--r--protocols/YAMN/src/browser/mailbrowser.cpp566
-rw-r--r--protocols/YAMN/src/filterplugin.cpp3
-rw-r--r--protocols/YAMN/src/mails/mails.cpp20
-rw-r--r--protocols/YAMN/src/main.cpp53
-rw-r--r--protocols/YAMN/src/main.h2
-rw-r--r--protocols/YAMN/src/proto/pop3/pop3comm.cpp417
-rw-r--r--protocols/YAMN/src/proto/pop3/pop3comm.h64
-rw-r--r--protocols/YAMN/src/proto/pop3/pop3opt.cpp389
-rw-r--r--protocols/YAMN/src/protoplugin.cpp55
-rw-r--r--protocols/YAMN/src/services.cpp39
-rw-r--r--protocols/YAMN/src/stdafx.h59
-rw-r--r--protocols/YAMN/src/synchro.cpp289
-rw-r--r--protocols/YAMN/src/version.h6
-rw-r--r--protocols/YAMN/src/yamn.cpp92
17 files changed, 992 insertions, 1433 deletions
diff --git a/protocols/YAMN/src/account.cpp b/protocols/YAMN/src/account.cpp
index 46b7782ab0..55c9dbb9a9 100644
--- a/protocols/YAMN/src/account.cpp
+++ b/protocols/YAMN/src/account.cpp
@@ -17,12 +17,6 @@ static mir_cs csAccountStatusCS;
// When 2 threads want to write to file...
static mir_cs csFileWritingCS;
-struct CExportedFunctions AccountExportedFcn[] =
-{
- {YAMN_GETSTATUSID, (void *)GetStatusFcn},
- {YAMN_SETSTATUSID, (void *)SetStatusFcn},
-};
-
struct CExportedServices AccountExportedSvc[] =
{
{MS_YAMN_CREATEPLUGINACCOUNT, CreatePluginAccountSvc},
@@ -39,7 +33,7 @@ struct CExportedServices AccountExportedSvc[] =
INT_PTR CreatePluginAccountSvc(WPARAM wParam, LPARAM lParam)
{
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN *)wParam;
uint32_t AccountVersion = (uint32_t)lParam;
//test if we are going to initialize members of suitable structure (structures of plugin and YAMN must match)
@@ -53,7 +47,7 @@ INT_PTR CreatePluginAccountSvc(WPARAM wParam, LPARAM lParam)
NewAccount = Plugin->Fcn->NewAccountFcnPtr(Plugin, YAMN_ACCOUNTVERSION);
else
//We suggest plugin uses standard CAccount structure, so we create it
- NewAccount = new struct CAccount;
+ NewAccount = new CAccount();
//If not created successfully
if (NewAccount == nullptr)
@@ -90,15 +84,7 @@ INT_PTR DeletePluginAccountSvc(WPARAM wParam, LPARAM)
int InitAccount(CAccount *Which)
{
- //initialize synchronizing objects
- Which->AccountAccessSO = new SWMRG;
- SWMRGInitialize(Which->AccountAccessSO, nullptr);
- Which->MessagesAccessSO = new SWMRG;
- SWMRGInitialize(Which->MessagesAccessSO, nullptr);
- Which->UsingThreads = new SCOUNTER;
- SWMRGInitialize(Which->MessagesAccessSO, nullptr);
-
- //zero memory, where timestamps are stored
+ // zero memory, where timestamps are stored
memset(&Which->LastChecked, 0, sizeof(Which->LastChecked));
memset(&Which->LastSChecked, 0, sizeof(Which->LastSChecked));
memset(&Which->LastSynchronised, 0, sizeof(Which->LastSynchronised));
@@ -111,7 +97,7 @@ int InitAccount(CAccount *Which)
Which->StatusFlags = YAMN_ACC_ST1 + YAMN_ACC_ST7;
Which->Next = nullptr;
- Which->Server = new struct CServer;
+ Which->Server = new CServer();
Which->AbleToWork = TRUE;
return 1;
@@ -132,11 +118,6 @@ void DeInitAccount(CAccount *Which)
delete[] Which->Server;
}
- SWMRGDelete(Which->AccountAccessSO);
- delete Which->AccountAccessSO;
- SWMRGDelete(Which->MessagesAccessSO);
- delete Which->MessagesAccessSO;
- delete Which->UsingThreads;
DeleteMessagesToEndFcn(Which, (HYAMNMAIL)Which->Mails);
}
@@ -144,10 +125,11 @@ void StopSignalFcn(CAccount *Which)
//set event that we are going to delete account
{
Which->AbleToWork = FALSE;
- //do not use synchronizing objects anymore
- //any access to these objects then ends with WAIT_FAILED
- SetEvent(Which->AccountAccessSO->hFinishEV);
- SetEvent(Which->MessagesAccessSO->hFinishEV);
+
+ // do not use synchronizing objects anymore
+ // any access to these objects then ends with WAIT_FAILED
+ Which->AccountAccessSO.Stop();
+ Which->MessagesAccessSO.Stop();
}
void CodeDecodeString(char *Dest, BOOL Encrypt)
@@ -426,9 +408,9 @@ uint32_t ReadMessagesFromMemory(CAccount *Which, char **Parser, char *End)
#endif
if (items == nullptr)
- items = ActualMail->MailData->TranslatedHeader = new struct CMimeItem;
+ items = ActualMail->MailData->TranslatedHeader = new CMimeItem();
else {
- items->Next = new struct CMimeItem;
+ items->Next = new CMimeItem();
items = items->Next;
}
if (items == nullptr)
@@ -548,15 +530,12 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End)
return Stat;
// Read mails
- WaitToWriteFcn(Which->MessagesAccessSO);
-
- if (Stat = ReadMessagesFromMemory(Which, Parser, End)) {
- WriteDoneFcn(Which->MessagesAccessSO);
- return Stat;
+ {
+ SWriteGuard sw(Which->MessagesAccessSO);
+ if (Stat = ReadMessagesFromMemory(Which, Parser, End))
+ return Stat;
}
- WriteDoneFcn(Which->MessagesAccessSO);
-
// Read timestamps
Which->LastChecked = *(SYSTEMTIME *)(*Parser);
(*Parser) += sizeof(SYSTEMTIME);
@@ -583,7 +562,7 @@ uint32_t ReadAccountFromMemory(CAccount *Which, char **Parser, char *End)
return 0;
}
-static INT_PTR PerformAccountReading(HYAMNPROTOPLUGIN Plugin, char *MemFile, char *End)
+static INT_PTR PerformAccountReading(YAMN_PROTOPLUGIN *Plugin, char *MemFile, char *End)
{
// Retrieve info for account from memory
char *Parser;
@@ -597,41 +576,38 @@ static INT_PTR PerformAccountReading(HYAMNPROTOPLUGIN Plugin, char *MemFile, cha
return EACC_FILEVERSION;
}
Parser = MemFile + sizeof(Ver);
-
- SWMRGWaitToWrite(Plugin->AccountBrowserSO, INFINITE);
-
- if (nullptr == (ActualAccount = (CAccount *)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)Plugin, (LPARAM)YAMN_ACCOUNTVERSION))) {
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
- delete[] MemFile;
- return EACC_ALLOC;
+ {
+ SWriteGuard swb(Plugin->AccountBrowserSO);
+ if (nullptr == (ActualAccount = (CAccount *)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)Plugin, (LPARAM)YAMN_ACCOUNTVERSION))) {
+ delete[] MemFile;
+ return EACC_ALLOC;
+ }
}
FirstAllocatedAccount = ActualAccount;
do {
CAccount *Temp;
+ {
+ SWriteGuard swb(Plugin->AccountBrowserSO);
+ Stat = ReadAccountFromMemory(ActualAccount, &Parser, End);
- WaitToWriteFcn(ActualAccount->AccountAccessSO);
- Stat = ReadAccountFromMemory(ActualAccount, &Parser, End);
+ if (ActualAccount->StatusFlags & (YAMN_ACC_STARTA | YAMN_ACC_STARTS))
+ ActualAccount->TimeLeft = 1; //check on loading
- if (ActualAccount->StatusFlags & (YAMN_ACC_STARTA | YAMN_ACC_STARTS))
- ActualAccount->TimeLeft = 1; //check on loading
+ if (Stat && (Stat != EACC_ENDOFFILE)) {
+ for (ActualAccount = FirstAllocatedAccount; ActualAccount != nullptr; ActualAccount = Temp) {
+ Temp = ActualAccount->Next;
+ delete ActualAccount;
+ }
+ delete[] MemFile;
+ if (Plugin->FirstAccount == FirstAllocatedAccount)
+ Plugin->FirstAccount = nullptr;
- if (Stat && (Stat != EACC_ENDOFFILE)) {
- for (ActualAccount = FirstAllocatedAccount; ActualAccount != nullptr; ActualAccount = Temp) {
- Temp = ActualAccount->Next;
- delete ActualAccount;
+ return (INT_PTR)Stat;
}
- delete[] MemFile;
- if (Plugin->FirstAccount == FirstAllocatedAccount)
- Plugin->FirstAccount = nullptr;
-
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
- return (INT_PTR)Stat;
}
- WriteDoneFcn(ActualAccount->AccountAccessSO);
-
if ((Stat != EACC_ENDOFFILE) && (nullptr == (ActualAccount = (CAccount *)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)Plugin, (LPARAM)YAMN_ACCOUNTVERSION)))) {
for (ActualAccount = FirstAllocatedAccount; ActualAccount != nullptr; ActualAccount = Temp) {
Temp = ActualAccount->Next;
@@ -641,12 +617,10 @@ static INT_PTR PerformAccountReading(HYAMNPROTOPLUGIN Plugin, char *MemFile, cha
if (Plugin->FirstAccount == FirstAllocatedAccount)
Plugin->FirstAccount = nullptr;
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
return EACC_ALLOC;
}
} while (Stat != EACC_ENDOFFILE);
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
delete[] MemFile;
return 0;
}
@@ -659,7 +633,7 @@ INT_PTR AddAccountsFromFileSvc(WPARAM wParam, LPARAM lParam)
if (Stat != NO_ERROR)
return (INT_PTR)Stat;
- return PerformAccountReading((HYAMNPROTOPLUGIN)wParam, MemFile, End);
+ return PerformAccountReading((YAMN_PROTOPLUGIN *)wParam, MemFile, End);
}
uint32_t WriteStringToFile(HANDLE File, char *Source)
@@ -727,31 +701,29 @@ DWORD WriteMessagesToFile(HANDLE File, CAccount *Which)
return 0;
}
-static INT_PTR PerformAccountWriting(HYAMNPROTOPLUGIN Plugin, HANDLE File)
+static INT_PTR PerformAccountWriting(YAMN_PROTOPLUGIN *Plugin, HANDLE File)
{
DWORD WrittenBytes, Stat;
CAccount *ActualAccount;
uint32_t Ver = YAMN_ACCOUNTFILEVERSION;
BOOL Writed = FALSE;
- uint32_t ReturnValue = 0, EnterCode;
+ uint32_t ReturnValue = 0;
- SWMRGWaitToRead(Plugin->AccountBrowserSO, INFINITE);
+ SReadGuard srb(Plugin->AccountBrowserSO);
try {
for (ActualAccount = Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) {
- EnterCode = WaitToReadFcn(ActualAccount->AccountAccessSO);
- if (EnterCode == WAIT_FINISH) //account is about to delete
- {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra == WAIT_FINISH) { //account is about to delete
ActualAccount = ActualAccount->Next;
continue;
}
- if (EnterCode == WAIT_FAILED) //account is deleted
+
+ if (sra == WAIT_FAILED) //account is deleted
break;
- if ((ActualAccount->Name == nullptr) || (*ActualAccount->Name == (wchar_t)0)) {
- ReadDoneFcn(ActualAccount->AccountAccessSO);
+ if ((ActualAccount->Name == nullptr) || (*ActualAccount->Name == (wchar_t)0))
continue;
- }
if (!Writed && !WriteFile(File, &Ver, sizeof(Ver), &WrittenBytes, nullptr))
throw (uint32_t)EACC_SYSTEM;
@@ -821,31 +793,20 @@ static INT_PTR PerformAccountWriting(HYAMNPROTOPLUGIN Plugin, HANDLE File)
if (Stat = ActualAccount->Plugin->Fcn->WritePluginOptsFcnPtr(File, ActualAccount))
throw (uint32_t)Stat;
- WaitToReadFcn(ActualAccount->MessagesAccessSO);
-
- if (Stat = WriteMessagesToFile(File, ActualAccount)) {
-
- ReadDoneFcn(ActualAccount->MessagesAccessSO);
+ if (Stat = WriteMessagesToFile(File, ActualAccount))
throw (uint32_t)Stat;
- }
-
- ReadDoneFcn(ActualAccount->MessagesAccessSO);
if ((!WriteFile(File, (char *)&ActualAccount->LastChecked, sizeof(SYSTEMTIME), &WrittenBytes, nullptr)) ||
(!WriteFile(File, (char *)&ActualAccount->LastSChecked, sizeof(SYSTEMTIME), &WrittenBytes, nullptr)) ||
(!WriteFile(File, (char *)&ActualAccount->LastSynchronised, sizeof(SYSTEMTIME), &WrittenBytes, nullptr)) ||
(!WriteFile(File, (char *)&ActualAccount->LastMail, sizeof(SYSTEMTIME), &WrittenBytes, nullptr)))
throw (uint32_t)Stat;
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
}
catch (uint32_t ErrorCode) {
- ReadDoneFcn(ActualAccount->AccountAccessSO);
ReturnValue = ErrorCode;
}
- SWMRGDoneReading(Plugin->AccountBrowserSO);
CloseHandle(File);
return 0;
}
@@ -853,7 +814,7 @@ static INT_PTR PerformAccountWriting(HYAMNPROTOPLUGIN Plugin, HANDLE File)
// Writes accounts to file
INT_PTR WriteAccountsToFileSvc(WPARAM wParam, LPARAM lParam)
{
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ 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);
@@ -865,23 +826,21 @@ INT_PTR WriteAccountsToFileSvc(WPARAM wParam, LPARAM lParam)
INT_PTR FindAccountByNameSvc(WPARAM wParam, LPARAM lParam)
{
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam;
char *SearchedAccount = (char *)lParam;
- CAccount *Finder;
- SWMRGWaitToRead(Plugin->AccountBrowserSO, INFINITE);
+ SReadGuard srb(Plugin->AccountBrowserSO);
- for (Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next)
+ for (auto *Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next)
if ((Finder->Name != nullptr) && (0 == mir_strcmp(SearchedAccount, Finder->Name)))
- break;
+ return (INT_PTR)Finder;
- SWMRGDoneReading(Plugin->AccountBrowserSO);
- return (INT_PTR)Finder;
+ return 0;
}
INT_PTR GetNextFreeAccountSvc(WPARAM wParam, LPARAM lParam)
{
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam;
CAccount *Finder;
if (Plugin->FirstAccount == nullptr) {
@@ -920,7 +879,7 @@ INT_PTR DeleteAccountSvc(WPARAM wParam, LPARAM lParam)
//4. wait until UsingThread Event is signaled
//5. delete account from memory
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam;
CAccount *Which = (CAccount *)lParam;
CAccount *Finder;
@@ -930,26 +889,24 @@ INT_PTR DeleteAccountSvc(WPARAM wParam, LPARAM lParam)
if (Plugin->Fcn->StopAccountFcnPtr != nullptr)
Plugin->Fcn->StopAccountFcnPtr(Which);
- //2. wait to get write access
- SWMRGWaitToWrite(Plugin->AccountBrowserSO, INFINITE);
+ {
+ // 2. wait to get write access
+ SWriteGuard swb(Plugin->AccountBrowserSO);
- //3. remove from queue (chained list)
- if (Plugin->FirstAccount == nullptr) {
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
- return 0;
- }
- if (Plugin->FirstAccount == Which) {
- Finder = Plugin->FirstAccount->Next;
- Plugin->FirstAccount = Finder;
- }
- else {
- for (Finder = Plugin->FirstAccount; Which != Finder->Next; Finder = Finder->Next);
- Finder->Next = Finder->Next->Next;
+ // 3. remove from queue (chained list)
+ if (Plugin->FirstAccount == nullptr) {
+ return 0;
+ }
+ if (Plugin->FirstAccount == Which) {
+ Finder = Plugin->FirstAccount->Next;
+ Plugin->FirstAccount = Finder;
+ }
+ else {
+ for (Finder = Plugin->FirstAccount; Which != Finder->Next; Finder = Finder->Next);
+ Finder->Next = Finder->Next->Next;
+ }
}
- //leave write access
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
-
//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?
@@ -968,16 +925,16 @@ INT_PTR DeleteAccountSvc(WPARAM wParam, LPARAM lParam)
void __cdecl DeleteAccountInBackground(void *Value)
{
CAccount *Which = (CAccount *)Value;
- WaitForSingleObject(Which->UsingThreads->Event, INFINITE);
+ WaitForSingleObject(Which->UsingThreads.GetEvent(), INFINITE);
CallService(MS_YAMN_DELETEPLUGINACCOUNT, (WPARAM)Which, 0);
}
-int StopAccounts(HYAMNPROTOPLUGIN Plugin)
+int StopAccounts(YAMN_PROTOPLUGIN *Plugin)
{
CAccount *Finder;
//1. wait to get write access
- SWMRGWaitToWrite(Plugin->AccountBrowserSO, INFINITE);
+ SWriteGuard swb(Plugin->AccountBrowserSO);
for (Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next) {
//2. set stop signal
@@ -987,36 +944,32 @@ int StopAccounts(HYAMNPROTOPLUGIN Plugin)
Plugin->Fcn->StopAccountFcnPtr(Finder);
}
- //leave write access
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
-
//Now, account is stopped. It can be removed from memory...
return 1;
}
-int WaitForAllAccounts(HYAMNPROTOPLUGIN Plugin, BOOL GetAccountBrowserAccess)
+int WaitForAllAccounts(YAMN_PROTOPLUGIN *Plugin, BOOL GetAccountBrowserAccess)
{
if (GetAccountBrowserAccess) {
//1. wait to get write access
- SWMRGWaitToWrite(Plugin->AccountBrowserSO, INFINITE);
+ Plugin->AccountBrowserSO.WaitToWrite();
}
for (CAccount *Finder = Plugin->FirstAccount; Finder != nullptr; Finder = Finder->Next) {
//2. wait for signal that account is not in use
- WaitForSingleObject(Finder->UsingThreads->Event, INFINITE);
- SetEvent(Finder->UsingThreads->Event);
+ WaitForSingleObject(Finder->UsingThreads.GetEvent(), INFINITE);
+ SetEvent(Finder->UsingThreads.GetEvent());
}
if (GetAccountBrowserAccess) {
//leave write access
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ Plugin->AccountBrowserSO.DoneWriting();
}
return 1;
}
-int DeleteAccounts(HYAMNPROTOPLUGIN Plugin)
+int DeleteAccounts(YAMN_PROTOPLUGIN *Plugin)
{
- //1. wait to get write access
- SWMRGWaitToWrite(Plugin->AccountBrowserSO, INFINITE);
+ SWriteGuard swb(Plugin->AccountBrowserSO);
WaitForAllAccounts(Plugin, FALSE);
@@ -1025,9 +978,6 @@ int DeleteAccounts(HYAMNPROTOPLUGIN Plugin)
DeletePluginAccountSvc((WPARAM)Finder, 0);
Finder = Next;
}
-
- //leave write access
- SWMRGDoneWriting(Plugin->AccountBrowserSO);
return 1;
}
diff --git a/protocols/YAMN/src/browser/badconnect.cpp b/protocols/YAMN/src/browser/badconnect.cpp
index 6e023ccf84..c6a2179f90 100644
--- a/protocols/YAMN/src/browser/badconnect.cpp
+++ b/protocols/YAMN/src/browser/badconnect.cpp
@@ -23,7 +23,8 @@ LRESULT CALLBACK BadConnectPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
si.cb = sizeof(si);
CAccount *ActualAccount = (CAccount *)PUGetPluginData(hWnd);
- if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra == WAIT_OBJECT_0) {
if (ActualAccount->BadConnectN.App != nullptr) {
wchar_t *Command;
if (ActualAccount->BadConnectN.AppParam != nullptr)
@@ -41,8 +42,6 @@ LRESULT CALLBACK BadConnectPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
delete[] Command;
}
}
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
PUDeletePopup(hWnd);
@@ -76,57 +75,57 @@ INT_PTR CALLBACK DlgProcYAMNBadConnection(HWND hDlg, UINT msg, WPARAM wParam, LP
wchar_t *Message1W = nullptr;
POPUPDATAW BadConnectPopup = {};
- ActualAccount = ((struct BadConnectionParam *)lParam)->account;
- ErrorCode = ((struct BadConnectionParam *)lParam)->errcode;
-
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO))
- return FALSE;
-
- int size = (int)(mir_strlen(ActualAccount->Name) + mir_strlen(Translate(BADCONNECTTITLE)));
- TitleStrA = new char[size];
- mir_snprintf(TitleStrA, size, Translate(BADCONNECTTITLE), ActualAccount->Name);
-
- ShowPopup = ActualAccount->BadConnectN.Flags & YAMN_ACC_POP;
- ShowMsg = ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG;
- ShowIco = ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO;
-
- if (ShowPopup) {
- BadConnectPopup.lchIcon = g_plugin.getIcon(IDI_BADCONNECT);
- BadConnectPopup.colorBack = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupB : GetSysColor(COLOR_BTNFACE);
- BadConnectPopup.colorText = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupT : GetSysColor(COLOR_WINDOWTEXT);
- BadConnectPopup.iSeconds = ActualAccount->BadConnectN.PopupTime;
+ ActualAccount = ((BadConnectionParam *)lParam)->account;
+ ErrorCode = ((BadConnectionParam *)lParam)->errcode;
+ {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (WAIT_OBJECT_0 != sra)
+ return FALSE;
+
+ int size = (int)(mir_strlen(ActualAccount->Name) + mir_strlen(Translate(BADCONNECTTITLE)));
+ TitleStrA = new char[size];
+ mir_snprintf(TitleStrA, size, Translate(BADCONNECTTITLE), ActualAccount->Name);
+
+ ShowPopup = ActualAccount->BadConnectN.Flags & YAMN_ACC_POP;
+ ShowMsg = ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG;
+ ShowIco = ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO;
+
+ if (ShowPopup) {
+ BadConnectPopup.lchIcon = g_plugin.getIcon(IDI_BADCONNECT);
+ BadConnectPopup.colorBack = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupB : GetSysColor(COLOR_BTNFACE);
+ BadConnectPopup.colorText = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupT : GetSysColor(COLOR_WINDOWTEXT);
+ BadConnectPopup.iSeconds = ActualAccount->BadConnectN.PopupTime;
+
+ BadConnectPopup.PluginWindowProc = BadConnectPopupProc;
+ BadConnectPopup.PluginData = ActualAccount;
+ mir_wstrncpy(BadConnectPopup.lpwzContactName, _A2T(ActualAccount->Name), _countof(BadConnectPopup.lpwzContactName));
+ }
- BadConnectPopup.PluginWindowProc = BadConnectPopupProc;
- BadConnectPopup.PluginData = ActualAccount;
- mir_wstrncpy(BadConnectPopup.lpwzContactName, _A2T(ActualAccount->Name), _countof(BadConnectPopup.lpwzContactName));
- }
+ if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr != nullptr) {
+ Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
+ SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
+ wcsncpy_s(BadConnectPopup.lpwzText, Message1W, _TRUNCATE);
+ if (ShowPopup)
+ PUAddPopupW(&BadConnectPopup);
+ }
+ else if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringAFcnPtr != nullptr) {
+ Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
+ SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
+ wcsncpy_s(BadConnectPopup.lpwzText, Message1W, _TRUNCATE);
+ if (ShowPopup)
+ PUAddPopupW(&BadConnectPopup);
+ }
+ else {
+ Message1W = TranslateT("Unknown error");
+ SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
+ wcsncpy_s(BadConnectPopup.lpwzText, Message1W, _TRUNCATE);
+ if (ShowPopup)
+ PUAddPopupW(&BadConnectPopup);
+ }
- if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr != nullptr) {
- Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
- SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
- wcsncpy_s(BadConnectPopup.lpwzText, Message1W, _TRUNCATE);
- if (ShowPopup)
- PUAddPopupW(&BadConnectPopup);
- }
- else if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringAFcnPtr != nullptr) {
- Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
- SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
- wcsncpy_s(BadConnectPopup.lpwzText, Message1W, _TRUNCATE);
- if (ShowPopup)
- PUAddPopupW(&BadConnectPopup);
+ if (!ShowMsg && !ShowIco)
+ DestroyWindow(hDlg);
}
- else {
- Message1W = TranslateT("Unknown error");
- SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
- wcsncpy_s(BadConnectPopup.lpwzText, Message1W, _TRUNCATE);
- if (ShowPopup)
- PUAddPopupW(&BadConnectPopup);
- }
-
- if (!ShowMsg && !ShowIco)
- DestroyWindow(hDlg);
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
SetWindowTextA(hDlg, TitleStrA);
delete[] TitleStrA;
@@ -141,7 +140,6 @@ INT_PTR CALLBACK DlgProcYAMNBadConnection(HWND hDlg, UINT msg, WPARAM wParam, LP
case WM_DESTROY:
{
NOTIFYICONDATA nid;
-
memset(&nid, 0, sizeof(NOTIFYICONDATA));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hDlg;
@@ -182,27 +180,22 @@ INT_PTR CALLBACK DlgProcYAMNBadConnection(HWND hDlg, UINT msg, WPARAM wParam, LP
return 0;
}
-void __cdecl BadConnection(void *Param)
+static void __cdecl BadConnection(void *Param)
{
MSG msg;
HWND hBadConnect;
CAccount *ActualAccount;
- struct BadConnectionParam MyParam = *(struct BadConnectionParam *)Param;
- ActualAccount = MyParam.account;
-
- SCIncFcn(ActualAccount->UsingThreads);
-
- // we will not use params in stack anymore
- SetEvent(MyParam.ThreadRunningEV);
+ auto *MyParam = (BadConnectionParam *)Param;
+ ActualAccount = MyParam->account;
- __try {
- hBadConnect = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_DLGBADCONNECT), nullptr, DlgProcYAMNBadConnection, (LPARAM)&MyParam);
- Window_SetIcon_IcoLib(hBadConnect, g_plugin.getIconHandle(IDI_BADCONNECT));
+ SCGuard sc(ActualAccount->UsingThreads);
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO))
- __leave;
+ hBadConnect = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_DLGBADCONNECT), nullptr, DlgProcYAMNBadConnection, (LPARAM)&MyParam);
+ Window_SetIcon_IcoLib(hBadConnect, g_plugin.getIconHandle(IDI_BADCONNECT));
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (WAIT_OBJECT_0 == sra) {
Skin_PlaySound(YAMN_CONNECTFAILSOUND);
if (ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG)
@@ -218,8 +211,7 @@ void __cdecl BadConnection(void *Param)
mir_snwprintf(nid.szTip, L"%S%s", ActualAccount->Name, TranslateT(" - connection error"));
Shell_NotifyIcon(NIM_ADD, &nid);
}
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
+ sra.Uninit();
UpdateWindow(hBadConnect);
while (GetMessage(&msg, nullptr, 0, 0)) {
@@ -231,20 +223,12 @@ void __cdecl BadConnection(void *Param)
if ((ActualAccount->Plugin->Fcn != nullptr) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr != nullptr) && ActualAccount->AbleToWork)
ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr();
}
- __finally {
- SCDecFcn(ActualAccount->UsingThreads);
- }
+ delete MyParam;
}
int RunBadConnection(CAccount *acc, UINT_PTR iErrorCode, void *pUserInfo)
{
- BadConnectionParam param = {CreateEvent(nullptr, FALSE, FALSE, nullptr), acc, iErrorCode, pUserInfo};
-
- HANDLE NewThread = mir_forkthread(BadConnection, &param);
- if (nullptr == NewThread)
- return 0;
-
- WaitForSingleObject(param.ThreadRunningEV, INFINITE);
- CloseHandle(param.ThreadRunningEV);
+ BadConnectionParam param = { acc, iErrorCode, pUserInfo };
+ mir_forkthread(BadConnection, new BadConnectionParam(param));
return 1;
}
diff --git a/protocols/YAMN/src/browser/browser.h b/protocols/YAMN/src/browser/browser.h
index 0cb3f1a248..4cf0b55ed4 100644
--- a/protocols/YAMN/src/browser/browser.h
+++ b/protocols/YAMN/src/browser/browser.h
@@ -1,35 +1,24 @@
#ifndef __MAILBROWSER_H
#define __MAILBROWSER_H
-typedef struct MailBrowserWinParam
-{
#define YAMN_MAILBROWSERVERSION 1
- HANDLE ThreadRunningEV;
+
+struct YAMN_MAILBROWSERPARAM
+{
CAccount *account;
uint32_t nflags; //flags YAMN_ACC_??? when new mails
uint32_t nnflags; //flags YAMN_ACC_??? when no new mails
void *Param;
-} YAMN_MAILBROWSERPARAM,*PYAMN_MAILBROWSERPARAM;
+};
-typedef struct MailShowMsgWinParam
+struct YAMN_MAILSHOWPARAM
{
- HANDLE ThreadRunningEV;
CAccount *account;
HYAMNMAIL mail;
-} YAMN_MAILSHOWPARAM, *PYAMN_MAILSHOWPARAM;
-
-typedef struct NoNewMailParam
-{
-#define YAMN_NONEWMAILVERSION 1
- HANDLE ThreadRunningEV;
- CAccount *account;
- uint32_t flags;
- void *Param;
-} YAMN_NONEWMAILPARAM,*PYAMN_NONEWMAILPARAM;
+};
struct BadConnectionParam
{
- HANDLE ThreadRunningEV;
CAccount *account;
UINT_PTR errcode;
void *Param;
diff --git a/protocols/YAMN/src/browser/mailbrowser.cpp b/protocols/YAMN/src/browser/mailbrowser.cpp
index 18710224ee..1a320322ec 100644
--- a/protocols/YAMN/src/browser/mailbrowser.cpp
+++ b/protocols/YAMN/src/browser/mailbrowser.cpp
@@ -151,11 +151,6 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l
// Dialog callback procedure for mail browser
INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-// MailBrowser thread function creates window if needed, tray icon and plays sound
-void __cdecl MailBrowser(void *Param);
-
-LRESULT CALLBACK ListViewSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
// Runs mail browser in new thread
INT_PTR RunMailBrowserSvc(WPARAM, LPARAM);
@@ -323,91 +318,92 @@ int UpdateMails(HWND hDlg, CAccount *ActualAccount, uint32_t nflags, uint32_t nn
BOOL RunMailBrowser, RunPopups;
struct CMailWinUserInfo *mwui = (struct CMailWinUserInfo *)GetWindowLongPtr(hDlg, DWLP_USER);
- //now we ensure read access for account and write access for its mails
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) {
- PostMessage(hDlg, WM_DESTROY, 0, 0);
- return UPDATE_FAIL;
- }
-
- if (WAIT_OBJECT_0 != WaitToWriteFcn(ActualAccount->MessagesAccessSO)) {
- ReadDoneFcn(ActualAccount->AccountAccessSO);
- PostMessage(hDlg, WM_DESTROY, 0, 0);
- return UPDATE_FAIL;
- }
- memset(&MN, 0, sizeof(MN));
+ //now we ensure read access for account and write access for its mails
+ {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (!sra.Succeeded()) {
+ PostMessage(hDlg, WM_DESTROY, 0, 0);
+ return UPDATE_FAIL;
+ }
- for (HYAMNMAIL msgq = (HYAMNMAIL)ActualAccount->Mails; msgq != nullptr; msgq = msgq->Next) {
- 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
- continue;
+ SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (!swm.Succeeded()) {
+ PostMessage(hDlg, WM_DESTROY, 0, 0);
+ return UPDATE_FAIL;
}
- else
- Loaded = true;
- IncrementMailCounters(msgq, &MN);
+ memset(&MN, 0, sizeof(MN));
- if (!Loaded)
- UnloadMailData(msgq); //do not keep data for mail in memory
- }
+ for (HYAMNMAIL msgq = (HYAMNMAIL)ActualAccount->Mails; msgq != nullptr; msgq = msgq->Next) {
+ 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
+ continue;
+ }
+ else
+ Loaded = true;
- if (mwui != nullptr)
- mwui->UpdateMailsMessagesAccess = TRUE;
-
- //Now we are going to check if extracting data from mail headers are needed.
- //If popups will be displayed or mailbrowser window
- if ((((mwui != nullptr) && !(mwui->RunFirstTime)) &&
- (
- ((nnflags & YAMN_ACC_MSGP) && !(MN.Real.BrowserUC + MN.Virtual.BrowserUC)) ||
- ((nflags & YAMN_ACC_MSGP) && (MN.Real.BrowserUC + MN.Virtual.BrowserUC))
- )
- ) || //if mail window was displayed before and flag YAMN_ACC_MSGP is set
- ((nnflags & YAMN_ACC_MSG) && !(MN.Real.BrowserUC + MN.Virtual.BrowserUC)) || //if needed to run mailbrowser when no unseen and no unseen mail found
- ((nflags & YAMN_ACC_MSG) && (MN.Real.BrowserUC + MN.Virtual.BrowserUC)) || //if unseen mails found, we sure run mailbrowser
- ((nflags & YAMN_ACC_ICO) && (MN.Real.SysTrayUC + MN.Virtual.SysTrayUC))
- ) //if needed to run systray
- RunMailBrowser = TRUE;
- else
- RunMailBrowser = FALSE;
+ IncrementMailCounters(msgq, &MN);
- // if some popups with mails are needed to show
- if ((nflags & YAMN_ACC_POP) && (ActualAccount->Flags & YAMN_ACC_POPN) && (MN.Real.PopupNC + MN.Virtual.PopupNC))
- RunPopups = TRUE;
- else RunPopups = FALSE;
+ if (!Loaded)
+ UnloadMailData(msgq); //do not keep data for mail in memory
+ }
- if (RunMailBrowser)
- ChangeExistingMailStatus(GetDlgItem(hDlg, IDC_LISTMAILS), ActualAccount);
- if (RunMailBrowser || RunPopups)
- AddNewMailsToListView(hDlg == nullptr ? nullptr : GetDlgItem(hDlg, IDC_LISTMAILS), ActualAccount, nflags);
-
- if (RunMailBrowser) {
- size_t len = mir_strlen(ActualAccount->Name) + mir_strlen(Translate(MAILBROWSERTITLE)) + 10; //+10 chars for numbers
- char *TitleStrA = new char[len];
- wchar_t *TitleStrW = new wchar_t[len];
-
- mir_snprintf(TitleStrA, len, Translate(MAILBROWSERTITLE), ActualAccount->Name, MN.Real.DisplayUC + MN.Virtual.DisplayUC, MN.Real.Display + MN.Virtual.Display);
- MultiByteToWideChar(CP_ACP, MB_USEGLYPHCHARS, TitleStrA, -1, TitleStrW, (int)mir_strlen(TitleStrA) + 1);
- SetWindowTextW(hDlg, TitleStrW);
- delete[] TitleStrA;
- delete[] TitleStrW;
- }
+ if (mwui != nullptr)
+ mwui->UpdateMailsMessagesAccess = TRUE;
+
+ //Now we are going to check if extracting data from mail headers are needed.
+ //If popups will be displayed or mailbrowser window
+ if ((((mwui != nullptr) && !(mwui->RunFirstTime)) &&
+ (
+ ((nnflags & YAMN_ACC_MSGP) && !(MN.Real.BrowserUC + MN.Virtual.BrowserUC)) ||
+ ((nflags & YAMN_ACC_MSGP) && (MN.Real.BrowserUC + MN.Virtual.BrowserUC))
+ )
+ ) || //if mail window was displayed before and flag YAMN_ACC_MSGP is set
+ ((nnflags & YAMN_ACC_MSG) && !(MN.Real.BrowserUC + MN.Virtual.BrowserUC)) || //if needed to run mailbrowser when no unseen and no unseen mail found
+ ((nflags & YAMN_ACC_MSG) && (MN.Real.BrowserUC + MN.Virtual.BrowserUC)) || //if unseen mails found, we sure run mailbrowser
+ ((nflags & YAMN_ACC_ICO) && (MN.Real.SysTrayUC + MN.Virtual.SysTrayUC))
+ ) //if needed to run systray
+ RunMailBrowser = TRUE;
+ else
+ RunMailBrowser = FALSE;
+
+ // if some popups with mails are needed to show
+ if ((nflags & YAMN_ACC_POP) && (ActualAccount->Flags & YAMN_ACC_POPN) && (MN.Real.PopupNC + MN.Virtual.PopupNC))
+ RunPopups = TRUE;
+ else RunPopups = FALSE;
+
+ if (RunMailBrowser)
+ ChangeExistingMailStatus(GetDlgItem(hDlg, IDC_LISTMAILS), ActualAccount);
+ if (RunMailBrowser || RunPopups)
+ AddNewMailsToListView(hDlg == nullptr ? nullptr : GetDlgItem(hDlg, IDC_LISTMAILS), ActualAccount, nflags);
+
+ if (RunMailBrowser) {
+ size_t len = mir_strlen(ActualAccount->Name) + mir_strlen(Translate(MAILBROWSERTITLE)) + 10; //+10 chars for numbers
+ char *TitleStrA = new char[len];
+ wchar_t *TitleStrW = new wchar_t[len];
+
+ mir_snprintf(TitleStrA, len, Translate(MAILBROWSERTITLE), ActualAccount->Name, MN.Real.DisplayUC + MN.Virtual.DisplayUC, MN.Real.Display + MN.Virtual.Display);
+ MultiByteToWideChar(CP_ACP, MB_USEGLYPHCHARS, TitleStrA, -1, TitleStrW, (int)mir_strlen(TitleStrA) + 1);
+ SetWindowTextW(hDlg, TitleStrW);
+ delete[] TitleStrA;
+ delete[] TitleStrW;
+ }
- DoMailActions(hDlg, ActualAccount, &MN, nflags, nnflags);
+ DoMailActions(hDlg, ActualAccount, &MN, nflags, nnflags);
- SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_NEW, 0, YAMN_MSG_NEW, YAMN_FLAG_REMOVE); //rempve the new flag
- if (!RunMailBrowser)
- SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_UNSEEN, YAMN_MSG_STAYUNSEEN, YAMN_MSG_UNSEEN, YAMN_FLAG_REMOVE); //remove the unseen flag when it was not displayed and it has not "stay unseen" flag set
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_NEW, 0, YAMN_MSG_NEW, YAMN_FLAG_REMOVE); //rempve the new flag
+ if (!RunMailBrowser)
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_UNSEEN, YAMN_MSG_STAYUNSEEN, YAMN_MSG_UNSEEN, YAMN_FLAG_REMOVE); //remove the unseen flag when it was not displayed and it has not "stay unseen" flag set
- if (mwui != nullptr) {
- mwui->UpdateMailsMessagesAccess = FALSE;
- mwui->RunFirstTime = FALSE;
+ if (mwui != nullptr) {
+ mwui->UpdateMailsMessagesAccess = FALSE;
+ mwui->RunFirstTime = FALSE;
+ }
}
- WriteDoneFcn(ActualAccount->MessagesAccessSO);
- ReadDoneFcn(ActualAccount->AccountAccessSO);
-
if (RunMailBrowser)
UpdateWindow(GetDlgItem(hDlg, IDC_LISTMAILS));
else if (hDlg != nullptr)
@@ -562,14 +558,11 @@ int AddNewMailsToListView(HWND hListView, CAccount *ActualAccount, uint32_t nfla
mir_wstrncpy(NewMailPopup.lpwzContactName, FromStr, _countof(NewMailPopup.lpwzContactName));
mir_wstrncpy(NewMailPopup.lpwzText, UnicodeHeader.Subject, _countof(NewMailPopup.lpwzText));
- PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)malloc(sizeof(YAMN_MAILSHOWPARAM));
- if (MailParam) {
- MailParam->account = ActualAccount;
- MailParam->mail = msgq;
- MailParam->ThreadRunningEV = nullptr;
- NewMailPopup.PluginData = MailParam;
- PUAddPopupW(&NewMailPopup);
- }
+ auto *MailParam = new YAMN_MAILSHOWPARAM;
+ MailParam->account = ActualAccount;
+ MailParam->mail = msgq;
+ NewMailPopup.PluginData = MailParam;
+ PUAddPopupW(&NewMailPopup);
}
if ((msgq->Flags & YAMN_MSG_UNSEEN) && (ActualAccount->NewMailN.Flags & YAMN_ACC_KBN))
@@ -765,7 +758,7 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
MCONTACT hContact = 0;
CAccount *Account;
if (PluginParam) {
- PYAMN_MAILSHOWPARAM MailParam = new YAMN_MAILSHOWPARAM;
+ YAMN_MAILSHOWPARAM *MailParam = new YAMN_MAILSHOWPARAM;
memcpy(MailParam, (PINT_PTR)PluginParam, sizeof(YAMN_MAILSHOWPARAM));
hContact = MailParam->account->hContact;
Account = MailParam->account;
@@ -782,11 +775,12 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
}
else Account = (CAccount *)hContact; //????
- if (WAIT_OBJECT_0 == WaitToReadFcn(Account->AccountAccessSO)) {
+ SReadGuard sra(Account->AccountAccessSO);
+ if (sra.Succeeded()) {
switch (msg) {
case WM_COMMAND:
{
- YAMN_MAILBROWSERPARAM Param = {(HANDLE)nullptr, Account,
+ YAMN_MAILBROWSERPARAM Param = { Account,
(Account->NewMailN.Flags & ~YAMN_ACC_POP) | YAMN_ACC_MSGP | YAMN_ACC_MSG,
(Account->NoNewMailN.Flags & ~YAMN_ACC_POP) | YAMN_ACC_MSGP | YAMN_ACC_MSG};
@@ -794,7 +788,6 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
}
break;
}
- ReadDoneFcn(Account->AccountAccessSO);
}
}
if ((Account->NewMailN.Flags & YAMN_ACC_CONT) && !(Account->NewMailN.Flags & YAMN_ACC_CONTNOEVENT))
@@ -807,8 +800,8 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
break;
case UM_FREEPLUGINDATA:
{
- PYAMN_MAILSHOWPARAM mpd = (PYAMN_MAILSHOWPARAM)PUGetPluginData(hWnd);
- if ((mpd) && (INT_PTR)mpd != -1)free(mpd);
+ auto *mpd = (YAMN_MAILSHOWPARAM*)PUGetPluginData(hWnd);
+ delete mpd;
return FALSE;
}
case UM_INITPOPUP:
@@ -858,11 +851,12 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l
}
else ActualAccount = (CAccount *)hContact;
- if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra.Succeeded()) {
switch (msg) {
case WM_COMMAND:
{
- YAMN_MAILBROWSERPARAM Param = {(HANDLE)nullptr, 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;
@@ -874,7 +868,6 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l
}
break;
}
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
PUDeletePopup(hWnd);
}
@@ -1183,7 +1176,7 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR
switch (msg) {
case WM_INITDIALOG:
{
- PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)lParam;
+ YAMN_MAILSHOWPARAM *MailParam = (YAMN_MAILSHOWPARAM*)lParam;
wchar_t *iHeaderW = nullptr;
wchar_t *iValueW = nullptr;
int StrLen;
@@ -1220,8 +1213,7 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR
case WM_YAMN_CHANGECONTENT:
{
- PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)
- (lParam ? lParam : GetWindowLongPtr(hDlg, DWLP_USER));
+ auto *MailParam = (YAMN_MAILSHOWPARAM*)(lParam ? lParam : GetWindowLongPtr(hDlg, DWLP_USER));
HWND hListView = GetDlgItem(hDlg, IDC_LISTHEADERS);
HWND hEdit = GetDlgItem(hDlg, IDC_EDITBODY);
//do not redraw
@@ -1373,11 +1365,10 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR
case WM_YAMN_STOPACCOUNT:
{
- PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)
- (lParam ? lParam : GetWindowLongPtr(hDlg, DWLP_USER));
-
+ auto *MailParam = (YAMN_MAILSHOWPARAM*)(lParam ? lParam : GetWindowLongPtr(hDlg, DWLP_USER));
if (nullptr == MailParam)
break;
+
if ((CAccount *)wParam != MailParam->account)
break;
@@ -1437,7 +1428,7 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR
if (wParam == SIZE_RESTORED) {
HWND hList = GetDlgItem(hDlg, IDC_LISTHEADERS);
HWND hEdit = GetDlgItem(hDlg, IDC_EDITBODY);
- BOOL isBodyShown = ((PYAMN_MAILSHOWPARAM)(GetWindowLongPtr(hDlg, DWLP_USER)))->mail->Flags & YAMN_MSG_BODYRECEIVED;
+ BOOL isBodyShown = ((YAMN_MAILSHOWPARAM*)(GetWindowLongPtr(hDlg, DWLP_USER)))->mail->Flags & YAMN_MSG_BODYRECEIVED;
HeadSizeX = LOWORD(lParam); //((LPRECT)lParam)->right-((LPRECT)lParam)->left;
HeadSizeY = HIWORD(lParam); //((LPRECT)lParam)->bottom-((LPRECT)lParam)->top;
int localSplitPos = (HeadSplitPos * HeadSizeY) / 1000;
@@ -1512,38 +1503,76 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR
void __cdecl ShowEmailThread(void *Param)
{
- struct MailShowMsgWinParam MyParam = *(struct MailShowMsgWinParam *)Param;
+ auto *MyParam = (YAMN_MAILSHOWPARAM *)Param;
- SCIncFcn(MyParam.account->UsingThreads);
+ SCGuard sc(MyParam->account->UsingThreads);
- if (MyParam.mail->MsgWindow) {
- //if (!BringWindowToTop(MyParam.mail->MsgWindow)) {
- if (!SetForegroundWindow(MyParam.mail->MsgWindow)) {
- SendMessage(MyParam.mail->MsgWindow, WM_DESTROY, 0, 0);
- MyParam.mail->MsgWindow = nullptr;
+ if (MyParam->mail->MsgWindow) {
+ if (!SetForegroundWindow(MyParam->mail->MsgWindow)) {
+ SendMessage(MyParam->mail->MsgWindow, WM_DESTROY, 0, 0);
+ MyParam->mail->MsgWindow = nullptr;
goto CREADTEVIEWMESSAGEWINDOW;
}
- if (IsIconic(MyParam.mail->MsgWindow))
- OpenIcon(MyParam.mail->MsgWindow);
+ if (IsIconic(MyParam->mail->MsgWindow))
+ OpenIcon(MyParam->mail->MsgWindow);
}
else {
CREADTEVIEWMESSAGEWINDOW:
- MyParam.mail->MsgWindow = CreateDialogParamW(g_plugin.getInst(), MAKEINTRESOURCEW(IDD_DLGSHOWMESSAGE), nullptr, DlgProcYAMNShowMessage, (LPARAM)&MyParam);
- WindowList_Add(YAMNVar.MessageWnds, MyParam.mail->MsgWindow);
+ MyParam->mail->MsgWindow = CreateDialogParamW(g_plugin.getInst(), MAKEINTRESOURCEW(IDD_DLGSHOWMESSAGE), nullptr, DlgProcYAMNShowMessage, (LPARAM)MyParam);
+ WindowList_Add(YAMNVar.MessageWnds, MyParam->mail->MsgWindow);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
- if (MyParam.mail->MsgWindow == nullptr || !IsDialogMessage(MyParam.mail->MsgWindow, &msg)) { /* Wine fix. */
+ if (MyParam->mail->MsgWindow == nullptr || !IsDialogMessage(MyParam->mail->MsgWindow, &msg)) { /* Wine fix. */
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
- WindowList_Remove(YAMNVar.MessageWnds, MyParam.mail->MsgWindow);
- MyParam.mail->MsgWindow = nullptr;
+ WindowList_Remove(YAMNVar.MessageWnds, MyParam->mail->MsgWindow);
+ MyParam->mail->MsgWindow = nullptr;
}
- SCDecFcn(MyParam.account->UsingThreads);
- delete (struct MailShowMsgWinParam *)Param;
+ delete MyParam;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Mail browser window
+
+static LRESULT CALLBACK ListViewSubclassProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HWND hwndParent = GetParent(hDlg);
+
+ switch (msg) {
+ case WM_GETDLGCODE:
+ {
+ LPMSG lpmsg = (LPMSG)lParam;
+ if (lpmsg != nullptr && lpmsg->message == WM_KEYDOWN && lpmsg->wParam == VK_RETURN)
+ return DLGC_WANTALLKEYS;
+ }
+ break;
+
+ case WM_KEYDOWN:
+ {
+ BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000;
+ BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000;
+ BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
+
+ switch (wParam) {
+ case 'A': // ctrl-a
+ if (!isAlt && !isShift && isCtrl) SendMessage(hwndParent, WM_COMMAND, IDC_BTNCHECKALL, 0);
+ break;
+ case VK_RETURN:
+ case VK_SPACE:
+ if (!isAlt && !isShift && !isCtrl) SendMessage(hwndParent, WM_YAMN_SHOWSELECTED, 0, 0);
+ break;
+ case VK_DELETE:
+ SendMessage(hwndParent, WM_COMMAND, IDC_BTNDEL, 0);
+ break;
+ }
+ }
+ break;
+ }
+ return mir_callNextSubclass(hDlg, ListViewSubclassProc, msg, wParam, lParam);
}
INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -1555,13 +1584,13 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
switch (msg) {
case WM_INITDIALOG:
{
- struct MailBrowserWinParam *MyParam = (struct MailBrowserWinParam *)lParam;
+ auto *MyParam = (YAMN_MAILBROWSERPARAM *)lParam;
ListView_SetUnicodeFormat(GetDlgItem(hDlg, IDC_LISTMAILS), TRUE);
ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_LISTMAILS), LVS_EX_FULLROWSELECT);
ActualAccount = MyParam->account;
- mwui = new struct CMailWinUserInfo;
+ mwui = new CMailWinUserInfo();
mwui->Account = ActualAccount;
mwui->TrayIconState = 0;
mwui->UpdateMailsMessagesAccess = FALSE;
@@ -1569,7 +1598,9 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
mwui->RunFirstTime = TRUE;
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)mwui);
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) {
+
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (!sra.Succeeded()) {
DestroyWindow(hDlg);
return FALSE;
}
@@ -1604,16 +1635,15 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
else
EnableWindow(GetDlgItem(hDlg, IDC_BTNAPP), FALSE);
- ReadDoneFcn(ActualAccount->AccountAccessSO);
+ sra.Uninit();
WindowList_Add(YAMNVar.MessageWnds, hDlg);
WindowList_Add(YAMNVar.NewMailAccountWnd, hDlg, (UINT_PTR)ActualAccount);
- {
- wchar_t accstatus[512];
- GetStatusFcn(ActualAccount, accstatus);
- SetDlgItemText(hDlg, IDC_STSTATUS, accstatus);
- }
+ wchar_t accstatus[512];
+ GetStatusFcn(ActualAccount, accstatus);
+ SetDlgItemText(hDlg, IDC_STSTATUS, accstatus);
+
SetTimer(hDlg, TIMER_FLASHING, 500, nullptr);
if (ActualAccount->hContact != NULL)
@@ -1657,31 +1687,29 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
WindowList_Remove(YAMNVar.NewMailAccountWnd, hDlg);
WindowList_Remove(YAMNVar.MessageWnds, hDlg);
+ {
+ SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (!swm.Succeeded())
+ break;
- if (WAIT_OBJECT_0 != WaitToWriteFcn(ActualAccount->MessagesAccessSO))
- break;
-
- //delete mails from queue, which are deleted from server (spam level 3 mails e.g.)
- for (HYAMNMAIL Parser = (HYAMNMAIL)ActualAccount->Mails; Parser != nullptr; Parser = Parser->Next) {
- 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);
+ // delete mails from queue, which are deleted from server (spam level 3 mails e.g.)
+ for (HYAMNMAIL Parser = (HYAMNMAIL)ActualAccount->Mails; Parser != nullptr; Parser = Parser->Next) {
+ 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);
+ }
}
- }
-
- //mark mails as read (remove "new" and "unseen" flags)
- if (mwui->Seen)
- SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY, 0, YAMN_MSG_NEW | YAMN_MSG_UNSEEN, 0);
-
- WriteDoneFcn(ActualAccount->MessagesAccessSO);
- NOTIFYICONDATA nid;
- memset(&nid, 0, sizeof(NOTIFYICONDATA));
+ // mark mails as read (remove "new" and "unseen" flags)
+ if (mwui->Seen)
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY, 0, YAMN_MSG_NEW | YAMN_MSG_UNSEEN, 0);
+ }
delete mwui;
SetWindowLongPtr(hDlg, DWLP_USER, NULL);
+ NOTIFYICONDATA nid = {};
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hDlg;
nid.uID = 0;
@@ -1769,17 +1797,17 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
switch (lParam) {
case WM_LBUTTONDBLCLK:
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) {
- return 0;
- }
+ {
+ SReadGuard sra(ActualAccount->AccountAccessSO, 0);
+ if (!sra.Succeeded())
+ return 0;
- if (ActualAccount->AbilityFlags & YAMN_ACC_BROWSE) {
- ShowWindow(hDlg, SW_SHOWNORMAL);
- SetForegroundWindow(hDlg);
+ if (ActualAccount->AbilityFlags & YAMN_ACC_BROWSE) {
+ ShowWindow(hDlg, SW_SHOWNORMAL);
+ SetForegroundWindow(hDlg);
+ }
+ else DestroyWindow(hDlg);
}
- else DestroyWindow(hDlg);
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
break;
}
break;
@@ -1797,7 +1825,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
ListView_GetItem(GetDlgItem(hDlg, IDC_LISTMAILS), &item);
HYAMNMAIL ActualMail = (HYAMNMAIL)item.lParam;
if (nullptr != ActualMail) {
- PYAMN_MAILSHOWPARAM MailParam = new YAMN_MAILSHOWPARAM;
+ auto *MailParam = new YAMN_MAILSHOWPARAM;
MailParam->account = GetWindowAccount(hDlg);
MailParam->mail = ActualMail;
mir_forkthread(ShowEmailThread, MailParam);
@@ -1842,7 +1870,8 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
- if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra.Succeeded()) {
if (ActualAccount->NewMailN.App != nullptr) {
wchar_t *Command;
if (ActualAccount->NewMailN.AppParam != nullptr)
@@ -1860,8 +1889,6 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
delete[] Command;
}
}
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
if (!(GetKeyState(VK_SHIFT) & 0x8000) && !(GetKeyState(VK_CONTROL) & 0x8000))
@@ -1883,58 +1910,56 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
LVITEM item;
item.stateMask = 0xFFFFFFFF;
-
- if (WAIT_OBJECT_0 == WaitToWriteFcn(ActualAccount->MessagesAccessSO)) {
- for (int i = 0; i < Items; i++) {
- item.iItem = i;
- item.iSubItem = 0;
- item.mask = LVIF_PARAM | LVIF_STATE;
- item.stateMask = 0xFFFFFFFF;
- ListView_GetItem(GetDlgItem(hDlg, IDC_LISTMAILS), &item);
- ActualMail = (HYAMNMAIL)item.lParam;
- if (nullptr == ActualMail)
- break;
- if (item.state & LVIS_SELECTED) {
- ActualMail->Flags |= YAMN_MSG_USERDELETE; //set to mail we are going to delete it
- Total++;
+ {
+ SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (swm.Succeeded()) {
+ for (int i = 0; i < Items; i++) {
+ item.iItem = i;
+ item.iSubItem = 0;
+ item.mask = LVIF_PARAM | LVIF_STATE;
+ item.stateMask = 0xFFFFFFFF;
+ ListView_GetItem(GetDlgItem(hDlg, IDC_LISTMAILS), &item);
+ ActualMail = (HYAMNMAIL)item.lParam;
+ if (nullptr == ActualMail)
+ break;
+ if (item.state & LVIS_SELECTED) {
+ ActualMail->Flags |= YAMN_MSG_USERDELETE; //set to mail we are going to delete it
+ Total++;
+ }
}
}
+ }
- // Enable write-access to mails
- WriteDoneFcn(ActualAccount->MessagesAccessSO);
-
- if (Total) {
- wchar_t DeleteMsg[1024];
-
- mir_snwprintf(DeleteMsg, TranslateT("Do you really want to delete %d selected mails?"), Total);
- if (IDOK == MessageBox(hDlg, DeleteMsg, TranslateT("Delete confirmation"), MB_OKCANCEL | MB_ICONWARNING)) {
- struct DeleteParam ParamToDeleteMails = {YAMN_DELETEVERSION, ThreadRunningEV, ActualAccount, nullptr};
-
- // Find if there's mail marked to delete, which was deleted before
- if (WAIT_OBJECT_0 == WaitToWriteFcn(ActualAccount->MessagesAccessSO)) {
- for (ActualMail = (HYAMNMAIL)ActualAccount->Mails; ActualMail != nullptr; ActualMail = ActualMail->Next) {
- 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
- continue;
- }
+ if (Total) {
+ wchar_t DeleteMsg[1024];
+
+ mir_snwprintf(DeleteMsg, TranslateT("Do you really want to delete %d selected mails?"), Total);
+ if (IDOK == MessageBox(hDlg, DeleteMsg, TranslateT("Delete confirmation"), MB_OKCANCEL | MB_ICONWARNING)) {
+ struct DeleteParam ParamToDeleteMails = {YAMN_DELETEVERSION, ThreadRunningEV, ActualAccount, nullptr};
+
+ // Find if there's mail marked to delete, which was deleted before
+ SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (swm.Succeeded()) {
+ for (ActualMail = (HYAMNMAIL)ActualAccount->Mails; ActualMail != nullptr; ActualMail = ActualMail->Next) {
+ 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
+ continue;
}
- // Set flag to marked mails that they can be deleted
- SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE, 0, YAMN_MSG_DELETEOK, 1);
- // Create new thread which deletes marked mails.
- HANDLE NewThread = mir_forkthread(ActualAccount->Plugin->Fcn->DeleteMailsFcnPtr, &ParamToDeleteMails);
- if (NewThread != nullptr)
- WaitForSingleObject(ThreadRunningEV, INFINITE);
-
- // Enable write-access to mails
- WriteDoneFcn(ActualAccount->MessagesAccessSO);
}
+ // Set flag to marked mails that they can be deleted
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE, 0, YAMN_MSG_DELETEOK, 1);
+ // Create new thread which deletes marked mails.
+ HANDLE NewThread = mir_forkthread(ActualAccount->Plugin->Fcn->DeleteMailsFcnPtr, &ParamToDeleteMails);
+ if (NewThread != nullptr)
+ WaitForSingleObject(ThreadRunningEV, INFINITE);
}
- else //else mark messages that they are not to be deleted
- SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE, 0, YAMN_MSG_USERDELETE, 0);
}
+ else //else mark messages that they are not to be deleted
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE, 0, YAMN_MSG_USERDELETE, 0);
}
+
CloseHandle(ThreadRunningEV);
if (g_plugin.getByte(YAMN_CLOSEDELETE, 0))
DestroyWindow(hDlg);
@@ -1990,7 +2015,8 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
case LVN_COLUMNCLICK:
if (nullptr != (ActualAccount = GetWindowAccount(hDlg))) {
NM_LISTVIEW *pNMListView = (NM_LISTVIEW *)lParam;
- if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra.Succeeded()) {
switch ((int)pNMListView->iSubItem) {
case 0:
bFrom = !bFrom;
@@ -2008,7 +2034,6 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
break;
}
ListView_SortItems(pNMListView->hdr.hwndFrom, ListViewCompareProc, pNMListView->iSubItem);
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
}
break;
@@ -2036,7 +2061,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
ActualMail = (HYAMNMAIL)readItemLParam(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec);
if (!umma)
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->MessagesAccessSO))
+ if (WAIT_OBJECT_0 != ActualAccount->MessagesAccessSO.WaitToRead())
return 0;
switch (ActualMail->Flags & YAMN_MSG_SPAMMASK) {
@@ -2060,7 +2085,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
PaintCode = CDRF_DODEFAULT;
if (!umma)
- ReadDoneFcn(ActualAccount->MessagesAccessSO);
+ ActualAccount->MessagesAccessSO.DoneReading();
}
break;
default:
@@ -2127,105 +2152,59 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR
return 0;
}
-LRESULT CALLBACK ListViewSubclassProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND hwndParent = GetParent(hDlg);
-
- switch (msg) {
- case WM_GETDLGCODE:
- {
- LPMSG lpmsg = (LPMSG)lParam;
- if (lpmsg != nullptr) {
- if (lpmsg->message == WM_KEYDOWN
- && lpmsg->wParam == VK_RETURN)
- return DLGC_WANTALLKEYS;
- }
- }
- break;
-
- case WM_KEYDOWN:
- {
- BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000;
- BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000;
- BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
-
- switch (wParam) {
- case 'A': // ctrl-a
- if (!isAlt && !isShift && isCtrl) SendMessage(hwndParent, WM_COMMAND, IDC_BTNCHECKALL, 0);
- break;
- case VK_RETURN:
- case VK_SPACE:
- if (!isAlt && !isShift && !isCtrl) SendMessage(hwndParent, WM_YAMN_SHOWSELECTED, 0, 0);
- break;
- case VK_DELETE:
- SendMessage(hwndParent, WM_COMMAND, IDC_BTNDEL, 0);
- break;
- }
- }
- break;
- }
- return mir_callNextSubclass(hDlg, ListViewSubclassProc, msg, wParam, lParam);
-}
-
-void __cdecl MailBrowser(void *Param)
+static void __cdecl MailBrowser(void *Param)
{
MSG msg;
HWND hMailBrowser;
BOOL WndFound = FALSE;
- struct MailBrowserWinParam MyParam = *(struct MailBrowserWinParam *)Param;
- CAccount *ActualAccount = MyParam.account;
- SCIncFcn(ActualAccount->UsingThreads);
-
- // we will not use params in stack anymore
- SetEvent(MyParam.ThreadRunningEV);
-
- __try {
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO))
- __leave;
+ auto *MyParam = (YAMN_MAILBROWSERPARAM *)Param;
+ CAccount *ActualAccount = MyParam->account;
+ SCGuard sc(ActualAccount->UsingThreads);
+ {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (!sra.Succeeded())
+ return;
if (!(ActualAccount->AbilityFlags & YAMN_ACC_BROWSE)) {
- MyParam.nflags = MyParam.nflags & ~YAMN_ACC_MSG;
- MyParam.nnflags = MyParam.nnflags & ~YAMN_ACC_MSG;
+ MyParam->nflags = MyParam->nflags & ~YAMN_ACC_MSG;
+ MyParam->nnflags = MyParam->nnflags & ~YAMN_ACC_MSG;
}
if (!(ActualAccount->AbilityFlags & YAMN_ACC_POPUP))
- MyParam.nflags = MyParam.nflags & ~YAMN_ACC_POP;
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
-
- if (nullptr != (hMailBrowser = WindowList_Find(YAMNVar.NewMailAccountWnd, (UINT_PTR)ActualAccount)))
- WndFound = TRUE;
-
- if ((hMailBrowser == nullptr) && ((MyParam.nflags & YAMN_ACC_MSG) || (MyParam.nflags & YAMN_ACC_ICO) || (MyParam.nnflags & YAMN_ACC_MSG))) {
- hMailBrowser = CreateDialogParamW(g_plugin.getInst(), MAKEINTRESOURCEW(IDD_DLGVIEWMESSAGES), nullptr, DlgProcYAMNMailBrowser, (LPARAM)&MyParam);
- Window_SetIcon_IcoLib(hMailBrowser, g_plugin.getIconHandle(IDI_NEWMAIL));
- MoveWindow(hMailBrowser, PosX, PosY, SizeX, SizeY, TRUE);
- }
+ MyParam->nflags = MyParam->nflags & ~YAMN_ACC_POP;
+ }
- if (hMailBrowser != nullptr) {
- struct CChangeContent Params = {MyParam.nflags, MyParam.nnflags}; //if this thread created window, just post message to update mails
+ if (nullptr != (hMailBrowser = WindowList_Find(YAMNVar.NewMailAccountWnd, (UINT_PTR)ActualAccount)))
+ WndFound = TRUE;
- SendMessage(hMailBrowser, WM_YAMN_CHANGECONTENT, (WPARAM)ActualAccount, (LPARAM)&Params); //we ensure this will do the thread who created the browser window
- }
- else UpdateMails(nullptr, ActualAccount, MyParam.nflags, MyParam.nnflags); //update mails without displaying or refreshing any window
+ if ((hMailBrowser == nullptr) && ((MyParam->nflags & YAMN_ACC_MSG) || (MyParam->nflags & YAMN_ACC_ICO ) || (MyParam->nnflags & YAMN_ACC_MSG))) {
+ hMailBrowser = CreateDialogParamW(g_plugin.getInst(), MAKEINTRESOURCEW(IDD_DLGVIEWMESSAGES), nullptr, DlgProcYAMNMailBrowser, (LPARAM)MyParam);
+ Window_SetIcon_IcoLib(hMailBrowser, g_plugin.getIconHandle(IDI_NEWMAIL));
+ MoveWindow(hMailBrowser, PosX, PosY, SizeX, SizeY, TRUE);
+ }
- if ((hMailBrowser != nullptr) && !WndFound) { //we process message loop only for thread that created window
- while (GetMessage(&msg, nullptr, 0, 0)) {
- if (hMailBrowser == nullptr || !IsDialogMessage(hMailBrowser, &msg)) { /* Wine fix. */
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
+ if (hMailBrowser != nullptr) {
+ // if this thread created window, just post message to update mails
+ struct CChangeContent Params = { MyParam->nflags, MyParam->nnflags };
+ SendMessage(hMailBrowser, WM_YAMN_CHANGECONTENT, (WPARAM)ActualAccount, (LPARAM)&Params); //we ensure this will do the thread who created the browser window
+ }
+ else UpdateMails(nullptr, ActualAccount, MyParam->nflags, MyParam->nnflags); //update mails without displaying or refreshing any window
+
+ if ((hMailBrowser != nullptr) && !WndFound) { //we process message loop only for thread that created window
+ while (GetMessage(&msg, nullptr, 0, 0)) {
+ if (hMailBrowser == nullptr || !IsDialogMessage(hMailBrowser, &msg)) { /* Wine fix. */
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
}
}
-
- if ((!WndFound) && (ActualAccount->Plugin->Fcn != nullptr) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr != nullptr) && ActualAccount->AbleToWork)
- ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr();
- }
- __finally {
- SCDecFcn(ActualAccount->UsingThreads);
}
+
+ if ((!WndFound) && (ActualAccount->Plugin->Fcn != nullptr) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr != nullptr) && ActualAccount->AbleToWork)
+ ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr();
+
+ delete MyParam;
}
INT_PTR RunMailBrowserSvc(WPARAM wParam, LPARAM lParam)
@@ -2233,16 +2212,7 @@ INT_PTR RunMailBrowserSvc(WPARAM wParam, LPARAM lParam)
if ((uint32_t)lParam != YAMN_MAILBROWSERVERSION)
return 0;
- PYAMN_MAILBROWSERPARAM Param = (PYAMN_MAILBROWSERPARAM)wParam;
-
- //an event for successfull copy parameters to which point a pointer in stack for new thread
- HANDLE ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- Param->ThreadRunningEV = ThreadRunningEV;
-
- HANDLE NewThread = mir_forkthread(MailBrowser, Param);
- if (NewThread != nullptr)
- WaitForSingleObject(ThreadRunningEV, INFINITE);
-
- CloseHandle(ThreadRunningEV);
+ auto *Param = (YAMN_MAILBROWSERPARAM*)wParam;
+ mir_forkthread(MailBrowser, new YAMN_MAILBROWSERPARAM(*Param));
return 1;
}
diff --git a/protocols/YAMN/src/filterplugin.cpp b/protocols/YAMN/src/filterplugin.cpp
index 451ea155aa..9d22962b8f 100644
--- a/protocols/YAMN/src/filterplugin.cpp
+++ b/protocols/YAMN/src/filterplugin.cpp
@@ -148,7 +148,7 @@ INT_PTR FilterMailSvc(WPARAM wParam, LPARAM lParam)
PYAMN_FILTERPLUGINQUEUE ActualPlugin;
mir_cslock lck(PluginRegCS);
- WaitToWriteFcn(Account->MessagesAccessSO);
+ SWriteGuard swa(Account->MessagesAccessSO);
for (ActualPlugin = FirstFilterPlugin; ActualPlugin != nullptr; ActualPlugin = ActualPlugin->Next)
if (ActualPlugin->Plugin->FilterFcn->FilterMailFcnPtr != nullptr)
@@ -164,6 +164,5 @@ INT_PTR FilterMailSvc(WPARAM wParam, LPARAM lParam)
if (YAMN_MSG_SPAML(Mail->Flags, YAMN_MSG_SPAML3))
Mail->Flags = Mail->Flags & ~(YAMN_MSG_MEMDELETE); //set message not to delete it immidiatelly from memory
- WriteDoneFcn(Account->MessagesAccessSO);
return 1;
}
diff --git a/protocols/YAMN/src/mails/mails.cpp b/protocols/YAMN/src/mails/mails.cpp
index 1385cb649d..87a4faaf42 100644
--- a/protocols/YAMN/src/mails/mails.cpp
+++ b/protocols/YAMN/src/mails/mails.cpp
@@ -91,18 +91,6 @@ HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From);
// mode- nonzero to set, else remove
void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From, uint32_t FlagsSet, uint32_t FlagsNotSet, uint32_t FlagsToSetRemove, int mode);
-struct CExportedFunctions MailExportedFcn[] =
-{
- {YAMN_SYNCHROMIMEMSGSID, (void *)SynchroMessagesFcn},
- {YAMN_TRANSLATEHEADERID, (void *)TranslateHeaderFcn},
- {YAMN_APPENDQUEUEID, (void *)AppendQueueFcn},
- {YAMN_DELETEMIMEQUEUEID, (void *)DeleteMessagesToEndFcn},
- {YAMN_DELETEMIMEMESSAGEID, (void *)DeleteMessageFromQueueFcn},
- {YAMN_FINDMIMEMESSAGEID, (void *)FindMessageByIDFcn},
- {YAMN_CREATENEWDELETEQUEUEID, (void *)CreateNewDeleteQueueFcn},
- {YAMN_SETREMOVEQUEUEFLAGSID, (void *)SetRemoveFlagsInQueueFcn},
-};
-
struct CExportedServices MailExportedSvc[] =
{
{MS_YAMN_CREATEACCOUNTMAIL, CreateAccountMailSvc},
@@ -147,7 +135,7 @@ INT_PTR CreateAccountMailSvc(WPARAM wParam, LPARAM lParam)
INT_PTR DeleteAccountMailSvc(WPARAM wParam, LPARAM lParam)
{
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam;
HYAMNMAIL OldMail = (HYAMNMAIL)lParam;
struct CMimeItem *TH;
@@ -315,7 +303,7 @@ void WINAPI DeleteMessagesToEndFcn(CAccount *Account, HYAMNMAIL From)
}
}
-void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode = 0)
+void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From, HYAMNMAIL Which, int mode)
{
uint32_t Number = Which->Number;
HYAMNMAIL Parser;
@@ -388,7 +376,7 @@ void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head)
} while (ENDLINEWS(finder));
if (Item != nullptr) {
- if (nullptr == (Item->Next = new struct CMimeItem))
+ if (nullptr == (Item->Next = new CMimeItem()))
break;
Item = Item->Next;
}
@@ -417,7 +405,7 @@ void WINAPI TranslateHeaderFcn(char *stream, int len, struct CMimeItem **head)
if (ENDLINE(finder))finder--;
prev2 = finder;
if (prev2 > prev1) { // yes, we have body
- if (nullptr == (Item->Next = new struct CMimeItem)) break; // Cant create new item?!
+ Item->Next = new CMimeItem();
Item = Item->Next;
Item->Next = nullptr;//just in case;
Item->name = new char[5]; strncpy(Item->name, "Body", 5);
diff --git a/protocols/YAMN/src/main.cpp b/protocols/YAMN/src/main.cpp
index c4979af1fb..3094e2a283 100644
--- a/protocols/YAMN/src/main.cpp
+++ b/protocols/YAMN/src/main.cpp
@@ -153,58 +153,6 @@ void LoadIcons()
g_plugin.registerIcon("YAMN", iconList);
}
-static void LoadPlugins()
-{
- wchar_t szSearchPath[MAX_PATH];
- mir_snwprintf(szSearchPath, L"%s\\Plugins\\YAMN\\*.dll", szMirandaDir);
-
- hDllPlugins = nullptr;
-
- WIN32_FIND_DATA fd;
- HANDLE hFind = FindFirstFile(szSearchPath, &fd);
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- //rewritten from Miranda sources... Needed because Win32 API has a bug in FindFirstFile, search is done for *.dlllllll... too
- wchar_t *dot = wcsrchr(fd.cFileName, '.');
- if (dot == nullptr)
- continue;
-
- // we have a dot
- int len = (int)mir_wstrlen(fd.cFileName); // find the length of the string
- wchar_t *end = fd.cFileName + len; // get a pointer to the NULL
- int safe = (end - dot) - 1; // figure out how many chars after the dot are "safe", not including NULL
-
- if ((safe != 3) || (mir_wstrcmpi(dot + 1, L"dll") != 0)) //not bound, however the "dll" string should mean only 3 chars are compared
- continue;
-
- wchar_t szPluginPath[MAX_PATH];
- mir_snwprintf(szPluginPath, L"%s\\Plugins\\YAMN\\%s", szMirandaDir, fd.cFileName);
- HINSTANCE hDll = LoadLibrary(szPluginPath);
- if (hDll == nullptr)
- continue;
-
- LOADFILTERFCN LoadFilter = (LOADFILTERFCN)GetProcAddress(hDll, "LoadFilter");
- if (nullptr == LoadFilter) {
- FreeLibrary(hDll);
- hDll = nullptr;
- continue;
- }
-
- if (!LoadFilter(GetFcnPtrSvc)) {
- FreeLibrary(hDll);
- hDll = nullptr;
- }
-
- if (hDll != nullptr) {
- hDllPlugins = (HINSTANCE *)realloc(hDllPlugins, (iDllPlugins + 1) * sizeof(HINSTANCE));
- hDllPlugins[iDllPlugins++] = hDll;
- }
- } while (FindNextFile(hFind, &fd));
-
- FindClose(hFind);
- }
-}
-
int CMPlugin::Load()
{
// we get the Miranda Root Path
@@ -267,7 +215,6 @@ int CMPlugin::Load()
HookEvents();
LoadIcons();
- LoadPlugins();
HOTKEYDESC hkd = {};
hkd.pszName = "YAMN_hotkey";
diff --git a/protocols/YAMN/src/main.h b/protocols/YAMN/src/main.h
index 971ba43c9f..79c56fefe0 100644
--- a/protocols/YAMN/src/main.h
+++ b/protocols/YAMN/src/main.h
@@ -31,7 +31,5 @@ extern unsigned char optDateTime;
// Loading Icon and checking for icolib
void LoadIcons();
-typedef INT_PTR (*LOADFILTERFCN)(MIRANDASERVICE GetYAMNFcn);
-
#endif
diff --git a/protocols/YAMN/src/proto/pop3/pop3comm.cpp b/protocols/YAMN/src/proto/pop3/pop3comm.cpp
index fc0f5819bb..ba793cd9d3 100644
--- a/protocols/YAMN/src/proto/pop3/pop3comm.cpp
+++ b/protocols/YAMN/src/proto/pop3/pop3comm.cpp
@@ -14,13 +14,15 @@
#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);
+
//--------------------------------------------------------------------------------------------------
HANDLE hNetLib = nullptr;
-PSCOUNTER CPOP3Account::AccountWriterSO = nullptr;
+SCOUNTER CPOP3Account::AccountWriterSO;
//Creates new CPOP3Account structure
-CAccount *WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN Plugin, DWORD CAccountVersion);
+CAccount *WINAPI CreatePOP3Account(YAMN_PROTOPLUGIN *Plugin, DWORD CAccountVersion);
//Deletes CPOP3Account structure
void WINAPI DeletePOP3Account(CAccount *Which);
@@ -48,7 +50,7 @@ HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account, DWORD CMimeMailVersion);
//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(HPOP3ACCOUNT ActualAccount, void *ParamToBadConnect, uint32_t POP3PluginParam, BOOL UseSSL);
+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
// WhichTemp- pointer to strucure containing needed information
@@ -87,9 +89,6 @@ void ExtractList(char *stream, int len, HYAMNMAIL queue);
void ExtractMail(char *stream, int len, HYAMNMAIL queue);
-YAMNExportedFcns *pYAMNFcn = nullptr;
-MailExportedFcns *pYAMNMailFcn = nullptr;
-
YAMN_PROTOIMPORTFCN POP3ProtocolFunctions =
{
CreatePOP3Account,
@@ -117,8 +116,7 @@ YAMN_MAILIMPORTFCN POP3MailFunctions =
nullptr,
};
-PYAMN_VARIABLES pYAMNVar = nullptr;
-HYAMNPROTOPLUGIN POP3Plugin = nullptr;
+YAMN_PROTOPLUGIN *POP3Plugin = nullptr;
YAMN_PROTOREGISTRATION POP3ProtocolRegistration =
{
@@ -138,24 +136,21 @@ HANDLE RegisterNLClient(char *name);
CPOP3Account::CPOP3Account()
{
- //NOTE! This constructor constructs CAccount structure. If your plugin is not internal,
- //you will need these constructors. All you need is in Account.cpp. Just copy to your source code
- //constructor and destructor of CAccount.
+ // NOTE! This constructor constructs CAccount structure. If your plugin is not internal,
+ // you will need these constructors. All you need is in Account.cpp. Just copy to your source code
+ // constructor and destructor of CAccount.
UseInternetFree = CreateEvent(nullptr, FALSE, TRUE, nullptr);
- InternetQueries = new SCOUNTER;
AbilityFlags = YAMN_ACC_BROWSE | YAMN_ACC_POPUP;
- SetAccountStatus((CAccount *)this, TranslateT("Disconnected"));
+ SetStatusFcn(this, TranslateT("Disconnected"));
}
CPOP3Account::~CPOP3Account()
{
CloseHandle(UseInternetFree);
- if (InternetQueries != nullptr)
- delete InternetQueries;
}
-CAccount *WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN, DWORD)
+CAccount* WINAPI CreatePOP3Account(YAMN_PROTOPLUGIN*, DWORD)
{
//First, we should check whether CAccountVersion matches.
//But this is internal plugin, so YAMN's CAccount structure and our CAccount structure are
@@ -164,75 +159,39 @@ CAccount *WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN, DWORD)
// if (CAccountVersion != YAMN_ACCOUNTVERSION) return NULL;
//Now it is needed to construct our POP3 account and return its handle
- return (CAccount *)new struct CPOP3Account();
+ return new CPOP3Account();
}
void WINAPI DeletePOP3Account(CAccount *Which)
{
- delete (HPOP3ACCOUNT)Which;
+ delete (CPOP3Account*)Which;
}
void WINAPI StopPOP3Account(CAccount *Which)
{
- ((HPOP3ACCOUNT)Which)->Client.Stopped = TRUE;
- if (((HPOP3ACCOUNT)Which)->Client.NetClient != nullptr) //we should inform also network client. Usefull only when network client implements this feature
- ((HPOP3ACCOUNT)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
int RegisterPOP3Plugin(WPARAM, LPARAM)
{
- // Get YAMN variables we can use
- if (nullptr == (pYAMNVar = (PYAMN_VARIABLES)CallService(MS_YAMN_GETVARIABLES, YAMN_VARIABLESVERSION, 0)))
- return 0;
-
- // We have to get pointers to YAMN exported functions: allocate structure and fill it
- if (nullptr == (pYAMNFcn = new struct YAMNExportedFcns)) {
-LBL_Error:
+ // Register new pop3 user in netlib
+ if (nullptr == (hNetLib = RegisterNLClient("YAMN (POP3)"))) {
UnLoadPOP3(nullptr);
return 0;
}
- // Register new pop3 user in netlib
- if (nullptr == (hNetLib = RegisterNLClient("YAMN (POP3)")))
- goto LBL_Error;
-
- pYAMNFcn->SetProtocolPluginFcnImportFcn = (YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_SETPROTOCOLPLUGINFCNIMPORTID, 0);
- pYAMNFcn->WaitToWriteFcn = (YAMN_WAITTOWRITEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_WAITTOWRITEID, 0);
- pYAMNFcn->WriteDoneFcn = (YAMN_WRITEDONEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_WRITEDONEID, 0);
- pYAMNFcn->WaitToReadFcn = (YAMN_WAITTOREADFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_WAITTOREADID, 0);
- pYAMNFcn->ReadDoneFcn = (YAMN_READDONEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_READDONEID, 0);
- pYAMNFcn->SCGetNumberFcn = (YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_SCGETNUMBERID, 0);
- pYAMNFcn->SCIncFcn = (YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_SCINCID, 0);
- pYAMNFcn->SCDecFcn = (YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_SCDECID, 0);
- pYAMNFcn->SetStatusFcn = (YAMN_SETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_SETSTATUSID, 0);
- pYAMNFcn->GetStatusFcn = (YAMN_GETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_GETSTATUSID, 0);
-
- if (nullptr == (pYAMNMailFcn = new struct MailExportedFcns))
- goto LBL_Error;
-
- pYAMNMailFcn->SynchroMessagesFcn = (YAMN_SYNCHROMIMEMSGSFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_SYNCHROMIMEMSGSID, 0);
- pYAMNMailFcn->TranslateHeaderFcn = (YAMN_TRANSLATEHEADERFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_TRANSLATEHEADERID, 0);
- pYAMNMailFcn->AppendQueueFcn = (YAMN_APPENDQUEUEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_APPENDQUEUEID, 0);
- pYAMNMailFcn->DeleteMessagesToEndFcn = (YAMN_DELETEMIMEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_DELETEMIMEQUEUEID, 0);
- pYAMNMailFcn->DeleteMessageFromQueueFcn = (YAMN_DELETEMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_DELETEMIMEMESSAGEID, 0);
- pYAMNMailFcn->FindMessageByIDFcn = (YAMN_FINDMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_FINDMIMEMESSAGEID, 0);
- pYAMNMailFcn->CreateNewDeleteQueueFcn = (YAMN_CREATENEWDELETEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR, (WPARAM)YAMN_CREATENEWDELETEQUEUEID, 0);
-
- //set static variable
- if (CPOP3Account::AccountWriterSO == nullptr)
- if (nullptr == (CPOP3Account::AccountWriterSO = new SCOUNTER))
- goto LBL_Error;
-
- //First, we register this plugin
- //it is quite impossible this function returns zero (failure) as YAMN and internal plugin structre versions are the same
+ // First, we register this plugin
+ // 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 = (HYAMNPROTOPLUGIN)CallService(MS_YAMN_REGISTERPROTOPLUGIN, (WPARAM)&POP3ProtocolRegistration, (LPARAM)YAMN_PROTOREGISTRATIONVERSION)))
+ if (nullptr == (POP3Plugin = (YAMN_PROTOPLUGIN*)CallService(MS_YAMN_REGISTERPROTOPLUGIN, (WPARAM)&POP3ProtocolRegistration, (LPARAM)YAMN_PROTOREGISTRATIONVERSION)))
return 0;
//Next we set our imported functions for YAMN
- if (!SetProtocolPluginFcnImport(POP3Plugin, &POP3ProtocolFunctions, YAMN_PROTOIMPORTFCNVERSION, &POP3MailFunctions, YAMN_MAILIMPORTFCNVERSION))
+ if (!SetProtocolPluginFcnImportFcn(POP3Plugin, &POP3ProtocolFunctions, YAMN_PROTOIMPORTFCNVERSION, &POP3MailFunctions, YAMN_MAILIMPORTFCNVERSION))
return 0;
//Then, we read all mails for accounts.
@@ -303,19 +262,9 @@ LBL_Error:
DWORD WINAPI UnLoadPOP3(void *)
{
- //pYAMNVar is only a pointr, no need delete or free
if (hNetLib) {
Netlib_CloseHandle(hNetLib); hNetLib = nullptr;
}
- if (CPOP3Account::AccountWriterSO) {
- delete CPOP3Account::AccountWriterSO; CPOP3Account::AccountWriterSO = nullptr;
- }
- if (pYAMNMailFcn) {
- delete pYAMNMailFcn; pYAMNMailFcn = nullptr;
- }
- if (pYAMNFcn) {
- delete pYAMNFcn; pYAMNFcn = nullptr;
- }
if (FileName) {
CallService(MS_YAMN_DELETEFILENAME, (WPARAM)FileName, 0); FileName = nullptr;
}
@@ -341,7 +290,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 *)&((HPOP3ACCOUNT)Which)->CP, sizeof(uint16_t), &WrittenBytes, nullptr)))
+ (!WriteFile(File, (char *)&((CPOP3Account*)Which)->CP, sizeof(uint16_t), &WrittenBytes, nullptr)))
return EACC_SYSTEM;
return 0;
}
@@ -359,12 +308,12 @@ DWORD WINAPI ReadPOP3Options(CAccount *Which, char **Parser, char *End)
if (Ver != POP3_FILEVERSION)
return EACC_FILECOMPATIBILITY;
- ((HPOP3ACCOUNT)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", ((HPOP3ACCOUNT)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;
@@ -387,7 +336,7 @@ HYAMNMAIL WINAPI CreatePOP3Mail(CAccount *Account, DWORD)
delete NewMail;
return nullptr;
}
- NewMail->MailData->CP = ((HPOP3ACCOUNT)Account)->CP;
+ NewMail->MailData->CP = ((CPOP3Account*)Account)->CP;
return (HYAMNMAIL)NewMail;
}
@@ -397,7 +346,7 @@ static void SetContactStatus(CAccount *account, int status)
g_plugin.setWord(account->hContact, "Status", status);
}
-static void PostErrorProc(HPOP3ACCOUNT ActualAccount, void *ParamToBadConnection, uint32_t POP3PluginParam, BOOL UseSSL)
+static void PostErrorProc(CPOP3Account* ActualAccount, void *ParamToBadConnection, uint32_t POP3PluginParam, BOOL UseSSL)
{
char *DataRX;
@@ -431,7 +380,7 @@ static void PostErrorProc(HPOP3ACCOUNT ActualAccount, void *ParamToBadConnection
catch (...) {
}
- SetAccountStatus(ActualAccount, TranslateT("Disconnected"));
+ SetStatusFcn(ActualAccount, TranslateT("Disconnected"));
//If we cannot allocate memory, do nothing
if (ErrorCode == nullptr) {
@@ -453,7 +402,7 @@ static void PostErrorProc(HPOP3ACCOUNT ActualAccount, void *ParamToBadConnection
//Checks POP3 account and synchronizes it
DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
{
- HPOP3ACCOUNT ActualAccount;
+ CPOP3Account* ActualAccount;
CPop3Client *MyClient;
HYAMNMAIL NewMails = nullptr, MsgQueuePtr = nullptr;
char *DataRX = nullptr, *Temp;
@@ -484,19 +433,18 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
// //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN".
// }
- ActualAccount = (HPOP3ACCOUNT)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;
- SCInc(ActualAccount->UsingThreads);
+ SCGuard sc(ActualAccount->UsingThreads);
//Unblock YAMN, signal that we have copied all parameters from YAMN thread stack
if (INVALID_HANDLE_VALUE != WhichTemp->ThreadRunningEV)
SetEvent(WhichTemp->ThreadRunningEV);
- if (WAIT_OBJECT_0 != WaitToRead(ActualAccount)) {
- SCDec(ActualAccount->UsingThreads);
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (!sra.Succeeded())
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.
@@ -507,19 +455,16 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
ActualCopied.ServerPasswd = _strdup(ActualAccount->Server->Passwd);
ActualCopied.NFlags = ActualAccount->NewMailN.Flags;
ActualCopied.NNFlags = ActualAccount->NoNewMailN.Flags;
-
- ReadDone(ActualAccount);
- SCInc(ActualAccount->InternetQueries); //increment counter, that there is one more thread waiting for connection
-
- WaitForSingleObject(ActualAccount->UseInternetFree, INFINITE); //wait until we can use connection
- SCDec(ActualAccount->InternetQueries);
-
+ sra.Uninit();
+ {
+ 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).
if (!ActualAccount->AbleToWork) {
SetEvent(ActualAccount->UseInternetFree);
- SCDec(ActualAccount->UsingThreads);
return 0;
}
UsingInternet = TRUE;
@@ -532,7 +477,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
// 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()) {
- SetAccountStatus(ActualAccount, TranslateT("Connecting to server"));
+ SetStatusFcn(ActualAccount, TranslateT("Connecting to server"));
DataRX = MyClient->Connect(ActualCopied.ServerName, ActualCopied.ServerPort, ActualCopied.Flags & YAMN_ACC_SSL23, ActualCopied.Flags & YAMN_ACC_NOTLS);
char *timestamp = nullptr;
@@ -552,7 +497,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
DataRX = nullptr;
}
- SetAccountStatus(ActualAccount, TranslateT("Entering POP3 account"));
+ SetStatusFcn(ActualAccount, TranslateT("Entering POP3 account"));
if (ActualCopied.Flags & YAMN_ACC_APOP) {
DataRX = MyClient->APOP(ActualCopied.ServerLogin, ActualCopied.ServerPasswd, timestamp);
@@ -572,7 +517,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
DataRX = nullptr;
}
}
- SetAccountStatus(ActualAccount, TranslateT("Searching for new mail message"));
+ SetStatusFcn(ActualAccount, TranslateT("Searching for new mail message"));
DataRX = MyClient->Stat();
@@ -607,58 +552,59 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
free(DataRX);
DataRX = nullptr;
}
+ {
+ SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (!swm.Succeeded())
+ throw (uint32_t)(ActualAccount->SystemError = EACC_STOPPED);
- if (WAIT_OBJECT_0 != MsgsWaitToWrite(ActualAccount))
- throw (uint32_t)(ActualAccount->SystemError = EACC_STOPPED);
-
- ActualAccount->LastChecked = now;
- for (MsgQueuePtr = (HYAMNMAIL)ActualAccount->Mails; MsgQueuePtr != nullptr; MsgQueuePtr = MsgQueuePtr->Next) {
- if (MsgQueuePtr->Flags & YAMN_MSG_BODYREQUESTED) {
- HYAMNMAIL NewMsgsPtr = nullptr;
- for (NewMsgsPtr = (HYAMNMAIL)NewMails; NewMsgsPtr != nullptr; NewMsgsPtr = NewMsgsPtr->Next) {
- if (!mir_strcmp(MsgQueuePtr->ID, NewMsgsPtr->ID)) {
- wchar_t accstatus[512];
- mir_snwprintf(accstatus, TranslateT("Reading body %s"), NewMsgsPtr->ID);
- SetAccountStatus(ActualAccount, accstatus);
- DataRX = MyClient->Top(MsgQueuePtr->Number, 100);
- if (DataRX != nullptr) {
- Temp = DataRX;
- while ((Temp < DataRX + MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++;
-
- if (OKLINE(DataRX))
- for (Temp = DataRX; (Temp < DataRX + MyClient->NetClient->Rcv) && (!ENDLINE(Temp)); Temp++);
- while ((Temp < DataRX + MyClient->NetClient->Rcv) && ENDLINE(Temp)) Temp++;
- }
- else
- continue;
- //delete all the headers of the old mail MsgQueuePtr->MailData->TranslatedHeader
- struct CMimeItem *TH = MsgQueuePtr->MailData->TranslatedHeader;
- if (TH) for (; MsgQueuePtr->MailData->TranslatedHeader != nullptr;) {
- TH = TH->Next;
- if (MsgQueuePtr->MailData->TranslatedHeader->name != nullptr)
- delete[] MsgQueuePtr->MailData->TranslatedHeader->name;
- if (MsgQueuePtr->MailData->TranslatedHeader->value != nullptr)
- delete[] MsgQueuePtr->MailData->TranslatedHeader->value;
- delete MsgQueuePtr->MailData->TranslatedHeader;
- MsgQueuePtr->MailData->TranslatedHeader = TH;
- }
+ ActualAccount->LastChecked = now;
+ for (MsgQueuePtr = (HYAMNMAIL)ActualAccount->Mails; MsgQueuePtr != nullptr; MsgQueuePtr = MsgQueuePtr->Next) {
+ if (MsgQueuePtr->Flags & YAMN_MSG_BODYREQUESTED) {
+ HYAMNMAIL NewMsgsPtr = nullptr;
+ for (NewMsgsPtr = (HYAMNMAIL)NewMails; NewMsgsPtr != nullptr; NewMsgsPtr = NewMsgsPtr->Next) {
+ if (!mir_strcmp(MsgQueuePtr->ID, NewMsgsPtr->ID)) {
+ wchar_t accstatus[512];
+ mir_snwprintf(accstatus, TranslateT("Reading body %s"), NewMsgsPtr->ID);
+ SetStatusFcn(ActualAccount, accstatus);
+ DataRX = MyClient->Top(MsgQueuePtr->Number, 100);
+ if (DataRX != nullptr) {
+ Temp = DataRX;
+ while ((Temp < DataRX + MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++;
+
+ if (OKLINE(DataRX))
+ for (Temp = DataRX; (Temp < DataRX + MyClient->NetClient->Rcv) && (!ENDLINE(Temp)); Temp++);
+ while ((Temp < DataRX + MyClient->NetClient->Rcv) && ENDLINE(Temp)) Temp++;
+ }
+ else
+ continue;
+ //delete all the headers of the old mail MsgQueuePtr->MailData->TranslatedHeader
+ struct CMimeItem *TH = MsgQueuePtr->MailData->TranslatedHeader;
+ if (TH) for (; MsgQueuePtr->MailData->TranslatedHeader != nullptr;) {
+ TH = TH->Next;
+ if (MsgQueuePtr->MailData->TranslatedHeader->name != nullptr)
+ delete[] MsgQueuePtr->MailData->TranslatedHeader->name;
+ if (MsgQueuePtr->MailData->TranslatedHeader->value != nullptr)
+ delete[] MsgQueuePtr->MailData->TranslatedHeader->value;
+ delete MsgQueuePtr->MailData->TranslatedHeader;
+ MsgQueuePtr->MailData->TranslatedHeader = TH;
+ }
- TranslateHeader(Temp, MyClient->NetClient->Rcv - (Temp - DataRX), &MsgQueuePtr->MailData->TranslatedHeader);
+ TranslateHeaderFcn(Temp, MyClient->NetClient->Rcv - (Temp - DataRX), &MsgQueuePtr->MailData->TranslatedHeader);
- MsgQueuePtr->Flags |= YAMN_MSG_BODYRECEIVED;
+ MsgQueuePtr->Flags |= YAMN_MSG_BODYRECEIVED;
- if (DataRX != nullptr)
- free(DataRX);
- DataRX = nullptr;
- break;
+ if (DataRX != nullptr)
+ free(DataRX);
+ DataRX = nullptr;
+ break;
+ }
}
}
}
- }
-
- SynchroMessages(ActualAccount, (HYAMNMAIL *)&ActualAccount->Mails, nullptr, (HYAMNMAIL *)&NewMails, nullptr); //we get only new mails on server!
- MsgsWriteDone(ActualAccount);
+ 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;
@@ -676,7 +622,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
BOOL autoretr = (ActualAccount->Flags & YAMN_ACC_BODY) != 0;
DataRX = MyClient->Top(MsgQueuePtr->Number, autoretr ? 100 : 0);
mir_snwprintf(accstatus, TranslateT("Reading new mail messages (%d%% done)"), 100 * i / msgs);
- SetAccountStatus(ActualAccount, accstatus);
+ SetStatusFcn(ActualAccount, accstatus);
if (DataRX != nullptr) {
Temp = DataRX;
@@ -689,7 +635,7 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
else
continue;
- TranslateHeader(Temp, MyClient->NetClient->Rcv - (Temp - DataRX), &MsgQueuePtr->MailData->TranslatedHeader);
+ TranslateHeaderFcn(Temp, MyClient->NetClient->Rcv - (Temp - DataRX), &MsgQueuePtr->MailData->TranslatedHeader);
#ifdef DEBUG_DECODE
@@ -713,19 +659,19 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
MsgQueuePtr = MsgQueuePtr->Next;
}
+
+ { SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (!swm.Succeeded())
+ throw (uint32_t)ActualAccount->SystemError == EACC_STOPPED;
- if (WAIT_OBJECT_0 != MsgsWaitToWrite(ActualAccount))
- throw (uint32_t)ActualAccount->SystemError == EACC_STOPPED;
-
- if (ActualAccount->Mails == nullptr)
- ActualAccount->Mails = NewMails;
- else {
- ActualAccount->LastMail = ActualAccount->LastChecked;
- AppendQueue((HYAMNMAIL)ActualAccount->Mails, NewMails);
+ if (ActualAccount->Mails == nullptr)
+ ActualAccount->Mails = NewMails;
+ else {
+ ActualAccount->LastMail = ActualAccount->LastChecked;
+ AppendQueueFcn((HYAMNMAIL)ActualAccount->Mails, NewMails);
+ }
}
- MsgsWriteDone(ActualAccount);
-
// 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};
@@ -736,14 +682,14 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
// if there is no waiting thread for internet connection close it
// else leave connection open
- if (0 == SCGetNumber(ActualAccount->InternetQueries)) {
+ if (0 == ActualAccount->InternetQueries.GetNumber()) {
DataRX = MyClient->Quit();
if (DataRX != nullptr)
free(DataRX);
DataRX = nullptr;
MyClient->NetClient->Disconnect();
- SetAccountStatus(ActualAccount, TranslateT("Disconnected"));
+ SetStatusFcn(ActualAccount, TranslateT("Disconnected"));
}
UsingInternet = FALSE;
@@ -756,14 +702,12 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
throw; //go to the main exception handling
}
- {
- YAMN_MAILBROWSERPARAM Param = {(HANDLE)nullptr, 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
+ CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, YAMN_MAILBROWSERVERSION);
- 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
- CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, (LPARAM)YAMN_MAILBROWSERVERSION);
- }
SetContactStatus(ActualAccount, ActualAccount->isCounting ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE);
}
#ifdef DEBUG_COMM
@@ -777,12 +721,13 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
#ifdef DEBUG_COMM
DebugLog(CommFile, "ERROR: %x\n", ErrorCode);
#endif
- if (WAIT_OBJECT_0 == MsgsWaitToWrite(ActualAccount)) {
- ActualAccount->LastChecked = now;
- MsgsWriteDone(ActualAccount);
+ {
+ SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (swm.Succeeded())
+ ActualAccount->LastChecked = now;
}
- DeleteMIMEQueue(ActualAccount, NewMails);
+ DeleteMessagesToEndFcn(ActualAccount, NewMails);
if (DataRX != nullptr)
free(DataRX);
@@ -809,7 +754,6 @@ DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp)
#endif
// WriteAccounts();
- SCDec(ActualAccount->UsingThreads);
return 0;
}
@@ -844,49 +788,46 @@ void __cdecl DeleteMailsPOP3(void *param)
// //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN".
// }
- HPOP3ACCOUNT ActualAccount = (HPOP3ACCOUNT)WhichTemp->AccountParam; //copy address of structure from calling thread to stack of this thread
+ 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;
- SCInc(ActualAccount->UsingThreads);
+ SCGuard sc(ActualAccount->UsingThreads);
if (INVALID_HANDLE_VALUE != WhichTemp->ThreadRunningEV)
SetEvent(WhichTemp->ThreadRunningEV);
+
+ { SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (!sra.Succeeded())
+ return;
- if (WAIT_OBJECT_0 != WaitToRead(ActualAccount)) {
- SCDec(ActualAccount->UsingThreads);
- return;
- }
-
- if (nullptr == (DeleteMails = (HYAMNMAIL)CreateNewDeleteQueue((HYAMNMAIL)ActualAccount->Mails))) //if there's no mail for deleting, return
- {
- if (POP3_DELETEFROMCHECK != POP3PluginParam) //We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked
- {
- YAMN_MAILBROWSERPARAM Param = {(HANDLE)nullptr, ActualAccount, YAMN_ACC_MSGP, YAMN_ACC_MSGP, YAMNParam}; //Just update the window
- CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, (LPARAM)YAMN_MAILBROWSERVERSION);
+ // if there's no mail for deleting, return
+ 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
+ CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, YAMN_MAILBROWSERVERSION);
+ }
+ return;
}
- SCDec(ActualAccount->UsingThreads);
- return;
- }
+ MyClient = &ActualAccount->Client;
- 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.
- ActualCopied.ServerName = _strdup(ActualAccount->Server->Name);
- ActualCopied.ServerPort = ActualAccount->Server->Port;
- ActualCopied.Flags = ActualAccount->Flags;
- ActualCopied.ServerLogin = _strdup(ActualAccount->Server->Login);
- ActualCopied.ServerPasswd = _strdup(ActualAccount->Server->Passwd);
- ActualCopied.NFlags = ActualAccount->NewMailN.Flags;
- ActualCopied.NNFlags = ActualAccount->NoNewMailN.Flags;
-
- ReadDone(ActualAccount);
-
- SCInc(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
- WaitForSingleObject(ActualAccount->UseInternetFree, INFINITE);
+ // 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;
+ ActualCopied.ServerLogin = _strdup(ActualAccount->Server->Login);
+ ActualCopied.ServerPasswd = _strdup(ActualAccount->Server->Passwd);
+ 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
+ WaitForSingleObject(ActualAccount->UseInternetFree, INFINITE);
+ }
- SCDec(ActualAccount->InternetQueries);
UsingInternet = TRUE;
try {
@@ -895,7 +836,7 @@ void __cdecl DeleteMailsPOP3(void *param)
DebugLog(CommFile, "<--------Communication-------->\n");
#endif
if ((MyClient->NetClient == nullptr) || !MyClient->NetClient->Connected()) {
- SetAccountStatus(ActualAccount, TranslateT("Connecting to server"));
+ SetStatusFcn(ActualAccount, TranslateT("Connecting to server"));
DataRX = MyClient->Connect(ActualCopied.ServerName, ActualCopied.ServerPort, ActualCopied.Flags & YAMN_ACC_SSL23, ActualCopied.Flags & YAMN_ACC_NOTLS);
@@ -914,7 +855,7 @@ void __cdecl DeleteMailsPOP3(void *param)
free(DataRX);
DataRX = nullptr;
}
- SetAccountStatus(ActualAccount, TranslateT("Entering POP3 account"));
+ SetStatusFcn(ActualAccount, TranslateT("Entering POP3 account"));
if (ActualAccount->Flags & YAMN_ACC_APOP) {
DataRX = MyClient->APOP(ActualCopied.ServerLogin, ActualCopied.ServerPasswd, timestamp);
@@ -940,7 +881,7 @@ void __cdecl DeleteMailsPOP3(void *param)
#endif
if (POP3_DELETEFROMCHECK != POP3PluginParam) //We do not need to get mails on server as we have already it from check function
{
- SetAccountStatus(ActualAccount, TranslateT("Deleting requested mails"));
+ SetStatusFcn(ActualAccount, TranslateT("Deleting requested mails"));
DataRX = MyClient->Stat();
@@ -983,16 +924,16 @@ void __cdecl DeleteMailsPOP3(void *param)
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
- SynchroMessages(ActualAccount, (HYAMNMAIL *)&DeleteMails, nullptr, (HYAMNMAIL *)&NewMails, nullptr);
+ SynchroMessagesFcn(ActualAccount, (HYAMNMAIL *)&DeleteMails, nullptr, (HYAMNMAIL *)&NewMails, nullptr);
}
}
- else SetAccountStatus(ActualAccount, TranslateT("Deleting spam"));
+ else SetStatusFcn(ActualAccount, TranslateT("Deleting spam"));
- if (WAIT_OBJECT_0 != MsgsWaitToWrite(ActualAccount))
- throw (uint32_t)EACC_STOPPED;
+ { SWriteGuard swm(ActualAccount->MessagesAccessSO);
+ if (!swm.Succeeded())
+ throw (uint32_t)EACC_STOPPED;
- if (msgs || POP3_DELETEFROMCHECK == POP3PluginParam) {
- try {
+ if (msgs || POP3_DELETEFROMCHECK == POP3PluginParam) {
HYAMNMAIL Temp;
for (i = 0, MsgQueuePtr = DeleteMails; MsgQueuePtr != nullptr; i++) {
@@ -1002,11 +943,11 @@ void __cdecl DeleteMailsPOP3(void *param)
Temp = MsgQueuePtr->Next;
if (POP3_FOK == MyClient->AckFlag) //if server answers that mail was deleted
{
- DeleteMIMEMessage((HYAMNMAIL *)&DeleteMails, MsgQueuePtr);
- HYAMNMAIL DeletedMail = FindMIMEMessageByID((HYAMNMAIL)ActualAccount->Mails, MsgQueuePtr->ID);
+ 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)
{
- DeleteMIMEMessage((HYAMNMAIL *)&ActualAccount->Mails, DeletedMail); //remove from queue
+ DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails, DeletedMail); //remove from queue
CallService(MS_YAMN_DELETEACCOUNTMAIL, (WPARAM)POP3Plugin, (LPARAM)DeletedMail);
}
else //else mark it only as "deleted mail"
@@ -1027,33 +968,27 @@ void __cdecl DeleteMailsPOP3(void *param)
else
MsgQueuePtr = MsgQueuePtr->Next;
}
- }
- catch (...) //if any exception in the code where we have write-access to account occured, don't forget to leave write-access
- {
- MsgsWriteDone(ActualAccount);
- throw; //and go to the main exception handling
- }
- 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
- SynchroMessages(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)
- else if (POP3_DELETEFROMCHECK != POP3PluginParam) {
- DeleteMIMEQueue(ActualAccount, (HYAMNMAIL)ActualAccount->Mails);
+ 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
+ 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)
+ else if (POP3_DELETEFROMCHECK != POP3PluginParam) {
+ DeleteMessagesToEndFcn(ActualAccount, (HYAMNMAIL)ActualAccount->Mails);
+ ActualAccount->Mails = nullptr;
+ }
+ }
+ else {
+ DeleteMessagesToEndFcn(ActualAccount, (HYAMNMAIL)ActualAccount->Mails);
ActualAccount->Mails = nullptr;
}
}
- else {
- DeleteMIMEQueue(ActualAccount, (HYAMNMAIL)ActualAccount->Mails);
- ActualAccount->Mails = nullptr;
- }
-
- MsgsWriteDone(ActualAccount);
+
#ifdef DEBUG_DECODE
DebugLog(DecodeFile, "</--------Deleting requested mails-------->\n");
#endif
@@ -1065,18 +1000,17 @@ void __cdecl DeleteMailsPOP3(void *param)
// else leave connection open
// if this functin was called from SynchroPOP3, then do not try to disconnect
if (POP3_DELETEFROMCHECK != POP3PluginParam) {
- YAMN_MAILBROWSERPARAM Param = {(HANDLE)nullptr, ActualAccount, ActualCopied.NFlags, YAMN_ACC_MSGP, YAMNParam};
-
- CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, (LPARAM)YAMN_MAILBROWSERVERSION);
+ YAMN_MAILBROWSERPARAM Param = { ActualAccount, ActualCopied.NFlags, YAMN_ACC_MSGP, YAMNParam};
+ CallService(MS_YAMN_MAILBROWSER, (WPARAM)&Param, YAMN_MAILBROWSERVERSION);
- if (0 == SCGetNumber(ActualAccount->InternetQueries)) {
+ if (0 == ActualAccount->InternetQueries.GetNumber()) {
DataRX = MyClient->Quit();
if (DataRX != nullptr)
free(DataRX);
DataRX = nullptr;
MyClient->NetClient->Disconnect();
- SetAccountStatus(ActualAccount, TranslateT("Disconnected"));
+ SetStatusFcn(ActualAccount, TranslateT("Disconnected"));
}
UsingInternet = FALSE;
@@ -1114,15 +1048,14 @@ void __cdecl DeleteMailsPOP3(void *param)
free(ActualCopied.ServerLogin);
free(ActualCopied.ServerPasswd);
- DeleteMIMEQueue(ActualAccount, NewMails);
- DeleteMIMEQueue(ActualAccount, DeleteMails);
+ DeleteMessagesToEndFcn(ActualAccount, NewMails);
+ DeleteMessagesToEndFcn(ActualAccount, DeleteMails);
#ifdef DEBUG_COMM
DebugLog(CommFile, "</--------Communication-------->\n");
#endif
// WriteAccounts();
- SCDec(ActualAccount->UsingThreads);
return;
}
diff --git a/protocols/YAMN/src/proto/pop3/pop3comm.h b/protocols/YAMN/src/proto/pop3/pop3comm.h
index f8edceb731..7a6d339d8d 100644
--- a/protocols/YAMN/src/proto/pop3/pop3comm.h
+++ b/protocols/YAMN/src/proto/pop3/pop3comm.h
@@ -3,38 +3,37 @@
#define POP3_FILEVERSION 1 //Version of aditional information stored in book file
-typedef struct CPOP3Account: public CAccount
+struct CPOP3Account : public CAccount
{
-// We can use SCOUNTER structure, because this is internal plugin.
-// This SO is used to determine if any POP3 account is in "write access" mode
- static PSCOUNTER AccountWriterSO;
+ // We can use SCOUNTER structure, because this is internal plugin.
+ // This SO is used to determine if any POP3 account is in "write access" mode
+ static SCOUNTER AccountWriterSO;
-// It is usefull to have client structure in account. With this structure we have access to account's socket.
-// This is related to InternetQueries and UseInternetFree
-// This member should be synchronized with UseInternetFree
+ // It is usefull to have client structure in account. With this structure we have access to account's socket.
+ // This is related to InternetQueries and UseInternetFree
+ // This member should be synchronized with UseInternetFree
class CPop3Client Client;
-// This member is usefull for MIME headers. It is default codepage, if no other codepage found
+ // This member is usefull for MIME headers. It is default codepage, if no other codepage found
uint16_t CP; //access only through AccountAccessSO
-// In this memeber last error code is stored
+ // In this memeber last error code is stored
uint32_t SystemError; //access through UseInternetFree
-// We use only counter from this object and it is # of threads waiting to work on internet.
-// We use event UseInternet to access critical sections.
-// It is usefull in 2 ways: we have mutual exclusion that only one thread works with account on internet.
-// Thread, which has done its work with account on internet can close socket, but it is not needed, when any other
-// thread wants to work (e.g. we have deleted mails, but when deleting, another thread wants to check new mail, so
-// we delete all needed mails and check if there's thread that wants to work. If yes, we do not need to quit session,
-// we leave socket open, and leave internet. Another thread then start checking and does not connect, does not send
-// user and password... because socket is open- it continues)
- PSCOUNTER InternetQueries;
+ // We use only counter from this object and it is # of threads waiting to work on internet.
+ // We use event UseInternet to access critical sections.
+ // It is usefull in 2 ways: we have mutual exclusion that only one thread works with account on internet.
+ // Thread, which has done its work with account on internet can close socket, but it is not needed, when any other
+ // thread wants to work (e.g. we have deleted mails, but when deleting, another thread wants to check new mail, so
+ // we delete all needed mails and check if there's thread that wants to work. If yes, we do not need to quit session,
+ // we leave socket open, and leave internet. Another thread then start checking and does not connect, does not send
+ // user and password... because socket is open- it continues)
+ SCOUNTER InternetQueries;
HANDLE UseInternetFree;
CPOP3Account();
~CPOP3Account();
-
-} POP3ACCOUNT,*HPOP3ACCOUNT;
+};
typedef struct POP3LayeredError
{
@@ -45,31 +44,6 @@ typedef struct POP3LayeredError
uint32_t SystemError;
} POP3_ERRORCODE,*PPOP3_ERRORCODE;
-struct YAMNExportedFcns
-{
- YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN SetProtocolPluginFcnImportFcn;
- YAMN_WAITTOWRITEFCN WaitToWriteFcn;
- YAMN_WRITEDONEFCN WriteDoneFcn;
- YAMN_WAITTOREADFCN WaitToReadFcn;
- YAMN_READDONEFCN ReadDoneFcn;
- YAMN_SCMANAGEFCN SCGetNumberFcn;
- YAMN_SCMANAGEFCN SCIncFcn;
- YAMN_SCMANAGEFCN SCDecFcn;
- YAMN_SETSTATUSFCN SetStatusFcn;
- YAMN_GETSTATUSFCN GetStatusFcn;
-};
-
-struct MailExportedFcns
-{
- YAMN_SYNCHROMIMEMSGSFCN SynchroMessagesFcn;
- YAMN_TRANSLATEHEADERFCN TranslateHeaderFcn;
- YAMN_APPENDQUEUEFCN AppendQueueFcn;
- YAMN_DELETEMIMEQUEUEFCN DeleteMessagesToEndFcn;
- YAMN_DELETEMIMEMESSAGEFCN DeleteMessageFromQueueFcn;
- YAMN_FINDMIMEMESSAGEFCN FindMessageByIDFcn;
- YAMN_CREATENEWDELETEQUEUEFCN CreateNewDeleteQueueFcn;
-};
-
enum
{
EACC_QUEUEALLOC=1, //memory allocation
diff --git a/protocols/YAMN/src/proto/pop3/pop3opt.cpp b/protocols/YAMN/src/proto/pop3/pop3opt.cpp
index 7cf85e5b76..25937acbbb 100644
--- a/protocols/YAMN/src/proto/pop3/pop3opt.cpp
+++ b/protocols/YAMN/src/proto/pop3/pop3opt.cpp
@@ -34,13 +34,13 @@ struct CBaseOptionsDlg : public CDlgBase
CDlgBase(g_plugin, iDlgId)
{}
- void DlgShowAccount(HPOP3ACCOUNT pAccount)
+ void DlgShowAccount(CPOP3Account* pAccount)
{
int i;
if (pAccount) {
// we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
- WaitToRead(pAccount);
+ SReadGuard sra(pAccount->AccountAccessSO);
DlgSetItemText(m_hwnd, IDC_EDITSERVER, pAccount->Server->Name);
DlgSetItemText(m_hwnd, IDC_EDITNAME, pAccount->Name);
@@ -89,9 +89,8 @@ struct CBaseOptionsDlg : public CDlgBase
CheckDlgButton(m_hwnd, IDC_CHECKCONTACTNOEVENT, pAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT ? BST_CHECKED : BST_UNCHECKED);
wchar_t accstatus[256];
- GetAccountStatus(pAccount, accstatus);
+ GetStatusFcn(pAccount, accstatus);
SetDlgItemText(m_hwnd, IDC_STSTATUS, accstatus);
- ReadDone(pAccount);
}
else {
DlgSetItemText(m_hwnd, IDC_EDITSERVER, nullptr);
@@ -172,11 +171,10 @@ struct CGeneralOptDlg : public CBaseOptionsDlg
static int g_iStatusControls[] = {IDC_CHECKST0, IDC_CHECKST1, IDC_CHECKST2, IDC_CHECKST3, IDC_CHECKST4, IDC_CHECKST5, IDC_CHECKST6, IDC_CHECKST7};
-static BOOL DlgShowAccountStatus(HWND hDlg, HPOP3ACCOUNT ActualAccount)
+static BOOL DlgShowAccountStatus(HWND hDlg, CPOP3Account* ActualAccount)
{
if (ActualAccount) {
- WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
-
+ SReadGuard sra(ActualAccount->AccountAccessSO);
CheckDlgButton(hDlg, IDC_CHECKST0, ActualAccount->StatusFlags & YAMN_ACC_ST0 ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_CHECKST1, ActualAccount->StatusFlags & YAMN_ACC_ST1 ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_CHECKST2, ActualAccount->StatusFlags & YAMN_ACC_ST2 ? BST_CHECKED : BST_UNCHECKED);
@@ -185,8 +183,6 @@ static BOOL DlgShowAccountStatus(HWND hDlg, HPOP3ACCOUNT ActualAccount)
CheckDlgButton(hDlg, IDC_CHECKST5, ActualAccount->StatusFlags & YAMN_ACC_ST5 ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_CHECKST6, ActualAccount->StatusFlags & YAMN_ACC_ST6 ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_CHECKST7, ActualAccount->StatusFlags & YAMN_ACC_ST7 ? BST_CHECKED : BST_UNCHECKED);
-
- ReadDone(ActualAccount);
}
else {
CheckDlgButton(hDlg, IDC_CHECKST0, BST_UNCHECKED);
@@ -203,10 +199,10 @@ static BOOL DlgShowAccountStatus(HWND hDlg, HPOP3ACCOUNT ActualAccount)
static INT_PTR CALLBACK DlgProcPOP3AccStatusOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM)
{
- static HPOP3ACCOUNT ActualAccount;
+ static CPOP3Account* ActualAccount;
switch (msg) {
case WM_INITDIALOG:
- ActualAccount = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput);
+ ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput);
if (ActualAccount != nullptr) {
DlgShowAccountStatus(hDlg, ActualAccount);
for (auto &it : g_iStatusControls)
@@ -252,7 +248,7 @@ class CAccOptDlg : public CBaseOptionsDlg
{
INT_PTR Result;
UCHAR ActualStatus;
- HPOP3ACCOUNT ActualAccount = nullptr;
+ CPOP3Account* ActualAccount = nullptr;
CCtrlCheck chkContact, chkSsl, chkApp;
CCtrlCombo cmbAccount, cmbCP;
@@ -338,15 +334,13 @@ public:
DlgShowAccount(0);
// Fill accounts
- WaitToReadSO(POP3Plugin->AccountBrowserSO);
-
- for (ActualAccount = (HPOP3ACCOUNT)POP3Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = (HPOP3ACCOUNT)ActualAccount->Next)
- if (ActualAccount->Name != nullptr)
- cmbAccount.AddStringA(ActualAccount->Name);
+ { SReadGuard srb(POP3Plugin->AccountBrowserSO);
+ for (ActualAccount = (CPOP3Account *)POP3Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = (CPOP3Account *)ActualAccount->Next)
+ if (ActualAccount->Name != nullptr)
+ cmbAccount.AddStringA(ActualAccount->Name);
+ }
cmbAccount.SetCurSel(0);
- ReadDoneSO(POP3Plugin->AccountBrowserSO);
-
// Fill code pages
cmbCP.AddString(TranslateT("Default"));
for (int i = 1; i < CPLENSUPP; i++) {
@@ -360,22 +354,22 @@ public:
ActualAccount = nullptr;
SendMessage(GetParent(m_hwnd), PSM_UNCHANGED, (WPARAM)m_hwnd, 0);
- WindowList_Add(pYAMNVar->MessageWnds, m_hwnd);
+ WindowList_Add(YAMNVar.MessageWnds, m_hwnd);
return true;
}
void OnDestroy() override
{
- WindowList_Remove(pYAMNVar->MessageWnds, m_hwnd);
+ WindowList_Remove(YAMNVar.MessageWnds, m_hwnd);
}
INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override
{
switch (msg) {
case WM_YAMN_CHANGESTATUS:
- if ((HPOP3ACCOUNT)wParam == ActualAccount) {
+ if ((CPOP3Account*)wParam == ActualAccount) {
wchar_t accstatus[256];
- GetAccountStatus(ActualAccount, accstatus);
+ GetStatusFcn(ActualAccount, accstatus);
SetDlgItemText(m_hwnd, IDC_STSTATUS, accstatus);
return TRUE;
}
@@ -386,7 +380,7 @@ public:
return TRUE;
case WM_YAMN_CHANGETIME:
- if ((HPOP3ACCOUNT)wParam == ActualAccount) {
+ if ((CPOP3Account*)wParam == ActualAccount) {
wchar_t Text[256];
mir_snwprintf(Text, TranslateT("Time left to next check [s]: %d"), (uint32_t)lParam);
SetDlgItemText(m_hwnd, IDC_STTIMELEFT, Text);
@@ -406,7 +400,7 @@ public:
void onKillFocus_Account(CCtrlCombo *)
{
GetDlgItemTextA(m_hwnd, IDC_COMBOACCOUNT, DlgInput, _countof(DlgInput));
- if (nullptr == (ActualAccount = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))) {
+ if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))) {
DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr);
EnableWindow(GetDlgItem(m_hwnd, IDC_BTNDEL), FALSE);
DlgEnableAccount(mir_strlen(DlgInput) > 0);
@@ -423,7 +417,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 = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) {
+ if ((Result == CB_ERR) || (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) {
DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr);
EnableWindow(GetDlgItem(m_hwnd, IDC_BTNDEL), FALSE);
}
@@ -515,7 +509,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 = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))))
+ || (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))))
return;
if (IDOK != MessageBox(m_hwnd, TranslateT("Do you really want to delete this account?"), TranslateT("Delete account confirmation"), MB_OKCANCEL | MB_ICONWARNING))
@@ -546,7 +540,8 @@ public:
char Text[MAX_PATH];
wchar_t TextW[MAX_PATH];
BOOL Translated, NewAcc = FALSE;
- size_t Length, index;
+ size_t Length;
+ int index;
if (!GetDlgItemTextA(m_hwnd, IDC_COMBOACCOUNT, Text, _countof(Text)))
return false;
@@ -600,129 +595,121 @@ public:
DlgSetItemTextW(m_hwnd, IDC_STTIMELEFT, TranslateT("Please wait while no account is in use."));
- if (nullptr == (ActualAccount = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)Text))) {
+ if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)Text))) {
NewAcc = TRUE;
- WaitToWriteSO(POP3Plugin->AccountBrowserSO);
- if (nullptr == (ActualAccount = (HPOP3ACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)POP3Plugin, (LPARAM)YAMN_ACCOUNTVERSION))) {
- WriteDoneSO(POP3Plugin->AccountBrowserSO);
+ SWriteGuard swb(POP3Plugin->AccountBrowserSO);
+ if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_GETNEXTFREEACCOUNT, (WPARAM)POP3Plugin, (LPARAM)YAMN_ACCOUNTVERSION))) {
+ swb.Uninit();
MessageBox(m_hwnd, TranslateT("Cannot allocate memory space for new account"), TranslateT("Memory error"), MB_OK);
return false;
}
DlgEnableAccount(true);
}
- else { // We have to get full access to AccountBrowser, so other iterating thrads cannot get new account until new account is right set
- WaitToWriteSO(POP3Plugin->AccountBrowserSO);
- }
-
- if (WAIT_OBJECT_0 != WaitToWrite(ActualAccount))
- WriteDoneSO(POP3Plugin->AccountBrowserSO);
-
- GetDlgItemTextA(m_hwnd, IDC_EDITNAME, Text, _countof(Text));
- if (!(Length = mir_strlen(Text)))
- return false;
- if (nullptr != ActualAccount->Name)
- delete[] ActualAccount->Name;
- ActualAccount->Name = new char[mir_strlen(Text) + 1];
- mir_strcpy(ActualAccount->Name, Text);
-
- GetDlgItemTextA(m_hwnd, IDC_EDITSERVER, Text, _countof(Text));
- if (nullptr != ActualAccount->Server->Name)
- delete[] ActualAccount->Server->Name;
- ActualAccount->Server->Name = new char[mir_strlen(Text) + 1];
- mir_strcpy(ActualAccount->Server->Name, Text);
-
- GetDlgItemTextA(m_hwnd, IDC_EDITLOGIN, Text, _countof(Text));
- if (nullptr != ActualAccount->Server->Login)
- delete[] ActualAccount->Server->Login;
- ActualAccount->Server->Login = new char[mir_strlen(Text) + 1];
- mir_strcpy(ActualAccount->Server->Login, Text);
-
- GetDlgItemTextA(m_hwnd, IDC_EDITPASS, Text, _countof(Text));
- if (nullptr != ActualAccount->Server->Passwd)
- delete[] ActualAccount->Server->Passwd;
- ActualAccount->Server->Passwd = new char[mir_strlen(Text) + 1];
- mir_strcpy(ActualAccount->Server->Passwd, Text);
-
- GetDlgItemTextW(m_hwnd, IDC_EDITAPP, TextW, _countof(TextW));
- if (nullptr != ActualAccount->NewMailN.App)
- delete[] ActualAccount->NewMailN.App;
- ActualAccount->NewMailN.App = new wchar_t[mir_wstrlen(TextW) + 1];
- mir_wstrcpy(ActualAccount->NewMailN.App, TextW);
-
- GetDlgItemTextW(m_hwnd, IDC_EDITAPPPARAM, TextW, _countof(TextW));
- if (nullptr != ActualAccount->NewMailN.AppParam)
- delete[] ActualAccount->NewMailN.AppParam;
- ActualAccount->NewMailN.AppParam = new wchar_t[mir_wstrlen(TextW) + 1];
- mir_wstrcpy(ActualAccount->NewMailN.AppParam, TextW);
-
- ActualAccount->Server->Port = Port;
- ActualAccount->Interval = Interval * 60;
-
- if (CB_ERR == (index = SendDlgItemMessage(m_hwnd, IDC_COMBOCP, CB_GETCURSEL, 0, 0)))
- index = CPDEFINDEX;
- ActualAccount->CP = CodePageNamesSupp[index].CP;
-
- if (NewAcc)
- ActualAccount->TimeLeft = Interval * 60;
-
- BOOL CheckStart = (IsDlgButtonChecked(m_hwnd, IDC_CHECKSTART) == BST_CHECKED);
- BOOL CheckForce = (IsDlgButtonChecked(m_hwnd, IDC_CHECKFORCE) == BST_CHECKED);
-
- ActualAccount->Flags =
- (Check ? YAMN_ACC_ENA : 0) |
- (CheckSSL ? YAMN_ACC_SSL23 : 0) |
- (CheckNoTLS ? YAMN_ACC_NOTLS : 0) |
- (CheckAPOP ? YAMN_ACC_APOP : 0) |
- (CheckABody ? YAMN_ACC_BODY : 0) |
- (ActualAccount->Flags & YAMN_ACC_POPN);
-
- ActualAccount->StatusFlags &= 0xFFFF;
- ActualAccount->StatusFlags |=
- (CheckStart ? YAMN_ACC_STARTS : 0) |
- (CheckForce ? YAMN_ACC_FORCE : 0);
-
- ActualAccount->NewMailN.Flags =
- (CheckMsg ? YAMN_ACC_MSG : 0) |
- (CheckIco ? YAMN_ACC_ICO : 0) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_POP) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_POPC) |
- (CheckApp ? YAMN_ACC_APP : 0) |
- (CheckKBN ? YAMN_ACC_KBN : 0) |
- (CheckContact ? YAMN_ACC_CONT : 0) |
- (CheckContactNick ? YAMN_ACC_CONTNICK : 0) |
- (CheckContactNoEvent ? YAMN_ACC_CONTNOEVENT : 0) |
- YAMN_ACC_MSGP; //this is default: when new mail arrives and window was displayed, leave it displayed.
-
- ActualAccount->NoNewMailN.Flags =
- (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP) |
- (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC) |
- (CheckNMsgP ? YAMN_ACC_MSGP : 0);
-
- ActualAccount->BadConnectN.Flags =
- (CheckFMsg ? YAMN_ACC_MSG : 0) |
- (CheckFIco ? YAMN_ACC_ICO : 0) |
- (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP) |
- (ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC);
-
- WriteDone(ActualAccount);
- WriteDoneSO(POP3Plugin->AccountBrowserSO);
+ {
+ SWriteGuard swa(ActualAccount->AccountAccessSO);
+ if (swa.Succeeded()) {
+ GetDlgItemTextA(m_hwnd, IDC_EDITNAME, Text, _countof(Text));
+ if (!(Length = mir_strlen(Text)))
+ return false;
+ if (nullptr != ActualAccount->Name)
+ delete[] ActualAccount->Name;
+ ActualAccount->Name = new char[mir_strlen(Text) + 1];
+ mir_strcpy(ActualAccount->Name, Text);
+
+ GetDlgItemTextA(m_hwnd, IDC_EDITSERVER, Text, _countof(Text));
+ if (nullptr != ActualAccount->Server->Name)
+ delete[] ActualAccount->Server->Name;
+ ActualAccount->Server->Name = new char[mir_strlen(Text) + 1];
+ mir_strcpy(ActualAccount->Server->Name, Text);
+
+ GetDlgItemTextA(m_hwnd, IDC_EDITLOGIN, Text, _countof(Text));
+ if (nullptr != ActualAccount->Server->Login)
+ delete[] ActualAccount->Server->Login;
+ ActualAccount->Server->Login = new char[mir_strlen(Text) + 1];
+ mir_strcpy(ActualAccount->Server->Login, Text);
+
+ GetDlgItemTextA(m_hwnd, IDC_EDITPASS, Text, _countof(Text));
+ if (nullptr != ActualAccount->Server->Passwd)
+ delete[] ActualAccount->Server->Passwd;
+ ActualAccount->Server->Passwd = new char[mir_strlen(Text) + 1];
+ mir_strcpy(ActualAccount->Server->Passwd, Text);
+
+ GetDlgItemTextW(m_hwnd, IDC_EDITAPP, TextW, _countof(TextW));
+ if (nullptr != ActualAccount->NewMailN.App)
+ delete[] ActualAccount->NewMailN.App;
+ ActualAccount->NewMailN.App = new wchar_t[mir_wstrlen(TextW) + 1];
+ mir_wstrcpy(ActualAccount->NewMailN.App, TextW);
+
+ GetDlgItemTextW(m_hwnd, IDC_EDITAPPPARAM, TextW, _countof(TextW));
+ if (nullptr != ActualAccount->NewMailN.AppParam)
+ delete[] ActualAccount->NewMailN.AppParam;
+ ActualAccount->NewMailN.AppParam = new wchar_t[mir_wstrlen(TextW) + 1];
+ mir_wstrcpy(ActualAccount->NewMailN.AppParam, TextW);
+
+ ActualAccount->Server->Port = Port;
+ ActualAccount->Interval = Interval * 60;
+
+ if (CB_ERR == (index = SendDlgItemMessage(m_hwnd, IDC_COMBOCP, CB_GETCURSEL, 0, 0)))
+ index = CPDEFINDEX;
+ ActualAccount->CP = CodePageNamesSupp[index].CP;
+
+ if (NewAcc)
+ ActualAccount->TimeLeft = Interval * 60;
+
+ BOOL CheckStart = (IsDlgButtonChecked(m_hwnd, IDC_CHECKSTART) == BST_CHECKED);
+ BOOL CheckForce = (IsDlgButtonChecked(m_hwnd, IDC_CHECKFORCE) == BST_CHECKED);
+
+ ActualAccount->Flags =
+ (Check ? YAMN_ACC_ENA : 0) |
+ (CheckSSL ? YAMN_ACC_SSL23 : 0) |
+ (CheckNoTLS ? YAMN_ACC_NOTLS : 0) |
+ (CheckAPOP ? YAMN_ACC_APOP : 0) |
+ (CheckABody ? YAMN_ACC_BODY : 0) |
+ (ActualAccount->Flags & YAMN_ACC_POPN);
+
+ ActualAccount->StatusFlags &= 0xFFFF;
+ ActualAccount->StatusFlags |=
+ (CheckStart ? YAMN_ACC_STARTS : 0) |
+ (CheckForce ? YAMN_ACC_FORCE : 0);
+
+ ActualAccount->NewMailN.Flags =
+ (CheckMsg ? YAMN_ACC_MSG : 0) |
+ (CheckIco ? YAMN_ACC_ICO : 0) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_POPC) |
+ (CheckApp ? YAMN_ACC_APP : 0) |
+ (CheckKBN ? YAMN_ACC_KBN : 0) |
+ (CheckContact ? YAMN_ACC_CONT : 0) |
+ (CheckContactNick ? YAMN_ACC_CONTNICK : 0) |
+ (CheckContactNoEvent ? YAMN_ACC_CONTNOEVENT : 0) |
+ YAMN_ACC_MSGP; //this is default: when new mail arrives and window was displayed, leave it displayed.
+
+ ActualAccount->NoNewMailN.Flags =
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC) |
+ (CheckNMsgP ? YAMN_ACC_MSGP : 0);
+
+ ActualAccount->BadConnectN.Flags =
+ (CheckFMsg ? YAMN_ACC_MSG : 0) |
+ (CheckFIco ? YAMN_ACC_ICO : 0) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC);
+ }
+ }
EnableWindow(GetDlgItem(m_hwnd, IDC_BTNDEL), TRUE);
DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr);
- index = SendDlgItemMessage(m_hwnd, IDC_COMBOACCOUNT, CB_GETCURSEL, 0, 0);
+ index = cmbAccount.GetCurSel();
+ cmbAccount.ResetContent();
- HPOP3ACCOUNT temp = ActualAccount;
-
- SendDlgItemMessage(m_hwnd, IDC_COMBOACCOUNT, CB_RESETCONTENT, 0, 0);
if (POP3Plugin->FirstAccount != nullptr)
- for (ActualAccount = (HPOP3ACCOUNT)POP3Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = (HPOP3ACCOUNT)ActualAccount->Next)
- if (ActualAccount->Name != nullptr)
- SendDlgItemMessageA(m_hwnd, IDC_COMBOACCOUNT, CB_ADDSTRING, 0, (LPARAM)ActualAccount->Name);
+ for (auto *p = POP3Plugin->FirstAccount; p != nullptr; p = p->Next)
+ if (p->Name != nullptr)
+ cmbAccount.AddStringA(p->Name);
- ActualAccount = temp;
- SendDlgItemMessage(m_hwnd, IDC_COMBOACCOUNT, CB_SETCURSEL, (WPARAM)index, (LPARAM)ActualAccount->Name);
+ index = cmbAccount.SetCurSel(index);
WritePOP3Accounts();
RefreshContact();
@@ -735,7 +722,7 @@ public:
class CPopupOptsDlg : public CBaseOptionsDlg
{
- HPOP3ACCOUNT ActualAccount = nullptr;
+ CPOP3Account* ActualAccount = nullptr;
UCHAR ActualStatus;
CCtrlCombo cmbAccount, cmbCP;
@@ -745,7 +732,7 @@ class CPopupOptsDlg : public CBaseOptionsDlg
void DlgShowAccountPopup()
{
if (ActualAccount) {
- WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ SReadGuard sra(ActualAccount->AccountAccessSO);
SetDlgItemInt(m_hwnd, IDC_EDITPOPS, ActualAccount->NewMailN.PopupTime, FALSE);
SetDlgItemInt(m_hwnd, IDC_EDITNPOPS, ActualAccount->NoNewMailN.PopupTime, FALSE);
SetDlgItemInt(m_hwnd, IDC_EDITFPOPS, ActualAccount->BadConnectN.PopupTime, FALSE);
@@ -758,7 +745,6 @@ class CPopupOptsDlg : public CBaseOptionsDlg
chkFcol.SetState(ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC);
CheckDlgButton(m_hwnd, IDC_RADIOPOPN, ActualAccount->Flags & YAMN_ACC_POPN ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(m_hwnd, IDC_RADIOPOP1, ActualAccount->Flags & YAMN_ACC_POPN ? BST_UNCHECKED : BST_CHECKED);
- ReadDone(ActualAccount);
}
else { // default
SetDlgItemInt(m_hwnd, IDC_EDITPOPS, 0, FALSE);
@@ -801,7 +787,7 @@ class CPopupOptsDlg : public CBaseOptionsDlg
void DlgShowAccountColors()
{
- WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ SReadGuard sra(ActualAccount->AccountAccessSO);
if (ActualAccount->NewMailN.Flags & YAMN_ACC_POPC) {
SendDlgItemMessage(m_hwnd, IDC_CPB, CPM_SETCOLOUR, 0, (LPARAM)ActualAccount->NewMailN.PopupB);
@@ -827,8 +813,6 @@ class CPopupOptsDlg : public CBaseOptionsDlg
SendDlgItemMessage(m_hwnd, IDC_CPNB, CPM_SETCOLOUR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
SendDlgItemMessage(m_hwnd, IDC_CPNT, CPM_SETCOLOUR, 0, (LPARAM)GetSysColor(COLOR_WINDOWTEXT));
}
-
- ReadDone(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
}
public:
@@ -859,19 +843,17 @@ public:
bool OnInitDialog() override
{
- WindowList_Add(pYAMNVar->MessageWnds, m_hwnd);
+ WindowList_Add(YAMNVar.MessageWnds, m_hwnd);
DlgEnableAccountPopup(false);
DlgShowAccountPopup();
-
- WaitToReadSO(POP3Plugin->AccountBrowserSO);
-
- if (POP3Plugin->FirstAccount != nullptr)
- for (ActualAccount = (HPOP3ACCOUNT)POP3Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = (HPOP3ACCOUNT)ActualAccount->Next)
- if (ActualAccount->Name != nullptr)
- cmbAccount.AddStringA(ActualAccount->Name);
-
- ReadDoneSO(POP3Plugin->AccountBrowserSO);
+ {
+ SReadGuard srb(POP3Plugin->AccountBrowserSO);
+ if (POP3Plugin->FirstAccount != nullptr)
+ for (ActualAccount = (CPOP3Account *)POP3Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = (CPOP3Account *)ActualAccount->Next)
+ if (ActualAccount->Name != nullptr)
+ cmbAccount.AddStringA(ActualAccount->Name);
+ }
ActualAccount = nullptr;
cmbAccount.SetCurSel(0);
return true;
@@ -879,13 +861,13 @@ public:
void OnDestroy() override
{
- WindowList_Remove(pYAMNVar->MessageWnds, m_hwnd);
+ WindowList_Remove(YAMNVar.MessageWnds, m_hwnd);
}
void onKillFocus_Account(CCtrlCombo *)
{
GetDlgItemTextA(m_hwnd, IDC_COMBOACCOUNT, DlgInput, _countof(DlgInput));
- if (nullptr == (ActualAccount = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))) {
+ if (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput))) {
DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr);
if (mir_strlen(DlgInput))
DlgEnableAccountPopup(true);
@@ -901,10 +883,10 @@ public:
void onSelChange_Account(CCtrlCombo *)
{
- int Result = SendDlgItemMessage(m_hwnd, IDC_COMBOACCOUNT, CB_GETCURSEL, 0, 0);
+ 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 = (HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) {
+ if ((Result == CB_ERR) || (nullptr == (ActualAccount = (CPOP3Account*)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)DlgInput)))) {
DlgSetItemText(m_hwnd, (WPARAM)IDC_STTIMELEFT, nullptr);
}
else {
@@ -1049,53 +1031,52 @@ public:
}
DlgSetItemTextW(m_hwnd, IDC_STTIMELEFT, TranslateT("Please wait while no account is in use."));
-
- ActualAccount->Flags =
- (ActualAccount->Flags & YAMN_ACC_ENA) |
- (ActualAccount->Flags & YAMN_ACC_SSL23) |
- (ActualAccount->Flags & YAMN_ACC_NOTLS) |
- (ActualAccount->Flags & YAMN_ACC_APOP) |
- (ActualAccount->Flags & YAMN_ACC_BODY) |
- (CheckPopN ? YAMN_ACC_POPN : 0);
-
- ActualAccount->NewMailN.Flags =
- (ActualAccount->NewMailN.Flags & YAMN_ACC_MSG) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_ICO) |
- (CheckPopup ? YAMN_ACC_POP : 0) |
- (CheckPopupW ? YAMN_ACC_POPC : 0) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_APP) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_KBN) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_CONT) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNICK) |
- (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT) |
- YAMN_ACC_MSGP;
-
- ActualAccount->NoNewMailN.Flags =
- (CheckNPopup ? YAMN_ACC_POP : 0) |
- (CheckNPopupW ? YAMN_ACC_POPC : 0) |
- (ActualAccount->NoNewMailN.Flags & YAMN_ACC_MSGP);
-
- ActualAccount->BadConnectN.Flags =
- (ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) |
- (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) |
- (CheckFPopup ? YAMN_ACC_POP : 0) |
- (CheckFPopupW ? YAMN_ACC_POPC : 0);
-
- ActualAccount->NewMailN.PopupB = SendDlgItemMessage(m_hwnd, IDC_CPB, CPM_GETCOLOUR, 0, 0);
- ActualAccount->NewMailN.PopupT = SendDlgItemMessage(m_hwnd, IDC_CPT, CPM_GETCOLOUR, 0, 0);
- ActualAccount->NewMailN.PopupTime = Time;
-
- ActualAccount->NoNewMailN.PopupB = SendDlgItemMessage(m_hwnd, IDC_CPNB, CPM_GETCOLOUR, 0, 0);
- ActualAccount->NoNewMailN.PopupT = SendDlgItemMessage(m_hwnd, IDC_CPNT, CPM_GETCOLOUR, 0, 0);
- ActualAccount->NoNewMailN.PopupTime = TimeN;
-
- ActualAccount->BadConnectN.PopupB = SendDlgItemMessage(m_hwnd, IDC_CPFB, CPM_GETCOLOUR, 0, 0);
- ActualAccount->BadConnectN.PopupT = SendDlgItemMessage(m_hwnd, IDC_CPFT, CPM_GETCOLOUR, 0, 0);
- ActualAccount->BadConnectN.PopupTime = TimeF;
-
- WriteDone(ActualAccount);
- WriteDoneSO(POP3Plugin->AccountBrowserSO);
-
+ {
+ SWriteGuard swa(ActualAccount->AccountAccessSO);
+
+ ActualAccount->Flags =
+ (ActualAccount->Flags & YAMN_ACC_ENA) |
+ (ActualAccount->Flags & YAMN_ACC_SSL23) |
+ (ActualAccount->Flags & YAMN_ACC_NOTLS) |
+ (ActualAccount->Flags & YAMN_ACC_APOP) |
+ (ActualAccount->Flags & YAMN_ACC_BODY) |
+ (CheckPopN ? YAMN_ACC_POPN : 0);
+
+ ActualAccount->NewMailN.Flags =
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_MSG) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_ICO) |
+ (CheckPopup ? YAMN_ACC_POP : 0) |
+ (CheckPopupW ? YAMN_ACC_POPC : 0) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_APP) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_KBN) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONT) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNICK) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT) |
+ YAMN_ACC_MSGP;
+
+ ActualAccount->NoNewMailN.Flags =
+ (CheckNPopup ? YAMN_ACC_POP : 0) |
+ (CheckNPopupW ? YAMN_ACC_POPC : 0) |
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_MSGP);
+
+ ActualAccount->BadConnectN.Flags =
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) |
+ (CheckFPopup ? YAMN_ACC_POP : 0) |
+ (CheckFPopupW ? YAMN_ACC_POPC : 0);
+
+ ActualAccount->NewMailN.PopupB = SendDlgItemMessage(m_hwnd, IDC_CPB, CPM_GETCOLOUR, 0, 0);
+ ActualAccount->NewMailN.PopupT = SendDlgItemMessage(m_hwnd, IDC_CPT, CPM_GETCOLOUR, 0, 0);
+ ActualAccount->NewMailN.PopupTime = Time;
+
+ ActualAccount->NoNewMailN.PopupB = SendDlgItemMessage(m_hwnd, IDC_CPNB, CPM_GETCOLOUR, 0, 0);
+ ActualAccount->NoNewMailN.PopupT = SendDlgItemMessage(m_hwnd, IDC_CPNT, CPM_GETCOLOUR, 0, 0);
+ ActualAccount->NoNewMailN.PopupTime = TimeN;
+
+ ActualAccount->BadConnectN.PopupB = SendDlgItemMessage(m_hwnd, IDC_CPFB, CPM_GETCOLOUR, 0, 0);
+ ActualAccount->BadConnectN.PopupT = SendDlgItemMessage(m_hwnd, IDC_CPFT, CPM_GETCOLOUR, 0, 0);
+ ActualAccount->BadConnectN.PopupTime = TimeF;
+ }
WritePOP3Accounts();
RefreshContact();
return TRUE;
diff --git a/protocols/YAMN/src/protoplugin.cpp b/protocols/YAMN/src/protoplugin.cpp
index b192ac1f5f..7732640fcb 100644
--- a/protocols/YAMN/src/protoplugin.cpp
+++ b/protocols/YAMN/src/protoplugin.cpp
@@ -8,12 +8,12 @@
//--------------------------------------------------------------------------------------------------
-PYAMN_PROTOPLUGINQUEUE FirstProtoPlugin = nullptr;
+YAMN_PROTOPLUGINQUEUE *FirstProtoPlugin = nullptr;
INT_PTR RegisterProtocolPluginSvc(WPARAM, LPARAM);
//Removes plugin from queue and deletes registration structures
-INT_PTR UnregisterProtocolPlugin(HYAMNPROTOPLUGIN Plugin);
+INT_PTR UnregisterProtocolPlugin(YAMN_PROTOPLUGIN *Plugin);
INT_PTR UnregisterProtocolPluginSvc(WPARAM, LPARAM);
@@ -27,12 +27,7 @@ INT_PTR UnregisterProtoPlugins();
// YAMNMailFcn- pointer to imported functions with mails
// YAMNMailFcnVer- version of YAMN_MAILIMPORTFCN, use YAMN_MAILIMPORTFCNVERSION
// returns nonzero if success
-int WINAPI SetProtocolPluginFcnImportFcn(HYAMNPROTOPLUGIN Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer);
-
-struct CExportedFunctions ProtoPluginExportedFcn[] =
-{
- {YAMN_SETPROTOCOLPLUGINFCNIMPORTID, (void *)SetProtocolPluginFcnImportFcn},
-};
+int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer);
struct CExportedServices ProtoPluginExportedSvc[] =
{
@@ -48,7 +43,7 @@ struct CExportedServices ProtoPluginExportedSvc[] =
INT_PTR RegisterProtocolPluginSvc(WPARAM wParam, LPARAM lParam)
{
PYAMN_PROTOREGISTRATION Registration = (PYAMN_PROTOREGISTRATION)wParam;
- HYAMNPROTOPLUGIN Plugin;
+ YAMN_PROTOPLUGIN *Plugin;
if (lParam != YAMN_PROTOREGISTRATIONVERSION)
return 0;
@@ -58,22 +53,15 @@ INT_PTR RegisterProtocolPluginSvc(WPARAM wParam, LPARAM lParam)
return (INT_PTR)NULL;
Plugin->PluginInfo = Registration;
-
Plugin->FirstAccount = nullptr;
-
- Plugin->AccountBrowserSO = new SWMRG;
- SWMRGInitialize(Plugin->AccountBrowserSO, nullptr);
-
Plugin->Fcn = nullptr;
Plugin->MailFcn = nullptr;
return (INT_PTR)Plugin;
}
-int WINAPI SetProtocolPluginFcnImportFcn(HYAMNPROTOPLUGIN Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer)
+int WINAPI SetProtocolPluginFcnImportFcn(YAMN_PROTOPLUGIN *Plugin, PYAMN_PROTOIMPORTFCN YAMNFcn, uint32_t YAMNFcnVer, PYAMN_MAILIMPORTFCN YAMNMailFcn, uint32_t YAMNMailFcnVer)
{
- PYAMN_PROTOPLUGINQUEUE Parser;
-
if (YAMNFcnVer != YAMN_PROTOIMPORTFCNVERSION)
return 0;
if (YAMNMailFcnVer != YAMN_MAILIMPORTFCNVERSION)
@@ -87,7 +75,9 @@ int WINAPI SetProtocolPluginFcnImportFcn(HYAMNPROTOPLUGIN Plugin, PYAMN_PROTOIMP
Plugin->MailFcn = YAMNMailFcn;
mir_cslock lck(PluginRegCS);
+
// We add protocol to the protocol list
+ YAMN_PROTOPLUGINQUEUE *Parser;
for (Parser = FirstProtoPlugin; Parser != nullptr && Parser->Next != nullptr; Parser = Parser->Next);
if (Parser == nullptr) {
FirstProtoPlugin = new YAMN_PROTOPLUGINQUEUE;
@@ -103,9 +93,9 @@ int WINAPI SetProtocolPluginFcnImportFcn(HYAMNPROTOPLUGIN Plugin, PYAMN_PROTOIMP
return 1;
}
-INT_PTR UnregisterProtocolPlugin(HYAMNPROTOPLUGIN Plugin)
+INT_PTR UnregisterProtocolPlugin(YAMN_PROTOPLUGIN *Plugin)
{
- PYAMN_PROTOPLUGINQUEUE Parser, Found;
+ YAMN_PROTOPLUGINQUEUE *Parser, *Found;
if (FirstProtoPlugin->Plugin == Plugin) {
Found = FirstProtoPlugin;
@@ -120,24 +110,23 @@ INT_PTR UnregisterProtocolPlugin(HYAMNPROTOPLUGIN Plugin)
else
Found = nullptr;
}
- if (Found != nullptr) {
- StopAccounts(Plugin);
- DeleteAccounts(Plugin);
- if (Plugin->Fcn->UnLoadFcn != nullptr)
- Plugin->Fcn->UnLoadFcn((void *)nullptr);
-
- delete Found->Plugin->AccountBrowserSO;
- delete Found->Plugin;
- delete Found;
- }
- else
- return 0;
- return 1;
+
+ if (!Found)
+ return 1;
+
+ StopAccounts(Plugin);
+ DeleteAccounts(Plugin);
+ if (Plugin->Fcn->UnLoadFcn != nullptr)
+ Plugin->Fcn->UnLoadFcn((void *)nullptr);
+
+ delete Found->Plugin;
+ delete Found;
+ return 0;
}
INT_PTR UnregisterProtocolPluginSvc(WPARAM wParam, LPARAM)
{
- HYAMNPROTOPLUGIN Plugin = (HYAMNPROTOPLUGIN)wParam;
+ YAMN_PROTOPLUGIN *Plugin = (YAMN_PROTOPLUGIN*)wParam;
mir_cslock lck(PluginRegCS);
UnregisterProtocolPlugin(Plugin);
diff --git a/protocols/YAMN/src/services.cpp b/protocols/YAMN/src/services.cpp
index 361fb01636..180b035a06 100644
--- a/protocols/YAMN/src/services.cpp
+++ b/protocols/YAMN/src/services.cpp
@@ -58,7 +58,8 @@ static INT_PTR ContactApplication(WPARAM wParam, LPARAM)
STARTUPINFOW si = {0};
si.cb = sizeof(si);
- if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra.Succeeded()) {
if (ActualAccount->NewMailN.App != nullptr) {
wchar_t *Command;
if (ActualAccount->NewMailN.AppParam != nullptr)
@@ -78,15 +79,13 @@ static INT_PTR ContactApplication(WPARAM wParam, LPARAM)
delete[] Command;
}
}
-
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
}
db_free(&dbv);
return 0;
}
-uint32_t WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, uint32_t dwTimeout);
+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
@@ -102,9 +101,8 @@ static INT_PTR AccountMailCheck(WPARAM wParam, LPARAM lParam)
return 0;
mir_cslock lck(PluginRegCS);
- if (WAIT_OBJECT_0 != SWMRGWaitToRead(ActualAccount->AccountAccessSO, 0)) {
- }
- else {
+ 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};
@@ -116,7 +114,6 @@ static INT_PTR AccountMailCheck(WPARAM wParam, LPARAM lParam)
CloseHandle(NewThread);
}
}
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
CloseHandle(ThreadRunningEV);
}
@@ -142,23 +139,17 @@ static INT_PTR ContactMailCheck(WPARAM hContact, LPARAM)
//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);
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) {
- }
- else {
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra.Succeeded()) {
if ((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) //account cannot be forced to check
{
- if (ActualAccount->Plugin->Fcn->ForceCheckFcnPtr == nullptr)
- ReadDoneFcn(ActualAccount->AccountAccessSO);
-
DWORD tid;
struct 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))
- ReadDoneFcn(ActualAccount->AccountAccessSO);
- else
+ if (CreateThread(nullptr, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr, &ParamToPlugin, 0, &tid))
WaitForSingleObject(ThreadRunningEV, INFINITE);
}
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
CloseHandle(ThreadRunningEV);
}
@@ -178,8 +169,9 @@ static INT_PTR ContactMailCheck(WPARAM hContact, LPARAM)
CAccount *ActualAccount = (CAccount *)CallService(MS_YAMN_FINDACCOUNTBYNAME, (WPARAM)POP3Plugin, (LPARAM)dbv.pszVal);
if (ActualAccount != nullptr) {
- if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
- YAMN_MAILBROWSERPARAM Param = {nullptr, ActualAccount, ActualAccount->NewMailN.Flags, ActualAccount->NoNewMailN.Flags, nullptr};
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (sra.Succeeded()) {
+ 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;
@@ -188,7 +180,6 @@ static INT_PTR ContactMailCheck(WPARAM hContact, LPARAM)
Param.nflags = Param.nflags & ~YAMN_ACC_POP;
RunMailBrowserSvc((WPARAM)&Param, YAMN_MAILBROWSERVERSION);
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
}
db_free(&dbv);
@@ -286,12 +277,6 @@ void CreateServiceFunctions(void)
CreateServiceFunction(YAMN_DBMODULE PS_LOADICON, Service_LoadIcon);
// Function with which protocol plugin can register
- CreateServiceFunction(MS_YAMN_GETFCNPTR, GetFcnPtrSvc);
-
- // Function returns pointer to YAMN variables
- CreateServiceFunction(MS_YAMN_GETVARIABLES, GetVariablesSvc);
-
- // Function with which protocol plugin can register
CreateServiceFunction(MS_YAMN_REGISTERPROTOPLUGIN, RegisterProtocolPluginSvc);
// Function with which protocol plugin can unregister
diff --git a/protocols/YAMN/src/stdafx.h b/protocols/YAMN/src/stdafx.h
index 38f1c1b5fe..25dda0a5f5 100644
--- a/protocols/YAMN/src/stdafx.h
+++ b/protocols/YAMN/src/stdafx.h
@@ -69,12 +69,10 @@ void UnInitDebug();
// From yamn.cpp
INT_PTR GetFcnPtrSvc(WPARAM wParam, LPARAM lParam);
-INT_PTR GetVariablesSvc(WPARAM, LPARAM);
+
void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD);
INT_PTR ForceCheckSvc(WPARAM, LPARAM);
-extern struct YAMNExportedFcns *pYAMNFcn;
-
// From account.cpp
INT_PTR CreatePluginAccountSvc(WPARAM wParam, LPARAM lParam);
INT_PTR DeletePluginAccountSvc(WPARAM wParam, LPARAM);
@@ -104,9 +102,9 @@ INT_PTR GetNextFreeAccountSvc(WPARAM wParam, LPARAM lParam);
INT_PTR DeleteAccountSvc(WPARAM wParam, LPARAM);
void __cdecl DeleteAccountInBackground(void *Which);
-int StopAccounts(HYAMNPROTOPLUGIN Plugin);
-int WaitForAllAccounts(HYAMNPROTOPLUGIN Plugin, BOOL GetAccountBrowserAccess = FALSE);
-int DeleteAccounts(HYAMNPROTOPLUGIN Plugin);
+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);
@@ -177,26 +175,21 @@ extern HANDLE hTTButton;
extern HCURSOR hCurSplitNS, hCurSplitWE;
extern UINT SecTimer;
-//From synchro.cpp
+// From synchro.cpp
void WINAPI DeleteMessagesToEndFcn(CAccount *Account, HYAMNMAIL From);
-uint32_t WINAPI WaitToWriteFcn(PSWMRG SObject, PSCOUNTER SCounter = nullptr);
-void WINAPI WriteDoneFcn(PSWMRG SObject, PSCOUNTER SCounter = nullptr);
-uint32_t WINAPI WaitToReadFcn(PSWMRG SObject);
-void WINAPI ReadDoneFcn(PSWMRG SObject);
-uint32_t WINAPI SCIncFcn(PSCOUNTER SCounter);
-uint32_t WINAPI SCDecFcn(PSCOUNTER SCounter);
-BOOL WINAPI SWMRGInitialize(PSWMRG, wchar_t *);
-void WINAPI SWMRGDelete(PSWMRG);
-uint32_t WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG, uint32_t dwTimeout);
-void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG);
-uint32_t WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, uint32_t dwTimeout);
-void WINAPI SWMRGDoneReading(PSWMRG pSWMRG);
-
-//From mails.cpp
+
+// 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);
-//From mime.cpp
+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);
+
+// From mime.cpp
void ExtractHeader(struct CMimeItem *items, int &CP, struct CHeader *head);
void ExtractShortHeader(struct CMimeItem *items, struct CShortHeader *head);
void DeleteHeaderContent(struct CHeader *head);
@@ -207,7 +200,7 @@ wchar_t *ParseMultipartBody(char *src, char *bond);
//From account.cpp
void WINAPI GetStatusFcn(CAccount *Which, wchar_t *Value);
-extern HYAMNPROTOPLUGIN POP3Plugin;
+extern YAMN_PROTOPLUGIN *POP3Plugin;
//from decode.cpp
int DecodeQuotedPrintable(char *Src, char *Dst, int DstLen, BOOL isQ);
@@ -217,21 +210,7 @@ int DecodeBase64(char *Src, char *Dst, int DstLen);
extern PYAMN_FILTERPLUGINQUEUE FirstFilterPlugin;
//From protoplugin.cpp
-extern PYAMN_PROTOPLUGINQUEUE FirstProtoPlugin;
-
-extern struct CExportedFunctions ProtoPluginExportedFcn[1];
-extern struct CExportedServices ProtoPluginExportedSvc[5];
-//From filterplugin.cpp
-extern struct CExportedFunctions FilterPluginExportedFcn[1];
-extern struct CExportedServices FilterPluginExportedSvc[2];
-//From synchro.cpp
-extern struct CExportedFunctions SynchroExportedFcn[7];
-//From account.cpp
-extern struct CExportedFunctions AccountExportedFcn[2];
-extern struct CExportedServices AccountExportedSvc[9];
-//From mails.cpp (MIME)
-extern struct CExportedFunctions MailExportedFcn[8];
-extern struct CExportedServices MailExportedSvc[5];
+extern YAMN_PROTOPLUGINQUEUE *FirstProtoPlugin;
extern char *iconDescs[];
extern char *iconNames[];
@@ -243,11 +222,7 @@ 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);
-extern void __cdecl MailBrowser(void *Param);
-extern void __cdecl BadConnection(void *Param);
extern PVOID TLSCtx;
extern PVOID SSLCtx;
-extern PYAMN_VARIABLES pYAMNVar;
-
#endif
diff --git a/protocols/YAMN/src/synchro.cpp b/protocols/YAMN/src/synchro.cpp
index 184156787d..d239f95434 100644
--- a/protocols/YAMN/src/synchro.cpp
+++ b/protocols/YAMN/src/synchro.cpp
@@ -7,157 +7,85 @@
#include "stdafx.h"
- // Initializes a SWMRG structure. This structure must be
- // initialized before any writer or reader threads attempt
- // to wait on it.
- // The structure must be allocated by the application and
- // the structure's address is passed as the first parameter.
- // The lpszName parameter is the name of the object. Pass
- // NULL if you do not want to share the object.
-BOOL WINAPI SWMRGInitialize(PSWMRG pSWMRG, wchar_t *Name);
-
-// Deletes the system resources associated with a SWMRG
-// structure. The structure must be deleted only when
-// no writer or reader threads in the calling process
-// will wait on it.
-void WINAPI SWMRGDelete(PSWMRG pSWMRG);
-
-// A writer thread calls this function to know when
-// it can successfully write to the shared data.
-// returns WAIT_FINISH when we are in write-access or WAIT_FAILED
-// when event about quick finishing is set (or when system returns fail when waiting for synchro object)
-uint32_t WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG, uint32_t dwTimeout);
-
-// A writer thread calls this function to let other threads
-// know that it no longer needs to write to the shared data.
-void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG);
-
-// A reader thread calls this function to know when
-// it can successfully read the shared data.
-// returns WAIT_FINISH when we are in read-access or WAIT_FAILED
-// when event about quick finishing is set (or when system returns fail when waiting for synchro object)
-uint32_t WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, uint32_t dwTimeout);
-
-// A reader thread calls this function to let other threads
-// know when it no longer needs to read the shared data.
-void WINAPI SWMRGDoneReading(PSWMRG pSWMRG);
-
-// WaitToReadFcn
-// is used to wait for read access with SWMRG SO, but it also increments counter if successfull
-// returns WAIT_FAILED or WAIT_FINISH
-// when WAIT_FAILED, we should not begin to access datas, we are not in read-access mode
-uint32_t WINAPI WaitToReadFcn(PSWMRG SObject);
-
-// WriteDoneFcn
-// is used to release read access with SWMRG SO, but it also decrements counter if successfull
-void WINAPI ReadDoneFcn(PSWMRG SObject);
-
-// This functions is for export purposes
-// Plugin can call this function to manage SCOUNTER synchronization object
-
-// Gets number value stored in SCOUNTER SO
-// Note you must not read the number from memory directly, because
-// CPU can stop reading thread when it has read HI-Word, then another thread
-// can change the value and then OS starts the previous thread, that reads the
-// LO-uint16_t of uint32_t. And the return value HI+LO-uint16_t is corrupted
-uint32_t WINAPI SCGetNumberFcn(PSCOUNTER SCounter);
-
-// Increments SCOUNTER and unsets event
-// Returns Number after incrementing
-uint32_t WINAPI SCIncFcn(PSCOUNTER SCounter);
-
-// Decrements SCOUNTER and sets event if zero
-// Returns Number after decrementing
-uint32_t WINAPI SCDecFcn(PSCOUNTER SCounter);
-
-struct CExportedFunctions SynchroExportedFcn[] =
+/////////////////////////////////////////////////////////////////////////////////////////
+// Initializes a SWMRG structure. This structure must be
+// initialized before any writer or reader threads attempt
+// to wait on it.
+// The structure must be allocated by the application and
+// the structure's address is passed as the first parameter.
+// The lpszName parameter is the name of the object. Pass
+// NULL if you do not want to share the object.
+
+SWMRG::SWMRG(wchar_t *Name)
{
- {YAMN_WAITTOWRITEID, (void *)WaitToWriteFcn},
- {YAMN_WRITEDONEID, (void *)WriteDoneFcn},
- {YAMN_WAITTOREADID, (void *)WaitToReadFcn},
- {YAMN_READDONEID, (void *)ReadDoneFcn},
- {YAMN_SCGETNUMBERID, (void *)SCGetNumberFcn},
- {YAMN_SCINCID, (void *)SCIncFcn},
- {YAMN_SCDECID, (void *)SCDecFcn},
-};
-
-//--------------------------------------------------------------------------------------------------
-//--------------------------------------------------------------------------------------------------
-
-void WINAPI SWMRGDelete(PSWMRG pSWMRG)
-{
- // Destroys any synchronization objects that were
- // successfully created.
- if (nullptr != pSWMRG->hEventNoWriter)
- CloseHandle(pSWMRG->hEventNoWriter);
- if (nullptr != pSWMRG->hEventNoReaders)
- CloseHandle(pSWMRG->hEventNoReaders);
- if (nullptr != pSWMRG->hSemNumReaders)
- CloseHandle(pSWMRG->hSemNumReaders);
- if (nullptr != pSWMRG->hFinishEV)
- CloseHandle(pSWMRG->hFinishEV);
-}
-
-BOOL WINAPI SWMRGInitialize(PSWMRG pSWMRG, wchar_t *Name)
-{
- pSWMRG->hEventNoWriter = nullptr;
- pSWMRG->hEventNoReaders = nullptr;
- pSWMRG->hSemNumReaders = nullptr;
- pSWMRG->hFinishEV = nullptr;
-
// Creates the automatic-reset event that is signalled when
// no writer threads are writing.
// Initially no reader threads are reading.
if (Name != nullptr)
Name[0] = (wchar_t)'W';
- pSWMRG->hEventNoWriter = CreateEvent(nullptr, FALSE, TRUE, Name);
+ hEventNoWriter = ::CreateEvent(nullptr, FALSE, TRUE, Name);
// Creates the manual-reset event that is signalled when
// no reader threads are reading.
// Initially no reader threads are reading.
if (Name != nullptr)
Name[0] = (wchar_t)'R';
- pSWMRG->hEventNoReaders = CreateEvent(nullptr, TRUE, TRUE, Name);
+ hEventNoReaders = ::CreateEvent(nullptr, TRUE, TRUE, Name);
// Initializes the variable that indicates the number of
// reader threads that are reading.
// Initially no reader threads are reading.
if (Name != nullptr)
Name[0] = (wchar_t)'C';
- pSWMRG->hSemNumReaders = CreateSemaphore(nullptr, 0, 0x7FFFFFFF, Name);
+ hSemNumReaders = ::CreateSemaphore(nullptr, 0, 0x7FFFFFFF, Name);
if (Name != nullptr)
Name[0] = (wchar_t)'F';
- pSWMRG->hFinishEV = CreateEvent(nullptr, TRUE, FALSE, Name);
+ hFinishEV = ::CreateEvent(nullptr, TRUE, FALSE, Name);
+}
- // If a synchronization object could not be created,
- // destroys any created objects and return failure.
- if ((nullptr == pSWMRG->hEventNoWriter) || (nullptr == pSWMRG->hEventNoReaders) || (nullptr == pSWMRG->hSemNumReaders) || (nullptr == pSWMRG->hFinishEV)) {
- SWMRGDelete(pSWMRG);
- return FALSE;
- }
- return TRUE;
+// Destroys any synchronization objects that were
+// successfully created.
+
+SWMRG::~SWMRG()
+{
+ if (nullptr != hEventNoWriter)
+ CloseHandle(hEventNoWriter);
+ if (nullptr != hEventNoReaders)
+ CloseHandle(hEventNoReaders);
+ if (nullptr != hSemNumReaders)
+ CloseHandle(hSemNumReaders);
+ if (nullptr != hFinishEV)
+ CloseHandle(hFinishEV);
}
-uint32_t WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG, uint32_t dwTimeout)
+/////////////////////////////////////////////////////////////////////////////////////////
+// SWMRGWaitToWrite
+// A writer thread calls this function to know when
+// it can successfully write to the shared data.
+// returns WAIT_FINISH when we are in write-access or WAIT_FAILED
+// when event about quick finishing is set (or when system returns fail when waiting for synchro object)
+
+uint32_t SWMRG::WaitToWrite(uint32_t dwTimeout)
{
uint32_t dw;
HANDLE aHandles[2];
+ // SSL_DebugLog("SWMRGWaitToWrite %p", this);
// We can write if the following are true:
// 1. No other threads are writing.
// 2. No threads are reading.
// But first we have to know if SWMRG structure is not about to delete
- aHandles[0] = pSWMRG->hEventNoWriter;
- aHandles[1] = pSWMRG->hEventNoReaders;
- if (WAIT_OBJECT_0 == (dw = WaitForSingleObject(pSWMRG->hFinishEV, 0)))
+ aHandles[0] = hEventNoWriter;
+ aHandles[1] = hEventNoReaders;
+ if (WAIT_OBJECT_0 == (dw = WaitForSingleObject(hFinishEV, 0)))
return WAIT_FINISH;
if (WAIT_FAILED == dw)
return dw;
dw = WaitForMultipleObjects(2, aHandles, TRUE, dwTimeout);
// if a request to delete became later, we should not catch it. Try once more to ask if account is not about to delete
- if ((dw != WAIT_FAILED) && (WAIT_OBJECT_0 == (WaitForSingleObject(pSWMRG->hFinishEV, 0)))) {
- SetEvent(pSWMRG->hEventNoWriter);
+ if ((dw != WAIT_FAILED) && (WAIT_OBJECT_0 == (WaitForSingleObject(hFinishEV, 0)))) {
+ SetEvent(hEventNoWriter);
return WAIT_FINISH;
}
@@ -170,32 +98,42 @@ uint32_t WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG, uint32_t dwTimeout)
return dw;
}
-void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG)
-// Presumably, a writer thread calling this function has
-// successfully called WaitToWrite. This means that we
-// do not have to wait on any synchronization objects
-// here because the writer already owns the Event.
+/////////////////////////////////////////////////////////////////////////////////////////
+// SWMRGDoneWriting
+// A writer thread calls this function to let other threads
+// know that it no longer needs to write to the shared data.
+
+void SWMRG::DoneWriting()
{
+ // SSL_DebugLog("SWMRGDoneWriting %p", this);
+
// Allow other writer/reader threads to use
// the SWMRG synchronization object.
- SetEvent(pSWMRG->hEventNoWriter);
+ SetEvent(hEventNoWriter);
}
-uint32_t WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, uint32_t dwTimeout)
+/////////////////////////////////////////////////////////////////////////////////////////
+// SWMRGWaitToRead
+// is used to wait for read access with SWMRG SO, but it also increments counter if successfull
+// returns WAIT_FAILED or WAIT_FINISH
+// when WAIT_FAILED, we should not begin to access datas, we are not in read-access mode
+
+uint32_t SWMRG::WaitToRead(uint32_t dwTimeout)
{
uint32_t dw;
LONG lPreviousCount;
+ // SSL_DebugLog("SWMRGWaitToRead %p", this);
// We can read if no threads are writing.
// And there's not request to delete structure
- if (WAIT_OBJECT_0 == (dw = WaitForSingleObject(pSWMRG->hFinishEV, 0)))
+ if (WAIT_OBJECT_0 == (dw = WaitForSingleObject(hFinishEV, 0)))
return WAIT_FINISH;
if (WAIT_FAILED == dw)
return dw;
- dw = WaitForSingleObject(pSWMRG->hEventNoWriter, dwTimeout);
+ dw = WaitForSingleObject(hEventNoWriter, dwTimeout);
// if a request to delete became later, we should not catch it. Try once more to ask if account is not about to delete
- if ((dw != WAIT_FAILED) && (WAIT_OBJECT_0 == (WaitForSingleObject(pSWMRG->hFinishEV, 0)))) {
- SetEvent(pSWMRG->hEventNoWriter);
+ if ((dw != WAIT_FAILED) && (WAIT_OBJECT_0 == (WaitForSingleObject(hFinishEV, 0)))) {
+ SetEvent(hEventNoWriter);
return WAIT_FINISH;
}
@@ -204,112 +142,123 @@ uint32_t WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, uint32_t dwTimeout)
// Increment the number of reader threads.
// But there can't be more than one thread incrementing readers,
// so this is why we use semaphore.
- ReleaseSemaphore(pSWMRG->hSemNumReaders, 1, &lPreviousCount);
+ ReleaseSemaphore(hSemNumReaders, 1, &lPreviousCount);
if (lPreviousCount == 0)
// If this is the first reader thread,
// set event to reflect this. Other reader threads can read, no writer thread can write.
- ResetEvent(pSWMRG->hEventNoReaders);
+ ResetEvent(hEventNoReaders);
// Allow other writer/reader threads to use
// the SWMRG synchronization object. hEventNoWrite is still non-signaled
// (it looks like writer is processing thread, but it is not true)
- SetEvent(pSWMRG->hEventNoWriter);
+ SetEvent(hEventNoWriter);
}
- return(dw);
+ return dw;
}
-void WINAPI SWMRGDoneReading(PSWMRG pSWMRG)
+/////////////////////////////////////////////////////////////////////////////////////////
+// SWMRGDoneReading
+// A reader thread calls this function to let other threads
+// know when it no longer needs to read the shared data.
+
+void SWMRG::DoneReading()
{
HANDLE aHandles[2];
LONG lNumReaders;
+ // SSL_DebugLog("SWMRGDoneReading %p", this);
// We can stop reading if the events are available,
// but when we stop reading we must also decrement the
// number of reader threads.
- aHandles[0] = pSWMRG->hEventNoWriter;
- aHandles[1] = pSWMRG->hSemNumReaders;
+ aHandles[0] = hEventNoWriter;
+ aHandles[1] = hSemNumReaders;
WaitForMultipleObjects(2, aHandles, TRUE, INFINITE);
// Get the remaining number of readers by releasing the
// semaphore and then restoring the count by immediately
// performing a wait.
- ReleaseSemaphore(pSWMRG->hSemNumReaders, 1, &lNumReaders);
- WaitForSingleObject(pSWMRG->hSemNumReaders, INFINITE);
+ ReleaseSemaphore(hSemNumReaders, 1, &lNumReaders);
+ WaitForSingleObject(hSemNumReaders, INFINITE);
// If there are no remaining readers,
// set the event to relect this.
if (lNumReaders == 0)
// If there are no reader threads,
// set our event to reflect this.
- SetEvent(pSWMRG->hEventNoReaders);
+ SetEvent(hEventNoReaders);
// Allow other writer/reader threads to use
// the SWMRG synchronization object.
// (it looks like writer is processing thread, but it is not true)
- SetEvent(pSWMRG->hEventNoWriter);
+ SetEvent(hEventNoWriter);
}
-uint32_t WINAPI WaitToWriteFcn(PSWMRG SObject, PSCOUNTER SCounter)
-{
- uint32_t EnterCode;
-
- if (WAIT_OBJECT_0 == (EnterCode = SWMRGWaitToWrite(SObject, INFINITE)))
- if (SCounter != nullptr)
- SCIncFcn(SCounter);
-
- return EnterCode;
-}
+/////////////////////////////////////////////////////////////////////////////////////////
+// SCOUNTER
-void WINAPI WriteDoneFcn(PSWMRG SObject, PSCOUNTER SCounter)
+SCOUNTER::SCOUNTER()
{
- SWMRGDoneWriting(SObject);
- if (SCounter != nullptr)
- SCDecFcn(SCounter);
+ InitializeCriticalSection(&CounterCS);
+ Event = CreateEvent(nullptr, FALSE, TRUE, nullptr);
+ SetEvent(Event);
}
-uint32_t WINAPI WaitToReadFcn(PSWMRG SObject)
+SCOUNTER::SCOUNTER(HANDLE InitializedEvent)
{
- uint32_t EnterCode = SWMRGWaitToRead(SObject, INFINITE);
- return EnterCode;
+ InitializeCriticalSection(&CounterCS);
+ Event = InitializedEvent;
+ SetEvent(Event);
}
-void WINAPI ReadDoneFcn(PSWMRG SObject)
+SCOUNTER::~SCOUNTER()
{
- SWMRGDoneReading(SObject);
+ DeleteCriticalSection(&CounterCS);
+ CloseHandle(Event);
}
-uint32_t WINAPI SCGetNumberFcn(PSCOUNTER SCounter)
-{
+// Gets number value stored in SCOUNTER SO
+// Note you must not read the number from memory directly, because
+// CPU can stop reading thread when it has read HI-Word, then another thread
+// can change the value and then OS starts the previous thread, that reads the
+// LO-uint16_t of uint32_t. And the return value HI+LO-uint16_t is corrupted
- EnterCriticalSection(&SCounter->CounterCS);
+uint32_t SCOUNTER::GetNumber()
+{
+ EnterCriticalSection(&CounterCS);
- uint32_t Temp = SCounter->Number;
+ uint32_t Temp = Number;
- LeaveCriticalSection(&SCounter->CounterCS);
+ LeaveCriticalSection(&CounterCS);
return Temp;
}
-uint32_t WINAPI SCIncFcn(PSCOUNTER SCounter)
+// Increments SCOUNTER and unsets event
+// Returns Number after incrementing
+
+uint32_t SCOUNTER::Inc()
{
- EnterCriticalSection(&SCounter->CounterCS);
+ EnterCriticalSection(&CounterCS);
- uint32_t Temp = ++SCounter->Number;
- ResetEvent(SCounter->Event);
+ uint32_t Temp = ++Number;
+ ResetEvent(Event);
- LeaveCriticalSection(&SCounter->CounterCS);
+ LeaveCriticalSection(&CounterCS);
return Temp;
}
-uint32_t WINAPI SCDecFcn(PSCOUNTER SCounter)
+// Decrements SCOUNTER and sets event if zero
+// Returns Number after decrementing
+
+uint32_t SCOUNTER::Dec()
{
uint32_t Temp;
- EnterCriticalSection(&SCounter->CounterCS);
+ EnterCriticalSection(&CounterCS);
- if (!(Temp = --SCounter->Number)) {
- SetEvent(SCounter->Event);
+ if (!(Temp = --Number)) {
+ SetEvent(Event);
}
- LeaveCriticalSection(&SCounter->CounterCS);
+ LeaveCriticalSection(&CounterCS);
return Temp;
}
diff --git a/protocols/YAMN/src/version.h b/protocols/YAMN/src/version.h
index 72bda16cfe..cd1a59c725 100644
--- a/protocols/YAMN/src/version.h
+++ b/protocols/YAMN/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
-#define __MINOR_VERSION 1
-#define __RELEASE_NUM 2
-#define __BUILD_NUM 7
+#define __MINOR_VERSION 2
+#define __RELEASE_NUM 1
+#define __BUILD_NUM 1
#include <stdver.h>
diff --git a/protocols/YAMN/src/yamn.cpp b/protocols/YAMN/src/yamn.cpp
index 2af7efd74f..753f269d3a 100644
--- a/protocols/YAMN/src/yamn.cpp
+++ b/protocols/YAMN/src/yamn.cpp
@@ -26,12 +26,6 @@ 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;
-//Returns pointer to YAMN exported function
-INT_PTR GetFcnPtrSvc(WPARAM wParam, LPARAM lParam);
-
-//Returns pointer to YAMN variables
-INT_PTR GetVariablesSvc(WPARAM wParam, 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, uint32_t);
@@ -55,45 +49,6 @@ INT_PTR ForceCheckSvc(WPARAM, LPARAM);
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
-INT_PTR GetFcnPtrSvc(WPARAM wParam, LPARAM)
-{
- int i;
-
- for (i=0;i<sizeof(ProtoPluginExportedFcn)/sizeof(ProtoPluginExportedFcn[0]);i++)
- if (0==mir_strcmp((char *)wParam, ProtoPluginExportedFcn[i].ID))
- return (INT_PTR)ProtoPluginExportedFcn[i].Ptr;
- for (i=0;i<sizeof(ProtoPluginExportedSvc)/sizeof(ProtoPluginExportedSvc[0]);i++)
- if (0==mir_strcmp((char *)wParam, ProtoPluginExportedSvc[i].ID))
- return (INT_PTR)ProtoPluginExportedSvc[i].Ptr;
- for (i=0;i<sizeof(SynchroExportedFcn)/sizeof(SynchroExportedFcn[0]);i++)
- if (0==mir_strcmp((char *)wParam, SynchroExportedFcn[i].ID))
- return (INT_PTR)SynchroExportedFcn[i].Ptr;
- for (i=0;i<sizeof(AccountExportedFcn)/sizeof(AccountExportedFcn[0]);i++)
- if (0==mir_strcmp((char *)wParam, AccountExportedFcn[i].ID))
- return (INT_PTR)AccountExportedFcn[i].Ptr;
- for (i=0;i<sizeof(AccountExportedSvc)/sizeof(AccountExportedSvc[0]);i++)
- if (0==mir_strcmp((char *)wParam, AccountExportedSvc[i].ID))
- return (INT_PTR)AccountExportedSvc[i].Ptr;
- for (i=0;i<sizeof(MailExportedFcn)/sizeof(MailExportedFcn[0]);i++)
- if (0==mir_strcmp((char *)wParam, MailExportedFcn[i].ID))
- return (INT_PTR)MailExportedFcn[i].Ptr;
- for (i=0;i<sizeof(MailExportedSvc)/sizeof(MailExportedSvc[0]);i++)
- if (0==mir_strcmp((char *)wParam, MailExportedSvc[i].ID))
- return (INT_PTR)MailExportedSvc[i].Ptr;
- for (i=0;i<sizeof(FilterPluginExportedFcn)/sizeof(FilterPluginExportedFcn[0]);i++)
- if (0==mir_strcmp((char *)wParam, FilterPluginExportedFcn[i].ID))
- return (INT_PTR)FilterPluginExportedFcn[i].Ptr;
- for (i=0;i<sizeof(FilterPluginExportedSvc)/sizeof(FilterPluginExportedSvc[0]);i++)
- if (0==mir_strcmp((char *)wParam, FilterPluginExportedSvc[i].ID))
- return (INT_PTR)FilterPluginExportedSvc[i].Ptr;
- return (INT_PTR)NULL;
-}
-
-INT_PTR GetVariablesSvc(WPARAM wParam, LPARAM)
-{
- return wParam==YAMN_VARIABLESVERSION ? (INT_PTR)&YAMNVar : (INT_PTR)NULL;
-}
-
void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD)
{
CAccount *ActualAccount;
@@ -112,15 +67,17 @@ void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD)
Status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
mir_cslock lck(PluginRegCS);
- for (PYAMN_PROTOPLUGINQUEUE ActualPlugin = FirstProtoPlugin; ActualPlugin != nullptr; ActualPlugin = ActualPlugin->Next) {
- if (WAIT_OBJECT_0 != SWMRGWaitToRead(ActualPlugin->Plugin->AccountBrowserSO, 0)) // we want to access accounts immiadtelly
+ for (YAMN_PROTOPLUGINQUEUE *ActualPlugin = FirstProtoPlugin; ActualPlugin != nullptr; ActualPlugin = ActualPlugin->Next) {
+ SReadGuard srb(ActualPlugin->Plugin->AccountBrowserSO, 0); // we want to access accounts immiadtelly
+ if (!srb.Succeeded())
return;
for (ActualAccount = ActualPlugin->Plugin->FirstAccount; ActualAccount != nullptr; ActualAccount = ActualAccount->Next) {
if (ActualAccount->Plugin == nullptr || ActualAccount->Plugin->Fcn == nullptr) //account not inited
continue;
- if (WAIT_OBJECT_0 != SWMRGWaitToRead(ActualAccount->AccountAccessSO, 0))
+ SReadGuard sra(ActualAccount->AccountAccessSO, 0);
+ if (!sra.Succeeded())
continue;
BOOL isAccountCounting = 0;
@@ -148,14 +105,11 @@ void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD)
ActualAccount->TimeLeft = ActualAccount->Interval;
HANDLE NewThread = CreateThread(nullptr, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->TimeoutFcnPtr, &ParamToPlugin, 0, &tid);
- if (NewThread == nullptr) {
- ReadDoneFcn(ActualAccount->AccountAccessSO);
+ if (NewThread == nullptr)
continue;
- }
- else {
- WaitForSingleObject(ThreadRunningEV, INFINITE);
- CloseHandle(NewThread);
- }
+
+ WaitForSingleObject(ThreadRunningEV, INFINITE);
+ CloseHandle(NewThread);
}
}
@@ -171,9 +125,7 @@ ChangeIsCountingStatusLabel:
break;
}
}
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
- SWMRGDoneReading(ActualPlugin->Plugin->AccountBrowserSO);
}
CloseHandle(ThreadRunningEV);
}
@@ -191,34 +143,30 @@ INT_PTR ForceCheckSvc(WPARAM, LPARAM)
if (WAIT_OBJECT_0 == WaitForSingleObject(ExitEV, 0))
return 0;
- {
- mir_cslock lck(PluginRegCS);
- for (PYAMN_PROTOPLUGINQUEUE ActualPlugin = FirstProtoPlugin; ActualPlugin != nullptr; ActualPlugin = ActualPlugin->Next) {
- SWMRGWaitToRead(ActualPlugin->Plugin->AccountBrowserSO, INFINITE);
+ { mir_cslock lck(PluginRegCS);
+
+ 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) {
if (ActualAccount->Plugin->Fcn == nullptr) //account not inited
continue;
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO))
+ SReadGuard sra(ActualAccount->AccountAccessSO);
+ if (!sra.Succeeded())
continue;
if ((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) { //account cannot be forced to check
- if (ActualAccount->Plugin->Fcn->ForceCheckFcnPtr == nullptr) {
- ReadDoneFcn(ActualAccount->AccountAccessSO);
+ if (ActualAccount->Plugin->Fcn->ForceCheckFcnPtr == nullptr)
continue;
- }
+
struct 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)) {
- ReadDoneFcn(ActualAccount->AccountAccessSO);
+ if (nullptr == CreateThread(nullptr, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr, &ParamToPlugin, 0, &tid))
continue;
- }
- else
- WaitForSingleObject(ThreadRunningEV, INFINITE);
+
+ WaitForSingleObject(ThreadRunningEV, INFINITE);
}
- ReadDoneFcn(ActualAccount->AccountAccessSO);
}
- SWMRGDoneReading(ActualPlugin->Plugin->AccountBrowserSO);
}
}