lync: add missing _ready() call for HTTP requests
[siplcs.git] / src / miranda / miranda-plugin.c
blob006d392f9d35e10e390fa3446f99c5e2cd5c0521
1 /**
2 * @file miranda-plugin.c
4 * pidgin-sipe
6 * Copyright (C) 2010-2015 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #pragma comment(lib, "Secur32.lib")
24 #ifdef HAVE_GSSAPI_GSSAPI_H
25 #pragma comment(lib, "krb5_32.lib")
26 #pragma comment(lib, "gssapi32.lib")
27 #pragma comment(lib, "comerr32.lib")
28 #endif
30 #include <windows.h>
31 #include <Windowsx.h>
32 #include <win2k.h>
33 #include <Richedit.h>
34 #include <stdio.h>
36 #include <glib.h>
38 #include "miranda-version.h"
39 #include "newpluginapi.h"
40 #include "m_protosvc.h"
41 #include "m_protoint.h"
42 #include "m_protomod.h"
43 #include "m_system.h"
44 #include "m_database.h"
45 #include "m_options.h"
46 #include "m_netlib.h"
47 #include "m_chat.h"
48 #include "m_clist.h"
49 #include "m_langpack.h"
50 #include "m_message.h"
51 #include "m_genmenu.h"
53 #include "sipe-common.h"
54 #include "sipe-backend.h"
55 #include "sipe-core.h"
56 #include "sipe-nls.h"
58 #include "miranda-private.h"
59 #include "miranda-resource.h"
61 /* FIXME: Not here */
62 void CreateProtoService(const SIPPROTO *pr, const char* szService, SipSimpleServiceFunc serviceProc);
64 HANDLE sipe_miranda_incoming_netlibuser = NULL;
65 CRITICAL_SECTION sipe_miranda_debug_CriticalSection;
67 gchar *sipe_backend_version(void)
69 char version[200];
71 if (CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof(version), (LPARAM)version)) {
72 strcpy(version, "Unknown");
75 return g_strdup_printf("Miranda %s SIPLCS " __DATE__ " " __TIME__, version );
79 * Miranda globals
81 * Global variables related to miranda core or UI
83 static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
84 HINSTANCE hInst;
85 PLUGINLINK* pluginLink;
86 struct MM_INTERFACE mmi;
87 int hLangpack;
90 * Dialog boxes
92 static void
93 EnableDlgItem(HWND hwndDlg, UINT control, gboolean enable)
95 EnableWindow(GetDlgItem(hwndDlg, control), enable);
98 static void
99 CheckDlgItem(HWND hwndDlg, UINT control, int state)
101 Button_SetCheck(GetDlgItem(hwndDlg, control), state);
104 INT_PTR CALLBACK DlgProcSipSimpleOptsAbout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
107 switch(msg)
109 case WM_INITDIALOG:
111 SIPPROTO *pr = (SIPPROTO *)lParam;
112 SETTEXTEX tex;
113 gchar *tmp, *about;
114 LOCK;
115 tmp = sipe_core_about();
116 about = sipe_miranda_html2rtf(tmp);
117 g_free(tmp);
118 UNLOCK;
120 TranslateDialogDefault(hwndDlg);
122 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
124 tex.flags = ST_DEFAULT;
125 tex.codepage = 437;
127 SendDlgItemMessage(hwndDlg, IDC_ABOUTSIPE, EM_SETTEXTEX, (WPARAM)&tex, (LPARAM)about );
129 g_free(about);
133 return FALSE;
136 static INT_PTR CALLBACK DlgProcSipSimpleOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
138 static int lock=0;
140 switch(msg)
142 case WM_INITDIALOG:
144 const SIPPROTO *pr = (const SIPPROTO *)lParam;
145 char *str;
146 gboolean state;
147 WORD iptype;
149 TranslateDialogDefault(hwndDlg);
151 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
153 lock++;
155 #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI)
156 state = sipe_miranda_getBool(pr, "sso", FALSE);
157 if (state)
159 CheckDlgItem(hwndDlg, IDC_USESSO, BST_CHECKED);
160 EnableDlgItem(hwndDlg, IDC_LOGIN, FALSE);
161 EnableDlgItem(hwndDlg, IDC_PASSWORD, FALSE);
162 } else {
163 #endif
164 CheckDlgItem(hwndDlg, IDC_USESSO, BST_UNCHECKED);
165 EnableDlgItem(hwndDlg, IDC_LOGIN, TRUE);
166 EnableDlgItem(hwndDlg, IDC_PASSWORD, TRUE);
167 #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI)
169 #endif
171 str = sipe_miranda_getString(pr, "username");
172 SetDlgItemTextA(hwndDlg, IDC_HANDLE, str);
173 SendDlgItemMessage(hwndDlg, IDC_HANDLE, EM_SETLIMITTEXT, 50, 0);
174 mir_free(str);
176 str = sipe_miranda_getString(pr, "login");
177 SetDlgItemTextA(hwndDlg, IDC_LOGIN, str);
178 SendDlgItemMessage(hwndDlg, IDC_LOGIN, EM_SETLIMITTEXT, 50, 0);
179 mir_free(str);
181 str = sipe_miranda_getString(pr, "password");
182 if (str) CallService(MS_DB_CRYPT_DECODESTRING, strlen(str),(LPARAM)str);
183 SetDlgItemTextA(hwndDlg, IDC_PASSWORD, str);
184 SendDlgItemMessage(hwndDlg, IDC_PASSWORD, EM_SETLIMITTEXT, 16, 0);
185 mir_free(str);
187 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_ADDSTRING, 0, (LPARAM)_T("Auto"));
188 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_ADDSTRING, 0, (LPARAM)_T("NTLM"));
189 #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI)
190 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_ADDSTRING, 0, (LPARAM)_T("Kerberos"));
191 #endif
192 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_ADDSTRING, 0, (LPARAM)_T("TLS-DSK"));
194 sipe_miranda_getWord(pr, NULL, "authscheme", &iptype);
195 if (iptype == SIPE_AUTHENTICATION_TYPE_NTLM)
196 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("NTLM"));
197 else if (iptype == SIPE_AUTHENTICATION_TYPE_KERBEROS)
198 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("Kerberos"));
199 else if (iptype == SIPE_AUTHENTICATION_TYPE_TLS_DSK)
200 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("TLS-DSK"));
201 else
202 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("Auto"));
204 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, CB_ADDSTRING, 0, (LPARAM)_T("Auto"));
205 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, CB_ADDSTRING, 0, (LPARAM)_T("SSL/TLS"));
206 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, CB_ADDSTRING, 0, (LPARAM)_T("TCP"));
208 str = sipe_miranda_getString(pr, "transport");
209 if (!str || !strcmp(str, "auto"))
210 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("Auto"));
211 else if (!strcmp(str, "tls"))
212 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("SSL/TLS"));
213 else if (!strcmp(str, "tcp"))
214 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, CB_SELECTSTRING, -1, (LPARAM)_T("TCP"));
216 str = sipe_miranda_getGlobalString("public_ip");
217 SetDlgItemTextA(hwndDlg, IDC_PUBLICIP, str);
218 SendDlgItemMessage(hwndDlg, IDC_PUBLICIP, EM_SETLIMITTEXT, 20, 0);
219 mir_free(str);
221 str = sipe_miranda_getGlobalString("ipprog");
222 SetDlgItemTextA(hwndDlg, IDC_IPPROGEXE, str);
223 SendDlgItemMessage(hwndDlg, IDC_IPPROGEXE, EM_SETLIMITTEXT, 60, 0);
224 mir_free(str);
226 str = sipe_miranda_get_local_ip();
227 SetDlgItemTextA(hwndDlg, IDC_IPLOCALFOUND, str);
229 sipe_miranda_getGlobalWord("iptype", &iptype);
230 if (iptype == SIPE_MIRANDA_IP_LOCAL)
232 CheckRadioButton(hwndDlg, IDC_IPLOCAL, IDC_IPPROG, IDC_IPLOCAL);
233 EnableDlgItem(hwndDlg, IDC_PUBLICIP, FALSE);
234 EnableDlgItem(hwndDlg, IDC_IPPROGEXE, FALSE);
235 } else if (iptype == SIPE_MIRANDA_IP_MANUAL) {
236 CheckRadioButton(hwndDlg, IDC_IPLOCAL, IDC_IPPROG, IDC_IPMANUAL);
237 EnableDlgItem(hwndDlg, IDC_PUBLICIP, TRUE);
238 EnableDlgItem(hwndDlg, IDC_IPPROGEXE, FALSE);
239 } else {
240 CheckRadioButton(hwndDlg, IDC_IPLOCAL, IDC_IPPROG, IDC_IPPROG);
241 EnableDlgItem(hwndDlg, IDC_PUBLICIP, FALSE);
242 EnableDlgItem(hwndDlg, IDC_IPPROGEXE, TRUE);
245 lock--;
246 return TRUE;
249 case WM_COMMAND:
251 int code = wParam >> 16;
252 int id = wParam & 0xffff;
254 if (LOWORD(wParam) == IDC_IPLOCAL)
256 CheckRadioButton(hwndDlg, IDC_IPLOCAL, IDC_IPPROG, IDC_IPLOCAL);
257 EnableDlgItem(hwndDlg, IDC_PUBLICIP, FALSE);
258 EnableDlgItem(hwndDlg, IDC_IPPROGEXE, FALSE);
259 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
260 } else if (LOWORD(wParam) == IDC_IPMANUAL) {
261 CheckRadioButton(hwndDlg, IDC_IPLOCAL, IDC_IPPROG, IDC_IPMANUAL);
262 EnableDlgItem(hwndDlg, IDC_PUBLICIP, TRUE);
263 EnableDlgItem(hwndDlg, IDC_IPPROGEXE, FALSE);
264 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
265 } else if (LOWORD(wParam) == IDC_IPPROG) {
266 CheckRadioButton(hwndDlg, IDC_IPLOCAL, IDC_IPPROG, IDC_IPPROG);
267 EnableDlgItem(hwndDlg, IDC_PUBLICIP, FALSE);
268 EnableDlgItem(hwndDlg, IDC_IPPROGEXE, TRUE);
269 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
270 } else if (LOWORD(wParam) == IDC_USESSO) {
271 if (IsDlgButtonChecked(hwndDlg, IDC_USESSO) == BST_CHECKED)
273 EnableDlgItem(hwndDlg, IDC_LOGIN, FALSE);
274 EnableDlgItem(hwndDlg, IDC_PASSWORD, FALSE);
275 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
276 } else {
277 CheckRadioButton(hwndDlg, IDC_SSO, IDC_MSO, IDC_MSO);
278 EnableDlgItem(hwndDlg, IDC_LOGIN, TRUE);
279 EnableDlgItem(hwndDlg, IDC_PASSWORD, TRUE);
281 } else if (!lock && (code == EN_CHANGE || code == CBN_SELCHANGE)) {
282 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
284 return TRUE;
287 case WM_NOTIFY:
289 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
291 char buf[100];
292 TCHAR tbuf[100];
294 const SIPPROTO *pr = (const SIPPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
296 GetDlgItemTextA(hwndDlg, IDC_HANDLE, buf, sizeof(buf));
297 sipe_miranda_setString(pr, "username", buf);
299 GetDlgItemTextA(hwndDlg, IDC_LOGIN, buf, sizeof(buf));
300 sipe_miranda_setString(pr, "login", buf);
302 GetDlgItemTextA(hwndDlg, IDC_PASSWORD, buf, sizeof(buf));
303 CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buf),(LPARAM)buf);
304 sipe_miranda_setString(pr, "password", buf);
306 SendDlgItemMessage(hwndDlg, IDC_CONNTYPE, WM_GETTEXT, 100, (LPARAM)tbuf );
308 if (!_tcscmp(tbuf, _T("Auto")))
309 sipe_miranda_setString(pr, "transport", "auto");
310 else if (!_tcscmp(tbuf, _T("SSL/TLS")))
311 sipe_miranda_setString(pr, "transport", "tls");
312 else if (!_tcscmp(tbuf, _T("TCP")))
313 sipe_miranda_setString(pr, "transport", "tcp");
315 SendDlgItemMessage(hwndDlg, IDC_AUTHTYPE, WM_GETTEXT, 100, (LPARAM)tbuf );
317 if (!_tcscmp(tbuf, _T("NTLM")))
318 sipe_miranda_setWord(pr, NULL, "authscheme", SIPE_AUTHENTICATION_TYPE_NTLM);
319 else if (!_tcscmp(tbuf, _T("Kerberos")))
320 sipe_miranda_setWord(pr, NULL, "authscheme", SIPE_AUTHENTICATION_TYPE_KERBEROS);
321 else if (!_tcscmp(tbuf, _T("TLS-DSK")))
322 sipe_miranda_setWord(pr, NULL, "authscheme", SIPE_AUTHENTICATION_TYPE_TLS_DSK);
323 else
324 sipe_miranda_setWord(pr, NULL, "authscheme", SIPE_AUTHENTICATION_TYPE_AUTOMATIC);
326 GetDlgItemTextA(hwndDlg, IDC_PUBLICIP, buf, sizeof(buf));
327 sipe_miranda_setGlobalString("public_ip", buf);
329 GetDlgItemTextA(hwndDlg, IDC_IPPROGEXE, buf, sizeof(buf));
330 sipe_miranda_setGlobalString("ipprog", buf);
332 if (IsDlgButtonChecked(hwndDlg, IDC_IPLOCAL) == BST_CHECKED)
334 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL);
335 } else if (IsDlgButtonChecked(hwndDlg, IDC_IPMANUAL) == BST_CHECKED) {
336 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_MANUAL);
337 } else {
338 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_PROG);
340 return TRUE;
342 return TRUE;
347 return FALSE;
350 INT_PTR CALLBACK DlgProcAccMgrUI(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
352 switch(msg)
354 case WM_INITDIALOG:
356 const SIPPROTO *pr = (const SIPPROTO *)lParam;
357 char *str;
358 gboolean sso;
360 TranslateDialogDefault(hwndDlg);
362 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
364 sso = sipe_miranda_getBool(pr, "sso", FALSE);
365 if (sso)
367 CheckRadioButton(hwndDlg, IDC_SSO, IDC_MSO, IDC_SSO);
368 EnableDlgItem(hwndDlg, IDC_LOGIN, FALSE);
369 EnableDlgItem(hwndDlg, IDC_PASSWORD, FALSE);
370 } else {
371 CheckRadioButton(hwndDlg, IDC_SSO, IDC_MSO, IDC_MSO);
372 EnableDlgItem(hwndDlg, IDC_LOGIN, TRUE);
373 EnableDlgItem(hwndDlg, IDC_PASSWORD, TRUE);
376 str = sipe_miranda_getString(pr, "username");
377 SetDlgItemTextA(hwndDlg, IDC_HANDLE, str);
378 mir_free(str);
380 str = sipe_miranda_getString(pr, "login");
381 SetDlgItemTextA(hwndDlg, IDC_LOGIN, str);
382 mir_free(str);
384 str = sipe_miranda_getString(pr, "password");
385 if (str) CallService(MS_DB_CRYPT_DECODESTRING, strlen(str),(LPARAM)str);
386 SetDlgItemTextA(hwndDlg, IDC_PASSWORD, str);
387 mir_free(str);
389 SendDlgItemMessage(hwndDlg, IDC_HANDLE, EM_SETLIMITTEXT, 50, 0);
390 SendDlgItemMessage(hwndDlg, IDC_LOGIN, EM_SETLIMITTEXT, 50, 0);
391 SendDlgItemMessage(hwndDlg, IDC_PASSWORD, EM_SETLIMITTEXT, 16, 0);
393 return TRUE;
396 case WM_COMMAND:
397 if (LOWORD(wParam) == IDC_SSO)
399 EnableDlgItem(hwndDlg, IDC_LOGIN, FALSE);
400 EnableDlgItem(hwndDlg, IDC_PASSWORD, FALSE);
401 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
402 } else if (LOWORD(wParam) == IDC_MSO) {
403 EnableDlgItem(hwndDlg, IDC_LOGIN, TRUE);
404 EnableDlgItem(hwndDlg, IDC_PASSWORD, TRUE);
405 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
406 } else if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == GetFocus()) {
407 switch(LOWORD(wParam))
409 case IDC_HANDLE:
410 case IDC_LOGIN:
411 case IDC_PASSWORD:
412 SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
413 break;
416 break;
418 case WM_NOTIFY:
419 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY)
421 char buf[100];
423 const SIPPROTO *pr = (const SIPPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
425 if (IsDlgButtonChecked(hwndDlg, IDC_SSO) == BST_CHECKED)
427 sipe_miranda_setBool(pr, "sso", TRUE);
428 } else {
429 sipe_miranda_setBool(pr, "sso", FALSE);
432 GetDlgItemTextA(hwndDlg, IDC_HANDLE, buf, sizeof(buf));
433 sipe_miranda_setString(pr, "username", buf);
435 GetDlgItemTextA(hwndDlg, IDC_LOGIN, buf, sizeof(buf));
436 sipe_miranda_setString(pr, "login", buf);
438 GetDlgItemTextA(hwndDlg, IDC_PASSWORD, buf, sizeof(buf));
439 CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buf),(LPARAM)buf);
440 sipe_miranda_setString(pr, "password", buf);
442 return TRUE;
444 break;
447 return FALSE;
452 * Miranda service support functions
454 * Functions called by our service functions
456 static void fix_contact_groups(SIPPROTO *pr)
458 GSList *contacts = sipe_miranda_buddy_find_all(pr, NULL, NULL);
459 char *group;
461 CONTACTS_FOREACH(contacts)
462 group = DBGetString(hContact, "CList", "Group");
463 sipe_miranda_setContactString(pr, hContact, "Group", group);
464 mir_free(group);
465 CONTACTS_FOREACH_END
469 static INT_PTR sipe_miranda_start_chat(SIPPROTO *pr, WPARAM wParam, LPARAM lParam)
471 HANDLE hContact = (HANDLE)wParam;
472 struct sipe_core_public *sipe_public = pr->sip;
474 DBVARIANT dbv;
475 if ( !DBGetContactSettingString( hContact, pr->proto.m_szModuleName, SIP_UNIQUEID, &dbv )) {
476 LOCK;
477 sipe_core_buddy_new_chat(sipe_public, dbv.pszVal);
478 UNLOCK;
479 DBFreeVariant( &dbv );
480 return TRUE;
483 return FALSE;
486 static void OnModulesLoaded(SIPPROTO *pr)
488 TCHAR descr[MAX_PATH];
489 NETLIBUSER nlu = {0};
490 GCREGISTER gcr;
491 DBEVENTTYPEDESCR eventType = {0};
493 SIPE_DEBUG_INFO_NOFORMAT("OnEvent::OnModulesLoaded");
495 nlu.cbSize = sizeof(nlu);
496 nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_TCHAR;
497 nlu.szSettingsModule = pr->proto.m_szModuleName;
498 _sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), pr->proto.m_tszUserName );
499 nlu.ptszDescriptiveName = descr;
501 pr->m_hServerNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
503 gcr.cbSize = sizeof(gcr);
504 gcr.dwFlags = 0;
505 gcr.pszModule = pr->proto.m_szModuleName;
506 gcr.pszModuleDispName = "Sip/Simple";
507 gcr.iMaxText = 0;
508 gcr.nColors = 0;
510 if (CallService(MS_GC_REGISTER, 0, (LPARAM)&gcr))
512 SIPE_DEBUG_INFO_NOFORMAT("OnEvent::OnModulesLoaded Failed to register chat");
515 // Register custom database events
516 eventType.cbSize = DBEVENTTYPEDESCR_SIZE;
517 eventType.module = pr->proto.m_szModuleName;
518 eventType.eventType = SIPE_EVENTTYPE_ERROR_NOTIFY;
519 eventType.descr = "Message error notification";
520 eventType.textService = SIPE_DB_GETEVENTTEXT_ERROR_NOTIFY;
521 eventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
522 // for now keep default "message" icon
523 CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&eventType);
525 eventType.cbSize = DBEVENTTYPEDESCR_SIZE;
526 eventType.module = pr->proto.m_szModuleName;
527 eventType.eventType = SIPE_EVENTTYPE_INFO_NOTIFY;
528 eventType.descr = "Message info notification";
529 eventType.textService = SIPE_DB_GETEVENTTEXT_INFO_NOTIFY;
530 eventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
531 // for now keep default "message" icon
532 CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&eventType);
534 eventType.cbSize = DBEVENTTYPEDESCR_SIZE;
535 eventType.module = pr->proto.m_szModuleName;
536 eventType.eventType = SIPE_EVENTTYPE_IM_TOPIC;
537 eventType.descr = "Chat topic set";
538 eventType.textService = SIPE_DB_GETEVENTTEXT_IM_TOPIC;
539 eventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
540 // for now keep default "message" icon
541 CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&eventType);
545 int OnOptionsInit(const SIPPROTO *pr, WPARAM wParam, LPARAM lParam)
547 OPTIONSDIALOGPAGE odp = {0};
548 HMODULE hUxTheme = 0;
550 if (IsWinVerXPPlus())
552 hUxTheme = GetModuleHandleA("uxtheme.dll");
553 if (hUxTheme)
554 pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
557 odp.cbSize = sizeof(odp);
558 odp.position = -800000000;
559 odp.hInstance = hInst;
560 odp.ptszGroup = LPGENT("Network");
561 odp.dwInitParam = (LPARAM)pr;
562 odp.ptszTitle = pr->proto.m_tszUserName;
563 odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
565 odp.ptszTab = LPGENT("Account");
566 odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SIPSIMPLE);
567 odp.pfnDlgProc = DlgProcSipSimpleOpts;
568 CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
570 odp.ptszTab = LPGENT("About");
571 odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SIPSIMPLE_ABOUT);
572 odp.pfnDlgProc = DlgProcSipSimpleOptsAbout;
573 CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
575 #if 0
577 odp.ptszTab = LPGENT("Features");
578 odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQFEATURES);
579 odp.pfnDlgProc = DlgProcIcqFeaturesOpts;
580 CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
582 odp.ptszTab = LPGENT("Privacy");
583 odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQPRIVACY);
584 odp.pfnDlgProc = DlgProcIcqPrivacyOpts;
585 CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
587 if (bPopUpService)
589 odp.position = 100000000;
590 odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUPS);
591 odp.groupPosition = 900000000;
592 odp.pfnDlgProc = DlgProcIcqPopupOpts;
593 odp.ptszGroup = LPGENT("Popups");
594 odp.ptszTab = NULL;
595 CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
597 #endif
598 return 0;
601 void sipe_miranda_close(SIPPROTO *pr)
603 struct sipe_core_public *sipe_public = pr->sip;
605 if (sipe_public) {
606 LOCK;
607 sipe_core_deallocate(sipe_public);
608 pr->sip = NULL;
609 UNLOCK;
611 // sipe_purple_chat_destroy_rejoin(purple_private);
612 // g_free(purple_private);
616 void set_buddies_offline(const SIPPROTO* pr)
618 HANDLE hContact;
620 hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
621 while (hContact) {
622 char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
623 if (szProto != NULL && !lstrcmpA(szProto, pr->proto.m_szModuleName)) {
624 if (DBGetContactSettingByte(hContact, pr->proto.m_szModuleName, "ChatRoom", 0) == 0)
625 DBWriteContactSettingWord(hContact, pr->proto.m_szModuleName, "Status", ID_STATUS_OFFLINE);
627 hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
631 int __stdcall show_vlc(void *data);
632 void sipe_miranda_login(SIPPROTO *pr) {
633 gchar *username = sipe_miranda_getString(pr, "username");
634 gchar *login = sipe_miranda_getString(pr, "login");
635 gchar *email = sipe_miranda_getString(pr, "email");
636 gchar *email_url = sipe_miranda_getString(pr, "email_url");
637 const gchar *errmsg;
638 gchar *password;
639 gchar *tmp = (char*)mir_calloc(1024);
640 int tmpstatus;
641 int ttype;
642 guint authentication_type = SIPE_AUTHENTICATION_TYPE_AUTOMATIC;
643 struct sipe_core_public *sipe_public;
645 // CloseHandle((HANDLE) mir_forkthreadex(show_vlc, NULL, 65536, NULL));
647 if (sipe_miranda_getStaticString(pr, NULL, "password", tmp, 1024 )) tmp[0] = '\0';
648 CallService(MS_DB_CRYPT_DECODESTRING, sizeof(tmp),(LPARAM)tmp);
649 password = g_strdup(tmp);
650 mir_free(tmp);
652 LOCK;
653 pr->sip = sipe_core_allocate(username,
654 // /* @TODO: is this correct?
655 // "sso" is only available when SSPI/Kerberos support is compiled in */
656 sipe_miranda_getBool(pr, "sso", FALSE),
657 login,
658 password,
659 email,
660 email_url,
661 &errmsg);
662 if (pr->sip) pr->sip->backend_private = pr;
663 sipe_public = pr->sip;
664 UNLOCK;
666 mir_free(username);
667 mir_free(login);
668 mir_free(email);
669 mir_free(email_url);
670 g_free(password);
672 if (!pr->sip) {
673 sipe_miranda_connection_error_reason(pr,
674 SIPE_CONNECTION_ERROR_INVALID_USERNAME,
675 errmsg);
676 return;
679 //sipe_miranda_chat_setup_rejoin(pr);
681 /* default is Auto */
682 sipe_miranda_getWord(pr, NULL, "authscheme", &authentication_type);
684 /* Set display name */
685 sipe_miranda_setStringUtf(pr, "Nick", pr->sip->sip_name);
687 /* Update connection progress */
688 tmpstatus = pr->proto.m_iStatus;
689 pr->proto.m_iStatus = ID_STATUS_CONNECTING;
690 sipe_miranda_SendBroadcast(pr, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)tmpstatus, ID_STATUS_CONNECTING);
692 tmp = sipe_miranda_getString(pr, "transport");
693 if (sipe_strequal(tmp, "auto")) {
694 ttype = SIPE_TRANSPORT_AUTO;
695 } else if (sipe_strequal(tmp, "tls")) {
696 ttype = SIPE_TRANSPORT_TLS;
697 } else {
698 ttype = SIPE_TRANSPORT_TCP;
700 mir_free(tmp);
702 LOCK;
703 sipe_core_transport_sip_connect(pr->sip,
704 ttype,
705 authentication_type,
706 NULL,
707 NULL);
708 UNLOCK;
711 void sipsimple_search_contact_cb( GList *columns, GList *results, GHashTable *opts, void *data )
713 SIPPROTO *pr = (SIPPROTO *)data;
714 GList *row, *col;
715 HANDLE hProcess = g_hash_table_lookup(opts, "searchid");
716 PROTOSEARCHRESULT psr = { 0 };
718 psr.cbSize = sizeof(psr);
720 row = results;
721 while (row)
723 gchar **name;
725 col = (GList*)row->data;
726 psr.id = (PROTOCHAR*)col->data;
728 col = g_list_next(col);
729 name = g_strsplit_set(col->data, ",", 2);
730 psr.nick = (FNAMECHAR*)col->data;
731 psr.firstName = (PROTOCHAR*)(name[0] ? name[1] : NULL);
732 psr.lastName = (PROTOCHAR*)name[0];
734 col = g_list_next(col);
735 /* company */
737 col = g_list_next(col);
738 /* country */
740 col = g_list_next(col);
741 psr.email = (PROTOCHAR*)col->data;
743 row = g_list_next(row);
744 sipe_miranda_SendBroadcast(pr, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, hProcess, (LPARAM) & psr);
745 g_strfreev(name);
748 sipe_miranda_SendBroadcast(pr, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, hProcess, 0);
752 static int OnGroupChange(SIPPROTO *pr, WPARAM w, LPARAM l )
754 CLISTGROUPCHANGE *gi = (CLISTGROUPCHANGE*)l;
755 HANDLE hContact = (HANDLE)w;
756 DBVARIANT dbv;
758 /* No contact => it's a group add/rename/remove */
759 if (!hContact)
761 gchar *oldname, *newname;
763 /* No old name => add */
764 if (!gi->pszOldName)
766 return 0;
768 /* No new name => delete */
769 else if (!gi->pszNewName)
771 SIPE_DEBUG_INFO("Removing group <%ls>", gi->pszOldName);
772 oldname = mir_t2a(gi->pszOldName);
773 LOCK;
774 sipe_core_group_remove(pr->sip, oldname);
775 UNLOCK;
776 mir_free(oldname);
777 return 0;
780 SIPE_DEBUG_INFO("Renaming group <%S> to <%S>", gi->pszOldName, gi->pszNewName);
781 oldname = mir_t2a(gi->pszOldName);
782 newname = mir_t2a(gi->pszNewName);
783 LOCK;
784 sipe_core_group_rename(pr->sip, oldname, newname);
785 UNLOCK;
786 mir_free(oldname);
787 mir_free(newname);
788 return 0;
791 if ( !DBGetContactSettingString( hContact, pr->proto.m_szModuleName, SIP_UNIQUEID, &dbv )) {
792 gchar *oldgroup;
793 gchar *who = g_strdup(dbv.pszVal);
794 DBFreeVariant( &dbv );
796 if (oldgroup = sipe_miranda_getContactString(pr, hContact, "Group"))
798 SIPE_DEBUG_INFO("Moving buddy <%s> from group <%ls> to group <%ls>", who, oldgroup, gi->pszNewName);
799 LOCK;
800 sipe_core_buddy_group(pr->sip, who, oldgroup, TCHAR2CHAR(gi->pszNewName));
801 UNLOCK;
802 mir_free(oldgroup);
803 } else {
804 gchar *name = mir_t2a(gi->pszNewName);
806 if (!g_str_has_prefix(name, "sip:")) {
807 gchar *newname = sip_uri_from_name(name);
808 mir_free(name);
809 name = mir_strdup(newname);
810 g_free(newname);
813 SIPE_DEBUG_INFO("Really adding buddy <%s> to list in group <%s>", who, name);
814 LOCK;
815 sipe_core_buddy_add(pr->sip, who, name);
816 UNLOCK;
817 mir_free(name);
820 g_free(who);
823 return TRUE;
826 static int sipe_miranda_build_chat_menu(SIPPROTO *pr, WPARAM w, LPARAM lParam )
828 GCMENUITEMS *gcmi= (GCMENUITEMS*) lParam;
830 if (gcmi->Type == MENU_ON_NICKLIST)
832 static struct gc_item Item[] = {
833 {"&Make Leader", 1, MENU_ITEM, FALSE},
836 gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
837 gcmi->Item = &Item[0];
840 return 0;
843 static int OnChatEvent(SIPPROTO *pr, WPARAM w, LPARAM l )
845 GCHOOK *hook = (GCHOOK*)l;
846 GCDEST *dst = hook->pDest;
848 if (dst->iType == GC_USER_MESSAGE) {
849 GCDEST gcd = {0};
850 GCEVENT gce = {0};
851 struct sipe_chat_session *session;
853 gcd.pszModule = pr->proto.m_szModuleName;
854 gcd.pszID = dst->pszID;
855 gcd.iType = GC_EVENT_GETITEMDATA;
857 gce.cbSize = sizeof(gce);
858 gce.pDest = &gcd;
861 if ((session = (struct sipe_chat_session*)CallService( MS_GC_EVENT, 0, (LPARAM)&gce )) == NULL)
863 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
864 return 0;
867 LOCK;
868 sipe_core_chat_send(pr->sip, session, hook->pszText);
869 UNLOCK;
871 return TRUE;
872 } else if (dst->iType == GC_USER_PRIVMESS) {
873 } else if (dst->iType == GC_USER_NICKLISTMENU) {
874 if (hook->dwData == 1)
876 SIPE_DEBUG_INFO("make leader <%s>", hook->pszUID);
880 return FALSE;
883 int OnPreBuildContactMenu(SIPPROTO *pr, WPARAM wParam, LPARAM lParam)
885 HANDLE hContact = (HANDLE)wParam;
886 int chatcount = CallService(MS_GC_GETSESSIONCOUNT, 0, (LPARAM)pr->proto.m_szModuleName);
887 int idx;
888 CLISTMENUITEM mi = {0};
889 GC_INFO gci = {0};
890 gpointer tmp;
892 mi.cbSize = sizeof(mi);
893 gci.pszModule = pr->proto.m_szModuleName;
895 /* Remove the old list */
896 while (pr->contactMenuChatItems)
898 SIPE_DEBUG_INFO("Removing old menuitem <%08x>", pr->contactMenuChatItems->data);
899 CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)pr->contactMenuChatItems->data, 0);
900 pr->contactMenuChatItems = g_slist_remove(pr->contactMenuChatItems, pr->contactMenuChatItems->data);
903 /* Add the main entry */
904 mi.pszName = "Invite to chat";
905 mi.flags = CMIF_NOTOFFLINE;
906 mi.position = 20;
907 tmp = (gpointer)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
908 pr->contactMenuChatItems = g_slist_append(pr->contactMenuChatItems, tmp);
910 mi.pszName = "New chat";
911 mi.hParentMenu = pr->contactMenuChatItems->data;
912 mi.flags = CMIF_ROOTHANDLE;
913 mi.popupPosition = 0;
914 mi.position=-10;
915 mi.pszService = g_strdup_printf("%s/StartChat", pr->proto.m_szModuleName);
916 mi.pszContactOwner = pr->proto.m_szModuleName;
917 tmp = (gpointer)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
918 g_free(mi.pszService);
919 pr->contactMenuChatItems = g_slist_append(pr->contactMenuChatItems, tmp);
921 for (idx=0 ; idx<chatcount ; idx++)
923 SIPE_DEBUG_INFO("Chat <%d> Menuitem <%08x>", idx, pr->contactMenuChatItems);
924 gci.iItem = idx;
925 gci.Flags = BYINDEX | NAME | ID;
926 if(!CallServiceSync( MS_GC_GETINFO, 0, (LPARAM)&gci )) {
927 SIPE_DEBUG_INFO("Chat <%s>", gci.pszName);
929 mi.pszName = gci.pszName;
930 mi.hParentMenu = pr->contactMenuChatItems->data;
931 mi.flags = CMIF_ROOTHANDLE;
932 mi.popupPosition = g_strdup(gci.pszID);
933 mi.position = idx;
934 mi.pszService = g_strdup_printf("%s/InviteToChat", pr->proto.m_szModuleName);
935 mi.pszContactOwner = pr->proto.m_szModuleName;
936 tmp = (gpointer)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
937 g_free(mi.pszService);
938 pr->contactMenuChatItems = g_slist_append(pr->contactMenuChatItems, tmp);
942 return 0;
945 INT_PTR SvcCreateAccMgrUI(const SIPPROTO *pr, WPARAM wParam, LPARAM lParam)
947 return (INT_PTR)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, DlgProcAccMgrUI, (LPARAM)pr);
952 * Miranda service functions
954 * The functions in our plugin that get called directly by core Miranda
956 static DWORD_PTR GetCaps( SIPPROTO *pr, int type, HANDLE hContact )
958 switch (type) {
959 case PFLAGNUM_1:
960 return PF1_IM | PF1_CHAT | PF1_FILE | PF1_MODEMSG
961 | PF1_SERVERCLIST | PF1_ADDED
962 | PF1_BASICSEARCH | PF1_ADDSEARCHRES
963 | PF1_SEARCHBYEMAIL | PF1_USERIDISEMAIL
964 | PF1_SEARCHBYNAME | PF1_EXTSEARCH
967 case PFLAGNUM_2:
968 return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY
969 | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND
970 | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE;
972 case PFLAGNUM_3:
973 return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY
974 | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND
975 | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE;
977 case PFLAGNUM_4:
978 return PF4_NOCUSTOMAUTH | PF4_IMSENDUTF | PF4_SUPPORTTYPING
979 | PF4_SUPPORTIDLE;
981 case PFLAGNUM_5:
982 return 0;
984 case PFLAG_UNIQUEIDSETTING:
985 return (DWORD_PTR) SIP_UNIQUEID;
986 break;
987 default:
988 SIPE_DEBUG_INFO("GetCaps: unknown type <%x>", type);
992 return 0;
995 static HICON GetIcon( SIPPROTO *pr, int iconIndex )
997 SIPE_DEBUG_INFO("GetIcon: unknown index <%x>", iconIndex);
998 return NULL;
1001 static int OnEvent( SIPPROTO *pr, PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam )
1003 SIPE_DEBUG_INFO("OnEvent: type <%x>", eventType);
1005 switch (eventType)
1007 case EV_PROTO_ONLOAD:
1008 OnModulesLoaded(pr);
1009 break;
1011 case EV_PROTO_ONREADYTOEXIT:
1012 break;
1014 case EV_PROTO_ONEXIT:
1015 break;
1017 case EV_PROTO_ONRENAME:
1018 break;
1020 case EV_PROTO_ONOPTIONS:
1021 return OnOptionsInit( pr, wParam, lParam );
1022 break;
1024 case EV_PROTO_ONERASE:
1025 break;
1029 return 0;
1032 static HANDLE AddToListByEvent( SIPPROTO *pr, int flags, int iContact, HANDLE hDbEvent )
1034 DBEVENTINFO dbei = {0};
1036 dbei.cbSize = sizeof(dbei);
1037 if ((dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == -1)
1038 return 0;
1040 dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob + 1);
1041 dbei.pBlob[dbei.cbBlob] = '\0';
1043 if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei))
1044 return 0; // failed to get event
1046 if (strcmp(dbei.szModule, pr->proto.m_szModuleName))
1047 return 0; // this event is not ours
1049 _NIF();
1050 SIPE_DEBUG_INFO("AddToListByEvent: flags <%x> iContact <%x>", flags, iContact);
1051 return NULL;
1054 static int Authorize( SIPPROTO *pr, HANDLE hContact )
1056 _NIF();
1057 SIPE_DEBUG_INFO_NOFORMAT("Authorize");
1058 return 0;
1061 static int AuthDeny( SIPPROTO *pr, HANDLE hContact, const PROTOCHAR* szReason )
1063 _NIF();
1064 SIPE_DEBUG_INFO("AuthDeny: reason <%s>", szReason);
1065 return 0;
1068 static int AuthRecv( SIPPROTO *pr, HANDLE hContact, PROTORECVEVENT* evt )
1070 _NIF();
1071 SIPE_DEBUG_INFO_NOFORMAT("AuthRecv");
1072 return 0;
1075 static int AuthRequest( SIPPROTO *pr, HANDLE hContact, const PROTOCHAR* szMessage )
1077 _NIF();
1078 SIPE_DEBUG_INFO("AuthRequest: message <%s>", szMessage);
1079 return 0;
1082 static HANDLE ChangeInfo( SIPPROTO *pr, int iInfoType, void* pInfoData )
1084 _NIF();
1085 SIPE_DEBUG_INFO("ChangeInfo: infotype <%x>", iInfoType);
1086 return NULL;
1089 static int FileCancel( SIPPROTO *pr, HANDLE hContact, HANDLE hTransfer )
1091 _NIF();
1092 SIPE_DEBUG_INFO_NOFORMAT("FileCancel");
1093 return 0;
1096 static int FileResume( SIPPROTO *pr, HANDLE hTransfer, int* action, const PROTOCHAR** szFilename )
1098 _NIF();
1099 SIPE_DEBUG_INFO("FileResume: action <%x>", action);
1100 return 0;
1103 static HANDLE SearchBasic( SIPPROTO *pr, const PROTOCHAR* id )
1105 return NULL;
1108 static HWND CreateExtendedSearchUI( SIPPROTO *pr, HWND owner )
1110 return CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SEARCHUI), (HWND)owner, NULL, (LPARAM)pr);
1113 static HANDLE AddToList( SIPPROTO *pr, int flags, PROTOSEARCHRESULT* psr )
1115 HANDLE hContact;
1116 gchar *id = g_strdup(TCHAR2CHAR(psr->id));
1118 /* Prepend sip: if needed */
1119 if (strncmp("sip:", id, 4)) {
1120 gchar *tmp = id;
1121 id = sip_uri_from_name(tmp);
1122 g_free(tmp);
1125 hContact = sipe_miranda_buddy_find(pr, id, NULL);
1126 if (hContact) {
1127 g_free(id);
1128 return hContact;
1131 hContact = ( HANDLE )CallService( MS_DB_CONTACT_ADD, 0, 0 );
1132 CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pr->proto.m_szModuleName );
1133 sipe_miranda_setContactString( pr, hContact, SIP_UNIQUEID, id ); // name
1134 if (psr->nick)
1136 /* server_alias */
1137 gchar *tmp = mir_t2a(psr->nick);
1138 sipe_miranda_setContactStringUtf( pr, hContact, "Nick", tmp );
1139 mir_free(tmp);
1142 g_free(id);
1143 return hContact;
1147 sipe_miranda_window_closed(SIPPROTO *pr, WPARAM wParam, LPARAM lParam)
1149 MessageWindowEventData* evt = (MessageWindowEventData*)lParam;
1151 SIPE_DEBUG_INFO("contact <%08x> module <%s> type <%02x> flags <%02x>",
1152 evt->hContact, evt->szModule, evt->uType, evt->uFlags);
1154 return 0;
1157 static int
1158 sipe_miranda_invite_to_chat(const SIPPROTO *pr, WPARAM wParam, LPARAM lParam)
1160 HANDLE hContact = (HANDLE)wParam;
1161 gchar *id = (gchar*)lParam;
1162 GCDEST gcd = {0};
1163 GCEVENT gce = {0};
1164 struct sipe_chat_session *session;
1165 gchar *uid;
1167 gcd.pszModule = pr->proto.m_szModuleName;
1168 gcd.pszID = id;
1169 gcd.iType = GC_EVENT_GETITEMDATA;
1171 gce.cbSize = sizeof(gce);
1172 gce.pDest = &gcd;
1174 if ((session = (struct sipe_chat_session*)CallService( MS_GC_EVENT, 0, (LPARAM)&gce )) == NULL)
1176 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
1177 return 0;
1180 uid = sipe_miranda_getContactString(pr, hContact, SIP_UNIQUEID);
1181 sipe_core_chat_invite(pr->sip, session, uid);
1183 mir_free(uid);
1184 g_free(id);
1185 return 0;
1189 * Main Miranda interface
1191 * The structures and functions that allow Miranda to recovnize and load
1192 * our plugin.
1195 /* Plugin information structure */
1196 PLUGININFOEX pluginInfo = {
1197 sizeof(PLUGININFOEX),
1198 "Office Communicator Protocol",
1199 PLUGIN_MAKE_VERSION(0,11,2,1),
1200 "Support for Microsoft Office Communicator",
1201 "Miranda support by Jochen De Smet, for core sipe support see homepage",
1202 "jochen.libsipe@leahnim.org",
1203 "(C)2009-2011",
1204 "https://sourceforge.net/projects/sipe",
1205 UNICODE_AWARE,
1206 0, //doesn't replace anything built-in
1207 #if defined( _UNICODE )
1208 { 0x842395ed, 0x4e56, 0x40e5, { 0x94, 0x25, 0x28, 0x29, 0xd8, 0xab, 0xae, 0xa5 } } // {842395ED-4E56-40e5-9425-2829D8ABAEA5}
1209 #else
1210 { 0x1ef8af37, 0xdec1, 0x4757, { 0x89, 0x78, 0xe8, 0xad, 0xd0, 0xd8, 0x6e, 0x7f } } // {1EF8AF37-DEC1-4757-8978-E8ADD0D86E7F}
1211 #endif
1214 __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
1216 // Only load for 0.8.0.29 or greater
1217 // We need the core stubs for PS_GETNAME and PS_GETSTATUS
1218 if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 9, 0, 0))
1220 MessageBoxA(
1221 NULL,
1222 "SIP/Simple plugin cannot be loaded. It requires Miranda IM 0.9.0.0 or later.",
1223 "SIP/Simple Plugin",
1224 MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST
1226 return NULL;
1229 return &pluginInfo;
1232 static const MUUID interfaces[] = {MIID_PROTOCOL, MIID_LAST};
1233 __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
1235 return interfaces;
1238 static PROTO_INTERFACE* sipsimpleProtoInit( const char* pszProtoName, const TCHAR* tszUserName )
1240 gchar *tmp;
1241 SIPPROTO *pr = (SIPPROTO *)mir_calloc(sizeof(SIPPROTO));
1242 pr->proto.vtbl = (PROTO_INTERFACE_VTBL*)mir_calloc(sizeof(PROTO_INTERFACE_VTBL));
1244 SIPE_DEBUG_INFO("protoname <%s> username <%ls>", pszProtoName, tszUserName);
1246 if (!InitializeCriticalSectionAndSpinCount(&pr->CriticalSection, 0))
1248 SIPE_DEBUG_ERROR_NOFORMAT("Can't initialize critical section");
1249 return NULL;
1252 tmp = sipe_miranda_getString(pr, "transport");
1253 if (!tmp)
1255 sipe_miranda_setString(pr, "transport", "auto");
1256 } else {
1257 mir_free(tmp);
1260 /* To make it easy to detect when a SIPPROTO* isn't a SIPPROTO* */
1261 strncpy(pr->_SIGNATURE, "AbandonAllHope..", sizeof(pr->_SIGNATURE));
1263 pr->main_thread_id = GetCurrentThreadId();
1264 pr->proto.m_iVersion = 2;
1265 pr->proto.m_szModuleName = mir_strdup(pszProtoName);
1266 pr->proto.m_tszUserName = mir_tstrdup(tszUserName);
1267 pr->proto.m_szProtoName = mir_strdup(pszProtoName);
1269 // set_buddies_offline(pr);
1270 fix_contact_groups(pr);
1272 /* Fill the function table */
1273 #define PROTO_FUNC(name,func) ((struct sipe_backend_private)(pr->proto)).vtbl->name = func;
1275 pr->proto.vtbl->AddToList = AddToList;
1276 pr->proto.vtbl->AddToListByEvent = AddToListByEvent;
1278 pr->proto.vtbl->Authorize = Authorize;
1279 pr->proto.vtbl->AuthDeny = AuthDeny;
1280 pr->proto.vtbl->AuthRecv = AuthRecv;
1281 pr->proto.vtbl->AuthRequest = AuthRequest;
1283 pr->proto.vtbl->ChangeInfo = ChangeInfo;
1285 pr->proto.vtbl->FileAllow = sipe_miranda_FileAllow;
1286 pr->proto.vtbl->FileCancel = FileCancel;
1287 pr->proto.vtbl->FileDeny = sipe_miranda_FileDeny;
1288 pr->proto.vtbl->FileResume = FileResume;
1290 pr->proto.vtbl->GetCaps = GetCaps;
1291 pr->proto.vtbl->GetIcon = GetIcon;
1292 pr->proto.vtbl->GetInfo = sipe_miranda_GetInfo;
1294 pr->proto.vtbl->SearchBasic = SearchBasic;
1295 pr->proto.vtbl->SearchByEmail = sipe_miranda_SearchByEmail;
1296 pr->proto.vtbl->SearchByName = sipe_miranda_SearchByName;
1297 pr->proto.vtbl->SearchAdvanced = sipe_miranda_SearchAdvanced;
1298 pr->proto.vtbl->CreateExtendedSearchUI = CreateExtendedSearchUI;
1300 pr->proto.vtbl->RecvMsg = sipe_miranda_RecvMsg;
1302 pr->proto.vtbl->SendMsg = sipe_miranda_SendMsg;
1304 pr->proto.vtbl->SetStatus = sipe_miranda_SetStatus;
1306 pr->proto.vtbl->GetAwayMsg = sipe_miranda_GetAwayMsg;
1307 pr->proto.vtbl->SetAwayMsg = sipe_miranda_SetAwayMsg;
1309 pr->proto.vtbl->UserIsTyping = sipe_miranda_UserIsTyping;
1311 pr->proto.vtbl->SendFile = sipe_miranda_SendFile;
1312 pr->proto.vtbl->RecvFile = sipe_miranda_RecvFile;
1314 pr->proto.vtbl->OnEvent = OnEvent;
1316 /* Setup services */
1317 CreateProtoService(pr, PS_CREATEACCMGRUI, &SvcCreateAccMgrUI );
1318 CreateProtoService(pr, "/InviteToChat", &sipe_miranda_invite_to_chat);
1319 CreateProtoService(pr, "/StartChat",&sipe_miranda_start_chat);
1321 #define HOOKEVENT(evt,func) HookEventObj(evt, func, pr)
1322 HOOKEVENT(ME_OPT_INITIALISE, &OnOptionsInit);
1323 HOOKEVENT(ME_CLIST_GROUPCHANGE, &OnGroupChange);
1324 HOOKEVENT(ME_GC_EVENT, &OnChatEvent);
1325 HOOKEVENT(ME_CLIST_PREBUILDCONTACTMENU, &OnPreBuildContactMenu);
1326 HOOKEVENT(ME_DB_CONTACT_DELETED, &sipe_miranda_buddy_delete);
1327 HOOKEVENT(ME_MSG_WINDOWEVENT, &sipe_miranda_window_closed);
1328 HOOKEVENT(ME_GC_BUILDMENU, &sipe_miranda_build_chat_menu);
1330 return (PROTO_INTERFACE*)pr;
1333 static int sipsimpleProtoUninit( PROTO_INTERFACE* _pr )
1335 SIPPROTO *pr = (SIPPROTO *)_pr;
1337 DeleteCriticalSection(&pr->CriticalSection);
1339 Netlib_CloseHandle(pr->m_hServerNetlibUser);
1340 mir_free(pr->proto.m_szProtoName);
1341 mir_free(pr->proto.m_szModuleName);
1342 mir_free(pr->proto.m_tszUserName);
1343 mir_free(pr->proto.vtbl);
1344 mir_free(pr);
1346 return 0;
1349 __declspec(dllexport) int Load(PLUGINLINK *link)
1351 PROTOCOLDESCRIPTOR pd = {0};
1352 NETLIBUSER nlu = {0};
1353 char *tmp;
1354 WORD iptype;
1356 pluginLink = link;
1358 sipe_core_init("");
1360 mir_getMMI( &mmi );
1362 /* Register the module */
1363 pd.cbSize = sizeof(pd);
1364 pd.szName = SIPSIMPLE_PROTOCOL_NAME;
1365 pd.type = PROTOTYPE_PROTOCOL;
1366 pd.fnInit = sipsimpleProtoInit;
1367 pd.fnUninit = sipsimpleProtoUninit;
1368 CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd);
1370 /* Protocolwide netlib user for incoming connections (also abused for logging) */
1371 nlu.cbSize = sizeof(nlu);
1372 nlu.flags = NUF_INCOMING | NUF_TCHAR | NUF_NOOPTIONS;
1373 nlu.szSettingsModule = SIPSIMPLE_PROTOCOL_NAME;
1374 nlu.minIncomingPorts = 10;
1376 InitializeCriticalSectionAndSpinCount(&sipe_miranda_debug_CriticalSection, 0);
1377 sipe_miranda_incoming_netlibuser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
1379 tmp = sipe_miranda_getGlobalString("public_ip");
1380 if (!tmp) {
1381 sipe_miranda_setGlobalString("public_ip", "0.0.0.0");
1382 } else {
1383 mir_free(tmp);
1386 if (!sipe_miranda_getGlobalWord("iptype", &iptype))
1388 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL);
1391 return 0;
1394 __declspec(dllexport) int Unload(void)
1396 Netlib_CloseHandle(sipe_miranda_incoming_netlibuser);
1397 sipe_miranda_incoming_netlibuser = NULL;
1398 DeleteCriticalSection(&sipe_miranda_debug_CriticalSection);
1399 sipe_core_destroy();
1400 return 0;
1403 BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
1405 hInst = hinstDLL;
1406 return TRUE;
1410 Local Variables:
1411 mode: c
1412 c-file-style: "bsd"
1413 indent-tabs-mode: t
1414 tab-width: 8
1415 End: