summaryrefslogtreecommitdiff
path: root/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.h
blob: 8bed5e1624850979c78e789cb5ebb8a50af7c336 (plain)
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
#ifndef _WSX22_IPC_SHAREDMEMORY
#define _WSX22_IPC_SHAREDMEMORY


#include "MirFoxCommons_logger.h"


//shared memory related definitions
#define CSMTHREAD_TICK_TIME		100		// 100ms - check exit every this time
#define CSMTHREAD_FIRSTRUN_TIME	100		// CSMTHREAD_FIRSTRUN_TIME * CSMTHREAD_TICK_TIME = 10s  - time to first run of checking csm state in csm thread (after thread start)
#define CSMTHREAD_NEXTRUN_TIME	100		// CSMTHREAD_NEXTRUN_TIME * CSMTHREAD_TICK_TIME = 10s  - time to next run of checking csm state in csm thread

#define SMUCONST_CSM_RECORD_VISABLETO_SIZEC_DEF 128
#define SMUCONST_CSM_RECORD_DNAME_SIZEC_DEF 78
#define SMUCONST_MSM_RECORD_DNAME_SIZEC_DEF 78



class ClientInstanceClass
{
public:
	std::wstring displayName;	//display name
	uint16_t recordId;			//id
};

class ContactClass
{
public:
	std::wstring displayName;	//display name
	uint64_t handle;			//miranda HANDLE to contact (casted pointer)
};

class AccountClass
{
public:
	std::wstring displayName;	//display name
	uint64_t handle;			//miranda HANDLE to account (casted pointer)
};



struct OpenOrCreateSMReturnStruct {
	int errorCode;
	uint16_t processCsmId;
};



/**
 * SharedMemory Utils
 *
 * Singleton pattern based on
 * http://www.codeproject.com/KB/threads/SingletonThreadSafety.aspx
 */
class SharedMemoryUtils
{

public:

	
	//constructor
	SharedMemoryUtils();
	//destructor
	~SharedMemoryUtils();


	/**
	 * open existing or create new central shared memory
	 *
	 * type - char - 'M' - Miranda, 'F' - Firefox
	 *
	 * return OpenOrCreateSMReturnStruct
	 * .errorCode
	 *  0 - ok, and .processCsmId = id of process record in csm
	 * -2 - no more available (Empty) records in central shared memory
	 * -3 - existing csm version is too high (from checkCsmVersion)
	 * -4 - existing csm version is too low (from checkCsmVersion)
	 */
	OpenOrCreateSMReturnStruct openOrCreateSM(char type, std::wstring& displayName, std::wstring& visableTo, bool doCommitSM);


	int addOptionToSM(int optionID, std::wstring& optionValue);

	int addTranslationToSM(int translationId, std::wstring& translationValue );

	int addAccountToSM(uint64_t mirandaAccountId, std::wstring& displayName);

	// group type:  R - root, N - normal
	int addGroupToSM(uint64_t mirandaGroupHandle, uint64_t parentGroupHandle, char groupType, std::wstring& displayName);

	int addContactToSM(uint64_t mirandaContactHandle, uint64_t mirandaAccountHandle, uint64_t mirandaGroupHandle, std::wstring& displayName);

	//call after openOrCreateSM and after creating sm thread
	int commitSM();


	// new functions to support refresh data in SM (compatible with v.4 SM version)
	// add record in working Miranda shared memory
	void refreshMsm_Add(char type, uint64_t mirandaId, std::wstring& displayName);
	// edit record in working Miranda shared memory
	void refreshMsm_Edit(char type, uint64_t mirandaId, std::wstring& displayName);
	// remove record in working Miranda shared memory
	void refreshMsm_Delete(char type, uint64_t mirandaId);


	//delete returned sm object after use
	boost::interprocess::windows_shared_memory* getSmById(const char* smName, std::size_t smSize);

