2 * @file miranda-plugin.c
6 * Copyright (C) 2010-12 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")
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
;
92 EnableDlgItem(HWND hwndDlg
, UINT control
, gboolean enable
)
94 EnableWindow(GetDlgItem(hwndDlg
, control
), enable
);
98 CheckDlgItem(HWND hwndDlg
, UINT control
, int state
)
100 Button_SetCheck(GetDlgItem(hwndDlg
, control
), state
);
103 INT_PTR CALLBACK
DlgProcSipSimpleOptsAbout(HWND hwndDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
110 SIPPROTO
*pr
= (SIPPROTO
*)lParam
;
114 tmp
= sipe_core_about();
115 about
= sipe_miranda_html2rtf(tmp
);
119 TranslateDialogDefault(hwndDlg
);
121 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
123 tex
.flags
= ST_DEFAULT
;
126 SendDlgItemMessage(hwndDlg
, IDC_ABOUTSIPE
, EM_SETTEXTEX
, (WPARAM
)&tex
, (LPARAM
)about
);
135 static INT_PTR CALLBACK
DlgProcSipSimpleOpts(HWND hwndDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
143 const SIPPROTO
*pr
= (const SIPPROTO
*)lParam
;
148 TranslateDialogDefault(hwndDlg
);
150 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
154 state
= sipe_miranda_getBool(pr
, "sso", FALSE
);
157 CheckDlgItem(hwndDlg
, IDC_USESSO
, BST_CHECKED
);
158 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
159 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
161 CheckDlgItem(hwndDlg
, IDC_USESSO
, BST_UNCHECKED
);
162 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
163 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
166 state
= sipe_miranda_getBool(pr
, "krb5", FALSE
);
168 CheckDlgItem(hwndDlg
, IDC_USEKRB
, BST_CHECKED
);
170 CheckDlgItem(hwndDlg
, IDC_USEKRB
, BST_UNCHECKED
);
172 str
= sipe_miranda_getString(pr
, "username");
173 SetDlgItemTextA(hwndDlg
, IDC_HANDLE
, str
);
174 SendDlgItemMessage(hwndDlg
, IDC_HANDLE
, EM_SETLIMITTEXT
, 50, 0);
177 str
= sipe_miranda_getString(pr
, "login");
178 SetDlgItemTextA(hwndDlg
, IDC_LOGIN
, str
);
179 SendDlgItemMessage(hwndDlg
, IDC_LOGIN
, EM_SETLIMITTEXT
, 50, 0);
182 str
= sipe_miranda_getString(pr
, "password");
183 if (str
) CallService(MS_DB_CRYPT_DECODESTRING
, strlen(str
),(LPARAM
)str
);
184 SetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, str
);
185 SendDlgItemMessage(hwndDlg
, IDC_PASSWORD
, EM_SETLIMITTEXT
, 16, 0);
188 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("Auto"));
189 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("SSL/TLS"));
190 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_ADDSTRING
, 0, (LPARAM
)_T("TCP"));
192 str
= sipe_miranda_getString(pr
, "transport");
193 if (!str
|| !strcmp(str
, "auto"))
194 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("Auto"));
195 else if (!strcmp(str
, "tls"))
196 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("SSL/TLS"));
197 else if (!strcmp(str
, "tcp"))
198 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, CB_SELECTSTRING
, -1, (LPARAM
)_T("TCP"));
200 str
= sipe_miranda_getGlobalString("public_ip");
201 SetDlgItemTextA(hwndDlg
, IDC_PUBLICIP
, str
);
202 SendDlgItemMessage(hwndDlg
, IDC_PUBLICIP
, EM_SETLIMITTEXT
, 20, 0);
205 str
= sipe_miranda_getGlobalString("ipprog");
206 SetDlgItemTextA(hwndDlg
, IDC_IPPROGEXE
, str
);
207 SendDlgItemMessage(hwndDlg
, IDC_IPPROGEXE
, EM_SETLIMITTEXT
, 60, 0);
210 str
= sipe_miranda_get_local_ip();
211 SetDlgItemTextA(hwndDlg
, IDC_IPLOCALFOUND
, str
);
213 sipe_miranda_getGlobalWord("iptype", &iptype
);
214 if (iptype
== SIPE_MIRANDA_IP_LOCAL
)
216 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPLOCAL
);
217 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
218 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
219 } else if (iptype
== SIPE_MIRANDA_IP_MANUAL
) {
220 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPMANUAL
);
221 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, TRUE
);
222 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
224 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPPROG
);
225 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
226 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, TRUE
);
235 int code
= wParam
>> 16;
236 int id
= wParam
& 0xffff;
238 if (LOWORD(wParam
) == IDC_IPLOCAL
)
240 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPLOCAL
);
241 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
242 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
243 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
244 } else if (LOWORD(wParam
) == IDC_IPMANUAL
) {
245 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPMANUAL
);
246 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, TRUE
);
247 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, FALSE
);
248 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
249 } else if (LOWORD(wParam
) == IDC_IPPROG
) {
250 CheckRadioButton(hwndDlg
, IDC_IPLOCAL
, IDC_IPPROG
, IDC_IPPROG
);
251 EnableDlgItem(hwndDlg
, IDC_PUBLICIP
, FALSE
);
252 EnableDlgItem(hwndDlg
, IDC_IPPROGEXE
, TRUE
);
253 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
254 } else if (LOWORD(wParam
) == IDC_USEKRB
) {
255 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
256 } else if (LOWORD(wParam
) == IDC_USESSO
) {
257 if (IsDlgButtonChecked(hwndDlg
, IDC_USESSO
) == BST_CHECKED
)
259 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
260 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
261 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
263 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_MSO
);
264 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
265 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
267 } else if (!lock
&& (code
== EN_CHANGE
|| code
== CBN_SELCHANGE
)) {
268 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
275 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
280 const SIPPROTO
*pr
= (const SIPPROTO
*)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
282 GetDlgItemTextA(hwndDlg
, IDC_HANDLE
, buf
, sizeof(buf
));
283 sipe_miranda_setString(pr
, "username", buf
);
285 GetDlgItemTextA(hwndDlg
, IDC_LOGIN
, buf
, sizeof(buf
));
286 sipe_miranda_setString(pr
, "login", buf
);
288 GetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, buf
, sizeof(buf
));
289 CallService(MS_DB_CRYPT_ENCODESTRING
, sizeof(buf
),(LPARAM
)buf
);
290 sipe_miranda_setString(pr
, "password", buf
);
292 SendDlgItemMessage(hwndDlg
, IDC_CONNTYPE
, WM_GETTEXT
, 100, (LPARAM
)tbuf
);
294 if (!_tcscmp(tbuf
, _T("Auto")))
295 sipe_miranda_setString(pr
, "transport", "auto");
296 else if (!_tcscmp(tbuf
, _T("SSL/TLS")))
297 sipe_miranda_setString(pr
, "transport", "tls");
298 else if (!_tcscmp(tbuf
, _T("TCP")))
299 sipe_miranda_setString(pr
, "transport", "tcp");
301 GetDlgItemTextA(hwndDlg
, IDC_PUBLICIP
, buf
, sizeof(buf
));
302 sipe_miranda_setGlobalString("public_ip", buf
);
304 GetDlgItemTextA(hwndDlg
, IDC_IPPROGEXE
, buf
, sizeof(buf
));
305 sipe_miranda_setGlobalString("ipprog", buf
);
307 if (IsDlgButtonChecked(hwndDlg
, IDC_USEKRB
) == BST_CHECKED
)
309 sipe_miranda_setBool(pr
, "krb5", TRUE
);
311 sipe_miranda_setBool(pr
, "krb5", FALSE
);
314 if (IsDlgButtonChecked(hwndDlg
, IDC_IPLOCAL
) == BST_CHECKED
)
316 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL
);
317 } else if (IsDlgButtonChecked(hwndDlg
, IDC_IPMANUAL
) == BST_CHECKED
) {
318 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_MANUAL
);
320 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_PROG
);
332 INT_PTR CALLBACK
DlgProcAccMgrUI(HWND hwndDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
338 const SIPPROTO
*pr
= (const SIPPROTO
*)lParam
;
342 TranslateDialogDefault(hwndDlg
);
344 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, lParam
);
346 sso
= sipe_miranda_getBool(pr
, "sso", FALSE
);
349 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_SSO
);
350 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
351 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
353 CheckRadioButton(hwndDlg
, IDC_SSO
, IDC_MSO
, IDC_MSO
);
354 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
355 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
358 str
= sipe_miranda_getString(pr
, "username");
359 SetDlgItemTextA(hwndDlg
, IDC_HANDLE
, str
);
362 str
= sipe_miranda_getString(pr
, "login");
363 SetDlgItemTextA(hwndDlg
, IDC_LOGIN
, str
);
366 str
= sipe_miranda_getString(pr
, "password");
367 if (str
) CallService(MS_DB_CRYPT_DECODESTRING
, strlen(str
),(LPARAM
)str
);
368 SetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, str
);
371 SendDlgItemMessage(hwndDlg
, IDC_HANDLE
, EM_SETLIMITTEXT
, 50, 0);
372 SendDlgItemMessage(hwndDlg
, IDC_LOGIN
, EM_SETLIMITTEXT
, 50, 0);
373 SendDlgItemMessage(hwndDlg
, IDC_PASSWORD
, EM_SETLIMITTEXT
, 16, 0);
379 if (LOWORD(wParam
) == IDC_SSO
)
381 EnableDlgItem(hwndDlg
, IDC_LOGIN
, FALSE
);
382 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, FALSE
);
383 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
384 } else if (LOWORD(wParam
) == IDC_MSO
) {
385 EnableDlgItem(hwndDlg
, IDC_LOGIN
, TRUE
);
386 EnableDlgItem(hwndDlg
, IDC_PASSWORD
, TRUE
);
387 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
388 } else if (HIWORD(wParam
) == EN_CHANGE
&& (HWND
)lParam
== GetFocus()) {
389 switch(LOWORD(wParam
))
394 SendMessage(GetParent(hwndDlg
), PSM_CHANGED
, 0, 0);
401 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
405 const SIPPROTO
*pr
= (const SIPPROTO
*)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
407 if (IsDlgButtonChecked(hwndDlg
, IDC_SSO
) == BST_CHECKED
)
409 sipe_miranda_setBool(pr
, "sso", TRUE
);
411 sipe_miranda_setBool(pr
, "sso", FALSE
);
414 GetDlgItemTextA(hwndDlg
, IDC_HANDLE
, buf
, sizeof(buf
));
415 sipe_miranda_setString(pr
, "username", buf
);
417 GetDlgItemTextA(hwndDlg
, IDC_LOGIN
, buf
, sizeof(buf
));
418 sipe_miranda_setString(pr
, "login", buf
);
420 GetDlgItemTextA(hwndDlg
, IDC_PASSWORD
, buf
, sizeof(buf
));
421 CallService(MS_DB_CRYPT_ENCODESTRING
, sizeof(buf
),(LPARAM
)buf
);
422 sipe_miranda_setString(pr
, "password", buf
);
434 * Miranda service support functions
436 * Functions called by our service functions
438 static void fix_contact_groups(SIPPROTO
*pr
)
440 GSList
*contacts
= sipe_miranda_buddy_find_all(pr
, NULL
, NULL
);
443 CONTACTS_FOREACH(contacts
)
444 group
= DBGetString(hContact
, "CList", "Group");
445 sipe_miranda_setContactString(pr
, hContact
, "Group", group
);
451 static INT_PTR
sipe_miranda_start_chat(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
453 HANDLE hContact
= (HANDLE
)wParam
;
454 struct sipe_core_public
*sipe_public
= pr
->sip
;
457 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
459 sipe_core_buddy_new_chat(sipe_public
, dbv
.pszVal
);
461 DBFreeVariant( &dbv
);
468 static void OnModulesLoaded(SIPPROTO
*pr
)
470 TCHAR descr
[MAX_PATH
];
471 NETLIBUSER nlu
= {0};
473 DBEVENTTYPEDESCR eventType
= {0};
475 SIPE_DEBUG_INFO_NOFORMAT("OnEvent::OnModulesLoaded");
477 nlu
.cbSize
= sizeof(nlu
);
478 nlu
.flags
= NUF_OUTGOING
| NUF_INCOMING
| NUF_TCHAR
;
479 nlu
.szSettingsModule
= pr
->proto
.m_szModuleName
;
480 _sntprintf(descr
, SIZEOF(descr
), TranslateT("%s server connection"), pr
->proto
.m_tszUserName
);
481 nlu
.ptszDescriptiveName
= descr
;
483 pr
->m_hServerNetlibUser
= (HANDLE
)CallService(MS_NETLIB_REGISTERUSER
, 0, (LPARAM
)&nlu
);
485 gcr
.cbSize
= sizeof(gcr
);
487 gcr
.pszModule
= pr
->proto
.m_szModuleName
;
488 gcr
.pszModuleDispName
= "Sip/Simple";
492 if (CallService(MS_GC_REGISTER
, 0, (LPARAM
)&gcr
))
494 SIPE_DEBUG_INFO_NOFORMAT("OnEvent::OnModulesLoaded Failed to register chat");
497 // Register custom database events
498 eventType
.cbSize
= DBEVENTTYPEDESCR_SIZE
;
499 eventType
.module
= pr
->proto
.m_szModuleName
;
500 eventType
.eventType
= SIPE_EVENTTYPE_ERROR_NOTIFY
;
501 eventType
.descr
= "Message error notification";
502 eventType
.textService
= SIPE_DB_GETEVENTTEXT_ERROR_NOTIFY
;
503 eventType
.flags
= DETF_HISTORY
| DETF_MSGWINDOW
;
504 // for now keep default "message" icon
505 CallService(MS_DB_EVENT_REGISTERTYPE
, 0, (LPARAM
)&eventType
);
507 eventType
.cbSize
= DBEVENTTYPEDESCR_SIZE
;
508 eventType
.module
= pr
->proto
.m_szModuleName
;
509 eventType
.eventType
= SIPE_EVENTTYPE_INFO_NOTIFY
;
510 eventType
.descr
= "Message info notification";
511 eventType
.textService
= SIPE_DB_GETEVENTTEXT_INFO_NOTIFY
;
512 eventType
.flags
= DETF_HISTORY
| DETF_MSGWINDOW
;
513 // for now keep default "message" icon
514 CallService(MS_DB_EVENT_REGISTERTYPE
, 0, (LPARAM
)&eventType
);
516 eventType
.cbSize
= DBEVENTTYPEDESCR_SIZE
;
517 eventType
.module
= pr
->proto
.m_szModuleName
;
518 eventType
.eventType
= SIPE_EVENTTYPE_IM_TOPIC
;
519 eventType
.descr
= "Chat topic set";
520 eventType
.textService
= SIPE_DB_GETEVENTTEXT_IM_TOPIC
;
521 eventType
.flags
= DETF_HISTORY
| DETF_MSGWINDOW
;
522 // for now keep default "message" icon
523 CallService(MS_DB_EVENT_REGISTERTYPE
, 0, (LPARAM
)&eventType
);
527 int OnOptionsInit(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
529 OPTIONSDIALOGPAGE odp
= {0};
530 HMODULE hUxTheme
= 0;
532 if (IsWinVerXPPlus())
534 hUxTheme
= GetModuleHandleA("uxtheme.dll");
536 pfnEnableThemeDialogTexture
= (BOOL (WINAPI
*)(HANDLE
, DWORD
))GetProcAddress(hUxTheme
, "EnableThemeDialogTexture");
539 odp
.cbSize
= sizeof(odp
);
540 odp
.position
= -800000000;
541 odp
.hInstance
= hInst
;
542 odp
.ptszGroup
= LPGENT("Network");
543 odp
.dwInitParam
= (LPARAM
)pr
;
544 odp
.ptszTitle
= pr
->proto
.m_tszUserName
;
545 odp
.flags
= ODPF_BOLDGROUPS
| ODPF_TCHAR
;
547 odp
.ptszTab
= LPGENT("Account");
548 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_SIPSIMPLE
);
549 odp
.pfnDlgProc
= DlgProcSipSimpleOpts
;
550 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
552 odp
.ptszTab
= LPGENT("About");
553 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_SIPSIMPLE_ABOUT
);
554 odp
.pfnDlgProc
= DlgProcSipSimpleOptsAbout
;
555 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
559 odp
.ptszTab
= LPGENT("Features");
560 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_ICQFEATURES
);
561 odp
.pfnDlgProc
= DlgProcIcqFeaturesOpts
;
562 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
564 odp
.ptszTab
= LPGENT("Privacy");
565 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_ICQPRIVACY
);
566 odp
.pfnDlgProc
= DlgProcIcqPrivacyOpts
;
567 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
571 odp
.position
= 100000000;
572 odp
.pszTemplate
= MAKEINTRESOURCEA(IDD_OPT_POPUPS
);
573 odp
.groupPosition
= 900000000;
574 odp
.pfnDlgProc
= DlgProcIcqPopupOpts
;
575 odp
.ptszGroup
= LPGENT("Popups");
577 CallService( MS_OPT_ADDPAGE
, wParam
, ( LPARAM
)&odp
);
583 void sipe_miranda_close(SIPPROTO
*pr
)
585 struct sipe_core_public
*sipe_public
= pr
->sip
;
589 sipe_core_deallocate(sipe_public
);
593 // sipe_purple_chat_destroy_rejoin(purple_private);
594 // g_free(purple_private);
598 void set_buddies_offline(const SIPPROTO
* pr
)
602 hContact
= (HANDLE
)CallService(MS_DB_CONTACT_FINDFIRST
, 0, 0);
604 char* szProto
= (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO
, (WPARAM
)hContact
, 0);
605 if (szProto
!= NULL
&& !lstrcmpA(szProto
, pr
->proto
.m_szModuleName
)) {
606 if (DBGetContactSettingByte(hContact
, pr
->proto
.m_szModuleName
, "ChatRoom", 0) == 0)
607 DBWriteContactSettingWord(hContact
, pr
->proto
.m_szModuleName
, "Status", ID_STATUS_OFFLINE
);
609 hContact
= (HANDLE
)CallService(MS_DB_CONTACT_FINDNEXT
, (WPARAM
)hContact
, 0);
613 int __stdcall
show_vlc(void *data
);
614 void sipe_miranda_login(SIPPROTO
*pr
) {
615 gchar
*username
= sipe_miranda_getString(pr
, "username");
616 gchar
*login
= sipe_miranda_getString(pr
, "login");
617 gchar
*email
= sipe_miranda_getString(pr
, "email");
618 gchar
*email_url
= sipe_miranda_getString(pr
, "email_url");
619 gchar
**domain_user
= g_strsplit_set(login
, "/\\", 2);
622 gchar
*tmp
= (char*)mir_calloc(1024);
625 guint authentication_type
;
626 struct sipe_core_public
*sipe_public
;
628 // CloseHandle((HANDLE) mir_forkthreadex(show_vlc, NULL, 65536, NULL));
630 if (sipe_miranda_getStaticString(pr
, NULL
, "password", tmp
, 1024 )) tmp
[0] = '\0';
631 CallService(MS_DB_CRYPT_DECODESTRING
, sizeof(tmp
),(LPARAM
)tmp
);
632 password
= g_strdup(tmp
);
636 pr
->sip
= sipe_core_allocate(username
,
637 domain_user
[0], domain_user
[0] != NULL
? domain_user
[1] : "",
642 if (pr
->sip
) pr
->sip
->backend_private
= pr
;
643 sipe_public
= pr
->sip
;
650 g_strfreev(domain_user
);
654 sipe_miranda_connection_error_reason(pr
,
655 SIPE_CONNECTION_ERROR_INVALID_USERNAME
,
660 //sipe_miranda_chat_setup_rejoin(pr);
662 /* default is NTLM */
663 authentication_type
= SIPE_AUTHENTICATION_TYPE_NTLM
;
665 if (sipe_miranda_getBool(pr
, "krb5", FALSE
))
666 authentication_type
= SIPE_AUTHENTICATION_TYPE_KERBEROS
;
668 /* TODO: configuration option for TLS-DSK? */
670 // /* @TODO: is this correct?
671 // "sso" is only available when Kerberos support is compiled in */
672 if (sipe_miranda_getBool(pr
, "sso", FALSE
))
673 SIPE_CORE_FLAG_SET(SSO
);
675 /* Set display name */
676 sipe_miranda_setStringUtf(pr
, "Nick", pr
->sip
->sip_name
);
678 /* Update connection progress */
679 tmpstatus
= pr
->proto
.m_iStatus
;
680 pr
->proto
.m_iStatus
= ID_STATUS_CONNECTING
;
681 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_STATUS
, ACKRESULT_SUCCESS
, (HANDLE
)tmpstatus
, ID_STATUS_CONNECTING
);
683 tmp
= sipe_miranda_getString(pr
, "transport");
684 if (sipe_strequal(tmp
, "auto")) {
685 ttype
= SIPE_TRANSPORT_AUTO
;
686 } else if (sipe_strequal(tmp
, "tls")) {
687 ttype
= SIPE_TRANSPORT_TLS
;
689 ttype
= SIPE_TRANSPORT_TCP
;
694 sipe_core_transport_sip_connect(pr
->sip
,
702 void sipsimple_search_contact_cb( GList
*columns
, GList
*results
, GHashTable
*opts
, void *data
)
704 SIPPROTO
*pr
= (SIPPROTO
*)data
;
706 HANDLE hProcess
= g_hash_table_lookup(opts
, "searchid");
707 PROTOSEARCHRESULT psr
= { 0 };
709 psr
.cbSize
= sizeof(psr
);
716 col
= (GList
*)row
->data
;
717 psr
.id
= (PROTOCHAR
*)col
->data
;
719 col
= g_list_next(col
);
720 name
= g_strsplit_set(col
->data
, ",", 2);
721 psr
.nick
= (FNAMECHAR
*)col
->data
;
722 psr
.firstName
= (PROTOCHAR
*)(name
[0] ? name
[1] : NULL
);
723 psr
.lastName
= (PROTOCHAR
*)name
[0];
725 col
= g_list_next(col
);
728 col
= g_list_next(col
);
731 col
= g_list_next(col
);
732 psr
.email
= (PROTOCHAR
*)col
->data
;
734 row
= g_list_next(row
);
735 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_SEARCH
, ACKRESULT_DATA
, hProcess
, (LPARAM
) & psr
);
739 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_SEARCH
, ACKRESULT_SUCCESS
, hProcess
, 0);
743 static int OnGroupChange(SIPPROTO
*pr
, WPARAM w
, LPARAM l
)
745 CLISTGROUPCHANGE
*gi
= (CLISTGROUPCHANGE
*)l
;
746 HANDLE hContact
= (HANDLE
)w
;
749 /* No contact => it's a group add/rename/remove */
752 gchar
*oldname
, *newname
;
754 /* No old name => add */
759 /* No new name => delete */
760 else if (!gi
->pszNewName
)
762 SIPE_DEBUG_INFO("Removing group <%ls>", gi
->pszOldName
);
763 oldname
= mir_t2a(gi
->pszOldName
);
765 sipe_core_group_remove(pr
->sip
, oldname
);
771 SIPE_DEBUG_INFO("Renaming group <%S> to <%S>", gi
->pszOldName
, gi
->pszNewName
);
772 oldname
= mir_t2a(gi
->pszOldName
);
773 newname
= mir_t2a(gi
->pszNewName
);
775 sipe_core_group_rename(pr
->sip
, oldname
, newname
);
782 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
784 gchar
*who
= g_strdup(dbv
.pszVal
);
785 DBFreeVariant( &dbv
);
787 if (oldgroup
= sipe_miranda_getContactString(pr
, hContact
, "Group"))
789 SIPE_DEBUG_INFO("Moving buddy <%s> from group <%ls> to group <%ls>", who
, oldgroup
, gi
->pszNewName
);
791 sipe_core_buddy_group(pr
->sip
, who
, oldgroup
, TCHAR2CHAR(gi
->pszNewName
));
795 gchar
*name
= mir_t2a(gi
->pszNewName
);
797 if (!g_str_has_prefix(name
, "sip:")) {
798 gchar
*newname
= sip_uri_from_name(name
);
800 name
= mir_strdup(newname
);
804 SIPE_DEBUG_INFO("Really adding buddy <%s> to list in group <%s>", who
, name
);
806 sipe_core_buddy_add(pr
->sip
, who
, name
);
817 static int sipe_miranda_build_chat_menu(SIPPROTO
*pr
, WPARAM w
, LPARAM lParam
)
819 GCMENUITEMS
*gcmi
= (GCMENUITEMS
*) lParam
;
821 if (gcmi
->Type
== MENU_ON_NICKLIST
)
823 static struct gc_item Item
[] = {
824 {"&Make Leader", 1, MENU_ITEM
, FALSE
},
827 gcmi
->nItems
= sizeof(Item
)/sizeof(Item
[0]);
828 gcmi
->Item
= &Item
[0];
834 static int OnChatEvent(SIPPROTO
*pr
, WPARAM w
, LPARAM l
)
836 GCHOOK
*hook
= (GCHOOK
*)l
;
837 GCDEST
*dst
= hook
->pDest
;
839 if (dst
->iType
== GC_USER_MESSAGE
) {
842 struct sipe_chat_session
*session
;
844 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
845 gcd
.pszID
= dst
->pszID
;
846 gcd
.iType
= GC_EVENT_GETITEMDATA
;
848 gce
.cbSize
= sizeof(gce
);
852 if ((session
= (struct sipe_chat_session
*)CallService( MS_GC_EVENT
, 0, (LPARAM
)&gce
)) == NULL
)
854 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
859 sipe_core_chat_send(pr
->sip
, session
, hook
->pszText
);
863 } else if (dst
->iType
== GC_USER_PRIVMESS
) {
864 } else if (dst
->iType
== GC_USER_NICKLISTMENU
) {
865 if (hook
->dwData
== 1)
867 SIPE_DEBUG_INFO("make leader <%s>", hook
->pszUID
);
874 int OnPreBuildContactMenu(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
876 HANDLE hContact
= (HANDLE
)wParam
;
877 int chatcount
= CallService(MS_GC_GETSESSIONCOUNT
, 0, (LPARAM
)pr
->proto
.m_szModuleName
);
879 CLISTMENUITEM mi
= {0};
883 mi
.cbSize
= sizeof(mi
);
884 gci
.pszModule
= pr
->proto
.m_szModuleName
;
886 /* Remove the old list */
887 while (pr
->contactMenuChatItems
)
889 SIPE_DEBUG_INFO("Removing old menuitem <%08x>", pr
->contactMenuChatItems
->data
);
890 CallService(MS_CLIST_REMOVECONTACTMENUITEM
, (WPARAM
)pr
->contactMenuChatItems
->data
, 0);
891 pr
->contactMenuChatItems
= g_slist_remove(pr
->contactMenuChatItems
, pr
->contactMenuChatItems
->data
);
894 /* Add the main entry */
895 mi
.pszName
= "Invite to chat";
896 mi
.flags
= CMIF_NOTOFFLINE
;
898 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
899 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
901 mi
.pszName
= "New chat";
902 mi
.hParentMenu
= pr
->contactMenuChatItems
->data
;
903 mi
.flags
= CMIF_ROOTHANDLE
;
904 mi
.popupPosition
= 0;
906 mi
.pszService
= g_strdup_printf("%s/StartChat", pr
->proto
.m_szModuleName
);
907 mi
.pszContactOwner
= pr
->proto
.m_szModuleName
;
908 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
909 g_free(mi
.pszService
);
910 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
912 for (idx
=0 ; idx
<chatcount
; idx
++)
914 SIPE_DEBUG_INFO("Chat <%d> Menuitem <%08x>", idx
, pr
->contactMenuChatItems
);
916 gci
.Flags
= BYINDEX
| NAME
| ID
;
917 if(!CallServiceSync( MS_GC_GETINFO
, 0, (LPARAM
)&gci
)) {
918 SIPE_DEBUG_INFO("Chat <%s>", gci
.pszName
);
920 mi
.pszName
= gci
.pszName
;
921 mi
.hParentMenu
= pr
->contactMenuChatItems
->data
;
922 mi
.flags
= CMIF_ROOTHANDLE
;
923 mi
.popupPosition
= g_strdup(gci
.pszID
);
925 mi
.pszService
= g_strdup_printf("%s/InviteToChat", pr
->proto
.m_szModuleName
);
926 mi
.pszContactOwner
= pr
->proto
.m_szModuleName
;
927 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
928 g_free(mi
.pszService
);
929 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
936 INT_PTR
SvcCreateAccMgrUI(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
938 return (INT_PTR
)CreateDialogParam(hInst
, MAKEINTRESOURCE(IDD_ACCMGRUI
), (HWND
)lParam
, DlgProcAccMgrUI
, (LPARAM
)pr
);
943 * Miranda service functions
945 * The functions in our plugin that get called directly by core Miranda
947 static DWORD_PTR
GetCaps( SIPPROTO
*pr
, int type
, HANDLE hContact
)
951 return PF1_IM
| PF1_CHAT
| PF1_FILE
| PF1_MODEMSG
952 | PF1_SERVERCLIST
| PF1_ADDED
953 | PF1_BASICSEARCH
| PF1_ADDSEARCHRES
954 | PF1_SEARCHBYEMAIL
| PF1_USERIDISEMAIL
955 | PF1_SEARCHBYNAME
| PF1_EXTSEARCH
959 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
960 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
961 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
964 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
965 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
966 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
969 return PF4_NOCUSTOMAUTH
| PF4_IMSENDUTF
| PF4_SUPPORTTYPING
975 case PFLAG_UNIQUEIDSETTING
:
976 return (DWORD_PTR
) SIP_UNIQUEID
;
979 SIPE_DEBUG_INFO("GetCaps: unknown type <%x>", type
);
986 static HICON
GetIcon( SIPPROTO
*pr
, int iconIndex
)
988 SIPE_DEBUG_INFO("GetIcon: unknown index <%x>", iconIndex
);
992 static int OnEvent( SIPPROTO
*pr
, PROTOEVENTTYPE eventType
, WPARAM wParam
, LPARAM lParam
)
994 SIPE_DEBUG_INFO("OnEvent: type <%x>", eventType
);
998 case EV_PROTO_ONLOAD
:
1002 case EV_PROTO_ONREADYTOEXIT
:
1005 case EV_PROTO_ONEXIT
:
1008 case EV_PROTO_ONRENAME
:
1011 case EV_PROTO_ONOPTIONS
:
1012 return OnOptionsInit( pr
, wParam
, lParam
);
1015 case EV_PROTO_ONERASE
:
1023 static HANDLE
AddToListByEvent( SIPPROTO
*pr
, int flags
, int iContact
, HANDLE hDbEvent
)
1025 DBEVENTINFO dbei
= {0};
1027 dbei
.cbSize
= sizeof(dbei
);
1028 if ((dbei
.cbBlob
= CallService(MS_DB_EVENT_GETBLOBSIZE
, (WPARAM
)hDbEvent
, 0)) == -1)
1031 dbei
.pBlob
= (PBYTE
)_alloca(dbei
.cbBlob
+ 1);
1032 dbei
.pBlob
[dbei
.cbBlob
] = '\0';
1034 if (CallService(MS_DB_EVENT_GET
, (WPARAM
)hDbEvent
, (LPARAM
)&dbei
))
1035 return 0; // failed to get event
1037 if (strcmp(dbei
.szModule
, pr
->proto
.m_szModuleName
))
1038 return 0; // this event is not ours
1041 SIPE_DEBUG_INFO("AddToListByEvent: flags <%x> iContact <%x>", flags
, iContact
);
1045 static int Authorize( SIPPROTO
*pr
, HANDLE hContact
)
1048 SIPE_DEBUG_INFO_NOFORMAT("Authorize");
1052 static int AuthDeny( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szReason
)
1055 SIPE_DEBUG_INFO("AuthDeny: reason <%s>", szReason
);
1059 static int AuthRecv( SIPPROTO
*pr
, HANDLE hContact
, PROTORECVEVENT
* evt
)
1062 SIPE_DEBUG_INFO_NOFORMAT("AuthRecv");
1066 static int AuthRequest( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szMessage
)
1069 SIPE_DEBUG_INFO("AuthRequest: message <%s>", szMessage
);
1073 static HANDLE
ChangeInfo( SIPPROTO
*pr
, int iInfoType
, void* pInfoData
)
1076 SIPE_DEBUG_INFO("ChangeInfo: infotype <%x>", iInfoType
);
1080 static int FileCancel( SIPPROTO
*pr
, HANDLE hContact
, HANDLE hTransfer
)
1083 SIPE_DEBUG_INFO_NOFORMAT("FileCancel");
1087 static int FileResume( SIPPROTO
*pr
, HANDLE hTransfer
, int* action
, const PROTOCHAR
** szFilename
)
1090 SIPE_DEBUG_INFO("FileResume: action <%x>", action
);
1094 static HANDLE
SearchBasic( SIPPROTO
*pr
, const PROTOCHAR
* id
)
1099 static HWND
CreateExtendedSearchUI( SIPPROTO
*pr
, HWND owner
)
1101 return CreateDialogParam(hInst
, MAKEINTRESOURCE(IDD_SEARCHUI
), (HWND
)owner
, NULL
, (LPARAM
)pr
);
1104 static HANDLE
AddToList( SIPPROTO
*pr
, int flags
, PROTOSEARCHRESULT
* psr
)
1107 gchar
*id
= g_strdup(TCHAR2CHAR(psr
->id
));
1109 /* Prepend sip: if needed */
1110 if (strncmp("sip:", id
, 4)) {
1112 id
= sip_uri_from_name(tmp
);
1116 hContact
= sipe_miranda_buddy_find(pr
, id
, NULL
);
1122 hContact
= ( HANDLE
)CallService( MS_DB_CONTACT_ADD
, 0, 0 );
1123 CallService( MS_PROTO_ADDTOCONTACT
, (WPARAM
)hContact
, (LPARAM
)pr
->proto
.m_szModuleName
);
1124 sipe_miranda_setContactString( pr
, hContact
, SIP_UNIQUEID
, id
); // name
1128 gchar
*tmp
= mir_t2a(psr
->nick
);
1129 sipe_miranda_setContactStringUtf( pr
, hContact
, "Nick", tmp
);
1138 sipe_miranda_window_closed(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1140 MessageWindowEventData
* evt
= (MessageWindowEventData
*)lParam
;
1142 SIPE_DEBUG_INFO("contact <%08x> module <%s> type <%02x> flags <%02x>",
1143 evt
->hContact
, evt
->szModule
, evt
->uType
, evt
->uFlags
);
1149 sipe_miranda_invite_to_chat(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1151 HANDLE hContact
= (HANDLE
)wParam
;
1152 gchar
*id
= (gchar
*)lParam
;
1155 struct sipe_chat_session
*session
;
1158 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
1160 gcd
.iType
= GC_EVENT_GETITEMDATA
;
1162 gce
.cbSize
= sizeof(gce
);
1165 if ((session
= (struct sipe_chat_session
*)CallService( MS_GC_EVENT
, 0, (LPARAM
)&gce
)) == NULL
)
1167 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
1171 uid
= sipe_miranda_getContactString(pr
, hContact
, SIP_UNIQUEID
);
1172 sipe_core_chat_invite(pr
->sip
, session
, uid
);
1180 * Main Miranda interface
1182 * The structures and functions that allow Miranda to recovnize and load
1186 /* Plugin information structure */
1187 PLUGININFOEX pluginInfo
= {
1188 sizeof(PLUGININFOEX
),
1189 "Office Communicator Protocol",
1190 PLUGIN_MAKE_VERSION(0,11,2,1),
1191 "Support for Microsoft Office Communicator",
1192 "Miranda support by Jochen De Smet, for core sipe support see homepage",
1193 "jochen.libsipe@leahnim.org",
1195 "https://sourceforge.net/projects/sipe",
1197 0, //doesn't replace anything built-in
1198 #if defined( _UNICODE )
1199 { 0x842395ed, 0x4e56, 0x40e5, { 0x94, 0x25, 0x28, 0x29, 0xd8, 0xab, 0xae, 0xa5 } } // {842395ED-4E56-40e5-9425-2829D8ABAEA5}
1201 { 0x1ef8af37, 0xdec1, 0x4757, { 0x89, 0x78, 0xe8, 0xad, 0xd0, 0xd8, 0x6e, 0x7f } } // {1EF8AF37-DEC1-4757-8978-E8ADD0D86E7F}
1205 __declspec(dllexport
) PLUGININFOEX
*MirandaPluginInfoEx(DWORD mirandaVersion
)
1207 // Only load for 0.8.0.29 or greater
1208 // We need the core stubs for PS_GETNAME and PS_GETSTATUS
1209 if (mirandaVersion
< PLUGIN_MAKE_VERSION(0, 9, 0, 0))
1213 "SIP/Simple plugin cannot be loaded. It requires Miranda IM 0.9.0.0 or later.",
1214 "SIP/Simple Plugin",
1215 MB_OK
| MB_ICONWARNING
| MB_SETFOREGROUND
| MB_TOPMOST
1223 static const MUUID interfaces
[] = {MIID_PROTOCOL
, MIID_LAST
};
1224 __declspec(dllexport
) const MUUID
* MirandaPluginInterfaces(void)
1229 static PROTO_INTERFACE
* sipsimpleProtoInit( const char* pszProtoName
, const TCHAR
* tszUserName
)
1232 SIPPROTO
*pr
= (SIPPROTO
*)mir_calloc(sizeof(SIPPROTO
));
1233 pr
->proto
.vtbl
= (PROTO_INTERFACE_VTBL
*)mir_calloc(sizeof(PROTO_INTERFACE_VTBL
));
1235 SIPE_DEBUG_INFO("protoname <%s> username <%ls>", pszProtoName
, tszUserName
);
1237 if (!InitializeCriticalSectionAndSpinCount(&pr
->CriticalSection
, 0))
1239 SIPE_DEBUG_ERROR_NOFORMAT("Can't initialize critical section");
1243 tmp
= sipe_miranda_getString(pr
, "transport");
1246 sipe_miranda_setString(pr
, "transport", "auto");
1251 /* To make it easy to detect when a SIPPROTO* isn't a SIPPROTO* */
1252 strncpy(pr
->_SIGNATURE
, "AbandonAllHope..", sizeof(pr
->_SIGNATURE
));
1254 pr
->main_thread_id
= GetCurrentThreadId();
1255 pr
->proto
.m_iVersion
= 2;
1256 pr
->proto
.m_szModuleName
= mir_strdup(pszProtoName
);
1257 pr
->proto
.m_tszUserName
= mir_tstrdup(tszUserName
);
1258 pr
->proto
.m_szProtoName
= mir_strdup(pszProtoName
);
1260 // set_buddies_offline(pr);
1261 fix_contact_groups(pr
);
1263 /* Fill the function table */
1264 pr
->proto
.vtbl
->AddToList
= AddToList
;
1265 pr
->proto
.vtbl
->AddToListByEvent
= AddToListByEvent
;
1267 pr
->proto
.vtbl
->Authorize
= Authorize
;
1268 pr
->proto
.vtbl
->AuthDeny
= AuthDeny
;
1269 pr
->proto
.vtbl
->AuthRecv
= AuthRecv
;
1270 pr
->proto
.vtbl
->AuthRequest
= AuthRequest
;
1272 pr
->proto
.vtbl
->ChangeInfo
= ChangeInfo
;
1274 pr
->proto
.vtbl
->FileAllow
= sipe_miranda_FileAllow
;
1275 pr
->proto
.vtbl
->FileCancel
= FileCancel
;
1276 pr
->proto
.vtbl
->FileDeny
= sipe_miranda_FileDeny
;
1277 pr
->proto
.vtbl
->FileResume
= FileResume
;
1279 pr
->proto
.vtbl
->GetCaps
= GetCaps
;
1280 pr
->proto
.vtbl
->GetIcon
= GetIcon
;
1281 pr
->proto
.vtbl
->GetInfo
= sipe_miranda_GetInfo
;
1283 pr
->proto
.vtbl
->SearchBasic
= SearchBasic
;
1284 pr
->proto
.vtbl
->SearchByEmail
= sipe_miranda_SearchByEmail
;
1285 pr
->proto
.vtbl
->SearchByName
= sipe_miranda_SearchByName
;
1286 pr
->proto
.vtbl
->SearchAdvanced
= sipe_miranda_SearchAdvanced
;
1287 pr
->proto
.vtbl
->CreateExtendedSearchUI
= CreateExtendedSearchUI
;
1289 pr
->proto
.vtbl
->RecvMsg
= sipe_miranda_RecvMsg
;
1291 pr
->proto
.vtbl
->SendMsg
= sipe_miranda_SendMsg
;
1293 pr
->proto
.vtbl
->SetStatus
= sipe_miranda_SetStatus
;
1295 pr
->proto
.vtbl
->GetAwayMsg
= sipe_miranda_GetAwayMsg
;
1296 pr
->proto
.vtbl
->SetAwayMsg
= sipe_miranda_SetAwayMsg
;
1298 pr
->proto
.vtbl
->UserIsTyping
= sipe_miranda_UserIsTyping
;
1300 pr
->proto
.vtbl
->SendFile
= sipe_miranda_SendFile
;
1301 pr
->proto
.vtbl
->RecvFile
= sipe_miranda_RecvFile
;
1303 pr
->proto
.vtbl
->OnEvent
= OnEvent
;
1305 /* Setup services */
1306 CreateProtoService(pr
, PS_CREATEACCMGRUI
, &SvcCreateAccMgrUI
);
1307 CreateProtoService(pr
, "/InviteToChat", &sipe_miranda_invite_to_chat
);
1308 CreateProtoService(pr
, "/StartChat",&sipe_miranda_start_chat
);
1310 #define HOOKEVENT(evt,func) HookEventObj(evt, func, pr)
1311 HOOKEVENT(ME_OPT_INITIALISE
, &OnOptionsInit
);
1312 HOOKEVENT(ME_CLIST_GROUPCHANGE
, &OnGroupChange
);
1313 HOOKEVENT(ME_GC_EVENT
, &OnChatEvent
);
1314 HOOKEVENT(ME_CLIST_PREBUILDCONTACTMENU
, &OnPreBuildContactMenu
);
1315 HOOKEVENT(ME_DB_CONTACT_DELETED
, &sipe_miranda_buddy_delete
);
1316 HOOKEVENT(ME_MSG_WINDOWEVENT
, &sipe_miranda_window_closed
);
1317 HOOKEVENT(ME_GC_BUILDMENU
, &sipe_miranda_build_chat_menu
);
1319 return (PROTO_INTERFACE
*)pr
;
1322 static int sipsimpleProtoUninit( PROTO_INTERFACE
* _pr
)
1324 SIPPROTO
*pr
= (SIPPROTO
*)_pr
;
1326 DeleteCriticalSection(&pr
->CriticalSection
);
1328 Netlib_CloseHandle(pr
->m_hServerNetlibUser
);
1329 mir_free(pr
->proto
.m_szProtoName
);
1330 mir_free(pr
->proto
.m_szModuleName
);
1331 mir_free(pr
->proto
.m_tszUserName
);
1332 mir_free(pr
->proto
.vtbl
);
1338 __declspec(dllexport
) int Load(PLUGINLINK
*link
)
1340 PROTOCOLDESCRIPTOR pd
= {0};
1341 NETLIBUSER nlu
= {0};
1351 /* Register the module */
1352 pd
.cbSize
= sizeof(pd
);
1353 pd
.szName
= SIPSIMPLE_PROTOCOL_NAME
;
1354 pd
.type
= PROTOTYPE_PROTOCOL
;
1355 pd
.fnInit
= sipsimpleProtoInit
;
1356 pd
.fnUninit
= sipsimpleProtoUninit
;
1357 CallService(MS_PROTO_REGISTERMODULE
, 0, (LPARAM
)&pd
);
1359 /* Protocolwide netlib user for incoming connections (also abused for logging) */
1360 nlu
.cbSize
= sizeof(nlu
);
1361 nlu
.flags
= NUF_INCOMING
| NUF_TCHAR
| NUF_NOOPTIONS
;
1362 nlu
.szSettingsModule
= SIPSIMPLE_PROTOCOL_NAME
;
1363 nlu
.minIncomingPorts
= 10;
1365 InitializeCriticalSectionAndSpinCount(&sipe_miranda_debug_CriticalSection
, 0);
1366 sipe_miranda_incoming_netlibuser
= (HANDLE
)CallService(MS_NETLIB_REGISTERUSER
, 0, (LPARAM
)&nlu
);
1368 tmp
= sipe_miranda_getGlobalString("public_ip");
1370 sipe_miranda_setGlobalString("public_ip", "0.0.0.0");
1375 if (!sipe_miranda_getGlobalWord("iptype", &iptype
))
1377 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL
);
1383 __declspec(dllexport
) int Unload(void)
1385 Netlib_CloseHandle(sipe_miranda_incoming_netlibuser
);
1386 sipe_miranda_incoming_netlibuser
= NULL
;
1387 DeleteCriticalSection(&sipe_miranda_debug_CriticalSection
);
1388 sipe_core_destroy();
1392 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
,DWORD fdwReason
,LPVOID lpvReserved
)