2 * @file miranda-plugin.c
6 * Copyright (C) 2010-2013 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("NTLM"));
188 #if defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_SSPI)
189 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("Kerberos"));
191 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("TLS-DSK"));
193 sipe_miranda_getWord(pr
, NULL
, "authscheme", &iptype
);
194 if (iptype
== SIPE_AUTHENTICATION_TYPE_NTLM
)
195 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("NTLM"));
196 else if (iptype
== SIPE_AUTHENTICATION_TYPE_KERBEROS
)
197 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("Kerberos"));
198 else if (!strcmp(str
, "tls-dsk"))
199 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("TLS-DSK"));
201 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("NTLM"));
203 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("Auto"));
204 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("SSL/TLS"));
205 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("TCP"));
207 str
= sipe_miranda_getString(pr
, "transport");
208 if (!str
|| !strcmp(str
, "auto"))
209 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("Auto"));
210 else if (!strcmp(str
, "tls"))
211 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("SSL/TLS"));
212 else if (!strcmp(str
, "tcp"))
213 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("TCP"));
215 str
= sipe_miranda_getGlobalString("public_ip");
216 SetDlgItemTextA(hwndDlg
, IDC_PUBLICIP
, str
);
217 SendDlgItemMessage(hwndDlg
, IDC_PUBLICIP
, EM_SETLIMITTEXT
, 20, 0);
220 str
= sipe_miranda_getGlobalString("ipprog");
221 SetDlgItemTextA(hwndDlg
, IDC_IPPROGEXE
, str
);
222 SendDlgItemMessage(hwndDlg
, IDC_IPPROGEXE
, EM_SETLIMITTEXT
, 60, 0);
225 str
= sipe_miranda_get_local_ip();
226 SetDlgItemTextA(hwndDlg
, IDC_IPLOCALFOUND
, str
);
228 sipe_miranda_getGlobalWord("iptype", &iptype
);
229 if (iptype
== SIPE_MIRANDA_IP_LOCAL
)
231 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPLOCAL
);
232 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
233 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
234 } else if (iptype
== SIPE_MIRANDA_IP_MANUAL
) {
235 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPMANUAL
);
236 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, TRUE
);
237 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
239 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPPROG
);
240 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
241 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, TRUE
);
250 int code
= wParam
>> 16;
251 int id
= wParam
& 0xffff;
253 if (LOWORD(wParam
) == IDC_IPLOCAL
)
255 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPLOCAL
);
256 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
257 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
258 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
259 } else if (LOWORD(wParam
) == IDC_IPMANUAL
) {
260 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPMANUAL
);
261 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, TRUE
);
262 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
263 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
264 } else if (LOWORD(wParam
) == IDC_IPPROG
) {
265 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPPROG
);
266 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
267 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, TRUE
);
268 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
269 } else if (LOWORD(wParam
) == IDC_USESSO
) {
270 if (IsDlgButtonChecked(hwndDlg
, IDC_USESSO
) == BST_CHECKED
)
272 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
273 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
274 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
276 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_MSO
);
277 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
278 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
280 } else if (!lock
&& (code
== EN_CHANGE
|| code
== CBN_SELCHANGE
)) {
281 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
288 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
293 const SIPPROTO
*pr
= (const SIPPROTO
*)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
295 GetDlgItemTextA(hwndDlg
, IDC_HANDLE
, buf
, sizeof(buf
));
296 sipe_miranda_setString(pr
, "username", buf
);
298 GetDlgItemTextA(hwndDlg
, IDC_LOGIN
, buf
, sizeof(buf
));
299 sipe_miranda_setString(pr
, "login", buf
);
301 GetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, buf
, sizeof(buf
));
302 CallService(MS_DB_CRYPT_ENCODESTRING
, sizeof(buf
),(LPARAM
)buf
);
303 sipe_miranda_setString(pr
, "password", buf
);
305 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, WM_GETTEXT
, 100, (LPARAM
)tbuf
);
307 if (!_tcscmp(tbuf
, _T("Auto")))
308 sipe_miranda_setString(pr
, "transport", "auto");
309 else if (!_tcscmp(tbuf
, _T("SSL/TLS")))
310 sipe_miranda_setString(pr
, "transport", "tls");
311 else if (!_tcscmp(tbuf
, _T("TCP")))
312 sipe_miranda_setString(pr
, "transport", "tcp");
314 SendDlgItemMessage(hwndDlg
, IDC_AUTHTYPE
, WM_GETTEXT
, 100, (LPARAM
)tbuf
);
316 if (!_tcscmp(tbuf
, _T("NTLM")))
317 sipe_miranda_setWord(pr
, NULL
, "authscheme", SIPE_AUTHENTICATION_TYPE_NTLM
);
318 else if (!_tcscmp(tbuf
, _T("Kerberos")))
319 sipe_miranda_setWord(pr
, NULL
, "authscheme", SIPE_AUTHENTICATION_TYPE_KERBEROS
);
320 else if (!_tcscmp(tbuf
, _T("TLS-DSK")))
321 sipe_miranda_setWord(pr
, NULL
, "authscheme", SIPE_AUTHENTICATION_TYPE_TLS_DSK
);
323 GetDlgItemTextA(hwndDlg
, IDC_PUBLICIP
, buf
, sizeof(buf
));
324 sipe_miranda_setGlobalString("public_ip", buf
);
326 GetDlgItemTextA(hwndDlg
, IDC_IPPROGEXE
, buf
, sizeof(buf
));
327 sipe_miranda_setGlobalString("ipprog", buf
);
329 if (IsDlgButtonChecked(hwndDlg
, IDC_IPLOCAL
) == BST_CHECKED
)
331 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL
);
332 } else if (IsDlgButtonChecked(hwndDlg
, IDC_IPMANUAL
) == BST_CHECKED
) {
333 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_MANUAL
);
335 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_PROG
);
347 INT_PTR CALLBACK
DlgProcAccMgrUI(HWND hwndDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
353 const SIPPROTO
*pr
= (const SIPPROTO
*)lParam
;
357 TranslateDialogDefault(hwndDlg
);
359 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
361 sso
= sipe_miranda_getBool(pr
, "sso", FALSE
);
364 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_SSO
);
365 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
366 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
368 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_MSO
);
369 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
370 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
373 str
= sipe_miranda_getString(pr
, "username");
374 SetDlgItemTextA(hwndDlg
, IDC_HANDLE
, str
);
377 str
= sipe_miranda_getString(pr
, "login");
378 SetDlgItemTextA(hwndDlg
, IDC_LOGIN
, str
);
381 str
= sipe_miranda_getString(pr
, "password");
382 if (str
) CallService(MS_DB_CRYPT_DECODESTRING
, strlen(str
),(LPARAM
)str
);
383 SetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, str
);
386 SendDlgItemMessage(hwndDlg
, IDC_HANDLE
, EM_SETLIMITTEXT
, 50, 0);
387 SendDlgItemMessage(hwndDlg
, IDC_LOGIN
, EM_SETLIMITTEXT
, 50, 0);
388 SendDlgItemMessage(hwndDlg
, IDC_PASSWORD
, EM_SETLIMITTEXT
, 16, 0);
394 if (LOWORD(wParam
) == IDC_SSO
)
396 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
397 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
398 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
399 } else if (LOWORD(wParam
) == IDC_MSO
) {
400 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
401 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
402 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
403 } else if (HIWORD(wParam
) == EN_CHANGE
&& (HWND
)lParam
== GetFocus()) {
404 switch(LOWORD(wParam
))
409 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
416 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
420 const SIPPROTO
*pr
= (const SIPPROTO
*)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
422 if (IsDlgButtonChecked(hwndDlg
, IDC_SSO
) == BST_CHECKED
)
424 sipe_miranda_setBool(pr
, "sso", TRUE
);
426 sipe_miranda_setBool(pr
, "sso", FALSE
);
429 GetDlgItemTextA(hwndDlg
, IDC_HANDLE
, buf
, sizeof(buf
));
430 sipe_miranda_setString(pr
, "username", buf
);
432 GetDlgItemTextA(hwndDlg
, IDC_LOGIN
, buf
, sizeof(buf
));
433 sipe_miranda_setString(pr
, "login", buf
);
435 GetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, buf
, sizeof(buf
));
436 CallService(MS_DB_CRYPT_ENCODESTRING
, sizeof(buf
),(LPARAM
)buf
);
437 sipe_miranda_setString(pr
, "password", buf
);
449 * Miranda service support functions
451 * Functions called by our service functions
453 static void fix_contact_groups(SIPPROTO
*pr
)
455 GSList
*contacts
= sipe_miranda_buddy_find_all(pr
, NULL
, NULL
);
458 CONTACTS_FOREACH(contacts
)
459 group
= DBGetString(hContact
, "CList", "Group");
460 sipe_miranda_setContactString(pr
, hContact
, "Group", group
);
466 static INT_PTR
sipe_miranda_start_chat(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
468 HANDLE hContact
= (HANDLE
)wParam
;
469 struct sipe_core_public
*sipe_public
= pr
->sip
;
472 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
474 sipe_core_buddy_new_chat(sipe_public
, dbv
.pszVal
);
476 DBFreeVariant( &dbv
);
483 static void OnModulesLoaded(SIPPROTO
*pr
)
485 TCHAR descr
[MAX_PATH
];
486 NETLIBUSER nlu
= {0};
488 DBEVENTTYPEDESCR eventType
= {0};
490 SIPE_DEBUG_INFO_NOFORMAT("OnEvent::OnModulesLoaded");
492 nlu
.cbSize
= sizeof(nlu
);
493 nlu
.flags
= NUF_OUTGOING
| NUF_INCOMING
| NUF_TCHAR
;
494 nlu
.szSettingsModule
= pr
->proto
.m_szModuleName
;
495 _sntprintf(descr
, SIZEOF(descr
), TranslateT("%s server connection"), pr
->proto
.m_tszUserName
);
496 nlu
.ptszDescriptiveName
= descr
;
498 pr
->m_hServerNetlibUser
= (HANDLE
)CallService(MS_NETLIB_REGISTERUSER
, 0, (LPARAM
)&nlu
);
500 gcr
.cbSize
= sizeof(gcr
);
502 gcr
.pszModule
= pr
->proto
.m_szModuleName
;
503 gcr
.pszModuleDispName
= "Sip/Simple";
507 if (CallService(MS_GC_REGISTER
, 0, (LPARAM
)&gcr
))
509 SIPE_DEBUG_INFO_NOFORMAT("OnEvent::OnModulesLoaded Failed to register chat");
512 // Register custom database events
513 eventType
.cbSize
= DBEVENTTYPEDESCR_SIZE
;
514 eventType
.module
= pr
->proto
.m_szModuleName
;
515 eventType
.eventType
= SIPE_EVENTTYPE_ERROR_NOTIFY
;
516 eventType
.descr
= "Message error notification";
517 eventType
.textService
= SIPE_DB_GETEVENTTEXT_ERROR_NOTIFY
;
518 eventType
.flags
= DETF_HISTORY
| DETF_MSGWINDOW
;
519 // for now keep default "message" icon
520 CallService(MS_DB_EVENT_REGISTERTYPE
, 0, (LPARAM
)&eventType
);
522 eventType
.cbSize
= DBEVENTTYPEDESCR_SIZE
;
523 eventType
.module
= pr
->proto
.m_szModuleName
;
524 eventType
.eventType
= SIPE_EVENTTYPE_INFO_NOTIFY
;
525 eventType
.descr
= "Message info notification";
526 eventType
.textService
= SIPE_DB_GETEVENTTEXT_INFO_NOTIFY
;
527 eventType
.flags
= DETF_HISTORY
| DETF_MSGWINDOW
;
528 // for now keep default "message" icon
529 CallService(MS_DB_EVENT_REGISTERTYPE
, 0, (LPARAM
)&eventType
);
531 eventType
.cbSize
= DBEVENTTYPEDESCR_SIZE
;
532 eventType
.module
= pr
->proto
.m_szModuleName
;
533 eventType
.eventType
= SIPE_EVENTTYPE_IM_TOPIC
;
534 eventType
.descr
= "Chat topic set";
535 eventType
.textService
= SIPE_DB_GETEVENTTEXT_IM_TOPIC
;
536 eventType
.flags
= DETF_HISTORY
| DETF_MSGWINDOW
;
537 // for now keep default "message" icon
538 CallService(MS_DB_EVENT_REGISTERTYPE
, 0, (LPARAM
)&eventType
);
542 int OnOptionsInit(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
544 OPTIONSDIALOGPAGE odp
= {0};
545 HMODULE hUxTheme
= 0;
547 if (IsWinVerXPPlus())
549 hUxTheme
= GetModuleHandleA("uxtheme.dll");
551 pfnEnableThemeDialogTexture
= (BOOL (WINAPI
*)(HANDLE
, DWORD
))GetProcAddress(hUxTheme
, "EnableThemeDialogTexture");
554 odp
.cbSize
= sizeof(odp
);
555 odp
.position
= -800000000;
556 odp
.hInstance
= hInst
;
557 odp
.ptszGroup
= LPGENT("Network");
558 odp
.dwInitParam
= (LPARAM
)pr
;
559 odp
.ptszTitle
= pr
->proto
.m_tszUserName
;
560 odp
.flags
= ODPF_BOLDGROUPS
| ODPF_TCHAR
;
562 odp
.ptszTab
= LPGENT("Account");
563 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_SIPSIMPLE
);
564 odp
.pfnDlgProc
= DlgProcSipSimpleOpts
;
565 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
567 odp
.ptszTab
= LPGENT("About");
568 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_SIPSIMPLE_ABOUT
);
569 odp
.pfnDlgProc
= DlgProcSipSimpleOptsAbout
;
570 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
574 odp
.ptszTab
= LPGENT("Features");
575 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_ICQFEATURES
);
576 odp
.pfnDlgProc
= DlgProcIcqFeaturesOpts
;
577 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
579 odp
.ptszTab
= LPGENT("Privacy");
580 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_ICQPRIVACY
);
581 odp
.pfnDlgProc
= DlgProcIcqPrivacyOpts
;
582 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
586 odp
.position
= 100000000;
587 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_POPUPS
);
588 odp
.groupPosition
= 900000000;
589 odp
.pfnDlgProc
= DlgProcIcqPopupOpts
;
590 odp
.ptszGroup
= LPGENT("Popups");
592 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
598 void sipe_miranda_close(SIPPROTO
*pr
)
600 struct sipe_core_public
*sipe_public
= pr
->sip
;
604 sipe_core_deallocate(sipe_public
);
608 // sipe_purple_chat_destroy_rejoin(purple_private);
609 // g_free(purple_private);
613 void set_buddies_offline(const SIPPROTO
* pr
)
617 hContact
= (HANDLE
)CallService(MS_DB_CONTACT_FINDFIRST
, 0, 0);
619 char* szProto
= (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO
, (WPARAM
)hContact
, 0);
620 if (szProto
!= NULL
&& !lstrcmpA(szProto
, pr
->proto
.m_szModuleName
)) {
621 if (DBGetContactSettingByte(hContact
, pr
->proto
.m_szModuleName
, "ChatRoom", 0) == 0)
622 DBWriteContactSettingWord(hContact
, pr
->proto
.m_szModuleName
, "Status", ID_STATUS_OFFLINE
);
624 hContact
= (HANDLE
)CallService(MS_DB_CONTACT_FINDNEXT
, (WPARAM
)hContact
, 0);
628 int __stdcall
show_vlc(void *data
);
629 void sipe_miranda_login(SIPPROTO
*pr
) {
630 gchar
*username
= sipe_miranda_getString(pr
, "username");
631 gchar
*login
= sipe_miranda_getString(pr
, "login");
632 gchar
*email
= sipe_miranda_getString(pr
, "email");
633 gchar
*email_url
= sipe_miranda_getString(pr
, "email_url");
634 gchar
**domain_user
= g_strsplit_set(login
, "/\\", 2);
637 gchar
*tmp
= (char*)mir_calloc(1024);
640 guint authentication_type
;
641 struct sipe_core_public
*sipe_public
;
643 // CloseHandle((HANDLE) mir_forkthreadex(show_vlc, NULL, 65536, NULL));
645 if (sipe_miranda_getStaticString(pr
, NULL
, "password", tmp
, 1024 )) tmp
[0] = '\0';
646 CallService(MS_DB_CRYPT_DECODESTRING
, sizeof(tmp
),(LPARAM
)tmp
);
647 password
= g_strdup(tmp
);
651 pr
->sip
= sipe_core_allocate(username
,
652 // /* @TODO: is this correct?
653 // "sso" is only available when SSPI/Kerberos support is compiled in */
654 sipe_miranda_getBool(pr
, "sso", FALSE
),
655 domain_user
[0], domain_user
[0] != NULL
? domain_user
[1] : "",
660 if (pr
->sip
) pr
->sip
->backend_private
= pr
;
661 sipe_public
= pr
->sip
;
668 g_strfreev(domain_user
);
672 sipe_miranda_connection_error_reason(pr
,
673 SIPE_CONNECTION_ERROR_INVALID_USERNAME
,
678 //sipe_miranda_chat_setup_rejoin(pr);
680 /* default is NTLM */
681 sipe_miranda_getWord(pr
, NULL
, "authscheme", &authentication_type
);
683 /* Set display name */
684 sipe_miranda_setStringUtf(pr
, "Nick", pr
->sip
->sip_name
);
686 /* Update connection progress */
687 tmpstatus
= pr
->proto
.m_iStatus
;
688 pr
->proto
.m_iStatus
= ID_STATUS_CONNECTING
;
689 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_STATUS
, ACKRESULT_SUCCESS
, (HANDLE
)tmpstatus
, ID_STATUS_CONNECTING
);
691 tmp
= sipe_miranda_getString(pr
, "transport");
692 if (sipe_strequal(tmp
, "auto")) {
693 ttype
= SIPE_TRANSPORT_AUTO
;
694 } else if (sipe_strequal(tmp
, "tls")) {
695 ttype
= SIPE_TRANSPORT_TLS
;
697 ttype
= SIPE_TRANSPORT_TCP
;
702 sipe_core_transport_sip_connect(pr
->sip
,
710 void sipsimple_search_contact_cb( GList
*columns
, GList
*results
, GHashTable
*opts
, void *data
)
712 SIPPROTO
*pr
= (SIPPROTO
*)data
;
714 HANDLE hProcess
= g_hash_table_lookup(opts
, "searchid");
715 PROTOSEARCHRESULT psr
= { 0 };
717 psr
.cbSize
= sizeof(psr
);
724 col
= (GList
*)row
->data
;
725 psr
.id
= (PROTOCHAR
*)col
->data
;
727 col
= g_list_next(col
);
728 name
= g_strsplit_set(col
->data
, ",", 2);
729 psr
.nick
= (FNAMECHAR
*)col
->data
;
730 psr
.firstName
= (PROTOCHAR
*)(name
[0] ? name
[1] : NULL
);
731 psr
.lastName
= (PROTOCHAR
*)name
[0];
733 col
= g_list_next(col
);
736 col
= g_list_next(col
);
739 col
= g_list_next(col
);
740 psr
.email
= (PROTOCHAR
*)col
->data
;
742 row
= g_list_next(row
);
743 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_SEARCH
, ACKRESULT_DATA
, hProcess
, (LPARAM
) & psr
);
747 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_SEARCH
, ACKRESULT_SUCCESS
, hProcess
, 0);
751 static int OnGroupChange(SIPPROTO
*pr
, WPARAM w
, LPARAM l
)
753 CLISTGROUPCHANGE
*gi
= (CLISTGROUPCHANGE
*)l
;
754 HANDLE hContact
= (HANDLE
)w
;
757 /* No contact => it's a group add/rename/remove */
760 gchar
*oldname
, *newname
;
762 /* No old name => add */
767 /* No new name => delete */
768 else if (!gi
->pszNewName
)
770 SIPE_DEBUG_INFO("Removing group <%ls>", gi
->pszOldName
);
771 oldname
= mir_t2a(gi
->pszOldName
);
773 sipe_core_group_remove(pr
->sip
, oldname
);
779 SIPE_DEBUG_INFO("Renaming group <%S> to <%S>", gi
->pszOldName
, gi
->pszNewName
);
780 oldname
= mir_t2a(gi
->pszOldName
);
781 newname
= mir_t2a(gi
->pszNewName
);
783 sipe_core_group_rename(pr
->sip
, oldname
, newname
);
790 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
792 gchar
*who
= g_strdup(dbv
.pszVal
);
793 DBFreeVariant( &dbv
);
795 if (oldgroup
= sipe_miranda_getContactString(pr
, hContact
, "Group"))
797 SIPE_DEBUG_INFO("Moving buddy <%s> from group <%ls> to group <%ls>", who
, oldgroup
, gi
->pszNewName
);
799 sipe_core_buddy_group(pr
->sip
, who
, oldgroup
, TCHAR2CHAR(gi
->pszNewName
));
803 gchar
*name
= mir_t2a(gi
->pszNewName
);
805 if (!g_str_has_prefix(name
, "sip:")) {
806 gchar
*newname
= sip_uri_from_name(name
);
808 name
= mir_strdup(newname
);
812 SIPE_DEBUG_INFO("Really adding buddy <%s> to list in group <%s>", who
, name
);
814 sipe_core_buddy_add(pr
->sip
, who
, name
);
825 static int sipe_miranda_build_chat_menu(SIPPROTO
*pr
, WPARAM w
, LPARAM lParam
)
827 GCMENUITEMS
*gcmi
= (GCMENUITEMS
*) lParam
;
829 if (gcmi
->Type
== MENU_ON_NICKLIST
)
831 static struct gc_item Item
[] = {
832 {"&Make Leader", 1, MENU_ITEM
, FALSE
},
835 gcmi
->nItems
= sizeof(Item
)/sizeof(Item
[0]);
836 gcmi
->Item
= &Item
[0];
842 static int OnChatEvent(SIPPROTO
*pr
, WPARAM w
, LPARAM l
)
844 GCHOOK
*hook
= (GCHOOK
*)l
;
845 GCDEST
*dst
= hook
->pDest
;
847 if (dst
->iType
== GC_USER_MESSAGE
) {
850 struct sipe_chat_session
*session
;
852 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
853 gcd
.pszID
= dst
->pszID
;
854 gcd
.iType
= GC_EVENT_GETITEMDATA
;
856 gce
.cbSize
= sizeof(gce
);
860 if ((session
= (struct sipe_chat_session
*)CallService( MS_GC_EVENT
, 0, (LPARAM
)&gce
)) == NULL
)
862 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
867 sipe_core_chat_send(pr
->sip
, session
, hook
->pszText
);
871 } else if (dst
->iType
== GC_USER_PRIVMESS
) {
872 } else if (dst
->iType
== GC_USER_NICKLISTMENU
) {
873 if (hook
->dwData
== 1)
875 SIPE_DEBUG_INFO("make leader <%s>", hook
->pszUID
);
882 int OnPreBuildContactMenu(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
884 HANDLE hContact
= (HANDLE
)wParam
;
885 int chatcount
= CallService(MS_GC_GETSESSIONCOUNT
, 0, (LPARAM
)pr
->proto
.m_szModuleName
);
887 CLISTMENUITEM mi
= {0};
891 mi
.cbSize
= sizeof(mi
);
892 gci
.pszModule
= pr
->proto
.m_szModuleName
;
894 /* Remove the old list */
895 while (pr
->contactMenuChatItems
)
897 SIPE_DEBUG_INFO("Removing old menuitem <%08x>", pr
->contactMenuChatItems
->data
);
898 CallService(MS_CLIST_REMOVECONTACTMENUITEM
, (WPARAM
)pr
->contactMenuChatItems
->data
, 0);
899 pr
->contactMenuChatItems
= g_slist_remove(pr
->contactMenuChatItems
, pr
->contactMenuChatItems
->data
);
902 /* Add the main entry */
903 mi
.pszName
= "Invite to chat";
904 mi
.flags
= CMIF_NOTOFFLINE
;
906 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
907 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
909 mi
.pszName
= "New chat";
910 mi
.hParentMenu
= pr
->contactMenuChatItems
->data
;
911 mi
.flags
= CMIF_ROOTHANDLE
;
912 mi
.popupPosition
= 0;
914 mi
.pszService
= g_strdup_printf("%s/StartChat", pr
->proto
.m_szModuleName
);
915 mi
.pszContactOwner
= pr
->proto
.m_szModuleName
;
916 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
917 g_free(mi
.pszService
);
918 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
920 for (idx
=0 ; idx
<chatcount
; idx
++)
922 SIPE_DEBUG_INFO("Chat <%d> Menuitem <%08x>", idx
, pr
->contactMenuChatItems
);
924 gci
.Flags
= BYINDEX
| NAME
| ID
;
925 if(!CallServiceSync( MS_GC_GETINFO
, 0, (LPARAM
)&gci
)) {
926 SIPE_DEBUG_INFO("Chat <%s>", gci
.pszName
);
928 mi
.pszName
= gci
.pszName
;
929 mi
.hParentMenu
= pr
->contactMenuChatItems
->data
;
930 mi
.flags
= CMIF_ROOTHANDLE
;
931 mi
.popupPosition
= g_strdup(gci
.pszID
);
933 mi
.pszService
= g_strdup_printf("%s/InviteToChat", pr
->proto
.m_szModuleName
);
934 mi
.pszContactOwner
= pr
->proto
.m_szModuleName
;
935 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
936 g_free(mi
.pszService
);
937 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
944 INT_PTR
SvcCreateAccMgrUI(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
946 return (INT_PTR
)CreateDialogParam(hInst
, MAKEINTRESOURCE(IDD_ACCMGRUI
), (HWND
)lParam
, DlgProcAccMgrUI
, (LPARAM
)pr
);
951 * Miranda service functions
953 * The functions in our plugin that get called directly by core Miranda
955 static DWORD_PTR
GetCaps( SIPPROTO
*pr
, int type
, HANDLE hContact
)
959 return PF1_IM
| PF1_CHAT
| PF1_FILE
| PF1_MODEMSG
960 | PF1_SERVERCLIST
| PF1_ADDED
961 | PF1_BASICSEARCH
| PF1_ADDSEARCHRES
962 | PF1_SEARCHBYEMAIL
| PF1_USERIDISEMAIL
963 | PF1_SEARCHBYNAME
| PF1_EXTSEARCH
967 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
968 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
969 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
972 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
973 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
974 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
977 return PF4_NOCUSTOMAUTH
| PF4_IMSENDUTF
| PF4_SUPPORTTYPING
983 case PFLAG_UNIQUEIDSETTING
:
984 return (DWORD_PTR
) SIP_UNIQUEID
;
987 SIPE_DEBUG_INFO("GetCaps: unknown type <%x>", type
);
994 static HICON
GetIcon( SIPPROTO
*pr
, int iconIndex
)
996 SIPE_DEBUG_INFO("GetIcon: unknown index <%x>", iconIndex
);
1000 static int OnEvent( SIPPROTO
*pr
, PROTOEVENTTYPE eventType
, WPARAM wParam
, LPARAM lParam
)
1002 SIPE_DEBUG_INFO("OnEvent: type <%x>", eventType
);
1006 case EV_PROTO_ONLOAD
:
1007 OnModulesLoaded(pr
);
1010 case EV_PROTO_ONREADYTOEXIT
:
1013 case EV_PROTO_ONEXIT
:
1016 case EV_PROTO_ONRENAME
:
1019 case EV_PROTO_ONOPTIONS
:
1020 return OnOptionsInit( pr
, wParam
, lParam
);
1023 case EV_PROTO_ONERASE
:
1031 static HANDLE
AddToListByEvent( SIPPROTO
*pr
, int flags
, int iContact
, HANDLE hDbEvent
)
1033 DBEVENTINFO dbei
= {0};
1035 dbei
.cbSize
= sizeof(dbei
);
1036 if ((dbei
.cbBlob
= CallService(MS_DB_EVENT_GETBLOBSIZE
, (WPARAM
)hDbEvent
, 0)) == -1)
1039 dbei
.pBlob
= (PBYTE
)_alloca(dbei
.cbBlob
+ 1);
1040 dbei
.pBlob
[dbei
.cbBlob
] = '\0';
1042 if (CallService(MS_DB_EVENT_GET
, (WPARAM
)hDbEvent
, (LPARAM
)&dbei
))
1043 return 0; // failed to get event
1045 if (strcmp(dbei
.szModule
, pr
->proto
.m_szModuleName
))
1046 return 0; // this event is not ours
1049 SIPE_DEBUG_INFO("AddToListByEvent: flags <%x> iContact <%x>", flags
, iContact
);
1053 static int Authorize( SIPPROTO
*pr
, HANDLE hContact
)
1056 SIPE_DEBUG_INFO_NOFORMAT("Authorize");
1060 static int AuthDeny( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szReason
)
1063 SIPE_DEBUG_INFO("AuthDeny: reason <%s>", szReason
);
1067 static int AuthRecv( SIPPROTO
*pr
, HANDLE hContact
, PROTORECVEVENT
* evt
)
1070 SIPE_DEBUG_INFO_NOFORMAT("AuthRecv");
1074 static int AuthRequest( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szMessage
)
1077 SIPE_DEBUG_INFO("AuthRequest: message <%s>", szMessage
);
1081 static HANDLE
ChangeInfo( SIPPROTO
*pr
, int iInfoType
, void* pInfoData
)
1084 SIPE_DEBUG_INFO("ChangeInfo: infotype <%x>", iInfoType
);
1088 static int FileCancel( SIPPROTO
*pr
, HANDLE hContact
, HANDLE hTransfer
)
1091 SIPE_DEBUG_INFO_NOFORMAT("FileCancel");
1095 static int FileResume( SIPPROTO
*pr
, HANDLE hTransfer
, int* action
, const PROTOCHAR
** szFilename
)
1098 SIPE_DEBUG_INFO("FileResume: action <%x>", action
);
1102 static HANDLE
SearchBasic( SIPPROTO
*pr
, const PROTOCHAR
* id
)
1107 static HWND
CreateExtendedSearchUI( SIPPROTO
*pr
, HWND owner
)
1109 return CreateDialogParam(hInst
, MAKEINTRESOURCE(IDD_SEARCHUI
), (HWND
)owner
, NULL
, (LPARAM
)pr
);
1112 static HANDLE
AddToList( SIPPROTO
*pr
, int flags
, PROTOSEARCHRESULT
* psr
)
1115 gchar
*id
= g_strdup(TCHAR2CHAR(psr
->id
));
1117 /* Prepend sip: if needed */
1118 if (strncmp("sip:", id
, 4)) {
1120 id
= sip_uri_from_name(tmp
);
1124 hContact
= sipe_miranda_buddy_find(pr
, id
, NULL
);
1130 hContact
= ( HANDLE
)CallService( MS_DB_CONTACT_ADD
, 0, 0 );
1131 CallService( MS_PROTO_ADDTOCONTACT
, (WPARAM
)hContact
, (LPARAM
)pr
->proto
.m_szModuleName
);
1132 sipe_miranda_setContactString( pr
, hContact
, SIP_UNIQUEID
, id
); // name
1136 gchar
*tmp
= mir_t2a(psr
->nick
);
1137 sipe_miranda_setContactStringUtf( pr
, hContact
, "Nick", tmp
);
1146 sipe_miranda_window_closed(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1148 MessageWindowEventData
* evt
= (MessageWindowEventData
*)lParam
;
1150 SIPE_DEBUG_INFO("contact <%08x> module <%s> type <%02x> flags <%02x>",
1151 evt
->hContact
, evt
->szModule
, evt
->uType
, evt
->uFlags
);
1157 sipe_miranda_invite_to_chat(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1159 HANDLE hContact
= (HANDLE
)wParam
;
1160 gchar
*id
= (gchar
*)lParam
;
1163 struct sipe_chat_session
*session
;
1166 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
1168 gcd
.iType
= GC_EVENT_GETITEMDATA
;
1170 gce
.cbSize
= sizeof(gce
);
1173 if ((session
= (struct sipe_chat_session
*)CallService( MS_GC_EVENT
, 0, (LPARAM
)&gce
)) == NULL
)
1175 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
1179 uid
= sipe_miranda_getContactString(pr
, hContact
, SIP_UNIQUEID
);
1180 sipe_core_chat_invite(pr
->sip
, session
, uid
);
1188 * Main Miranda interface
1190 * The structures and functions that allow Miranda to recovnize and load
1194 /* Plugin information structure */
1195 PLUGININFOEX pluginInfo
= {
1196 sizeof(PLUGININFOEX
),
1197 "Office Communicator Protocol",
1198 PLUGIN_MAKE_VERSION(0,11,2,1),
1199 "Support for Microsoft Office Communicator",
1200 "Miranda support by Jochen De Smet, for core sipe support see homepage",
1201 "jochen.libsipe@leahnim.org",
1203 "https://sourceforge.net/projects/sipe",
1205 0, //doesn't replace anything built-in
1206 #if defined( _UNICODE )
1207 { 0x842395ed, 0x4e56, 0x40e5, { 0x94, 0x25, 0x28, 0x29, 0xd8, 0xab, 0xae, 0xa5 } } // {842395ED-4E56-40e5-9425-2829D8ABAEA5}
1209 { 0x1ef8af37, 0xdec1, 0x4757, { 0x89, 0x78, 0xe8, 0xad, 0xd0, 0xd8, 0x6e, 0x7f } } // {1EF8AF37-DEC1-4757-8978-E8ADD0D86E7F}
1213 __declspec(dllexport
) PLUGININFOEX
*MirandaPluginInfoEx(DWORD mirandaVersion
)
1215 // Only load for 0.8.0.29 or greater
1216 // We need the core stubs for PS_GETNAME and PS_GETSTATUS
1217 if (mirandaVersion
< PLUGIN_MAKE_VERSION(0, 9, 0, 0))
1221 "SIP/Simple plugin cannot be loaded. It requires Miranda IM 0.9.0.0 or later.",
1222 "SIP/Simple Plugin",
1223 MB_OK
| MB_ICONWARNING
| MB_SETFOREGROUND
| MB_TOPMOST
1231 static const MUUID interfaces
[] = {MIID_PROTOCOL
, MIID_LAST
};
1232 __declspec(dllexport
) const MUUID
* MirandaPluginInterfaces(void)
1237 static PROTO_INTERFACE
* sipsimpleProtoInit( const char* pszProtoName
, const TCHAR
* tszUserName
)
1240 SIPPROTO
*pr
= (SIPPROTO
*)mir_calloc(sizeof(SIPPROTO
));
1241 pr
->proto
.vtbl
= (PROTO_INTERFACE_VTBL
*)mir_calloc(sizeof(PROTO_INTERFACE_VTBL
));
1243 SIPE_DEBUG_INFO("protoname <%s> username <%ls>", pszProtoName
, tszUserName
);
1245 if (!InitializeCriticalSectionAndSpinCount(&pr
->CriticalSection
, 0))
1247 SIPE_DEBUG_ERROR_NOFORMAT("Can't initialize critical section");
1251 tmp
= sipe_miranda_getString(pr
, "transport");
1254 sipe_miranda_setString(pr
, "transport", "auto");
1259 /* To make it easy to detect when a SIPPROTO* isn't a SIPPROTO* */
1260 strncpy(pr
->_SIGNATURE
, "AbandonAllHope..", sizeof(pr
->_SIGNATURE
));
1262 pr
->main_thread_id
= GetCurrentThreadId();
1263 pr
->proto
.m_iVersion
= 2;
1264 pr
->proto
.m_szModuleName
= mir_strdup(pszProtoName
);
1265 pr
->proto
.m_tszUserName
= mir_tstrdup(tszUserName
);
1266 pr
->proto
.m_szProtoName
= mir_strdup(pszProtoName
);
1268 // set_buddies_offline(pr);
1269 fix_contact_groups(pr
);
1271 /* Fill the function table */
1272 #define PROTO_FUNC(name,func) ((struct sipe_backend_private)(pr->proto)).vtbl->name = func;
1274 pr
->proto
.vtbl
->AddToList
= AddToList
;
1275 pr
->proto
.vtbl
->AddToListByEvent
= AddToListByEvent
;
1277 pr
->proto
.vtbl
->Authorize
= Authorize
;
1278 pr
->proto
.vtbl
->AuthDeny
= AuthDeny
;
1279 pr
->proto
.vtbl
->AuthRecv
= AuthRecv
;
1280 pr
->proto
.vtbl
->AuthRequest
= AuthRequest
;
1282 pr
->proto
.vtbl
->ChangeInfo
= ChangeInfo
;
1284 pr
->proto
.vtbl
->FileAllow
= sipe_miranda_FileAllow
;
1285 pr
->proto
.vtbl
->FileCancel
= FileCancel
;
1286 pr
->proto
.vtbl
->FileDeny
= sipe_miranda_FileDeny
;
1287 pr
->proto
.vtbl
->FileResume
= FileResume
;
1289 pr
->proto
.vtbl
->GetCaps
= GetCaps
;
1290 pr
->proto
.vtbl
->GetIcon
= GetIcon
;
1291 pr
->proto
.vtbl
->GetInfo
= sipe_miranda_GetInfo
;
1293 pr
->proto
.vtbl
->SearchBasic
= SearchBasic
;
1294 pr
->proto
.vtbl
->SearchByEmail
= sipe_miranda_SearchByEmail
;
1295 pr
->proto
.vtbl
->SearchByName
= sipe_miranda_SearchByName
;
1296 pr
->proto
.vtbl
->SearchAdvanced
= sipe_miranda_SearchAdvanced
;
1297 pr
->proto
.vtbl
->CreateExtendedSearchUI
= CreateExtendedSearchUI
;
1299 pr
->proto
.vtbl
->RecvMsg
= sipe_miranda_RecvMsg
;
1301 pr
->proto
.vtbl
->SendMsg
= sipe_miranda_SendMsg
;
1303 pr
->proto
.vtbl
->SetStatus
= sipe_miranda_SetStatus
;
1305 pr
->proto
.vtbl
->GetAwayMsg
= sipe_miranda_GetAwayMsg
;
1306 pr
->proto
.vtbl
->SetAwayMsg
= sipe_miranda_SetAwayMsg
;
1308 pr
->proto
.vtbl
->UserIsTyping
= sipe_miranda_UserIsTyping
;
1310 pr
->proto
.vtbl
->SendFile
= sipe_miranda_SendFile
;
1311 pr
->proto
.vtbl
->RecvFile
= sipe_miranda_RecvFile
;
1313 pr
->proto
.vtbl
->OnEvent
= OnEvent
;
1315 /* Setup services */
1316 CreateProtoService(pr
, PS_CREATEACCMGRUI
, &SvcCreateAccMgrUI
);
1317 CreateProtoService(pr
, "/InviteToChat", &sipe_miranda_invite_to_chat
);
1318 CreateProtoService(pr
, "/StartChat",&sipe_miranda_start_chat
);
1320 #define HOOKEVENT(evt,func) HookEventObj(evt, func, pr)
1321 HOOKEVENT(ME_OPT_INITIALISE
, &OnOptionsInit
);
1322 HOOKEVENT(ME_CLIST_GROUPCHANGE
, &OnGroupChange
);
1323 HOOKEVENT(ME_GC_EVENT
, &OnChatEvent
);
1324 HOOKEVENT(ME_CLIST_PREBUILDCONTACTMENU
, &OnPreBuildContactMenu
);
1325 HOOKEVENT(ME_DB_CONTACT_DELETED
, &sipe_miranda_buddy_delete
);
1326 HOOKEVENT(ME_MSG_WINDOWEVENT
, &sipe_miranda_window_closed
);
1327 HOOKEVENT(ME_GC_BUILDMENU
, &sipe_miranda_build_chat_menu
);
1329 return (PROTO_INTERFACE
*)pr
;
1332 static int sipsimpleProtoUninit( PROTO_INTERFACE
* _pr
)
1334 SIPPROTO
*pr
= (SIPPROTO
*)_pr
;
1336 DeleteCriticalSection(&pr
->CriticalSection
);
1338 Netlib_CloseHandle(pr
->m_hServerNetlibUser
);
1339 mir_free(pr
->proto
.m_szProtoName
);
1340 mir_free(pr
->proto
.m_szModuleName
);
1341 mir_free(pr
->proto
.m_tszUserName
);
1342 mir_free(pr
->proto
.vtbl
);
1348 __declspec(dllexport
) int Load(PLUGINLINK
*link
)
1350 PROTOCOLDESCRIPTOR pd
= {0};
1351 NETLIBUSER nlu
= {0};
1361 /* Register the module */
1362 pd
.cbSize
= sizeof(pd
);
1363 pd
.szName
= SIPSIMPLE_PROTOCOL_NAME
;
1364 pd
.type
= PROTOTYPE_PROTOCOL
;
1365 pd
.fnInit
= sipsimpleProtoInit
;
1366 pd
.fnUninit
= sipsimpleProtoUninit
;
1367 CallService(MS_PROTO_REGISTERMODULE
, 0, (LPARAM
)&pd
);
1369 /* Protocolwide netlib user for incoming connections (also abused for logging) */
1370 nlu
.cbSize
= sizeof(nlu
);
1371 nlu
.flags
= NUF_INCOMING
| NUF_TCHAR
| NUF_NOOPTIONS
;
1372 nlu
.szSettingsModule
= SIPSIMPLE_PROTOCOL_NAME
;
1373 nlu
.minIncomingPorts
= 10;
1375 InitializeCriticalSectionAndSpinCount(&sipe_miranda_debug_CriticalSection
, 0);
1376 sipe_miranda_incoming_netlibuser
= (HANDLE
)CallService(MS_NETLIB_REGISTERUSER
, 0, (LPARAM
)&nlu
);
1378 tmp
= sipe_miranda_getGlobalString("public_ip");
1380 sipe_miranda_setGlobalString("public_ip", "0.0.0.0");
1385 if (!sipe_miranda_getGlobalWord("iptype", &iptype
))
1387 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL
);
1393 __declspec(dllexport
) int Unload(void)
1395 Netlib_CloseHandle(sipe_miranda_incoming_netlibuser
);
1396 sipe_miranda_incoming_netlibuser
= NULL
;
1397 DeleteCriticalSection(&sipe_miranda_debug_CriticalSection
);
1398 sipe_core_destroy();
1402 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
,DWORD fdwReason
,LPVOID lpvReserved
)