2 * @file miranda-plugin.c
6 * Copyright (C) 2010-11 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 struct sipe_core_public
*sipe_public
;
627 // CloseHandle((HANDLE) mir_forkthreadex(show_vlc, NULL, 65536, NULL));
629 if (sipe_miranda_getStaticString(pr
, NULL
, "password", tmp
, 1024 )) tmp
[0] = '\0';
630 CallService(MS_DB_CRYPT_DECODESTRING
, sizeof(tmp
),(LPARAM
)tmp
);
631 password
= g_strdup(tmp
);
635 pr
->sip
= sipe_core_allocate(username
,
636 domain_user
[0], domain_user
[0] != NULL
? domain_user
[1] : "",
641 if (pr
->sip
) pr
->sip
->backend_private
= pr
;
642 sipe_public
= pr
->sip
;
649 g_strfreev(domain_user
);
653 sipe_miranda_connection_error_reason(pr
,
654 SIPE_CONNECTION_ERROR_INVALID_USERNAME
,
659 //sipe_miranda_chat_setup_rejoin(pr);
662 if (sipe_miranda_getBool(pr
, "krb5", FALSE
))
663 SIPE_CORE_FLAG_SET(KRB5
);
665 // /* @TODO: is this correct?
666 // "sso" is only available when Kerberos support is compiled in */
667 if (sipe_miranda_getBool(pr
, "sso", FALSE
))
668 SIPE_CORE_FLAG_SET(SSO
);
670 /* Set display name */
671 sipe_miranda_setStringUtf(pr
, "Nick", pr
->sip
->sip_name
);
673 /* Update connection progress */
674 tmpstatus
= pr
->proto
.m_iStatus
;
675 pr
->proto
.m_iStatus
= ID_STATUS_CONNECTING
;
676 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_STATUS
, ACKRESULT_SUCCESS
, (HANDLE
)tmpstatus
, ID_STATUS_CONNECTING
);
678 tmp
= sipe_miranda_getString(pr
, "transport");
679 if (sipe_strequal(tmp
, "auto")) {
680 ttype
= SIPE_TRANSPORT_AUTO
;
681 } else if (sipe_strequal(tmp
, "tls")) {
682 ttype
= SIPE_TRANSPORT_TLS
;
684 ttype
= SIPE_TRANSPORT_TCP
;
689 sipe_core_transport_sip_connect(pr
->sip
,
696 void sipsimple_search_contact_cb( GList
*columns
, GList
*results
, GHashTable
*opts
, void *data
)
698 SIPPROTO
*pr
= (SIPPROTO
*)data
;
700 HANDLE hProcess
= g_hash_table_lookup(opts
, "searchid");
701 PROTOSEARCHRESULT psr
= { 0 };
703 psr
.cbSize
= sizeof(psr
);
710 col
= (GList
*)row
->data
;
711 psr
.id
= (PROTOCHAR
*)col
->data
;
713 col
= g_list_next(col
);
714 name
= g_strsplit_set(col
->data
, ",", 2);
715 psr
.nick
= (FNAMECHAR
*)col
->data
;
716 psr
.firstName
= (PROTOCHAR
*)(name
[0] ? name
[1] : NULL
);
717 psr
.lastName
= (PROTOCHAR
*)name
[0];
719 col
= g_list_next(col
);
722 col
= g_list_next(col
);
725 col
= g_list_next(col
);
726 psr
.email
= (PROTOCHAR
*)col
->data
;
728 row
= g_list_next(row
);
729 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_SEARCH
, ACKRESULT_DATA
, hProcess
, (LPARAM
) & psr
);
733 sipe_miranda_SendBroadcast(pr
, NULL
, ACKTYPE_SEARCH
, ACKRESULT_SUCCESS
, hProcess
, 0);
737 static int OnGroupChange(SIPPROTO
*pr
, WPARAM w
, LPARAM l
)
739 CLISTGROUPCHANGE
*gi
= (CLISTGROUPCHANGE
*)l
;
740 HANDLE hContact
= (HANDLE
)w
;
743 /* No contact => it's a group add/rename/remove */
746 gchar
*oldname
, *newname
;
748 /* No old name => add */
753 /* No new name => delete */
754 else if (!gi
->pszNewName
)
756 SIPE_DEBUG_INFO("Removing group <%ls>", gi
->pszOldName
);
757 oldname
= mir_t2a(gi
->pszOldName
);
759 sipe_core_group_remove(pr
->sip
, oldname
);
765 SIPE_DEBUG_INFO("Renaming group <%S> to <%S>", gi
->pszOldName
, gi
->pszNewName
);
766 oldname
= mir_t2a(gi
->pszOldName
);
767 newname
= mir_t2a(gi
->pszNewName
);
769 sipe_core_group_rename(pr
->sip
, oldname
, newname
);
776 if ( !DBGetContactSettingString( hContact
, pr
->proto
.m_szModuleName
, SIP_UNIQUEID
, &dbv
)) {
778 gchar
*who
= g_strdup(dbv
.pszVal
);
779 DBFreeVariant( &dbv
);
781 if (oldgroup
= sipe_miranda_getContactString(pr
, hContact
, "Group"))
783 SIPE_DEBUG_INFO("Moving buddy <%s> from group <%ls> to group <%ls>", who
, oldgroup
, gi
->pszNewName
);
785 sipe_core_buddy_group(pr
->sip
, who
, oldgroup
, TCHAR2CHAR(gi
->pszNewName
));
789 gchar
*name
= mir_t2a(gi
->pszNewName
);
791 if (!g_str_has_prefix(name
, "sip:")) {
792 gchar
*newname
= sip_uri_from_name(name
);
794 name
= mir_strdup(newname
);
798 SIPE_DEBUG_INFO("Really adding buddy <%s> to list in group <%s>", who
, name
);
800 sipe_core_buddy_add(pr
->sip
, who
, name
);
811 static int sipe_miranda_build_chat_menu(SIPPROTO
*pr
, WPARAM w
, LPARAM lParam
)
813 GCMENUITEMS
*gcmi
= (GCMENUITEMS
*) lParam
;
815 if (gcmi
->Type
== MENU_ON_NICKLIST
)
817 static struct gc_item Item
[] = {
818 {"&Make Leader", 1, MENU_ITEM
, FALSE
},
821 gcmi
->nItems
= sizeof(Item
)/sizeof(Item
[0]);
822 gcmi
->Item
= &Item
[0];
828 static int OnChatEvent(SIPPROTO
*pr
, WPARAM w
, LPARAM l
)
830 GCHOOK
*hook
= (GCHOOK
*)l
;
831 GCDEST
*dst
= hook
->pDest
;
833 if (dst
->iType
== GC_USER_MESSAGE
) {
836 struct sipe_chat_session
*session
;
838 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
839 gcd
.pszID
= dst
->pszID
;
840 gcd
.iType
= GC_EVENT_GETITEMDATA
;
842 gce
.cbSize
= sizeof(gce
);
846 if ((session
= (struct sipe_chat_session
*)CallService( MS_GC_EVENT
, 0, (LPARAM
)&gce
)) == NULL
)
848 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
853 sipe_core_chat_send(pr
->sip
, session
, hook
->pszText
);
857 } else if (dst
->iType
== GC_USER_PRIVMESS
) {
858 } else if (dst
->iType
== GC_USER_NICKLISTMENU
) {
859 if (hook
->dwData
== 1)
861 SIPE_DEBUG_INFO("make leader <%s>", hook
->pszUID
);
868 int OnPreBuildContactMenu(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
870 HANDLE hContact
= (HANDLE
)wParam
;
871 int chatcount
= CallService(MS_GC_GETSESSIONCOUNT
, 0, (LPARAM
)pr
->proto
.m_szModuleName
);
873 CLISTMENUITEM mi
= {0};
877 mi
.cbSize
= sizeof(mi
);
878 gci
.pszModule
= pr
->proto
.m_szModuleName
;
880 /* Remove the old list */
881 while (pr
->contactMenuChatItems
)
883 SIPE_DEBUG_INFO("Removing old menuitem <%08x>", pr
->contactMenuChatItems
->data
);
884 CallService(MS_CLIST_REMOVECONTACTMENUITEM
, (WPARAM
)pr
->contactMenuChatItems
->data
, 0);
885 pr
->contactMenuChatItems
= g_slist_remove(pr
->contactMenuChatItems
, pr
->contactMenuChatItems
->data
);
888 /* Add the main entry */
889 mi
.pszName
= "Invite to chat";
890 mi
.flags
= CMIF_NOTOFFLINE
;
892 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
893 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
895 mi
.pszName
= "New chat";
896 mi
.hParentMenu
= pr
->contactMenuChatItems
->data
;
897 mi
.flags
= CMIF_ROOTHANDLE
;
898 mi
.popupPosition
= 0;
900 mi
.pszService
= g_strdup_printf("%s/StartChat", pr
->proto
.m_szModuleName
);
901 mi
.pszContactOwner
= pr
->proto
.m_szModuleName
;
902 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
903 g_free(mi
.pszService
);
904 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
906 for (idx
=0 ; idx
<chatcount
; idx
++)
908 SIPE_DEBUG_INFO("Chat <%d> Menuitem <%08x>", idx
, pr
->contactMenuChatItems
);
910 gci
.Flags
= BYINDEX
| NAME
| ID
;
911 if(!CallServiceSync( MS_GC_GETINFO
, 0, (LPARAM
)&gci
)) {
912 SIPE_DEBUG_INFO("Chat <%s>", gci
.pszName
);
914 mi
.pszName
= gci
.pszName
;
915 mi
.hParentMenu
= pr
->contactMenuChatItems
->data
;
916 mi
.flags
= CMIF_ROOTHANDLE
;
917 mi
.popupPosition
= g_strdup(gci
.pszID
);
919 mi
.pszService
= g_strdup_printf("%s/InviteToChat", pr
->proto
.m_szModuleName
);
920 mi
.pszContactOwner
= pr
->proto
.m_szModuleName
;
921 tmp
= (gpointer
)CallService(MS_CLIST_ADDCONTACTMENUITEM
, 0, (LPARAM
)&mi
);
922 g_free(mi
.pszService
);
923 pr
->contactMenuChatItems
= g_slist_append(pr
->contactMenuChatItems
, tmp
);
930 INT_PTR
SvcCreateAccMgrUI(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
932 return (INT_PTR
)CreateDialogParam(hInst
, MAKEINTRESOURCE(IDD_ACCMGRUI
), (HWND
)lParam
, DlgProcAccMgrUI
, (LPARAM
)pr
);
937 * Miranda service functions
939 * The functions in our plugin that get called directly by core Miranda
941 static DWORD_PTR
GetCaps( SIPPROTO
*pr
, int type
, HANDLE hContact
)
945 return PF1_IM
| PF1_CHAT
| PF1_FILE
| PF1_MODEMSG
946 | PF1_SERVERCLIST
| PF1_ADDED
947 | PF1_BASICSEARCH
| PF1_ADDSEARCHRES
948 | PF1_SEARCHBYEMAIL
| PF1_USERIDISEMAIL
949 | PF1_SEARCHBYNAME
| PF1_EXTSEARCH
953 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
954 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
955 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
958 return PF2_ONLINE
| PF2_INVISIBLE
| PF2_SHORTAWAY
959 | PF2_LONGAWAY
| PF2_LIGHTDND
| PF2_HEAVYDND
960 | PF2_OUTTOLUNCH
| PF2_ONTHEPHONE
| PF2_IDLE
;
963 return PF4_NOCUSTOMAUTH
| PF4_IMSENDUTF
| PF4_SUPPORTTYPING
969 case PFLAG_UNIQUEIDSETTING
:
970 return (DWORD_PTR
) SIP_UNIQUEID
;
973 SIPE_DEBUG_INFO("GetCaps: unknown type <%x>", type
);
980 static HICON
GetIcon( SIPPROTO
*pr
, int iconIndex
)
982 SIPE_DEBUG_INFO("GetIcon: unknown index <%x>", iconIndex
);
986 static int OnEvent( SIPPROTO
*pr
, PROTOEVENTTYPE eventType
, WPARAM wParam
, LPARAM lParam
)
988 SIPE_DEBUG_INFO("OnEvent: type <%x>", eventType
);
992 case EV_PROTO_ONLOAD
:
996 case EV_PROTO_ONREADYTOEXIT
:
999 case EV_PROTO_ONEXIT
:
1002 case EV_PROTO_ONRENAME
:
1005 case EV_PROTO_ONOPTIONS
:
1006 return OnOptionsInit( pr
, wParam
, lParam
);
1009 case EV_PROTO_ONERASE
:
1017 static HANDLE
AddToListByEvent( SIPPROTO
*pr
, int flags
, int iContact
, HANDLE hDbEvent
)
1019 DBEVENTINFO dbei
= {0};
1021 dbei
.cbSize
= sizeof(dbei
);
1022 if ((dbei
.cbBlob
= CallService(MS_DB_EVENT_GETBLOBSIZE
, (WPARAM
)hDbEvent
, 0)) == -1)
1025 dbei
.pBlob
= (PBYTE
)_alloca(dbei
.cbBlob
+ 1);
1026 dbei
.pBlob
[dbei
.cbBlob
] = '\0';
1028 if (CallService(MS_DB_EVENT_GET
, (WPARAM
)hDbEvent
, (LPARAM
)&dbei
))
1029 return 0; // failed to get event
1031 if (strcmp(dbei
.szModule
, pr
->proto
.m_szModuleName
))
1032 return 0; // this event is not ours
1035 SIPE_DEBUG_INFO("AddToListByEvent: flags <%x> iContact <%x>", flags
, iContact
);
1039 static int Authorize( SIPPROTO
*pr
, HANDLE hContact
)
1042 SIPE_DEBUG_INFO_NOFORMAT("Authorize");
1046 static int AuthDeny( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szReason
)
1049 SIPE_DEBUG_INFO("AuthDeny: reason <%s>", szReason
);
1053 static int AuthRecv( SIPPROTO
*pr
, HANDLE hContact
, PROTORECVEVENT
* evt
)
1056 SIPE_DEBUG_INFO_NOFORMAT("AuthRecv");
1060 static int AuthRequest( SIPPROTO
*pr
, HANDLE hContact
, const PROTOCHAR
* szMessage
)
1063 SIPE_DEBUG_INFO("AuthRequest: message <%s>", szMessage
);
1067 static HANDLE
ChangeInfo( SIPPROTO
*pr
, int iInfoType
, void* pInfoData
)
1070 SIPE_DEBUG_INFO("ChangeInfo: infotype <%x>", iInfoType
);
1074 static int FileCancel( SIPPROTO
*pr
, HANDLE hContact
, HANDLE hTransfer
)
1077 SIPE_DEBUG_INFO_NOFORMAT("FileCancel");
1081 static int FileResume( SIPPROTO
*pr
, HANDLE hTransfer
, int* action
, const PROTOCHAR
** szFilename
)
1084 SIPE_DEBUG_INFO("FileResume: action <%x>", action
);
1088 static HANDLE
SearchBasic( SIPPROTO
*pr
, const PROTOCHAR
* id
)
1093 static HWND
CreateExtendedSearchUI( SIPPROTO
*pr
, HWND owner
)
1095 return CreateDialogParam(hInst
, MAKEINTRESOURCE(IDD_SEARCHUI
), (HWND
)owner
, NULL
, (LPARAM
)pr
);
1098 static HANDLE
AddToList( SIPPROTO
*pr
, int flags
, PROTOSEARCHRESULT
* psr
)
1101 gchar
*id
= g_strdup(TCHAR2CHAR(psr
->id
));
1103 /* Prepend sip: if needed */
1104 if (strncmp("sip:", id
, 4)) {
1106 id
= sip_uri_from_name(tmp
);
1110 hContact
= sipe_miranda_buddy_find(pr
, id
, NULL
);
1116 hContact
= ( HANDLE
)CallService( MS_DB_CONTACT_ADD
, 0, 0 );
1117 CallService( MS_PROTO_ADDTOCONTACT
, (WPARAM
)hContact
, (LPARAM
)pr
->proto
.m_szModuleName
);
1118 sipe_miranda_setContactString( pr
, hContact
, SIP_UNIQUEID
, id
); // name
1122 gchar
*tmp
= mir_t2a(psr
->nick
);
1123 sipe_miranda_setContactStringUtf( pr
, hContact
, "Nick", tmp
);
1132 sipe_miranda_window_closed(SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1134 MessageWindowEventData
* evt
= (MessageWindowEventData
*)lParam
;
1136 SIPE_DEBUG_INFO("contact <%08x> module <%s> type <%02x> flags <%02x>",
1137 evt
->hContact
, evt
->szModule
, evt
->uType
, evt
->uFlags
);
1143 sipe_miranda_invite_to_chat(const SIPPROTO
*pr
, WPARAM wParam
, LPARAM lParam
)
1145 HANDLE hContact
= (HANDLE
)wParam
;
1146 gchar
*id
= (gchar
*)lParam
;
1149 struct sipe_chat_session
*session
;
1152 gcd
.pszModule
= pr
->proto
.m_szModuleName
;
1154 gcd
.iType
= GC_EVENT_GETITEMDATA
;
1156 gce
.cbSize
= sizeof(gce
);
1159 if ((session
= (struct sipe_chat_session
*)CallService( MS_GC_EVENT
, 0, (LPARAM
)&gce
)) == NULL
)
1161 SIPE_DEBUG_WARNING_NOFORMAT("Failed to get chat session");
1165 uid
= sipe_miranda_getContactString(pr
, hContact
, SIP_UNIQUEID
);
1166 sipe_core_chat_invite(pr
->sip
, session
, uid
);
1174 * Main Miranda interface
1176 * The structures and functions that allow Miranda to recovnize and load
1180 /* Plugin information structure */
1181 PLUGININFOEX pluginInfo
= {
1182 sizeof(PLUGININFOEX
),
1183 "Office Communicator Protocol",
1184 PLUGIN_MAKE_VERSION(0,11,2,1),
1185 "Support for Microsoft Office Communicator",
1186 "Miranda support by Jochen De Smet, for core sipe support see homepage",
1187 "jochen.libsipe@leahnim.org",
1189 "https://sourceforge.net/projects/sipe",
1191 0, //doesn't replace anything built-in
1192 #if defined( _UNICODE )
1193 { 0x842395ed, 0x4e56, 0x40e5, { 0x94, 0x25, 0x28, 0x29, 0xd8, 0xab, 0xae, 0xa5 } } // {842395ED-4E56-40e5-9425-2829D8ABAEA5}
1195 { 0x1ef8af37, 0xdec1, 0x4757, { 0x89, 0x78, 0xe8, 0xad, 0xd0, 0xd8, 0x6e, 0x7f } } // {1EF8AF37-DEC1-4757-8978-E8ADD0D86E7F}
1199 __declspec(dllexport
) PLUGININFOEX
*MirandaPluginInfoEx(DWORD mirandaVersion
)
1201 // Only load for 0.8.0.29 or greater
1202 // We need the core stubs for PS_GETNAME and PS_GETSTATUS
1203 if (mirandaVersion
< PLUGIN_MAKE_VERSION(0, 9, 0, 0))
1207 "SIP/Simple plugin cannot be loaded. It requires Miranda IM 0.9.0.0 or later.",
1208 "SIP/Simple Plugin",
1209 MB_OK
| MB_ICONWARNING
| MB_SETFOREGROUND
| MB_TOPMOST
1217 static const MUUID interfaces
[] = {MIID_PROTOCOL
, MIID_LAST
};
1218 __declspec(dllexport
) const MUUID
* MirandaPluginInterfaces(void)
1223 static PROTO_INTERFACE
* sipsimpleProtoInit( const char* pszProtoName
, const TCHAR
* tszUserName
)
1226 SIPPROTO
*pr
= (SIPPROTO
*)mir_calloc(sizeof(SIPPROTO
));
1227 pr
->proto
.vtbl
= (PROTO_INTERFACE_VTBL
*)mir_calloc(sizeof(PROTO_INTERFACE_VTBL
));
1229 SIPE_DEBUG_INFO("protoname <%s> username <%ls>", pszProtoName
, tszUserName
);
1231 if (!InitializeCriticalSectionAndSpinCount(&pr
->CriticalSection
, 0))
1233 SIPE_DEBUG_ERROR_NOFORMAT("Can't initialize critical section");
1237 tmp
= sipe_miranda_getString(pr
, "transport");
1240 sipe_miranda_setString(pr
, "transport", "auto");
1245 /* To make it easy to detect when a SIPPROTO* isn't a SIPPROTO* */
1246 strncpy(pr
->_SIGNATURE
, "AbandonAllHope..", sizeof(pr
->_SIGNATURE
));
1248 pr
->main_thread_id
= GetCurrentThreadId();
1249 pr
->proto
.m_iVersion
= 2;
1250 pr
->proto
.m_szModuleName
= mir_strdup(pszProtoName
);
1251 pr
->proto
.m_tszUserName
= mir_tstrdup(tszUserName
);
1252 pr
->proto
.m_szProtoName
= mir_strdup(pszProtoName
);
1254 // set_buddies_offline(pr);
1255 fix_contact_groups(pr
);
1257 /* Fill the function table */
1258 pr
->proto
.vtbl
->AddToList
= AddToList
;
1259 pr
->proto
.vtbl
->AddToListByEvent
= AddToListByEvent
;
1261 pr
->proto
.vtbl
->Authorize
= Authorize
;
1262 pr
->proto
.vtbl
->AuthDeny
= AuthDeny
;
1263 pr
->proto
.vtbl
->AuthRecv
= AuthRecv
;
1264 pr
->proto
.vtbl
->AuthRequest
= AuthRequest
;
1266 pr
->proto
.vtbl
->ChangeInfo
= ChangeInfo
;
1268 pr
->proto
.vtbl
->FileAllow
= sipe_miranda_FileAllow
;
1269 pr
->proto
.vtbl
->FileCancel
= FileCancel
;
1270 pr
->proto
.vtbl
->FileDeny
= sipe_miranda_FileDeny
;
1271 pr
->proto
.vtbl
->FileResume
= FileResume
;
1273 pr
->proto
.vtbl
->GetCaps
= GetCaps
;
1274 pr
->proto
.vtbl
->GetIcon
= GetIcon
;
1275 pr
->proto
.vtbl
->GetInfo
= sipe_miranda_GetInfo
;
1277 pr
->proto
.vtbl
->SearchBasic
= SearchBasic
;
1278 pr
->proto
.vtbl
->SearchByEmail
= sipe_miranda_SearchByEmail
;
1279 pr
->proto
.vtbl
->SearchByName
= sipe_miranda_SearchByName
;
1280 pr
->proto
.vtbl
->SearchAdvanced
= sipe_miranda_SearchAdvanced
;
1281 pr
->proto
.vtbl
->CreateExtendedSearchUI
= CreateExtendedSearchUI
;
1283 pr
->proto
.vtbl
->RecvMsg
= sipe_miranda_RecvMsg
;
1285 pr
->proto
.vtbl
->SendMsg
= sipe_miranda_SendMsg
;
1287 pr
->proto
.vtbl
->SetStatus
= sipe_miranda_SetStatus
;
1289 pr
->proto
.vtbl
->GetAwayMsg
= sipe_miranda_GetAwayMsg
;
1290 pr
->proto
.vtbl
->SetAwayMsg
= sipe_miranda_SetAwayMsg
;
1292 pr
->proto
.vtbl
->UserIsTyping
= sipe_miranda_UserIsTyping
;
1294 pr
->proto
.vtbl
->SendFile
= sipe_miranda_SendFile
;
1295 pr
->proto
.vtbl
->RecvFile
= sipe_miranda_RecvFile
;
1297 pr
->proto
.vtbl
->OnEvent
= OnEvent
;
1299 /* Setup services */
1300 CreateProtoService(pr
, PS_CREATEACCMGRUI
, &SvcCreateAccMgrUI
);
1301 CreateProtoService(pr
, "/InviteToChat", &sipe_miranda_invite_to_chat
);
1302 CreateProtoService(pr
, "/StartChat",&sipe_miranda_start_chat
);
1304 #define HOOKEVENT(evt,func) HookEventObj(evt, func, pr)
1305 HOOKEVENT(ME_OPT_INITIALISE
, &OnOptionsInit
);
1306 HOOKEVENT(ME_CLIST_GROUPCHANGE
, &OnGroupChange
);
1307 HOOKEVENT(ME_GC_EVENT
, &OnChatEvent
);
1308 HOOKEVENT(ME_CLIST_PREBUILDCONTACTMENU
, &OnPreBuildContactMenu
);
1309 HOOKEVENT(ME_DB_CONTACT_DELETED
, &sipe_miranda_buddy_delete
);
1310 HOOKEVENT(ME_MSG_WINDOWEVENT
, &sipe_miranda_window_closed
);
1311 HOOKEVENT(ME_GC_BUILDMENU
, &sipe_miranda_build_chat_menu
);
1313 return (PROTO_INTERFACE
*)pr
;
1316 static int sipsimpleProtoUninit( PROTO_INTERFACE
* _pr
)
1318 SIPPROTO
*pr
= (SIPPROTO
*)_pr
;
1320 DeleteCriticalSection(&pr
->CriticalSection
);
1322 Netlib_CloseHandle(pr
->m_hServerNetlibUser
);
1323 mir_free(pr
->proto
.m_szProtoName
);
1324 mir_free(pr
->proto
.m_szModuleName
);
1325 mir_free(pr
->proto
.m_tszUserName
);
1326 mir_free(pr
->proto
.vtbl
);
1332 __declspec(dllexport
) int Load(PLUGINLINK
*link
)
1334 PROTOCOLDESCRIPTOR pd
= {0};
1335 NETLIBUSER nlu
= {0};
1345 /* Register the module */
1346 pd
.cbSize
= sizeof(pd
);
1347 pd
.szName
= SIPSIMPLE_PROTOCOL_NAME
;
1348 pd
.type
= PROTOTYPE_PROTOCOL
;
1349 pd
.fnInit
= sipsimpleProtoInit
;
1350 pd
.fnUninit
= sipsimpleProtoUninit
;
1351 CallService(MS_PROTO_REGISTERMODULE
, 0, (LPARAM
)&pd
);
1353 /* Protocolwide netlib user for incoming connections (also abused for logging) */
1354 nlu
.cbSize
= sizeof(nlu
);
1355 nlu
.flags
= NUF_INCOMING
| NUF_TCHAR
| NUF_NOOPTIONS
;
1356 nlu
.szSettingsModule
= SIPSIMPLE_PROTOCOL_NAME
;
1357 nlu
.minIncomingPorts
= 10;
1359 InitializeCriticalSectionAndSpinCount(&sipe_miranda_debug_CriticalSection
, 0);
1360 sipe_miranda_incoming_netlibuser
= (HANDLE
)CallService(MS_NETLIB_REGISTERUSER
, 0, (LPARAM
)&nlu
);
1362 tmp
= sipe_miranda_getGlobalString("public_ip");
1364 sipe_miranda_setGlobalString("public_ip", "0.0.0.0");
1369 if (!sipe_miranda_getGlobalWord("iptype", &iptype
))
1371 sipe_miranda_setGlobalWord("iptype", SIPE_MIRANDA_IP_LOCAL
);
1377 __declspec(dllexport
) int Unload(void)
1379 Netlib_CloseHandle(sipe_miranda_incoming_netlibuser
);
1380 sipe_miranda_incoming_netlibuser
= NULL
;
1381 DeleteCriticalSection(&sipe_miranda_debug_CriticalSection
);
1382 sipe_core_destroy();
1386 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
,DWORD fdwReason
,LPVOID lpvReserved
)