2 * @file miranda-plugin.c
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")
38 #include "miranda-version.h"
39 #include "newpluginapi.h"
40 #include "m_protosvc.h"
41 #include "m_protoint.h"
42 #include "m_protomod.h"
44 #include "m_database.h"
45 #include "m_options.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"
58 #include "miranda-private.h"
59 #include "miranda-resource.h"
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)
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
);
81 * Global variables related to miranda core or UI
83 static BOOL (WINAPI
*pfnEnableThemeDialogTexture
)(HANDLE
, DWORD
) = 0;
85 PLUGINLINK
* pluginLink
;
86 struct MM_INTERFACE mmi
;
93 EnableDlgItem(HWND hwndDlg
, UINT control
, gboolean enable
)
95 EnableWindow(GetDlgItem(hwndDlg
, control
), enable
);
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
)
111 SIPPROTO
*pr
= (SIPPROTO
*)lParam
;
115 tmp
= sipe_core_about();
116 about
= sipe_miranda_html2rtf(tmp
);
120 TranslateDialogDefault(hwndDlg
);
122 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
124 tex
.flags
= ST_DEFAULT
;
127 SendDlgItemMessage(hwndDlg
, IDC_ABOUTSIPE
, EM_SETTEXTEX
, (WPARAM
)&tex
, (LPARAM
)about
);
136 static INT_PTR CALLBACK
DlgProcSipSimpleOpts(HWND hwndDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
144 const SIPPROTO
*pr
= (const SIPPROTO
*)lParam
;
149 TranslateDialogDefault(hwndDlg
);
151 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
155 #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI)
156 state
= sipe_miranda_getBool(pr
, "sso", FALSE
);
159 CheckDlgItem(hwndDlg
, IDC_USESSO
, BST_CHECKED
);
160 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
161 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
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)
171 str
= sipe_miranda_getString(pr
, "username");
172 SetDlgItemTextA(hwndDlg
, IDC_HANDLE
, str
);
173 SendDlgItemMessage(hwndDlg
, IDC_HANDLE
, EM_SETLIMITTEXT
, 50, 0);
176 str
= sipe_miranda_getString(pr
, "login");
177 SetDlgItemTextA(hwndDlg
, IDC_LOGIN
, str
);
178 SendDlgItemMessage(hwndDlg
, IDC_LOGIN
, EM_SETLIMITTEXT
, 50, 0);
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);
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"));
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"));
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);
221 str
= sipe_miranda_getGlobalString("ipprog");
222 SetDlgItemTextA(hwndDlg
, IDC_IPPROGEXE
, str
);
223 SendDlgItemMessage(hwndDlg
, IDC_IPPROGEXE
, EM_SETLIMITTEXT
, 60, 0);
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
);
240 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPPROG
);
241 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
242 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, TRUE
);
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);
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);
289 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
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
);
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
);
338 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_PROG
);
350 INT_PTR CALLBACK
DlgProcAccMgrUI(HWND hwndDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
356 const SIPPROTO
*pr
= (const SIPPROTO
*)lParam
;
360 TranslateDialogDefault(hwndDlg
);
362 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
364 sso
= sipe_miranda_getBool(pr
, "sso", FALSE
);
367 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_SSO
);
368 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
369 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
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
);
380 str
= sipe_miranda_getString(pr
, "login");
381 SetDlgItemTextA(hwndDlg
, IDC_LOGIN
, 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
);
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);
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
))
412 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
419 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
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
);
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
);
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
);
461 CONTACTS_FOREACH(contacts
)
462 group
= DBGetString(hContact
, "CList", "Group");
463 sipe_miranda_setContactString(pr
, hContact
, "Group", group
);
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
;
475 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
477 sipe_core_buddy_new_chat(sipe_public
, dbv
.pszVal
);
479 DBFreeVariant( &dbv
);
486 static void OnModulesLoaded(SIPPROTO
*pr
)
488 TCHAR descr
[MAX_PATH
];
489 NETLIBUSER nlu
= {0};
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
);
505 gcr
.pszModule
= pr
->proto
.m_szModuleName
;
506 gcr
.pszModuleDispName
= "Sip/Simple";
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");
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
);
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
);
589 odp
.position
= 100000000;
590 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_POPUPS
);
591 odp
.groupPosition
= 900000000;
592 odp
.pfnDlgProc
= DlgProcIcqPopupOpts
;
593 odp
.ptszGroup
= LPGENT("Popups");
595 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
601 void sipe_miranda_close(SIPPROTO
*pr
)
603 struct sipe_core_public
*sipe_public
= pr
->sip
;
607 sipe_core_deallocate(sipe_public
);
611 // sipe_purple_chat_destroy_rejoin(purple_private);
612 // g_free(purple_private);
616 void set_buddies_offline(const SIPPROTO
* pr
)
620 hContact
= (HANDLE
)CallService(MS_DB_CONTACT_FINDFIRST
, 0, 0);
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");
639 gchar
*tmp
= (char*)mir_calloc(1024);
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
);
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
),
662 if (pr
->sip
) pr
->sip
->backend_private
= pr
;
663 sipe_public
= pr
->sip
;
673 sipe_miranda_connection_error_reason(pr
,
674 SIPE_CONNECTION_ERROR_INVALID_USERNAME
,
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
;
698 ttype
= SIPE_TRANSPORT_TCP
;
703 sipe_core_transport_sip_connect(pr
->sip
,
711 void sipsimple_search_contact_cb( GList
*columns
, GList
*results
, GHashTable
*opts
, void *data
)
713 SIPPROTO
*pr
= (SIPPROTO
*)data
;
715 HANDLE hProcess
= g_hash_table_lookup(opts
, "searchid");
716 PROTOSEARCHRESULT psr
= { 0 };
718 psr
.cbSize
= sizeof(psr
);
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
);
737 col
= g_list_next(col
);
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
);
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
;
758 /* No contact => it's a group add/rename/remove */
761 gchar
*oldname
, *newname
;
763 /* No old name => add */
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
);
774 sipe_core_group_remove(pr
->sip
, oldname
);
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
);
784 sipe_core_group_rename(pr
->sip
, oldname
, newname
);
791 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
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
);
800 sipe_core_buddy_group(pr
->sip
, who
, oldgroup
, TCHAR2CHAR(gi
->pszNewName
));
804 gchar
*name
= mir_t2a(gi
->pszNewName
);
806 if (!g_str_has_prefix(name
, "sip:")) {
807 gchar
*newname
= sip_uri_from_name(name
);
809 name
= mir_strdup(newname
);
813 SIPE_DEBUG_INFO("Really adding buddy <%s> to list in group <%s>", who
, name
);
815 sipe_core_buddy_add(pr
->sip
, who
, name
);
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];
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
) {
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
);
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");
868 sipe_core_chat_send(pr
->sip
, session
, hook
->pszText
);
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
);
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
);
888 CLISTMENUITEM mi
= {0};
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
;
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;
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
);
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
);
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
);
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
)
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
968 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
969 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
970 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
973 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
974 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
975 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
978 return PF4_NOCUSTOMAUTH
| PF4_IMSENDUTF
| PF4_SUPPORTTYPING
984 case PFLAG_UNIQUEIDSETTING
:
985 return (DWORD_PTR
) SIP_UNIQUEID
;
988 SIPE_DEBUG_INFO("GetCaps: unknown type <%x>", type
);
995 static HICON
GetIcon( SIPPROTO
*pr
, int iconIndex
)
997 SIPE_DEBUG_INFO("GetIcon: unknown index <%x>", iconIndex
);
1001 static int OnEvent( SIPPROTO
*pr
, PROTOEVENTTYPE eventType
, WPARAM wParam
, LPARAM lParam
)
1003 SIPE_DEBUG_INFO("OnEvent: type <%x>", eventType
);
1007 case EV_PROTO_ONLOAD
:
1008 OnModulesLoaded(pr
);
1011 case EV_PROTO_ONREADYTOEXIT
:
1014 case EV_PROTO_ONEXIT
:
1017 case EV_PROTO_ONRENAME
:
1020 case EV_PROTO_ONOPTIONS
:
1021 return OnOptionsInit( pr
, wParam
, lParam
);
1024 case EV_PROTO_ONERASE
:
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)
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
1050 SIPE_DEBUG_INFO("AddToListByEvent: flags <%x> iContact <%x>", flags
, iContact
);
1054 static int Authorize( SIPPROTO
*pr
, HANDLE hContact
)
1057 SIPE_DEBUG_INFO_NOFORMAT("Authorize");
1061 static int AuthDeny( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szReason
)
1064 SIPE_DEBUG_INFO("AuthDeny: reason <%s>", szReason
);
1068 static int AuthRecv( SIPPROTO
*pr
, HANDLE hContact
, PROTORECVEVENT
* evt
)
1071 SIPE_DEBUG_INFO_NOFORMAT("AuthRecv");
1075 static int AuthRequest( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szMessage
)
1078 SIPE_DEBUG_INFO("AuthRequest: message <%s>", szMessage
);
1082 static HANDLE
ChangeInfo( SIPPROTO
*pr
, int iInfoType
, void* pInfoData
)
1085 SIPE_DEBUG_INFO("ChangeInfo: infotype <%x>", iInfoType
);
1089 static int FileCancel( SIPPROTO
*pr
, HANDLE hContact
, HANDLE hTransfer
)
1092 SIPE_DEBUG_INFO_NOFORMAT("FileCancel");
1096 static int FileResume( SIPPROTO
*pr
, HANDLE hTransfer
, int* action
, const PROTOCHAR
** szFilename
)
1099 SIPE_DEBUG_INFO("FileResume: action <%x>", action
);
1103 static HANDLE
SearchBasic( SIPPROTO
*pr
, const PROTOCHAR
* id
)
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
)
1116 gchar
*id
= g_strdup(TCHAR2CHAR(psr
->id
));
1118 /* Prepend sip: if needed */
1119 if (strncmp("sip:", id
, 4)) {
1121 id
= sip_uri_from_name(tmp
);
1125 hContact
= sipe_miranda_buddy_find(pr
, id
, NULL
);
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
1137 gchar
*tmp
= mir_t2a(psr
->nick
);
1138 sipe_miranda_setContactStringUtf( pr
, hContact
, "Nick", tmp
);
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
);
1158 sipe_miranda_invite_to_chat(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1160 HANDLE hContact
= (HANDLE
)wParam
;
1161 gchar
*id
= (gchar
*)lParam
;
1164 struct sipe_chat_session
*session
;
1167 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
1169 gcd
.iType
= GC_EVENT_GETITEMDATA
;
1171 gce
.cbSize
= sizeof(gce
);
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");
1180 uid
= sipe_miranda_getContactString(pr
, hContact
, SIP_UNIQUEID
);
1181 sipe_core_chat_invite(pr
->sip
, session
, uid
);
1189 * Main Miranda interface
1191 * The structures and functions that allow Miranda to recovnize and load
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",
1204 "https://sourceforge.net/projects/sipe",
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}
1210 { 0x1ef8af37, 0xdec1, 0x4757, { 0x89, 0x78, 0xe8, 0xad, 0xd0, 0xd8, 0x6e, 0x7f } } // {1EF8AF37-DEC1-4757-8978-E8ADD0D86E7F}
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))
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
1232 static const MUUID interfaces
[] = {MIID_PROTOCOL
, MIID_LAST
};
1233 __declspec(dllexport
) const MUUID
* MirandaPluginInterfaces(void)
1238 static PROTO_INTERFACE
* sipsimpleProtoInit( const char* pszProtoName
, const TCHAR
* tszUserName
)
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");
1252 tmp
= sipe_miranda_getString(pr
, "transport");
1255 sipe_miranda_setString(pr
, "transport", "auto");
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
);
1349 __declspec(dllexport
) int Load(PLUGINLINK
*link
)
1351 PROTOCOLDESCRIPTOR pd
= {0};
1352 NETLIBUSER nlu
= {0};
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");
1381 sipe_miranda_setGlobalString("public_ip", "0.0.0.0");
1386 if (!sipe_miranda_getGlobalWord("iptype", &iptype
))
1388 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL
);
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();
1403 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
,DWORD fdwReason
,LPVOID lpvReserved
)