1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
/*
* This file defines all needed parameters for one account.
* Other plugin can use this (so YAMN does not check it and another plugin can inform YAMN about new mail e.g.),
* this can be usefull for plugins like MSN (Hotmail notify)
*
* (c) majvan 2002-2004
*/
#ifndef __ACCOUNT_H
#define __ACCOUNT_H
#include <windows.h>
#include <tchar.h>
//
//================================== OTHER DEFINITIONS ========================================
//
enum
{
// Error codes returned from functions (services) working with account book files
EACC_SYSTEM = 1, //use GetLastError() to retrieve detailed information about error
EACC_ALLOC, //problem with memory allocation
EACC_FILECOMPATIBILITY, //file is corrupted
EACC_ENDOFFILE, //unexpected end of file occured
EACC_FILEVERSION, //file should be YAMN book format, but newer version that expected
EACC_FILESIZE, //file has wrong size
};
enum
{
// Status of account
// used in messages WM_YAMN_CHANGESTATUS
// used also in function GetStatus and SetStatus
ACC_IDLE = 0, //account is IDLE (no work is performed with account)
ACC_FINDING, //DNS lookup for account
ACC_CONNECTING, //connecting in progress
ACC_LOGGING, //logging in progress
ACC_WORKING, //working
ACC_DISCONNECTING, //disconnecting from server
};
#define YAMN_ACC_MSG 0x00000002 // Shows dialog
#define YAMN_ACC_ICO 0x00000004 // Shows system tray icon (1)
#define YAMN_ACC_ICOB 0x00000008 // not used now, enables tray icon flashing (1)
#define YAMN_ACC_APP 0x00000010 // Runs application (1)
#define YAMN_ACC_POP 0x00000020 // Shows popup
#define YAMN_ACC_POPC 0x00000040 // Use custom colors in popup
#define YAMN_ACC_MSGP 0x00000080 // Persistant messgage. This means, when an situation occurs (e.g. new mail) and message is displayed, it is not destroyed when YAMN_ACC_MSG is not set
#define YAMN_ACC_KBN 0x00000100 // Use Keyboard notify
#define YAMN_ACC_CONT 0x00000200 // Use Contact notify
#define YAMN_ACC_CONTNICK 0x00000400 // Use Contact Nick replacement
#define YAMN_ACC_CONTNOEVENT 0x00000800 // Suppress event for this contact
struct YAMN_NOTIFICATION
{
//(1) - usable only in newmail notification
DWORD Flags = 0;
COLORREF PopupB = 0;
COLORREF PopupT = 0;
DWORD PopupTime = 0;
WCHAR *App = nullptr;
WCHAR *AppParam = nullptr;
// These parameters are not stored in standard YAMN book file and therefore must be set by plugin
char *Sound = nullptr;
HICON TrayIcon1 = nullptr;
HICON TrayIcon2 = nullptr;
};
struct CServer
{
char *Name = nullptr;
DWORD Port = 0;
char *Login = nullptr;
// Password encryption definitions
#define STARTCODEPSW 0x50
#define ADDCODEPSW 0x0
char *Passwd = nullptr;
};
//
//================================== ACCOUNT DEFINITION ==================================
//
#define WAIT_FINISH WAIT_OBJECT_0+1
// This structure is used to get semaphore-like synchronization:
// Includes incrementing, decrementing DWORD value and if DWORD is zero, sets event
class SCOUNTER
{
HANDLE Event;
uint32_t Number = 0;
CRITICAL_SECTION CounterCS;
public:
SCOUNTER();
SCOUNTER(HANDLE InitializedEvent);
~SCOUNTER();
__forceinline HANDLE GetEvent() const { return Event; }
uint32_t GetNumber();
uint32_t Inc();
uint32_t Dec();
};
struct SCGuard
{
SCOUNTER &pSC;
__forceinline SCGuard(SCOUNTER &sc) :
pSC(sc)
{
sc.Inc();
}
__forceinline ~SCGuard()
{
pSC.Dec();
}
};
// The single-writer/multiple-reader guard
// compound synchronization object (SO)
// Notices: Copyright (c) 1995-1997 Jeffrey Richter
// Changes: majvan, only one process implementation,
// hFinishEV event added- signals when we do not want to use this SO anymore
class SWMRG
{
// This event guards access to the other objects
// managed by this data structure and also indicates
// whether any writer threads are writing.
HANDLE hEventNoWriter;
// This manual-reset event is signaled when
// no reader threads are reading.
HANDLE hEventNoReaders;
// This value is used simply as a counter.
// (the count is the number of reader threads)
HANDLE hSemNumReaders;
// The request is for not to enter critical section
// for writing or reading due to going to delete guard
HANDLE hFinishEV;
public:
SWMRG(wchar_t *Name = nullptr);
~SWMRG();
uint32_t WaitToWrite(uint32_t dwTimeout = INFINITE);
void DoneWriting();
uint32_t WaitToRead(uint32_t dwTimeout = INFINITE);
void DoneReading();
void Stop()
{
::SetEvent(hFinishEV);
}
};
struct SReadGuard
{
SWMRG &pSO;
uint32_t dwError;
SReadGuard(SWMRG &so, uint32_t timeout = INFINITE) :
pSO(so)
{
dwError = so.WaitToRead(timeout);
}
~SReadGuard()
{
Uninit();
}
bool Succeeded() const
{
return dwError == WAIT_OBJECT_0;
}
void Uninit()
{
if (dwError == WAIT_OBJECT_0) {
pSO.DoneReading();
dwError = WAIT_FINISH;
}
}
operator uint32_t() const { return dwError; }
};
struct SWriteGuard
{
SWMRG &pSO;
uint32_t dwError;
SWriteGuard(SWMRG &so, uint32_t timeout = INFINITE) :
pSO(so)
{
dwError = so.WaitToWrite(timeout);
}
~SWriteGuard()
{
Uninit();
}
bool Succeeded() const
{
return dwError == WAIT_OBJECT_0;
}
void Uninit()
{
if (dwError == WAIT_OBJECT_0) {
pSO.DoneWriting();
dwError = WAIT_FINISH;
}
}
operator uint32_t() const { return dwError; }
};
/////////////////////////////////////////////////////////////////////////////////////////
// CAccount - basic email account class
struct CAccount
{
#define YAMN_ACCOUNTFILEVERSION 2 //version of standard file format (YAMN book file format)
// If changes are made in this structure, version is changed.
// So then YAMN does not initialzie your structure, if version does not matches.
BOOL AbleToWork; // This is set to TRUE by default. When it is needed to stop working on this account, YAMN sets this to zero.
struct YAMN_PROTOPLUGIN *Plugin; // free access, because this member should not be changed. The same as YAMN_PLUGIN structure
char *Name; // access only through AccountAccessSO
CServer *Server; //access only through AccountAccessSO
WORD Interval; //access only through AccountAccessSO
// YAMN account flags (set by user)
#define YAMN_ACC_ENA 0x00000001 //Enables account. If account is disabled, no countdown is performed
#define YAMN_ACC_POPN 0x00000002 //Shows one popup per one new mail or for N mails
#define YAMN_ACC_APOP 0x00000004 //Use APOP authentication
#define YAMN_ACC_SSL23 0x00000008 //Use SSLv2,3
#define YAMN_ACC_NOTLS 0x00000010 //Don't try StartTLS (STLS) even available
#define YAMN_ACC_BODY 0x00000020 //Always retrieve body of the message
DWORD Flags; //access only through AccountAccessSO
// YAMN account flags (set by plugin)
#define YAMN_ACC_BROWSE 0x00000001 //Can browse mails. On this account we can run mailbrowser window
#define YAMN_ACC_POPUP 0x00000002 //Popups of new mail belonging to this account can be showed
DWORD AbilityFlags;
// YAMN account status flags
#define YAMN_ACC_ST0 0x00000001 // Check (countdown) when Offline
#define YAMN_ACC_ST1 0x00000002 // Check (countdown) when Online
#define YAMN_ACC_ST2 0x00000004 // Check (countdown) when Away
#define YAMN_ACC_ST3 0x00000008 // Check (countdown) when Not available
#define YAMN_ACC_ST4 0x00000010 // Check (countdown) when Occupied
#define YAMN_ACC_ST5 0x00000020 // Check (countdown) when DND
#define YAMN_ACC_ST6 0x00000040 // Check (countdown) when Free for chat
#define YAMN_ACC_ST7 0x00000080 // Check (countdown) when Invisible
#define YAMN_ACC_STARTA 0x00010000 // Check on start anyway
#define YAMN_ACC_STARTS 0x00020000 // Check on start regarding to status setting
#define YAMN_ACC_FORCE 0x00040000 // Check when "check new mail" item pressed (it is called forced checking)
DWORD StatusFlags; // access only through AccountAccessSO
// Plugin flags. Use this DWORD if you want YAMN to store it to YAMN book file. You can set here any value
DWORD PluginFlags;
YAMN_NOTIFICATION NewMailN; //access only through AccountAccessSO
YAMN_NOTIFICATION NoNewMailN; //access only through AccountAccessSO
YAMN_NOTIFICATION BadConnectN; //access only through AccountAccessSO
SYSTEMTIME LastChecked; //last check, access only through AccountAccessSO
SYSTEMTIME LastSChecked; //last check (successfull), access only through AccountAccessSO
SYSTEMTIME LastSynchronised; //last synchronisation (successfull), access only through AccountAccessSO
SYSTEMTIME LastMail; //last check when new mail detected, access only through AccountAccessSO
TCHAR Status[255]; //access only through GetStatusFcn() and SetStatusFcn() functions
DWORD TimeLeft; //access only through AccountAccessSO
HANDLE Mails; //access only through MessagesAccessSO
// Account members are mostly the same, but there can be protocol (POP3,IMAP...) special features.
// To use them, only inherit this class and add your own features.
// First idea was to add pointer to void, where plugin can store its own values.
// But this solution is better in my opinion.
// This is event with counter. Event is signaled when no threads are using account (and will not be using)
// Very usefull for account delete operation
SCOUNTER UsingThreads;
// We have to achieve, that only one thread can write to account and more threads can read.
// Writing to account means that we change account parameters
// Reading from account meands we read account parameters
// Use WaitToRead(), ReadDone(), WaitToWrite(), WriteDone() synchronization functions
// For plugins, this is a pointer to void. It does not matter for plugin what is this variable for,
// because plugin works only with synchronization routines. And why is this void * ? It is because
// plugin does not need to include headers for SWMRG structures...
SWMRG AccountAccessSO;
// We have to achieve, that only one thread can write to account mails and more threads can read.
// While some thread writes mails, other thread can write to account. This can be small problem, but it never appears in YAMN.
// But you should think about this note if you want to add some features in the future
// Writing to messages means any changes to message queue or message data
// Reading from messages means reading message queue (browsing through all messages) or reading message data
// Use MsgsWaitToRead(),MsgsReadDone(),MsgsWaitToWrite(),MsgsWriteDone() synchronization functions
SWMRG MessagesAccessSO;
//For clist contact notification
MCONTACT hContact;
BOOL isCounting;
CAccount *Next;
};
#endif
|