	//returns:
	// 0 - ok
	// 1 - record error (state != 'W' (working) or wrong displayName)
	// -3 - existing csm version is too high (from checkCsmVersion)
	// -4 - existing csm version is too low (from checkCsmVersion)
	int checkCSM(boost::interprocess::windows_shared_memory* checkedCsm, uint16_t processCsmId, std::wstring& displayNameProfile);

	void updateCsmTimestamp(boost::interprocess::windows_shared_memory& updateCsm, uint16_t processCsmId);

	//for every other CSM records with 'W' status, check if record is outdated, if yes then delete this record
	void checkAnotherCsm(boost::interprocess::windows_shared_memory& checkedCsm, uint16_t processCsmId);

	//unload and free shared memory records and structures
	void unloadSharedMemory(uint16_t processCsmId);

	//execute before start creating MSMs
	void resetMsmParameters();


	////FUNCTIONS FOR FIREFOX

	//return true if any client (miranda instance) is available in csm for current firefox profile
	bool isAnyMirandaCsmRecordAvailable(std::wstring& forThisProfileName);

	//return number of records in clientInstanceNamesList, empty list as parameter
	int getClientInstances(boost::ptr_list<ClientInstanceClass> * clientInstancesListPtr, std::wstring& forThisProfileName);

	//return number of records in contactsListPtr, empty list as parameter
	int getContacts(boost::ptr_list<ContactClass> * contactsListPtr, unsigned short clientRecordNo);

	//return number of records in accountsListPtr, empty list as parameter
	int getAccounts(boost::ptr_list<AccountClass> * accountsListPtr, unsigned short clientRecordNo);

	////FUNCTIONS FOR FIREFOX - end




	const char* getCsmName();
	std::string getMsmName(uint16_t id, int currentNumber);
	std::size_t getCsmTotalSize();
	std::size_t getMsmTotalSize();



	//static method that returns only instance of SharedMemoryUtils
	static SharedMemoryUtils * getInstance()
	{
		//initialized always from one thread at a time
		if (m_pOnlyOneInstance == NULL) {
			if (m_pOnlyOneInstance == NULL) {
				m_pOnlyOneInstance = new SharedMemoryUtils();
			}
		}
		return m_pOnlyOneInstance;
	}


private:

	//holds one and only object of MySingleton
	static SharedMemoryUtils* m_pOnlyOneInstance;
	
	MFLogger* logger;


	//global variables
	boost::interprocess::windows_shared_memory* csm;
	boost::ptr_list<boost::interprocess::windows_shared_memory> msmList;
	


	bool isCsmInited(boost::interprocess::windows_shared_memory& csm);
	void initCsm(boost::interprocess::windows_shared_memory& csm);

	//return:
	//	0 - versions match,
	// -3 - existing csm version is too high
	// -4 - existing csm version is too low
	int checkCsmVersion(boost::interprocess::windows_shared_memory& csm);

	uint16_t allocateRecordInCsm(boost::interprocess::windows_shared_memory& csm, char type, std::wstring& displayName, std::wstring& visableTo, bool doCommitSM);

	time_t mfGetCurrentTimestamp();

	int addRecordToMsm(char type, uint64_t agcHandle, uint64_t accountHandle, uint64_t groupHandle, char status, std::wstring& value);

	int checkCsmRecord(boost::interprocess::windows_shared_memory& checkedCsm, uint16_t processCsmId, std::wstring& displayNameProfile);
	
	void freeCsmRecord(boost::interprocess::windows_shared_memory& csm, uint16_t recordNo);

	bool isTokenOnList(std::wstring& token, std::wstring& tokensList);

	//free own record in csm
	void unloadFromCSM(uint16_t processCsmId);

	//free msm instances
	void unloadMSMs();

	uint16_t processCsmId;
	int freeMsmRecordsCount;
	int nextMsmNumber;  //from 1
	
	
};


#endif //#ifndef _WSX22_IPC_SHAREDMEMORY