From 50421b7809c47bd95c59b4a5627e2f89c8bccfa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Tue, 29 Oct 2013 08:47:48 +0000 Subject: SkypeClassic: Folders structure and project cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@6668 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeClassic/Skript1.aps | Bin 122080 -> 0 bytes protocols/SkypeClassic/Skript1.rc | 484 --- protocols/SkypeClassic/SkypeClassic_10.vcxproj | 321 +- protocols/SkypeClassic/alogon.cpp | 129 - protocols/SkypeClassic/alogon.h | 1 - protocols/SkypeClassic/changelog.txt | 330 -- protocols/SkypeClassic/contacts.cpp | 419 --- protocols/SkypeClassic/contacts.h | 11 - protocols/SkypeClassic/debug.cpp | 75 - protocols/SkypeClassic/debug.h | 23 - protocols/SkypeClassic/docs/changelog.txt | 330 ++ protocols/SkypeClassic/docs/readme.txt | 47 + protocols/SkypeClassic/ezxml/ezxml.c | 1033 ------ protocols/SkypeClassic/ezxml/ezxml.h | 167 - protocols/SkypeClassic/gchat.cpp | 910 ------ protocols/SkypeClassic/gchat.h | 47 - protocols/SkypeClassic/memlist.cpp | 248 -- protocols/SkypeClassic/memlist.h | 43 - protocols/SkypeClassic/msglist.cpp | 86 - protocols/SkypeClassic/msglist.h | 15 - protocols/SkypeClassic/msgq.cpp | 90 - protocols/SkypeClassic/msgq.h | 64 - protocols/SkypeClassic/pthread.cpp | 70 - protocols/SkypeClassic/pthread.h | 26 - protocols/SkypeClassic/readme.txt | 47 - protocols/SkypeClassic/res/Resource.rc | 439 +++ protocols/SkypeClassic/res/Version.rc | 42 + protocols/SkypeClassic/resource.h | 124 - protocols/SkypeClassic/skype.cpp | 3381 ------------------- protocols/SkypeClassic/skype.h | 181 -- protocols/SkypeClassic/skypeapi.cpp | 1706 ---------- protocols/SkypeClassic/skypeapi.h | 69 - protocols/SkypeClassic/skypeopt.cpp | 968 ------ protocols/SkypeClassic/skypeopt.h | 49 - protocols/SkypeClassic/skypeprofile.cpp | 145 - protocols/SkypeClassic/skypeprofile.h | 33 - protocols/SkypeClassic/skypeproxy.h | 7 - protocols/SkypeClassic/skypeproxy/skypeproxy.c | 651 ---- protocols/SkypeClassic/skypeproxy/skypeproxy.h | 36 - protocols/SkypeClassic/skypesvc.cpp | 187 -- protocols/SkypeClassic/skypesvc.h | 24 - protocols/SkypeClassic/src/alogon.cpp | 129 + protocols/SkypeClassic/src/alogon.h | 1 + protocols/SkypeClassic/src/contacts.cpp | 419 +++ protocols/SkypeClassic/src/contacts.h | 11 + protocols/SkypeClassic/src/debug.cpp | 75 + protocols/SkypeClassic/src/debug.h | 23 + protocols/SkypeClassic/src/ezxml/ezxml.c | 1033 ++++++ protocols/SkypeClassic/src/ezxml/ezxml.h | 167 + protocols/SkypeClassic/src/gchat.cpp | 910 ++++++ protocols/SkypeClassic/src/gchat.h | 47 + protocols/SkypeClassic/src/memlist.cpp | 248 ++ protocols/SkypeClassic/src/memlist.h | 43 + protocols/SkypeClassic/src/msglist.cpp | 86 + protocols/SkypeClassic/src/msglist.h | 15 + protocols/SkypeClassic/src/msgq.cpp | 90 + protocols/SkypeClassic/src/msgq.h | 64 + protocols/SkypeClassic/src/pthread.cpp | 70 + protocols/SkypeClassic/src/pthread.h | 26 + protocols/SkypeClassic/src/resource.h | 124 + protocols/SkypeClassic/src/skype.cpp | 3382 ++++++++++++++++++++ protocols/SkypeClassic/src/skype.h | 183 ++ protocols/SkypeClassic/src/skypeapi.cpp | 1706 ++++++++++ protocols/SkypeClassic/src/skypeapi.h | 69 + protocols/SkypeClassic/src/skypeopt.cpp | 968 ++++++ protocols/SkypeClassic/src/skypeopt.h | 49 + protocols/SkypeClassic/src/skypeprofile.cpp | 145 + protocols/SkypeClassic/src/skypeprofile.h | 33 + protocols/SkypeClassic/src/skypeproxy.h | 7 + protocols/SkypeClassic/src/skypeproxy/skypeproxy.c | 651 ++++ protocols/SkypeClassic/src/skypeproxy/skypeproxy.h | 36 + protocols/SkypeClassic/src/skypesvc.cpp | 187 ++ protocols/SkypeClassic/src/skypesvc.h | 24 + protocols/SkypeClassic/src/utf8.cpp | 334 ++ protocols/SkypeClassic/src/utf8.h | 47 + protocols/SkypeClassic/src/util.cpp | 57 + protocols/SkypeClassic/src/util.h | 7 + protocols/SkypeClassic/src/version.h | 20 + protocols/SkypeClassic/src/voiceservice.cpp | 156 + protocols/SkypeClassic/src/voiceservice.h | 18 + protocols/SkypeClassic/utf8.cpp | 334 -- protocols/SkypeClassic/utf8.h | 47 - protocols/SkypeClassic/util.cpp | 57 - protocols/SkypeClassic/util.h | 7 - protocols/SkypeClassic/voiceservice.cpp | 156 - protocols/SkypeClassic/voiceservice.h | 18 - 86 files changed, 12593 insertions(+), 12744 deletions(-) delete mode 100644 protocols/SkypeClassic/Skript1.aps delete mode 100644 protocols/SkypeClassic/Skript1.rc delete mode 100644 protocols/SkypeClassic/alogon.cpp delete mode 100644 protocols/SkypeClassic/alogon.h delete mode 100644 protocols/SkypeClassic/changelog.txt delete mode 100644 protocols/SkypeClassic/contacts.cpp delete mode 100644 protocols/SkypeClassic/contacts.h delete mode 100644 protocols/SkypeClassic/debug.cpp delete mode 100644 protocols/SkypeClassic/debug.h create mode 100644 protocols/SkypeClassic/docs/changelog.txt create mode 100644 protocols/SkypeClassic/docs/readme.txt delete mode 100644 protocols/SkypeClassic/ezxml/ezxml.c delete mode 100644 protocols/SkypeClassic/ezxml/ezxml.h delete mode 100644 protocols/SkypeClassic/gchat.cpp delete mode 100644 protocols/SkypeClassic/gchat.h delete mode 100644 protocols/SkypeClassic/memlist.cpp delete mode 100644 protocols/SkypeClassic/memlist.h delete mode 100644 protocols/SkypeClassic/msglist.cpp delete mode 100644 protocols/SkypeClassic/msglist.h delete mode 100644 protocols/SkypeClassic/msgq.cpp delete mode 100644 protocols/SkypeClassic/msgq.h delete mode 100644 protocols/SkypeClassic/pthread.cpp delete mode 100644 protocols/SkypeClassic/pthread.h delete mode 100644 protocols/SkypeClassic/readme.txt create mode 100644 protocols/SkypeClassic/res/Resource.rc create mode 100644 protocols/SkypeClassic/res/Version.rc delete mode 100644 protocols/SkypeClassic/resource.h delete mode 100644 protocols/SkypeClassic/skype.cpp delete mode 100644 protocols/SkypeClassic/skype.h delete mode 100644 protocols/SkypeClassic/skypeapi.cpp delete mode 100644 protocols/SkypeClassic/skypeapi.h delete mode 100644 protocols/SkypeClassic/skypeopt.cpp delete mode 100644 protocols/SkypeClassic/skypeopt.h delete mode 100644 protocols/SkypeClassic/skypeprofile.cpp delete mode 100644 protocols/SkypeClassic/skypeprofile.h delete mode 100644 protocols/SkypeClassic/skypeproxy.h delete mode 100644 protocols/SkypeClassic/skypeproxy/skypeproxy.c delete mode 100644 protocols/SkypeClassic/skypeproxy/skypeproxy.h delete mode 100644 protocols/SkypeClassic/skypesvc.cpp delete mode 100644 protocols/SkypeClassic/skypesvc.h create mode 100644 protocols/SkypeClassic/src/alogon.cpp create mode 100644 protocols/SkypeClassic/src/alogon.h create mode 100644 protocols/SkypeClassic/src/contacts.cpp create mode 100644 protocols/SkypeClassic/src/contacts.h create mode 100644 protocols/SkypeClassic/src/debug.cpp create mode 100644 protocols/SkypeClassic/src/debug.h create mode 100644 protocols/SkypeClassic/src/ezxml/ezxml.c create mode 100644 protocols/SkypeClassic/src/ezxml/ezxml.h create mode 100644 protocols/SkypeClassic/src/gchat.cpp create mode 100644 protocols/SkypeClassic/src/gchat.h create mode 100644 protocols/SkypeClassic/src/memlist.cpp create mode 100644 protocols/SkypeClassic/src/memlist.h create mode 100644 protocols/SkypeClassic/src/msglist.cpp create mode 100644 protocols/SkypeClassic/src/msglist.h create mode 100644 protocols/SkypeClassic/src/msgq.cpp create mode 100644 protocols/SkypeClassic/src/msgq.h create mode 100644 protocols/SkypeClassic/src/pthread.cpp create mode 100644 protocols/SkypeClassic/src/pthread.h create mode 100644 protocols/SkypeClassic/src/resource.h create mode 100644 protocols/SkypeClassic/src/skype.cpp create mode 100644 protocols/SkypeClassic/src/skype.h create mode 100644 protocols/SkypeClassic/src/skypeapi.cpp create mode 100644 protocols/SkypeClassic/src/skypeapi.h create mode 100644 protocols/SkypeClassic/src/skypeopt.cpp create mode 100644 protocols/SkypeClassic/src/skypeopt.h create mode 100644 protocols/SkypeClassic/src/skypeprofile.cpp create mode 100644 protocols/SkypeClassic/src/skypeprofile.h create mode 100644 protocols/SkypeClassic/src/skypeproxy.h create mode 100644 protocols/SkypeClassic/src/skypeproxy/skypeproxy.c create mode 100644 protocols/SkypeClassic/src/skypeproxy/skypeproxy.h create mode 100644 protocols/SkypeClassic/src/skypesvc.cpp create mode 100644 protocols/SkypeClassic/src/skypesvc.h create mode 100644 protocols/SkypeClassic/src/utf8.cpp create mode 100644 protocols/SkypeClassic/src/utf8.h create mode 100644 protocols/SkypeClassic/src/util.cpp create mode 100644 protocols/SkypeClassic/src/util.h create mode 100644 protocols/SkypeClassic/src/version.h create mode 100644 protocols/SkypeClassic/src/voiceservice.cpp create mode 100644 protocols/SkypeClassic/src/voiceservice.h delete mode 100644 protocols/SkypeClassic/utf8.cpp delete mode 100644 protocols/SkypeClassic/utf8.h delete mode 100644 protocols/SkypeClassic/util.cpp delete mode 100644 protocols/SkypeClassic/util.h delete mode 100644 protocols/SkypeClassic/voiceservice.cpp delete mode 100644 protocols/SkypeClassic/voiceservice.h (limited to 'protocols') diff --git a/protocols/SkypeClassic/Skript1.aps b/protocols/SkypeClassic/Skript1.aps deleted file mode 100644 index d99f14a71e..0000000000 Binary files a/protocols/SkypeClassic/Skript1.aps and /dev/null differ diff --git a/protocols/SkypeClassic/Skript1.rc b/protocols/SkypeClassic/Skript1.rc deleted file mode 100644 index f93a1fae83..0000000000 --- a/protocols/SkypeClassic/Skript1.rc +++ /dev/null @@ -1,484 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_SETAVATAR DIALOGEX 0, 0, 222, 131 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Set",IDC_SETAVATAR,10,108,45,13,WS_GROUP - PUSHBUTTON "Delete",IDC_DELETEAVATAR,57,108,45,13 - CONTROL "",IDC_AVATAR,"Static",SS_BITMAP | SS_CENTERIMAGE | - SS_SUNKEN | WS_GROUP,10,10,96,93 -END - -IDD_OPT_DEFAULT DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Start Skype with Miranda IM if not running using the following command line options:", - IDC_STARTSKYPE,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,10 - CONTROL "/NOSPLASH - Don't show splash screen on startup", - IDC_NOSPLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,17, - 264,12 - CONTROL "/MINIMIZED - Start Skype minimized",IDC_MINIMIZED, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,28,264,12 - CONTROL "/NOTRAY - Skype tray icon becomes grey and is therefore ""invisible""", - IDC_NOTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,40, - 264,12 - CONTROL "/REMOVEABLE - For running portable skype", - IDC_REMOVEABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36, - 51,264,12 - CONTROL "/SECONDARY - This is the second instance",IDC_SECONDARY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,62,264,12 - CONTROL "/DATAPATH - Specify Skype data folder*",IDC_DATAPATHO, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,74,264,12 - EDITTEXT IDC_DATAPATH,47,88,236,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BROWSEDP,285,87,16,15 - CONTROL "Use custom Skype executable*",IDC_CUSTOMCOMMAND,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,36,103,264,10 - EDITTEXT IDC_COMMANDLINE,47,116,236,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BROWSECMDL,285,115,16,15 - CTEXT "* Relative path root is Miranda IM folder", - IDC_STATIC_PATHINFO,10,136,290,8,NOT WS_GROUP - CONTROL "Shutdown Skype when you close Miranda IM",IDC_SHUTDOWN, - "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,151, - 290,10 - CONTROL "Unload Skype when you change to Offline status", - IDC_UNLOADOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,164,290,11 - LTEXT "Try at least",IDC_STATIC,10,185,39,8 - EDITTEXT IDC_CONNATTEMPTS,52,183,21,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "times to connect to Skype API before giving up", - IDC_STATIC,78,185,224,8,NOT WS_GROUP - LTEXT "User name:",IDC_STATIC,10,206,38,8 - EDITTEXT IDC_USERNAME,52,204,79,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,148,206,34,8 - EDITTEXT IDC_PASSWORD,186,204,79,12,ES_PASSWORD | ES_AUTOHSCROLL -END - -IDD_DIAL DIALOGEX 0, 0, 198, 46 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -CAPTION "Dial" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Number:",IDC_STATIC,7,8,30,11 - COMBOBOX IDC_NUMBER,41,6,149,13,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - DEFPUSHBUTTON "Dial",IDDIAL,88,25,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,141,25,50,14 -END - -IDD_CALLSTAT DIALOGEX 0, 0, 220, 67 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "%s is calling" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Join conference with %s",IDC_JOIN,"Button", - BS_AUTORADIOBUTTON | WS_GROUP,7,7,206,10 - CONTROL "Answer call; set call to %s on hold",IDC_HOLD,"Button", - BS_AUTORADIOBUTTON,7,19,206,10 - CONTROL "Hang up",IDC_HANGUP,"Button",BS_AUTORADIOBUTTON,7,31, - 206,10 - DEFPUSHBUTTON "OK",IDOK,163,46,50,14,WS_GROUP -END - -IDD_INPUTBOX DIALOGEX 0, 0, 221, 46 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - EDITTEXT IDC_TEXT,7,7,207,13,ES_AUTOHSCROLL | WS_GROUP - DEFPUSHBUTTON "OK",IDOK,112,25,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,165,25,50,14 -END - -IDD_OPTIONS DIALOGEX 0, 0, 313, 249 -STYLE DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Tab1",IDC_OPTIONSTAB,"SysTabControl32",0x0,0,-1,313,250 -END - -IDD_OPT_PROXY DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Use Skype proxy connection over network instead of local Skype API", - IDC_USES2S,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,9 - LTEXT "Host:",IDC_STATIC_HOST,20,21,18,10 - EDITTEXT IDC_HOST,41,19,133,12,ES_AUTOHSCROLL - LTEXT "Port:",IDC_STATIC_PORT,180,21,16,10,0,WS_EX_RIGHT - EDITTEXT IDC_PORT,200,19,29,12,ES_AUTOHSCROLL | ES_NUMBER - CTEXT "* You must restart Miranda IM in order to let the settings take effect", - IDC_STATIC_RESTART,10,54,290,8,NOT WS_GROUP - CONTROL "This Skype proxy requires password authentication:", - IDC_REQPASS,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,20,38,176,9 - EDITTEXT IDC_PASSWORD,200,36,82,12,ES_PASSWORD | ES_AUTOHSCROLL -END - -IDD_SETDETAILS DIALOGEX 0, 0, 216, 151 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Name:",IDC_STATIC,7,6,61,9 - EDITTEXT IDC_FULLNAME,73,4,141,12,ES_AUTOHSCROLL - LTEXT "Birthday:",IDC_STATIC,7,20,61,9 - CONTROL "DateTimePicker1",IDC_BIRTHDAY,"SysDateTimePick32", - DTS_RIGHTALIGN | DTS_APPCANPARSE | WS_TABSTOP,73,18,62, - 12 - LTEXT "Sex:",IDC_STATIC,7,34,61,9 - COMBOBOX IDC_SEX,73,32,141,12,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "City:",IDC_STATIC,7,48,61,9 - EDITTEXT IDC_CITY,73,46,141,12,ES_AUTOHSCROLL - LTEXT "Country:",IDC_STATIC,7,62,61,9 - EDITTEXT IDC_COUNTRY,73,60,141,12,ES_AUTOHSCROLL - LTEXT "Province:",IDC_STATIC,7,76,61,9 - EDITTEXT IDC_PROVINCE,73,74,141,12,ES_AUTOHSCROLL - LTEXT "Home phone:",IDC_STATIC,7,90,61,9 - EDITTEXT IDC_HOMEPHONE,73,88,141,12,ES_AUTOHSCROLL - LTEXT "Office phone:",IDC_STATIC,7,104,61,9 - EDITTEXT IDC_OFFICEPHONE,73,102,141,12,ES_AUTOHSCROLL - LTEXT "Homepage:",IDC_STATIC,7,118,61,9 - EDITTEXT IDC_HOMEPAGE,73,116,141,12,ES_AUTOHSCROLL - PUSHBUTTON "Save",IDC_SAVEDETAILS,170,134,45,14,WS_GROUP -END - -IDD_OPT_ADVANCED DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Enable Skype menu options (currently: Find/Add user)", - IDC_ENABLEMENU,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,9 - CONTROL "Use popup plugin for displaying messages ",IDC_USEPOPUP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,290,9 - CONTROL "Suppress all error messages (not recommended, but if it annoys you... ;)", - IDC_NOERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,34, - 290,9 - CONTROL "Use group chat interface for conversations (requires group chat module)", - IDC_GROUPCHAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 49,290,9 - CONTROL "Mark group chat message as read to avoid notification", - IDC_GROUPCHATREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,64,290,9 - CONTROL "Keep requested online status on startup under every circumstance", - IDC_KEEPSTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 79,290,9 - CONTROL "Use time zone patch",IDC_TIMEZONE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,94,290,9 - CONTROL "Ignore time zones",IDC_IGNTZ,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,109,290,9 - CONTROL "Show default skype avatar for contacts", - IDC_SHOWDEFAULTAVATAR,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,124,290,9 - CONTROL "Suppress call summary chat message", - IDC_SUPPRESSCALLSUMMARYMESSAGE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,139,290,9 - CONTROL "Disable support for N/A and SkypeMe status (for Skype 4+)", - IDC_NOSKYPE3STATS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,154,290,9 - CONTROL "Show full name in contact list instead of nickname", - IDC_SHOWFULLNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,169,290,9 - LTEXT "SkypeOut contacts are in status:",IDC_STATIC,10,186,108, - 8 - COMBOBOX IDC_SKYPEOUTSTAT,120,184,79,54,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Cleanup Nicknames",IDC_CLEANUP,9,201,80,14,BS_MULTILINE | - WS_GROUP -END - -IDD_OPT_POPUP DIALOGEX 0, 0, 310, 228 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Skype Popups",IDC_STATIC,0,1,309,227 - GROUPBOX "Incoming Calls",IDC_STATIC,6,16,297,62,WS_GROUP - CONTROL "Show incoming calls",IDC_POPUPINCOMING,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,28,278,8 - EDITTEXT IDC_POPUPTIME,16,41,20,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "seconds",IDC_STATIC,41,43,92,8,NOT WS_GROUP - CONTROL "",IDC_POPUPBACKCOLOR,"ColourPicker",WS_GROUP | - WS_TABSTOP,142,40,39,12 - LTEXT "Background",IDC_STATIC_POPUPBACKCOLOR,186,42,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - CONTROL "Use Windows colors",IDC_USEWINCOLORS,"Button", - BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16,58, - 121,8 - CONTROL "",IDC_POPUPTEXTCOLOR,"ColourPicker",WS_TABSTOP,142,55, - 39,12 - LTEXT "Text",IDC_STATIC_POPUPTEXTCOLOR,186,56,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - PUSHBUTTON "Preview",IDC_PREVIEW,247,58,50,14,WS_GROUP - GROUPBOX "Error Messages",IDC_STATIC,6,81,297,62,WS_GROUP - CONTROL "Display error messages",IDC_POPUPERROR,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,94,278,8 - EDITTEXT IDC_POPUPTIMEERR,16,107,20,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "seconds",IDC_STATIC,41,109,92,8,NOT WS_GROUP - CONTROL "",IDC_POPUPBACKCOLORERR,"ColourPicker",WS_GROUP | - WS_TABSTOP,142,106,39,12 - LTEXT "Background",IDC_STATIC_POPUPBACKCOLORERR,186,108,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - CONTROL "Use Windows colors",IDC_USEWINCOLORSERR,"Button", - BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16, - 124,121,8 - CONTROL "",IDC_POPUPTEXTCOLORERR,"ColourPicker",WS_TABSTOP,142, - 121,39,12 - LTEXT "Text",IDC_STATIC_POPUPTEXTCOLORERR,186,123,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - PUSHBUTTON "Preview",IDC_PREVIEWERR,247,124,50,14,WS_GROUP -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE -BEGIN - IDD_SETAVATAR, DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 212 - TOPMARGIN, 10 - BOTTOMMARGIN, 121 - END - - IDD_OPT_DEFAULT, DIALOG - BEGIN - LEFTMARGIN, 1 - VERTGUIDE, 10 - VERTGUIDE, 300 - TOPMARGIN, 4 - END - - IDD_DIAL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 190 - TOPMARGIN, 6 - BOTTOMMARGIN, 39 - END - - IDD_CALLSTAT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 213 - TOPMARGIN, 7 - BOTTOMMARGIN, 60 - END - - IDD_INPUTBOX, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 214 - TOPMARGIN, 7 - BOTTOMMARGIN, 39 - END - - IDD_OPTIONS, DIALOG - BEGIN - RIGHTMARGIN, 311 - BOTTOMMARGIN, 243 - END - - IDD_OPT_PROXY, DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 300 - TOPMARGIN, 4 - BOTTOMMARGIN, 221 - END - - IDD_SETDETAILS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 214 - TOPMARGIN, 4 - BOTTOMMARGIN, 148 - END - - IDD_OPT_ADVANCED, DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 300 - TOPMARGIN, 4 - BOTTOMMARGIN, 221 - HORZGUIDE, 4 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_SKYPE ICON DISCARDABLE "res\\skype.ico" -IDI_INVITE ICON DISCARDABLE "res\\Invite.ico" -IDI_ADD ICON DISCARDABLE "res\\add.ico" -IDI_IMPORT ICON DISCARDABLE "res\\import.ico" -IDI_ERRORS ICON DISCARDABLE "res\\error.ico" -IDI_MESSAGE ICON DISCARDABLE "res\\message.ico" -IDI_CALL ICON DISCARDABLE "res\\call.ico" -IDI_CALLSKYPEOUT ICON DISCARDABLE "res\\skypeout.ico" -IDI_HOLD ICON DISCARDABLE "res\\hold.ico" -IDI_RESUME ICON DISCARDABLE "res\\resume.ico" -IDI_HANGUP ICON DISCARDABLE "res\\hang_up.ico" -IDI_ONLINE ICON DISCARDABLE "res\\online.ico" -IDI_CHAT ICON DISCARDABLE "res\\chat.ico" -IDI_AWAY ICON DISCARDABLE "res\\away.ico" -IDI_NA ICON DISCARDABLE "res\\na.ico" -IDI_OCCUPIED ICON DISCARDABLE "res\\occupied.ico" -IDI_DND ICON DISCARDABLE "res\\dnd.ico" -IDI_INVISIBLE ICON DISCARDABLE "res\\invisible.ico" -IDI_OFFLINE ICON DISCARDABLE "res\\offline.ico" -IDI_PHONE ICON DISCARDABLE "res\\phone.ico" - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,0,54 - PRODUCTVERSION 0,0,0,54 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "Miranda IM community\0" - VALUE "FileDescription", "Skype\0" - VALUE "FileVersion", "0, 0, 0, 54\0" - VALUE "InternalName", "Skype\0" - VALUE "LegalCopyright", "Copyright © 2007-2012 leecher - tweety - jls17\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "Skype.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Skype Protocol for Miranda IM\0" - VALUE "ProductVersion", "0, 0, 0, 54\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_CALL BITMAP MOVEABLE PURE "res\\call.bmp" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// Deutsch (Österreich) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE MOVEABLE PURE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE MOVEABLE PURE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE MOVEABLE PURE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Deutsch (Österreich) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/protocols/SkypeClassic/SkypeClassic_10.vcxproj b/protocols/SkypeClassic/SkypeClassic_10.vcxproj index 78f59c77ca..0d5715e233 100644 --- a/protocols/SkypeClassic/SkypeClassic_10.vcxproj +++ b/protocols/SkypeClassic/SkypeClassic_10.vcxproj @@ -50,6 +50,81 @@ x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {5F9243AE-C6C9-4F42-B670-67A97767A50B} Skype_protocol @@ -997,252 +1072,6 @@ - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - diff --git a/protocols/SkypeClassic/alogon.cpp b/protocols/SkypeClassic/alogon.cpp deleted file mode 100644 index 8002d495fc..0000000000 --- a/protocols/SkypeClassic/alogon.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "skype.h" -#include "debug.h" - -extern char g_szProtoName[]; -extern HANDLE SkypeReady; - -/** - * Purpose: Retrieves class name from window - * - * Note: This is some sort of hack to return static local variable, - * but it works :) - */ -static const TCHAR* getClassName(HWND wnd) -{ - static TCHAR className[256]; - - *className=0; - GetClassName(wnd, &className[0], sizeof(className)/sizeof(className[0])); - return className; -} - -/** - * Purpose: Finds a window - * - * Note: This function relies on Skype window placement. - * It should work for Skype 3.x - */ -static HWND findWindow(HWND parent, const TCHAR* childClassName) -{ - // Get child window - // This window is not combo box or edit box - HWND wnd = GetWindow(parent, GW_CHILD); - while(wnd != NULL && _tcscmp(getClassName(wnd), childClassName) != 0) - wnd = GetWindow(wnd, GW_HWNDNEXT); - - return wnd; -} - -static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) -{ - DWORD dwPID; - const TCHAR *lpszClassName; - - - GetWindowThreadProcessId(hWnd,&dwPID); - if (lParam != 0 && dwPID != (DWORD)lParam) return TRUE; - lpszClassName = getClassName(hWnd); - if(_tcscmp(lpszClassName, _T("tSkMainForm.UnicodeClass")) == 0 || - _tcscmp(lpszClassName, _T("TLoginForm.UnicodeClass")) == 0) - { - HWND loginControl = GetWindow(hWnd, GW_CHILD); - - LOG(("setUserNamePasswordThread: Skype window found!")); - - // Sleep for some time, while Skype is loading - // It loads slowly :( - //Sleep(5000); - LOG (("TLoginControl = %S", getClassName(loginControl))); - - // Check for login control - if(_tcscmp(getClassName(loginControl), _T("TLoginControl")) == 0) - { - // Find user name window - HWND userName = findWindow(loginControl, _T("TNavigableTntComboBox.UnicodeClass")); - HWND password = findWindow(loginControl, _T("TNavigableTntEdit.UnicodeClass")); - - LOG (("userName=%08X; password=%08X", userName, password)); - if (userName && password) - { - // Set user name and password - DBVARIANT dbv; - - if(!db_get_ws(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) - { - SendMessageW(userName, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); - db_free(&dbv); - } - - if(!db_get_ws(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) - { - SendMessageW(password, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); - db_free(&dbv); - SendMessageW(password, WM_CHAR, 13, 0); - } - - - SendMessageW(hWnd, - WM_COMMAND, - 0x4a8, // sign-in button; WARNING: This ID can change during newer Skype versions - (LPARAM)findWindow(loginControl, _T("TTntButton.UnicodeClass"))); - } - return FALSE; - } - - } - return TRUE; -} - -DWORD WINAPI setUserNamePasswordThread(LPVOID lpDummy) -{ - DWORD dwPid = (DWORD)lpDummy; - HANDLE mutex = CreateMutex(NULL, TRUE, _T("setUserNamePasswordMutex")); - - // Check double entrance - if(GetLastError() == ERROR_ALREADY_EXISTS) - return 0; - - WaitForSingleObject(SkypeReady, 5000); - EnumWindows (EnumWindowsProc, dwPid); - - ReleaseMutex(mutex); - CloseHandle(mutex); - return 0; -} - -/** - * Purpose: Finds Skype window and sets user name and password. - * - * Note: This function relies on Skype window placement. - * It should work for Skype 3.x - */ -void setUserNamePassword(int dwPid) -{ - DWORD threadId; - CreateThread(NULL, 0, &setUserNamePasswordThread, (LPVOID)dwPid, 0, &threadId); - - // Give time to thread - Sleep(100); -} diff --git a/protocols/SkypeClassic/alogon.h b/protocols/SkypeClassic/alogon.h deleted file mode 100644 index 00d2e7e703..0000000000 --- a/protocols/SkypeClassic/alogon.h +++ /dev/null @@ -1 +0,0 @@ -void setUserNamePassword(int dwPid); diff --git a/protocols/SkypeClassic/changelog.txt b/protocols/SkypeClassic/changelog.txt deleted file mode 100644 index 60526b1116..0000000000 --- a/protocols/SkypeClassic/changelog.txt +++ /dev/null @@ -1,330 +0,0 @@ -NOTES ------ - - You have to manually disable popup of messages in SKYPE, as there is - currently no function in the API to do this - Got to File/Options/Instant messages and disable the checkboxes there - - -CODE ----- - Currently a real mess. At least I splitted it up a bit now. - But hey, it kinda works... ;) - -HISTORY -------- - -0.0.0.45 - ! "NA" and "Free for chat" status are available again; NA is supported by skype and Free for chat - uses skypes "Skype Me" status; better leave it that way - ! changes to the mood message of a contact were only visible after a status change - ! plugin was crashing when status changed to offline and a proxy is used - -0.0.0.44 - ! menu item "Hang up (Skype)" was show on none skype contacts - ! fixed serveral bugs in skype startup (including starting skype twice) - ! show connecting state correctly - ! hangup while ringing caused a state where contact isnt callable anymore - * removed "NA" and "Free for chat" status - -0.0.0.43 - + Added option to suppress summary chat message after call is finished (jls17) - ! Fix hangup causes a dial command if opponent hangs up a little bit earlier (jls17) - ! removed empty chat message on incoming call - ! empty mood message is send to skype correctly - - -0.0.0.42 - + Added a trick to identify skype 3 version (fingerprint) -0.0.0.41 - + Added option to enter user name and password. (Patch by NN) - -0.0.0.40 - + Support for new core service: get avatar caps - + Option to show/hide default avatar for contacts - + Hide Skype Avatar page in user details if >= #27 - -0.0.0.39 - + Voice service support in normall calls - no support for SkypeOut yet (pescuma) - ! Made options dialog a little bit smaller, removed frame and set bold frame for popups (pescuma) - + Add more status to manage for away message - -0.0.0.38 - ! Fix the load for pre 0.7.0 #17 build - * Patch by pescuma for avatar. - -0.0.0.37 - ! Avoid empty message from myself on first message received. - + Add the Get user avatar interface - * Change the get user info thread - * code cleanup - + Support for miranda 0.8 - ! Correct use of folder plugin (using "avatar cache folder"\SKYPE). - -0.0.0.36 - ! When settings skype offline, first set proto off then contacts. - * move the broadcast of status change out of if statement in status change. - * Set contacts ofline on plugin load (avoid skype contact to be online if starts skype is not checked) - ! Fix the use of datapath for portable skype - * Allow to choose no splash - no tray - minimized even if start skype with miranda is not checked. - ! Fix bug with timestamp in irc - -0.0.0.35 - * Use unicode nick, status message, city and country in skype profile. - ! Fix for sending status change when offline - * Do not send message to skype if not attached (avoid trying to connect to api at startup) - ! Fix crash on recieving message with groupchat checked. - -0.0.0.34 - + Try to identify if chat message comes from a group chat or not - + Add a option to flag group chat message as read if not using chat.dll for group chat. - ! Fix the check of message type (group chat or normal) - -0.0.0.33 - ! Fix for flags of event and metacontact (thanks SJE) - * Next step to custom popup support (in popup option page) - ! Fix infinite for error popup - -0.0.0.32 - ! Improvemnt of the Action message support. - ! Fix empty message on first chat with a contact. - -0.0.0.31 - + First step to Action Message support ( /me ) - + Updater support for File Listing. - + First step to a custom popup for call notification. - -0.0.0.30 - + Add an option to enable/disable the timezone patch - -0.0.0.29 - ! Try to fix the bug (set skype offline when closing miranda) - -0.0.0.28 - * Improved portable skype integration - -0.0.0.27 - * Try to fix the start using custom command line - + Close skype using custom command line too - -0.0.0.26 - + Add a way to use a custom command line to start skype. - -0.0.0.25 - ! patch from markcs about timezones. - ! shutdown patch by sje - -0.0.0.24 - * Change options dialog (use tabsrmm uxtheme) - -0.0.0.23 - ! Wrong db entry name for cellular (cellucar) - + Set mirver using is video capabale to identify skype 2.0 user - -0.0.0.22 - * Options page redesigned - * Work around to force refresh of avatar in MyDetail (w8 the avatar change service) - * Change Skype protocol to Skype in options->Network - * Free buffer in status message retrieve - * First step to a details info page. - -0.0.0.21 - * Some minor bugfixes - * Severe bugfix: Message sending routine worked incorrectly (no errors were shown - even if there were sending-errors) - * Removed PingPong - thread in favour of WM_TIMER - * Fixed critical section unlocking in skypeapi.c. In certain cases, critical sections - were not left correctly. - * Fixed a bug that caused Miranda to crash on exit with Newstatusnotify plugin - (thanks to TioDuke for reporting) - * Hopefully fixed the nasty bug that caused Miranda to lockup on exit. - -0.0.0.20 - * Split service and options in two new cpp file. - * Put the default attemps number to 10 - -0.0.0.19 - * Add avatar support for own user only (no api to ge contacts avatar) - * Add set status message. - * Add Get status message for contact where viewing contact details - * Change icons (thanks to Faith Healer) - * Updater support (BETA ONLY) - * DBeEditor known module support - * Mods to avoid warning in VC++ 8 - * Implement the MyDetail requested services - -0.0.0.18 - * HOTFIX - Double File-Transfer icon removed. Please note that you can't send files - via drag & drop, because of the nature of Skype API - Skype wants to open its own - "File/Open" dialog, so I cannot supply a path to the file to be sent, therefore I - had to add a seperate File-sending function rather than using Miranda's function. - -0.0.0.17 - * Startup of Skype in a seperate thread was not solved properly. Now it should really - start in background - * The hack for the statusmode-bug is optional in the settings and is turned off - per default. (Thx to Eddie Hung for reporting problems and help) - * Added an ugly hack for the Skype-API offline bug (grr.. ) - * Nickname is now set correctly. To cleanup the existing Nicks, please go to - the options page an push the "Cleanup Nicknames" button. - This will clean out entries where the Nick was set to the Skype handle - * Fixed a bug in the message sending routine that caused errors in communication - (missed messages in Skype that were not fetched..) - * Added "Hold call" feature while calling - * Added support for conference calls (if a second user is calling while you - are in a conversation, you can now choose whether to block the call or let - the user join you in a conference with the existing caller or to put the - other caller on hold) - * Fixed a bug in the code for adding users that were just searched via the - Skype search-window but never have been in contact list. - * Fixed some bugs (memleak, nick error, ..) in the Search-Routine for - Skype-contacts. (thx to Deadman for reporting) - * Fixed a bug with unknown SKYPE_IN contacts - * Added file-sending capability (requires new Skype-version) - * Did a litte code-cleanup - * Adding / Removing contacts can now be done via the Miranda standard-dialogs if - you use the newest Skype-Version - * With the new Skype-version you are able to handle Authorisation-Requests via Miranda - now. - -0.0.0.16 - * Fixed a severe memory-allocation bug in utf8-encoded messages that caused random - crashes (oops :-O) - Thanks to Ary Dvoretz for reporting. - * Bug in SkypeStatusMode-Bug fix from last release fixed (protocol stayed offline) - * Now onlinestatus for SkypeOut-Contacts is configurable - * Made Menu-Options translatable - * Added support for calling SkypeOut-Phonenumbers. You can now dial a PSTN-Number - by calling "Do a SkypeOut call" in the main menu (or top toolbar if the - toptoolbar plugin is installed) and entering a number or - by right-clicking on a non-Skype contact and selecting "Call using SkypeOut", - if there is a phone-Number entry in the User's-Details. - This, of course, is only working if you have SkypeOut privilege - -0.0.0.15 - * Fixed a crash on Miranda-exit when error occured on Skype-Protocol start - * Fixed Bug #0000006: Now user is asked if he wants to enable the Protocol - for the current profile, if he starts with a new profile. - * Fixed Bug #0000002: Now interfacing with Skype is really stopped on going - offline if the option is enabled. (PingPong-thread killed) - - This also applies on closing Skype - * Fixed a memory leak in MsgFetchThread that appeared in the last version because - of the groupchat-implementation (free() within wrong if clause, ooops ;) - * Fixed Bug #0000005: When there is a msg from a user that is not on Skype's contact - list, the user is now added PALF_TEMPORARY and disappears again on next Miranda-start - * Implemented a fix for Skype API's statusmode bug reported by Markus Mützel: - If you change the online status while Skype is still connecting, Skype changes to - the FIRST state that it was requested to change to, after going online, instead of - the LAST state. However the bug was not reproducable for me. - * Fixed broken popup-support (I hope) - * CHANGE of behaviour (inspired by Bug #0000007): - If you turn off "Start Skype with Miranda", the plugin wouldn't search for a - running Skype instance anymore. - * Now when going online and Skype is not launched, Skype will be launched via a - seperate thread (in background) so that Miranda isn't blocked while Skype is loading - * Options Dlg. should now be translateable too. - -0.0.0.14 - - * Miranda crash on exit if Skype was not found installed should be - fixed by now. - * Implemented compatibility layer for Skype API Protocol V3 and above. - * Removed some useless code introduced in 0.0.0.12 - * Added some fixes made by TioDuke (thank you!) - - Using your own Nick instead of your Skype-Handle in conversations - - LastName 3rd token & above are not ignored any more - - Status modes "On the phone" and "out to lunch" are mapped now - * Fixed a bug that caused "Skype API not available" messages under high load. - (thanks to Romeo28 for testing!) - * Fixed a bug that caused Message sending thread to wait forever if sending - a message times out (causing dead threads) - * Skype contact list should be synced now when Skype-Status changes. - (thx to Markus Mützel for Bugreport) - * Implemented a garbage collector that removes old messages from queue - in order to prevent possible memory exhaustion - * Added option to disable all modal Error-message dialog boxes (as people - keep telling me that they are annoyed by them) - * Added langpack support for error messages - * Added option to increase the time the protocol is waiting for Skype - * Added groupchat functions. WARNING: For testing purposes only! - Currently there is a memleak which I cannot find, but even worse, - Skype API doesn't seem to support sending to a groupchat, inviting etc. - So this is currently only experimental! When you send to a groupchat you - currently send single messages to every user seperately. Skype staff - didn't answer my question about sending to groupchats so far, so it - depends on them when this feature will be available for real use. - -0.0.0.13 - A few minor fixes: - * Logging off users shouldn't flood the StatusNotify-Plugin now. - * Popup-plugin can be enabled/disabled in the options dlg. - * Implemented support for SkypeOut contacts (they caused crashes) - * Now using Nick instead of Skype-Handle as Contact list name on - adding new users, if it is available. - -0.0.0.12 - Bugfixing because of strange Skype API behaviour: - * Adding of contacts that are just searched, but not added in Skype - should be prevented now. - * Version number correct again. - -0.0.0.11 - Only minor bugfixes: - * The gender in user-details is now saved correctly to the DB - (thanks to LeON for the hint!) - * The Apply-Button should now be disabled in the options DLG by default - (thanks to sje for the bug report) - * Contactlist should be reinitialized after a SYNC-Problem now. - * Bug with usernames that contain commas should be fixed - * Protocol messages are now shown as popups if Popup-plugin is installed - -0.0.0.10 - * Hopefully recovery after sync problem works a bit better now - (Sync-Problem Messages are no longer shown) - * Now you can hang up a call directly from a contact's context menu - * Now implemented support for using Skype over a network. You can use - the included skypeproxy service to in/output Skype API messages - on a socket and can connect to it with the plugin. - So you can, for example, launch the skypeproxy service on your - Windows-server (eeek! :P) and control Skype from your workstation - using Miranda. (requested feature by foosmate) - * Now you can accept incoming calls via Miranda (or hang them up) - * The status mode bug (clist status menu was not updated properly) - should be fixed by now. - * The logfile in the dbeug-build should now always be written to the - Miranda directory. - -0.0.0.9 - * Fixed bug with error when starting Skype with Miranda ("Wheee...") - * As Skype seems to use new, UNDOCUMENTED Message types (I think it's - a severe Skype-API bug) I adapted the plugin so that it works - with new API now. This fixes the problem of not being able to receive - messages in new Skype versions. - Skype now sends "MESSAGE TYPE SAID" instead of "MESSAGE TYPE TEXT", - the bug has been reported to Skype forum. - (http://forum.skype.com/viewtopic.php?t=15435) - * Fixed a memory leak in Message-receiving routine - * Added UTF8-support for Contact properties (does this fix something?) - * Fixed a memory leak in Startup-routine - * Finally renamed Plugin from SKYPE_PROTOCOL to SKYPE internally. - Hopefully it will upgrade your existing DB seamlessly. - * Now all threads should be sync with Miranda as I'm using the pthread- - functions "borrowed" from Yahoo protocol. - -0.0.0.8 - * Now there is support for the "Occupied" mode, which is mapped to DND - This is useful for users who do a global statusmodechange so that Skype - gets to "Occupied" state instead of staying online. - * Now the protocol doesn't disable itself when you chose to not start - Skype on startup, instead it stays offline and starts Skype when you - try to go online. - -0.0.0.7 - * Fixed a bug that caused a lockup on Plugin startup (when a Window was not - reacting to the HWND_BROADCAST) (thx to Cool Blue) - * Fixed a bug in the Startup-procedure.. - * Now Skype doesn't go offline when you close Miranda (thx to Egodust) - * Now it should really work unter WIN98 (thx to TioDuke for testing) - * Implemented feature for Shutting down Skype on going offline and - restarting Skype on changing to online mode again, as many people requested. - -0.0.0.6 - * Added feature requests from kreisquadratur: - * Option to disable Skype-Menuitems - * Fixed bug with Apply-Button - * Using a nicer Skype-Icon now - * Now using Skype-Timestamp for messages - * Implementing importing history from skype (see contextmenu of contact) - * Fixed bug with processing first message of MESSAGES - List - * Found out, that RegisterClass() doesn't work for UNICODE-Programs on - non-UNICODE win98, therefore return-value check for RegisterClass removed - * Fixed a bug that caused a "We got a Sync problem :(" - -0.0.0.5 - * Fixed a bug that caused the plugin to crash with bigger contact lists - (Skype API was flooded on startup) - -0.0.0.4 - * Missed messages are fetched now - * User details work now - * More verbose error msgs now (to help Win98 user debugging his problem) - * Added option for starting skype with miranda and shutting down - Skype when closing miranda. - * You can now chose the command line options to pass to Skype on startup - * Hopefully the bug with multiple Call - Entries per user is fixed now - * Protocol name is now "Skype", not "Skype_protocol" - Remember this - when updating, so DELETE skype_protocol.dll first!! - * Secured Message Queue with a Mutex - * Fixed a Message-receiving bug that could cause delays in message-processing - * Adding a Contact in Skype now also adds it to Miranda immediately - (Deleting should also work, but doesn't because of a Skype API bug) - * Added searching for contacts, but this feature seems to be quite useless, - as Skype API doesn't support adding contacts, so you still have to add - your contacts in the Skype program, sorry - In order to do this comfortably, I added a Miranda Menu-Item for adding - Skype-contacts. - -0.0.0.3 - * I hope it's thread-safe now - * Changing the Online-Status should work correctly now - * Fixed "We got a sync problem :(" bug - big thx to Azzie - * Now starts Skype more in the background as proposed by Kreisquadratur - * Implemented PING-PONG with Skype to detect if Connection to Skype API - was lost - * Launching of Skype by Miranda improved diff --git a/protocols/SkypeClassic/contacts.cpp b/protocols/SkypeClassic/contacts.cpp deleted file mode 100644 index 8e25ae7c9d..0000000000 --- a/protocols/SkypeClassic/contacts.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Contactlist management functions - */ - -#include "skype.h" -#include "skypeapi.h" -#include "debug.h" -#include "pthread.h" -#include "gchat.h" -#include "voiceservice.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -#include -#pragma warning (pop) - -#pragma warning (disable: 4706) // assignment within conditional expression - -// Imported Globals -extern HINSTANCE hInst; -extern BOOL bSkypeOut, bIsImoproxy; -extern char protocol, g_szProtoName[]; - -// Handles -static HANDLE hMenuCallItem, hMenuCallHangup, hMenuSkypeOutCallItem, hMenuHoldCallItem, hMenuFileTransferItem, hMenuChatInitItem; - -// Check if alpha blending icons are supported -// Seems to be not neccessary -/* -BOOL SupportAlphaIcons(void) { - HANDLE hMod; - DLLVERSIONINFO tDVI={0}; - BOOL retval=FALSE; - FARPROC pDllGetVersion; - - if (!(hMod=LoadLibrary("comctl32.dll"))) return FALSE; - if (pDllGetVersion=GetProcAddress(hMod, "DllGetVersion")) { - tDVI.cbSize=sizeof(tDVI); - if (!pDllGetVersion ((DLLVERSIONINFO *)&tDVI)) { - if (GetDeviceCaps(GetDC(NULL), BITSPIXEL)*GetDeviceCaps(GetDC(NULL), PLANES)>=32 && - tDVI.dwMajorVersion>=6) - retval=TRUE; - } - } - FreeLibrary(hMod); - return retval; -} -*/ - -CLISTMENUITEM CallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Call (Skype)"); - mi.pszService=SKYPE_CALL; - - return mi; -} - -CLISTMENUITEM SkypeOutCallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_HIDDEN|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALLSKYPEOUT)); - mi.ptszName=LPGENT("Call using SkypeOut"); - mi.pszService=SKYPEOUT_CALL; - - return mi; -} - -CLISTMENUITEM HupItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Hang up call (Skype)"); - mi.pszService=SKYPE_CALLHANGUP; - - return mi; -} - -CLISTMENUITEM SkypeOutHupItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); - mi.ptszName=LPGENT("Hang up SkypeOut call"); - mi.pszService=SKYPEOUT_CALL; - return mi; -} - -CLISTMENUITEM HoldCallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HOLD)); - mi.ptszName=LPGENT("Hold call"); - mi.pszService=SKYPE_HOLDCALL; - return mi; -} - -CLISTMENUITEM ResumeCallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_RESUME)); - mi.ptszName=LPGENT("Resume call"); - mi.pszService=SKYPE_HOLDCALL; - return mi; -} - -CLISTMENUITEM FileTransferItem(void) { - CLISTMENUITEM mi={0}; - - // Stolen from file.c of Miranda core - mi.cbSize=sizeof(mi); - mi.position=-2000020000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE); - mi.ptszName=LPGENT("&File"); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.pszService=SKYPE_SENDFILE; - return mi; -} - -CLISTMENUITEM ChatInitItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000020000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon( hInst, MAKEINTRESOURCE( IDI_INVITE )); - mi.ptszName=LPGENT("&Open groupchat"); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.pszService=SKYPE_CHATNEW; - return mi; -} - -HANDLE add_contextmenu(HANDLE hContact) { - CLISTMENUITEM mi; - - UNREFERENCED_PARAMETER(hContact); - - if (!HasVoiceService()) { - mi=CallItem(); - hMenuCallItem=Menu_AddContactMenuItem(&mi); - mi=HupItem(); - hMenuCallHangup=Menu_AddContactMenuItem(&mi); - } - - mi=SkypeOutCallItem(); - hMenuSkypeOutCallItem=Menu_AddContactMenuItem(&mi); - - if (!HasVoiceService()) { - mi=HoldCallItem(); - hMenuHoldCallItem=Menu_AddContactMenuItem(&mi); - } - - // We cannot use flag PF1_FILESEND for sending files, as Skype opens its own - // sendfile-Dialog. - mi=FileTransferItem(); - hMenuFileTransferItem=Menu_AddContactMenuItem(&mi); - - mi=ChatInitItem(); - hMenuChatInitItem=Menu_AddContactMenuItem(&mi); - - - ZeroMemory(&mi,sizeof(mi)); - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Import Skype history"); - mi.pszService=SKYPE_IMPORTHISTORY; - return Menu_AddContactMenuItem(&mi); -} - -HANDLE add_mainmenu(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ADD)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Add Skype contact"); - mi.pszService=SKYPE_ADDUSER; - return Menu_AddMainMenuItem(&mi); - -} - -int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - CLISTMENUITEM mi; - char *szProto; - BOOL callAvailable = FALSE; - BOOL hangupAvailable = FALSE; - - UNREFERENCED_PARAMETER(lParam); - - if (!(szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0))) return 0; - - if (!HasVoiceService()) { - // Clear hold-Item in case it exists - mi=HoldCallItem(); - mi.flags|=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); - } - - if (!strcmp(szProto, SKYPE_PROTONAME)) { - if (!HasVoiceService()) { - if (!db_get((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - if (db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)) - mi=ResumeCallItem(); else mi=HoldCallItem(); - mi.flags=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); - - callAvailable = FALSE; - hangupAvailable = TRUE; - - db_free(&dbv); - } else { callAvailable = TRUE; hangupAvailable = FALSE; } - - if (db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)!=0) { - callAvailable = FALSE; - hangupAvailable = FALSE; - } - - mi = CallItem(); - mi.flags |= CMIM_ALL | (!callAvailable?CMIF_HIDDEN:0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallItem,(LPARAM)&mi); - - mi = HupItem(); - mi.flags |= CMIM_ALL | (!hangupAvailable?CMIF_HIDDEN:0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallHangup,(LPARAM)&mi); - } - - // Clear SkypeOut menu in case it exists - mi=SkypeOutCallItem(); - mi.flags|=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); - - // File sending and groupchat-creation works starting with protocol version 5 - if (protocol>=5) { - mi=FileTransferItem(); - if (db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) - mi.flags ^= CMIF_HIDDEN; - mi.flags |= CMIM_FLAGS; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuFileTransferItem,(LPARAM)&mi); - } - - if (protocol>=5 || bIsImoproxy) { - mi=ChatInitItem(); - if (db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0) && - db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) - mi.flags ^= CMIF_HIDDEN; - mi.flags |= CMIM_FLAGS; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuChatInitItem,(LPARAM)&mi); - } - - } else if (bSkypeOut) { - if (!db_get((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - mi=SkypeOutHupItem(); - db_free(&dbv); - } else { - mi=SkypeOutCallItem(); - if(!db_get((HANDLE)wParam,"UserInfo","MyPhone0",&dbv)) { - db_free(&dbv); - mi.flags=0; - } - } - mi.flags|=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); - } - - return 0; -} - -/* -int ClistDblClick(WPARAM wParam, LPARAM lParam) { - char *szProto; - - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, wParam, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && - db_get_w((HANDLE)wParam, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)==ID_STATUS_ONTHEPHONE) { - SkypeCall(wParam, 0); - } - - return 0; -} -*/ - -HANDLE find_contact(char *name) { - char *szProto; - int tCompareResult; - HANDLE hContact; - DBVARIANT dbv; - - // already on list? - for (hContact=(HANDLE)db_find_first();hContact != NULL;hContact=db_find_next(hContact)) - { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) - { - if (db_get_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; - tCompareResult = strcmp(dbv.pszVal, name); - db_free(&dbv); - if (tCompareResult) continue; - return hContact; // already there, return handle - } - } - return NULL; -} -HANDLE find_contactT(TCHAR *name) { - char *szProto; - int tCompareResult; - HANDLE hContact; - DBVARIANT dbv; - - // already on list? - for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) - { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) - { - if (db_get_ts(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; - tCompareResult = _tcscmp(dbv.ptszVal, name); - db_free(&dbv); - if (tCompareResult) continue; - return hContact; // already there, return handle - } - } - return NULL; -} - - -HANDLE add_contact(char *name, DWORD flags) { - HANDLE hContact; - - // already on list? - if (hContact=find_contact(name)) { - if (!(flags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 1)) { - db_unset( hContact, "CList", "NotOnList" ); - db_unset( hContact, "CList", "Hidden" ); - } - LOG(("add_contact: Found %s", name)); - return hContact; // already there, return handle - } - // no, so add - - LOG(("add_contact: Adding %s", name)); - hContact=(HANDLE)CallServiceSync(MS_DB_CONTACT_ADD, 0, 0); - if (hContact) { - if (CallServiceSync(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact,(LPARAM)SKYPE_PROTONAME)!=0) { - LOG(("add_contact: Ouch! MS_PROTO_ADDTOCONTACT failed for some reason")); - CallServiceSync(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); - return NULL; - } - if (name[0]) db_set_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, name); - - if (flags & PALF_TEMPORARY ) { - db_set_b(hContact, "CList", "NotOnList", 1); - db_set_b(hContact, "CList", "Hidden", 1); - } - if (name[0]) { - SkypeSend("GET USER %s DISPLAYNAME", name); - } else {LOG(("add_contact: Info: The contact added has no name."));} - } else {LOG(("add_contact: Ouch! MS_DB_CONTACT_ADD failed for some reason"));} - LOG(("add_contact succeeded")); - return hContact; -} - -void logoff_contacts(BOOL bCleanup) { - HANDLE hContact; - char *szProto; - DBVARIANT dbv={0}; - - LOG(("logoff_contacts: Logging off contacts.")); - for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME)) - { - if (db_get_w(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) - db_set_w(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE); - - db_unset(hContact, SKYPE_PROTONAME, "CallId"); - if (db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==1) - { - if (db_get_ts(hContact, SKYPE_PROTONAME, "ChatRoomID", &dbv)) continue; - RemChat (dbv.ptszVal); - db_free(&dbv); - } - if (db_get_s(hContact, SKYPE_PROTONAME, "Typing_Stream", &dbv) == 0) - { - if (bCleanup) SkypeSend ("ALTER APPLICATION libpurple_typing DISCONNECT %s", dbv.pszVal); - db_free(&dbv); - db_unset(hContact, SKYPE_PROTONAME, "Typing_Stream"); - } - - } - } - if (bCleanup && (protocol>=5 || bIsImoproxy)) SkypeSend ("DELETE APPLICATION libpurple_typing"); -} diff --git a/protocols/SkypeClassic/contacts.h b/protocols/SkypeClassic/contacts.h deleted file mode 100644 index 35a400c3e9..0000000000 --- a/protocols/SkypeClassic/contacts.h +++ /dev/null @@ -1,11 +0,0 @@ -// Prototypes -HANDLE add_contextmenu(HANDLE hContact); -HANDLE find_contact(char *name); -HANDLE find_contactT(TCHAR *name); -HANDLE add_contact(char *name, DWORD flags); -HANDLE add_mainmenu(void); -CLISTMENUITEM HupItem(void); -CLISTMENUITEM CallItem(void); -void logoff_contacts(BOOL bCleanup); -int PrebuildContactMenu(WPARAM, LPARAM); -//int ClistDblClick(WPARAM, LPARAM); \ No newline at end of file diff --git a/protocols/SkypeClassic/debug.cpp b/protocols/SkypeClassic/debug.cpp deleted file mode 100644 index a5d7067e8e..0000000000 --- a/protocols/SkypeClassic/debug.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _DEBUG -#pragma warning (disable: 4206) // nonstandard extension used : translation unit is empty -#else -#include "debug.h" - -#define WIN32_LEAN_AND_MEAN -//#include -#include -//#include -#include "skype.h" -#include -#include - -#define INITBUF 1024 /* Initial size of buffer */ - -#pragma warning (disable: 4706) // assignment within conditional expression - -extern char g_szProtoName[]; - -static CRITICAL_SECTION m_WriteFileMutex; -static FILE *m_fpLogFile = NULL; -static char *m_szLogBuf = NULL; -static DWORD m_iBufSize = 0; - -void init_debug(void) { - char *p; - char logfile[MAX_PATH]; - - ZeroMemory(logfile, sizeof(logfile)); - p=logfile+GetModuleFileNameA(NULL, logfile, sizeof(logfile)); - if (!(p=strrchr (logfile, '\\'))) p=logfile; else p++; - sprintf (p, "%s_log.txt", SKYPE_PROTONAME); - m_szLogBuf = calloc (1, (m_iBufSize = INITBUF)); - m_fpLogFile = fopen(logfile, "a"); - InitializeCriticalSection(&m_WriteFileMutex); -} - -void end_debug (void) { - if (m_szLogBuf) free (m_szLogBuf); - if (m_fpLogFile) fclose (m_fpLogFile); - DeleteCriticalSection(&m_WriteFileMutex); -} - -void do_log(const char *pszFormat, ...) { - char *ct, *pNewBuf; - va_list ap; - time_t lt; - int iLen; - - if (!m_szLogBuf || !m_fpLogFile) return; - EnterCriticalSection(&m_WriteFileMutex); - time(<); - ct=ctime(<); - ct[strlen(ct)-1]=0; - do - { - va_start(ap, pszFormat); - iLen = _vsnprintf(m_szLogBuf, m_iBufSize, pszFormat, ap); - va_end(ap); - if (iLen == -1) - { - if (!(pNewBuf = (char*)realloc (m_szLogBuf, m_iBufSize*2))) - { - iLen = strlen (m_szLogBuf); - break; - } - m_szLogBuf = pNewBuf; - m_iBufSize*=2; - } - } while (iLen == -1); - fprintf (m_fpLogFile, sizeof(time_t) == sizeof(int) ? "%s (%ld) [%08X] %s\n" : "%s (%lld) [%08X] %s\n", ct, lt, GetCurrentThreadId(), m_szLogBuf); - fflush (m_fpLogFile); - LeaveCriticalSection(&m_WriteFileMutex); -} -#endif \ No newline at end of file diff --git a/protocols/SkypeClassic/debug.h b/protocols/SkypeClassic/debug.h deleted file mode 100644 index 9582246251..0000000000 --- a/protocols/SkypeClassic/debug.h +++ /dev/null @@ -1,23 +0,0 @@ -//#define DEBUG_RELEASE 1 - -#ifdef DEBUG_RELEASE - #define _DEBUG 1 -#endif - -#ifdef _DEBUG - void init_debug(void); - void end_debug (void); - void do_log(const char *pszFormat, ...); - #define DEBUG_OUT(a) OUTPUT(a) - #define TRACE(a) OutputDebugString(a) - #define TRACEA(a) OutputDebugStringA(a) - #define TRACEW(a) OutputDebugStringW(a) - #define LOG(a) do_log a -#else - #define DEBUG_OUT(a) - #define LOG(a) - #define TRACE(a) - #define TRACEA(a) - #define TRACEW(a) -#endif - diff --git a/protocols/SkypeClassic/docs/changelog.txt b/protocols/SkypeClassic/docs/changelog.txt new file mode 100644 index 0000000000..60526b1116 --- /dev/null +++ b/protocols/SkypeClassic/docs/changelog.txt @@ -0,0 +1,330 @@ +NOTES +----- + + You have to manually disable popup of messages in SKYPE, as there is + currently no function in the API to do this + Got to File/Options/Instant messages and disable the checkboxes there + + +CODE +---- + Currently a real mess. At least I splitted it up a bit now. + But hey, it kinda works... ;) + +HISTORY +------- + +0.0.0.45 - ! "NA" and "Free for chat" status are available again; NA is supported by skype and Free for chat + uses skypes "Skype Me" status; better leave it that way + ! changes to the mood message of a contact were only visible after a status change + ! plugin was crashing when status changed to offline and a proxy is used + +0.0.0.44 - ! menu item "Hang up (Skype)" was show on none skype contacts + ! fixed serveral bugs in skype startup (including starting skype twice) + ! show connecting state correctly + ! hangup while ringing caused a state where contact isnt callable anymore + * removed "NA" and "Free for chat" status + +0.0.0.43 - + Added option to suppress summary chat message after call is finished (jls17) + ! Fix hangup causes a dial command if opponent hangs up a little bit earlier (jls17) + ! removed empty chat message on incoming call + ! empty mood message is send to skype correctly + + +0.0.0.42 - + Added a trick to identify skype 3 version (fingerprint) +0.0.0.41 - + Added option to enter user name and password. (Patch by NN) + +0.0.0.40 - + Support for new core service: get avatar caps + + Option to show/hide default avatar for contacts + + Hide Skype Avatar page in user details if >= #27 + +0.0.0.39 - + Voice service support in normall calls - no support for SkypeOut yet (pescuma) + ! Made options dialog a little bit smaller, removed frame and set bold frame for popups (pescuma) + + Add more status to manage for away message + +0.0.0.38 - ! Fix the load for pre 0.7.0 #17 build + * Patch by pescuma for avatar. + +0.0.0.37 - ! Avoid empty message from myself on first message received. + + Add the Get user avatar interface + * Change the get user info thread + * code cleanup + + Support for miranda 0.8 + ! Correct use of folder plugin (using "avatar cache folder"\SKYPE). + +0.0.0.36 - ! When settings skype offline, first set proto off then contacts. + * move the broadcast of status change out of if statement in status change. + * Set contacts ofline on plugin load (avoid skype contact to be online if starts skype is not checked) + ! Fix the use of datapath for portable skype + * Allow to choose no splash - no tray - minimized even if start skype with miranda is not checked. + ! Fix bug with timestamp in irc + +0.0.0.35 - * Use unicode nick, status message, city and country in skype profile. + ! Fix for sending status change when offline + * Do not send message to skype if not attached (avoid trying to connect to api at startup) + ! Fix crash on recieving message with groupchat checked. + +0.0.0.34 - + Try to identify if chat message comes from a group chat or not + + Add a option to flag group chat message as read if not using chat.dll for group chat. + ! Fix the check of message type (group chat or normal) + +0.0.0.33 - ! Fix for flags of event and metacontact (thanks SJE) + * Next step to custom popup support (in popup option page) + ! Fix infinite for error popup + +0.0.0.32 - ! Improvemnt of the Action message support. + ! Fix empty message on first chat with a contact. + +0.0.0.31 - + First step to Action Message support ( /me ) + + Updater support for File Listing. + + First step to a custom popup for call notification. + +0.0.0.30 - + Add an option to enable/disable the timezone patch + +0.0.0.29 - ! Try to fix the bug (set skype offline when closing miranda) + +0.0.0.28 - * Improved portable skype integration + +0.0.0.27 - * Try to fix the start using custom command line + + Close skype using custom command line too + +0.0.0.26 - + Add a way to use a custom command line to start skype. + +0.0.0.25 - ! patch from markcs about timezones. + ! shutdown patch by sje + +0.0.0.24 - * Change options dialog (use tabsrmm uxtheme) + +0.0.0.23 - ! Wrong db entry name for cellular (cellucar) + + Set mirver using is video capabale to identify skype 2.0 user + +0.0.0.22 - * Options page redesigned + * Work around to force refresh of avatar in MyDetail (w8 the avatar change service) + * Change Skype protocol to Skype in options->Network + * Free buffer in status message retrieve + * First step to a details info page. + +0.0.0.21 - * Some minor bugfixes + * Severe bugfix: Message sending routine worked incorrectly (no errors were shown + even if there were sending-errors) + * Removed PingPong - thread in favour of WM_TIMER + * Fixed critical section unlocking in skypeapi.c. In certain cases, critical sections + were not left correctly. + * Fixed a bug that caused Miranda to crash on exit with Newstatusnotify plugin + (thanks to TioDuke for reporting) + * Hopefully fixed the nasty bug that caused Miranda to lockup on exit. + +0.0.0.20 - * Split service and options in two new cpp file. + * Put the default attemps number to 10 + +0.0.0.19 - * Add avatar support for own user only (no api to ge contacts avatar) + * Add set status message. + * Add Get status message for contact where viewing contact details + * Change icons (thanks to Faith Healer) + * Updater support (BETA ONLY) + * DBeEditor known module support + * Mods to avoid warning in VC++ 8 + * Implement the MyDetail requested services + +0.0.0.18 - * HOTFIX - Double File-Transfer icon removed. Please note that you can't send files + via drag & drop, because of the nature of Skype API - Skype wants to open its own + "File/Open" dialog, so I cannot supply a path to the file to be sent, therefore I + had to add a seperate File-sending function rather than using Miranda's function. + +0.0.0.17 - * Startup of Skype in a seperate thread was not solved properly. Now it should really + start in background + * The hack for the statusmode-bug is optional in the settings and is turned off + per default. (Thx to Eddie Hung for reporting problems and help) + * Added an ugly hack for the Skype-API offline bug (grr.. ) + * Nickname is now set correctly. To cleanup the existing Nicks, please go to + the options page an push the "Cleanup Nicknames" button. + This will clean out entries where the Nick was set to the Skype handle + * Fixed a bug in the message sending routine that caused errors in communication + (missed messages in Skype that were not fetched..) + * Added "Hold call" feature while calling + * Added support for conference calls (if a second user is calling while you + are in a conversation, you can now choose whether to block the call or let + the user join you in a conference with the existing caller or to put the + other caller on hold) + * Fixed a bug in the code for adding users that were just searched via the + Skype search-window but never have been in contact list. + * Fixed some bugs (memleak, nick error, ..) in the Search-Routine for + Skype-contacts. (thx to Deadman for reporting) + * Fixed a bug with unknown SKYPE_IN contacts + * Added file-sending capability (requires new Skype-version) + * Did a litte code-cleanup + * Adding / Removing contacts can now be done via the Miranda standard-dialogs if + you use the newest Skype-Version + * With the new Skype-version you are able to handle Authorisation-Requests via Miranda + now. + +0.0.0.16 - * Fixed a severe memory-allocation bug in utf8-encoded messages that caused random + crashes (oops :-O) - Thanks to Ary Dvoretz for reporting. + * Bug in SkypeStatusMode-Bug fix from last release fixed (protocol stayed offline) + * Now onlinestatus for SkypeOut-Contacts is configurable + * Made Menu-Options translatable + * Added support for calling SkypeOut-Phonenumbers. You can now dial a PSTN-Number + by calling "Do a SkypeOut call" in the main menu (or top toolbar if the + toptoolbar plugin is installed) and entering a number or + by right-clicking on a non-Skype contact and selecting "Call using SkypeOut", + if there is a phone-Number entry in the User's-Details. + This, of course, is only working if you have SkypeOut privilege + +0.0.0.15 - * Fixed a crash on Miranda-exit when error occured on Skype-Protocol start + * Fixed Bug #0000006: Now user is asked if he wants to enable the Protocol + for the current profile, if he starts with a new profile. + * Fixed Bug #0000002: Now interfacing with Skype is really stopped on going + offline if the option is enabled. (PingPong-thread killed) + - This also applies on closing Skype + * Fixed a memory leak in MsgFetchThread that appeared in the last version because + of the groupchat-implementation (free() within wrong if clause, ooops ;) + * Fixed Bug #0000005: When there is a msg from a user that is not on Skype's contact + list, the user is now added PALF_TEMPORARY and disappears again on next Miranda-start + * Implemented a fix for Skype API's statusmode bug reported by Markus Mützel: + If you change the online status while Skype is still connecting, Skype changes to + the FIRST state that it was requested to change to, after going online, instead of + the LAST state. However the bug was not reproducable for me. + * Fixed broken popup-support (I hope) + * CHANGE of behaviour (inspired by Bug #0000007): + If you turn off "Start Skype with Miranda", the plugin wouldn't search for a + running Skype instance anymore. + * Now when going online and Skype is not launched, Skype will be launched via a + seperate thread (in background) so that Miranda isn't blocked while Skype is loading + * Options Dlg. should now be translateable too. + +0.0.0.14 - + * Miranda crash on exit if Skype was not found installed should be + fixed by now. + * Implemented compatibility layer for Skype API Protocol V3 and above. + * Removed some useless code introduced in 0.0.0.12 + * Added some fixes made by TioDuke (thank you!) + - Using your own Nick instead of your Skype-Handle in conversations + - LastName 3rd token & above are not ignored any more + - Status modes "On the phone" and "out to lunch" are mapped now + * Fixed a bug that caused "Skype API not available" messages under high load. + (thanks to Romeo28 for testing!) + * Fixed a bug that caused Message sending thread to wait forever if sending + a message times out (causing dead threads) + * Skype contact list should be synced now when Skype-Status changes. + (thx to Markus Mützel for Bugreport) + * Implemented a garbage collector that removes old messages from queue + in order to prevent possible memory exhaustion + * Added option to disable all modal Error-message dialog boxes (as people + keep telling me that they are annoyed by them) + * Added langpack support for error messages + * Added option to increase the time the protocol is waiting for Skype + * Added groupchat functions. WARNING: For testing purposes only! + Currently there is a memleak which I cannot find, but even worse, + Skype API doesn't seem to support sending to a groupchat, inviting etc. + So this is currently only experimental! When you send to a groupchat you + currently send single messages to every user seperately. Skype staff + didn't answer my question about sending to groupchats so far, so it + depends on them when this feature will be available for real use. + +0.0.0.13 - A few minor fixes: + * Logging off users shouldn't flood the StatusNotify-Plugin now. + * Popup-plugin can be enabled/disabled in the options dlg. + * Implemented support for SkypeOut contacts (they caused crashes) + * Now using Nick instead of Skype-Handle as Contact list name on + adding new users, if it is available. + +0.0.0.12 - Bugfixing because of strange Skype API behaviour: + * Adding of contacts that are just searched, but not added in Skype + should be prevented now. + * Version number correct again. + +0.0.0.11 - Only minor bugfixes: + * The gender in user-details is now saved correctly to the DB + (thanks to LeON for the hint!) + * The Apply-Button should now be disabled in the options DLG by default + (thanks to sje for the bug report) + * Contactlist should be reinitialized after a SYNC-Problem now. + * Bug with usernames that contain commas should be fixed + * Protocol messages are now shown as popups if Popup-plugin is installed + +0.0.0.10 - * Hopefully recovery after sync problem works a bit better now + (Sync-Problem Messages are no longer shown) + * Now you can hang up a call directly from a contact's context menu + * Now implemented support for using Skype over a network. You can use + the included skypeproxy service to in/output Skype API messages + on a socket and can connect to it with the plugin. + So you can, for example, launch the skypeproxy service on your + Windows-server (eeek! :P) and control Skype from your workstation + using Miranda. (requested feature by foosmate) + * Now you can accept incoming calls via Miranda (or hang them up) + * The status mode bug (clist status menu was not updated properly) + should be fixed by now. + * The logfile in the dbeug-build should now always be written to the + Miranda directory. + +0.0.0.9 - * Fixed bug with error when starting Skype with Miranda ("Wheee...") + * As Skype seems to use new, UNDOCUMENTED Message types (I think it's + a severe Skype-API bug) I adapted the plugin so that it works + with new API now. This fixes the problem of not being able to receive + messages in new Skype versions. + Skype now sends "MESSAGE TYPE SAID" instead of "MESSAGE TYPE TEXT", + the bug has been reported to Skype forum. + (http://forum.skype.com/viewtopic.php?t=15435) + * Fixed a memory leak in Message-receiving routine + * Added UTF8-support for Contact properties (does this fix something?) + * Fixed a memory leak in Startup-routine + * Finally renamed Plugin from SKYPE_PROTOCOL to SKYPE internally. + Hopefully it will upgrade your existing DB seamlessly. + * Now all threads should be sync with Miranda as I'm using the pthread- + functions "borrowed" from Yahoo protocol. + +0.0.0.8 - * Now there is support for the "Occupied" mode, which is mapped to DND + This is useful for users who do a global statusmodechange so that Skype + gets to "Occupied" state instead of staying online. + * Now the protocol doesn't disable itself when you chose to not start + Skype on startup, instead it stays offline and starts Skype when you + try to go online. + +0.0.0.7 - * Fixed a bug that caused a lockup on Plugin startup (when a Window was not + reacting to the HWND_BROADCAST) (thx to Cool Blue) + * Fixed a bug in the Startup-procedure.. + * Now Skype doesn't go offline when you close Miranda (thx to Egodust) + * Now it should really work unter WIN98 (thx to TioDuke for testing) + * Implemented feature for Shutting down Skype on going offline and + restarting Skype on changing to online mode again, as many people requested. + +0.0.0.6 - * Added feature requests from kreisquadratur: + * Option to disable Skype-Menuitems + * Fixed bug with Apply-Button + * Using a nicer Skype-Icon now + * Now using Skype-Timestamp for messages + * Implementing importing history from skype (see contextmenu of contact) + * Fixed bug with processing first message of MESSAGES - List + * Found out, that RegisterClass() doesn't work for UNICODE-Programs on + non-UNICODE win98, therefore return-value check for RegisterClass removed + * Fixed a bug that caused a "We got a Sync problem :(" + +0.0.0.5 - * Fixed a bug that caused the plugin to crash with bigger contact lists + (Skype API was flooded on startup) + +0.0.0.4 - * Missed messages are fetched now + * User details work now + * More verbose error msgs now (to help Win98 user debugging his problem) + * Added option for starting skype with miranda and shutting down + Skype when closing miranda. + * You can now chose the command line options to pass to Skype on startup + * Hopefully the bug with multiple Call - Entries per user is fixed now + * Protocol name is now "Skype", not "Skype_protocol" - Remember this + when updating, so DELETE skype_protocol.dll first!! + * Secured Message Queue with a Mutex + * Fixed a Message-receiving bug that could cause delays in message-processing + * Adding a Contact in Skype now also adds it to Miranda immediately + (Deleting should also work, but doesn't because of a Skype API bug) + * Added searching for contacts, but this feature seems to be quite useless, + as Skype API doesn't support adding contacts, so you still have to add + your contacts in the Skype program, sorry + In order to do this comfortably, I added a Miranda Menu-Item for adding + Skype-contacts. + +0.0.0.3 - * I hope it's thread-safe now + * Changing the Online-Status should work correctly now + * Fixed "We got a sync problem :(" bug - big thx to Azzie + * Now starts Skype more in the background as proposed by Kreisquadratur + * Implemented PING-PONG with Skype to detect if Connection to Skype API + was lost + * Launching of Skype by Miranda improved diff --git a/protocols/SkypeClassic/docs/readme.txt b/protocols/SkypeClassic/docs/readme.txt new file mode 100644 index 0000000000..333f92d90a --- /dev/null +++ b/protocols/SkypeClassic/docs/readme.txt @@ -0,0 +1,47 @@ +Skype Protocol - Maybe we can call it beta now? ;) + +As so many people requested it, here is now a implementation of the Skype +protocol for Miranda IM. +Note, that this is just a wrapper for the Skype-API, which means that Skype +has to be running while you use this plugin. +The plugin should be able to launch Skype, if it is not running on startup. +Please note, that I never coded a protocol-plugin for Miranda before, so +expect it to be buggy and unstable, I hope I have some time to correct the +severest bugs and to add more features soon. +No warranty, whatsoever! I suggest that you back up your existing Miranda +Database before using this plugin, just to be sure you have a backup if +it runs amok ;-) Feel free to improve the ugly sourcecode. +Please give me feedback, if it works for you, it would be interesting. + +NOTES - READ THEM CAREFULLY! +---------------------------- + + * You need Skype 1.0.0.97 or above in order to have access to the Skype API + * You have to manually disable popup of messages in SKYPE, as there is + currently no function in the API to do this + Got to File/Options/Short messages and disable the checkboxes there + Otherwise you would get all Skype-Messages twice (in Skype AND Miranda) + * If you always get "Unknown event" when a call is incoming and you are using + the NewEventNotify-plugin or Tabsrmm then go to the plugin's options + (Sessions / Event Notifications / Announce events of type) and disable + "other events" there. + * Importing history for a contact can be launched by clickting "import History" + in the context menu of a contact. The importing takes place in the background. + AS soon, as it's finished, you will be notified by a messagebox. + This feature is still buggy and quite a bit unpredictable. + * There is a nice Iconset with the original Skype-Icons created by X-Byte + Thanks for that. Grab it at http://dose.0wnz.at/Skype/Skype_icons.zip + * Skype API bug: When you set Skype offline via API, the contacts stay online + I made a Miranda-sie workaround for this now, but it's a Skype-API bug, + not a plugin-bug + * Skype API bug: when you rename Skypeout-contacts in Skype, their new nicks + aren't sent correctly via the API, instead, the previous nick is sent and + therefore the Miranda-name is not up-to-date after nick change. + This is not a plugin bug either. +BUGS +---- + + * To track bugs, you have to make a Debug-Build out from the source. + The plugin then will log the Skype-API communication to a logfile + called skype_log.txt so that we may se what caused the crash. + diff --git a/protocols/SkypeClassic/ezxml/ezxml.c b/protocols/SkypeClassic/ezxml/ezxml.c deleted file mode 100644 index 24c02fbd70..0000000000 --- a/protocols/SkypeClassic/ezxml/ezxml.c +++ /dev/null @@ -1,1033 +0,0 @@ -/* ezxml.c - * - * Copyright 2004-2006 Aaron Voisine - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#if defined(WIN32) || defined(_WIN32) -#include -#ifndef EZXML_NOMMAP -#define EZXML_NOMMAP -#endif -#endif - -#include -#include -#include -#include -#include -#if !defined(WIN32) && !defined(_WIN32) -#include -#endif -#include -#ifndef EZXML_NOMMAP -#include -#endif // EZXML_NOMMAP -#include -#include "ezxml.h" - -#if defined(WIN32) || defined(_WIN32) -#define vsnprintf _vsnprintf -#define snprintf _snprintf -#define open _open -#define read _read -#define write _write -#define close _close -#endif - -#define EZXML_WS "\t\r\n " // whitespace -#define EZXML_ERRL 128 // maximum error string length - -typedef struct ezxml_root *ezxml_root_t; -struct ezxml_root { // additional data for the root tag - struct ezxml xml; // is a super-struct built on top of ezxml struct - ezxml_t cur; // current xml tree insertion point - char *m; // original xml string - size_t len; // length of allocated memory for mmap, -1 for malloc - char *u; // UTF-8 conversion of string if original was UTF-16 - char *s; // start of work area - char *e; // end of work area - char **ent; // general entities (ampersand sequences) - char ***attr; // default attributes - char ***pi; // processing instructions - short standalone; // non-zero if - char err[EZXML_ERRL]; // error string -}; - -char *EZXML_NIL[] = { NULL }; // empty, null terminated array of strings - -// returns the first child tag with the given name or NULL if not found -ezxml_t ezxml_child(ezxml_t xml, const char *name) -{ - xml = (xml) ? xml->child : NULL; - while (xml && strcmp(name, xml->name)) xml = xml->sibling; - return xml; -} - -// returns the Nth tag with the same name in the same subsection or NULL if not -// found -ezxml_t ezxml_idx(ezxml_t xml, int idx) -{ - for (; xml && idx; idx--) xml = xml->next; - return xml; -} - -// returns the value of the requested tag attribute or NULL if not found -const char *ezxml_attr(ezxml_t xml, const char *attr) -{ - int i = 0, j = 1; - ezxml_root_t root = (ezxml_root_t)xml; - - if (! xml || ! xml->attr) return NULL; - while (xml->attr[i] && strcmp(attr, xml->attr[i])) i += 2; - if (xml->attr[i]) return xml->attr[i + 1]; // found attribute - - while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag - for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++); - if (! root->attr[i]) return NULL; // no matching default attributes - while (root->attr[i][j] && strcmp(attr, root->attr[i][j])) j += 3; - return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; // found default -} - -// same as ezxml_get but takes an already initialized va_list -ezxml_t ezxml_vget(ezxml_t xml, va_list ap) -{ - char *name = va_arg(ap, char *); - int idx = -1; - - if (name && *name) { - idx = va_arg(ap, int); - xml = ezxml_child(xml, name); - } - return (idx < 0) ? xml : ezxml_vget(ezxml_idx(xml, idx), ap); -} - -// Traverses the xml tree to retrieve a specific subtag. Takes a variable -// length list of tag names and indexes. The argument list must be terminated -// by either an index of -1 or an empty string tag name. Example: -// title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1); -// This retrieves the title of the 3rd book on the 1st shelf of library. -// Returns NULL if not found. -ezxml_t ezxml_get(ezxml_t xml, ...) -{ - va_list ap; - ezxml_t r; - - va_start(ap, xml); - r = ezxml_vget(xml, ap); - va_end(ap); - return r; -} - -// returns a null terminated array of processing instructions for the given -// target -const char **ezxml_pi(ezxml_t xml, const char *target) -{ - ezxml_root_t root = (ezxml_root_t)xml; - int i = 0; - - if (! root) return (const char **)EZXML_NIL; - while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag - while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target - return (const char **)((root->pi[i]) ? root->pi[i] + 1 : EZXML_NIL); -} - -// set an error string and return root -ezxml_t ezxml_err(ezxml_root_t root, char *s, const char *err, ...) -{ - va_list ap; - int line = 1; - char *t, fmt[EZXML_ERRL]; - - for (t = root->s; t < s; t++) if (*t == '\n') line++; - snprintf(fmt, EZXML_ERRL, "[error near line %d]: %s", line, err); - - va_start(ap, err); - vsnprintf(root->err, EZXML_ERRL, fmt, ap); - va_end(ap); - - return &root->xml; -} - -// Recursively decodes entity and character references and normalizes new lines -// ent is a null terminated array of alternating entity names and values. set t -// to '&' for general entity decoding, '%' for parameter entity decoding, 'c' -// for cdata sections, ' ' for attribute normalization, or '*' for non-cdata -// attribute normalization. Returns s, or if the decoded string is longer than -// s, returns a malloced string that must be freed. -char *ezxml_decode(char *s, char **ent, char t) -{ - char *e, *r = s, *m = s; - long b, c, d, l; - - for (; *s; s++) { // normalize line endings - while (*s == '\r') { - *(s++) = '\n'; - if (*s == '\n') memmove(s, (s + 1), strlen(s)); - } - } - - for (s = r; ; ) { - while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace(*s)) s++; - - if (! *s) break; - else if (t != 'c' && ! strncmp(s, "&#", 2)) { // character reference - if (s[2] == 'x') c = strtol(s + 3, &e, 16); // base 16 - else c = strtol(s + 2, &e, 10); // base 10 - if (! c || *e != ';') { s++; continue; } // not a character ref - - if (c < 0x80) *(s++) = c; // US-ASCII subset - else { // multi-byte UTF-8 sequence - for (b = 0, d = c; d; d /= 2) b++; // number of bits in c - b = (b - 2) / 5; // number of bytes in payload - *(s++) = (0xFF << (7 - b)) | (c >> (6 * b)); // head - while (b) *(s++) = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload - } - - memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';'))); - } - else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) || - (*s == '%' && t == '%')) { // entity reference - for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); - b += 2); // find entity in entity list - - if (ent[b++]) { // found a match - if ((c = strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) { - l = (d = (s - r)) + c + strlen(e); // new length - r = (r == m) ? strcpy(malloc(l), r) : realloc(r, l); - e = strchr((s = r + d), ';'); // fix up pointers - } - - memmove(s + c, e + 1, strlen(e)); // shift rest of string - strncpy(s, ent[b], c); // copy in replacement text - } - else s++; // not a known entity - } - else if ((t == ' ' || t == '*') && isspace(*s)) *(s++) = ' '; - else s++; // no decoding needed - } - - if (t == '*') { // normalize spaces for non-cdata attributes - for (s = r; *s; s++) { - if ((l = strspn(s, " "))) memmove(s, s + l, strlen(s + l) + 1); - while (*s && *s != ' ') s++; - } - if (--s >= r && *s == ' ') *s = '\0'; // trim any trailing space - } - return r; -} - -// called when parser finds start of new tag -void ezxml_open_tag(ezxml_root_t root, char *name, char **attr) -{ - ezxml_t xml = root->cur; - - if (xml->name) xml = ezxml_add_child(xml, name, strlen(xml->txt)); - else xml->name = name; // first open tag - - xml->attr = attr; - root->cur = xml; // update tag insertion point -} - -// called when parser finds character content between open and closing tag -void ezxml_char_content(ezxml_root_t root, char *s, size_t len, char t) -{ - ezxml_t xml = root->cur; - char *m = s; - size_t l; - - if (! xml || ! xml->name || ! len) return; // sanity check - - s[len] = '\0'; // null terminate text (calling functions anticipate this) - len = strlen(s = ezxml_decode(s, root->ent, t)) + 1; - - if (! *(xml->txt)) xml->txt = s; // initial character content - else { // allocate our own memory and make a copy - xml->txt = (xml->flags & EZXML_TXTM) // allocate some space - ? realloc(xml->txt, (l = strlen(xml->txt)) + len) - : strcpy(malloc((l = strlen(xml->txt)) + len), xml->txt); - strcpy(xml->txt + l, s); // add new char content - if (s != m) free(s); // free s if it was malloced by ezxml_decode() - } - - if (xml->txt != m) ezxml_set_flag(xml, EZXML_TXTM); -} - -// called when parser finds closing tag -ezxml_t ezxml_close_tag(ezxml_root_t root, char *name, char *s) -{ - if (! root->cur || ! root->cur->name || strcmp(name, root->cur->name)) - return ezxml_err(root, s, "unexpected closing tag ", name); - - root->cur = root->cur->parent; - return NULL; -} - -// checks for circular entity references, returns non-zero if no circular -// references are found, zero otherwise -int ezxml_ent_ok(char *name, char *s, char **ent) -{ - int i; - - for (; ; s++) { - while (*s && *s != '&') s++; // find next entity reference - if (! *s) return 1; - if (! strncmp(s + 1, name, strlen(name))) return 0; // circular ref. - for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i])); i += 2); - if (ent[i] && ! ezxml_ent_ok(name, ent[i + 1], ent)) return 0; - } -} - -// called when the parser finds a processing instruction -void ezxml_proc_inst(ezxml_root_t root, char *s, size_t len) -{ - int i = 0, j = 1; - char *target = s; - - s[len] = '\0'; // null terminate instruction - if (*(s += strcspn(s, EZXML_WS))) { - *s = '\0'; // null terminate target - s += strspn(s + 1, EZXML_WS) + 1; // skip whitespace after target - } - - if (! strcmp(target, "xml")) { // - if ((s = strstr(s, "standalone")) && ! strncmp(s + strspn(s + 10, - EZXML_WS "='\"") + 10, "yes", 3)) root->standalone = 1; - return; - } - - if (! root->pi[0]) *(root->pi = malloc(sizeof(char **))) = NULL; //first pi - - while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target - if (! root->pi[i]) { // new target - root->pi = realloc(root->pi, sizeof(char **) * (i + 2)); - root->pi[i] = malloc(sizeof(char *) * 3); - root->pi[i][0] = target; - root->pi[i][1] = (char *)(root->pi[i + 1] = NULL); // terminate pi list - root->pi[i][2] = strdup(""); // empty document position list - } - - while (root->pi[i][j]) j++; // find end of instruction list for this target - root->pi[i] = realloc(root->pi[i], sizeof(char *) * (j + 3)); - root->pi[i][j + 2] = realloc(root->pi[i][j + 1], j + 1); - strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<"); - root->pi[i][j + 1] = NULL; // null terminate pi list for this target - root->pi[i][j] = s; // set instruction -} - -// called when the parser finds an internal doctype subset -short ezxml_internal_dtd(ezxml_root_t root, char *s, size_t len) -{ - char q, *c, *t, *n = NULL, *v, **ent, **pe; - int i, j; - - pe = memcpy(malloc(sizeof(EZXML_NIL)), EZXML_NIL, sizeof(EZXML_NIL)); - - for (s[len] = '\0'; s; ) { - while (*s && *s != '<' && *s != '%') s++; // find next declaration - - if (! *s) break; - else if (! strncmp(s, "'); - continue; - } - - for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++); - ent = realloc(ent, (i + 3) * sizeof(char *)); // space for next ent - if (*c == '%') pe = ent; - else root->ent = ent; - - *(++s) = '\0'; // null terminate name - if ((s = strchr(v, q))) *(s++) = '\0'; // null terminate value - ent[i + 1] = ezxml_decode(v, pe, '%'); // set value - ent[i + 2] = NULL; // null terminate entity list - if (! ezxml_ent_ok(n, ent[i + 1], ent)) { // circular reference - if (ent[i + 1] != v) free(ent[i + 1]); - ezxml_err(root, v, "circular entity declaration &%s", n); - break; - } - else ent[i] = n; // set entity name - } - else if (! strncmp(s, "")) == '>') continue; - else *s = '\0'; // null terminate tag name - for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0]); i++); - - while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') { - if (*(s = n + strcspn(n, EZXML_WS))) *s = '\0'; // attr name - else { ezxml_err(root, t, "malformed ") - 1; - if (*c == ' ') continue; // cdata is default, nothing to do - v = NULL; - } - else if ((*s == '"' || *s == '\'') && // default value - (s = strchr(v = s + 1, *s))) *s = '\0'; - else { ezxml_err(root, t, "malformed attr[i]) { // new tag name - root->attr = (! i) ? malloc(2 * sizeof(char **)) - : realloc(root->attr, - (i + 2) * sizeof(char **)); - root->attr[i] = malloc(2 * sizeof(char *)); - root->attr[i][0] = t; // set tag name - root->attr[i][1] = (char *)(root->attr[i + 1] = NULL); - } - - for (j = 1; root->attr[i][j]; j += 3); // find end of list - root->attr[i] = realloc(root->attr[i], - (j + 4) * sizeof(char *)); - - root->attr[i][j + 3] = NULL; // null terminate list - root->attr[i][j + 2] = c; // is it cdata? - root->attr[i][j + 1] = (v) ? ezxml_decode(v, root->ent, *c) - : NULL; - root->attr[i][j] = n; // attribute name - } - } - else if (! strncmp(s, ""); // comments - else if (! strncmp(s, ""))) - ezxml_proc_inst(root, c, s++ - c); - } - else if (*s == '<') s = strchr(s, '>'); // skip other declarations - else if (*(s++) == '%' && ! root->standalone) break; - } - - free(pe); - return ! *root->err; -} - -// Converts a UTF-16 string to UTF-8. Returns a new string that must be freed -// or NULL if no conversion was needed. -char *ezxml_str2utf8(char **s, size_t *len) -{ - char *u; - size_t l = 0, sl, max = *len; - long c, d; - int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1; - - if (be == -1) return NULL; // not UTF-16 - - u = malloc(max); - for (sl = 2; sl < *len - 1; sl += 2) { - c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) //UTF-16BE - : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); //UTF-16LE - if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { // high-half - d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) - : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); - c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000; - } - - while (l + 6 > max) u = realloc(u, max += EZXML_BUFSIZE); - if (c < 0x80) u[l++] = c; // US-ASCII subset - else { // multi-byte UTF-8 sequence - for (b = 0, d = c; d; d /= 2) b++; // bits in c - b = (b - 2) / 5; // bytes in payload - u[l++] = (0xFF << (7 - b)) | (c >> (6 * b)); // head - while (b) u[l++] = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload - } - } - return *s = realloc(u, *len = l); -} - -// frees a tag attribute list -void ezxml_free_attr(char **attr) { - int i = 0; - char *m; - - if (! attr || attr == EZXML_NIL) return; // nothing to free - while (attr[i]) i += 2; // find end of attribute list - m = attr[i + 1]; // list of which names and values are malloced - for (i = 0; m[i]; i++) { - if (m[i] & EZXML_NAMEM) free(attr[i * 2]); - if (m[i] & EZXML_TXTM) free(attr[(i * 2) + 1]); - } - free(m); - free(attr); -} - -// parse the given xml string and return an ezxml structure -ezxml_t ezxml_parse_str(char *s, size_t len) -{ - ezxml_root_t root = (ezxml_root_t)ezxml_new(NULL); - char q, e, *d, **attr, **a = NULL; // initialize a to avoid compile warning - int l, i, j; - - root->m = s; - if (! len) return ezxml_err(root, NULL, "root tag missing"); - root->u = ezxml_str2utf8(&s, &len); // convert utf-16 to utf-8 - root->e = (root->s = s) + len; // record start and end of work area - - e = s[len - 1]; // save end char - s[len - 1] = '\0'; // turn end char into null terminator - - while (*s && *s != '<') s++; // find first tag - if (! *s) return ezxml_err(root, s, "root tag missing"); - - for (; ; ) { - attr = (char **)EZXML_NIL; - d = ++s; - - if (isalpha(*s) || *s == '_' || *s == ':' || *s < '\0') { // new tag - if (! root->cur) - return ezxml_err(root, d, "markup outside of root element"); - - s += strcspn(s, EZXML_WS "/>"); - while (isspace(*s)) *(s++) = '\0'; // null terminate tag name - - if (*s && *s != '/' && *s != '>') // find tag in default attr list - for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++); - - for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { // new attrib - attr = (l) ? realloc(attr, (l + 4) * sizeof(char *)) - : malloc(4 * sizeof(char *)); // allocate space - attr[l + 3] = (l) ? realloc(attr[l + 1], (l / 2) + 2) - : malloc(2); // mem for list of maloced vals - strcpy(attr[l + 3] + (l / 2), " "); // value is not malloced - attr[l + 2] = NULL; // null terminate list - attr[l + 1] = ""; // temporary attribute value - attr[l] = s; // set attribute name - - s += strcspn(s, EZXML_WS "=/>"); - if (*s == '=' || isspace(*s)) { - *(s++) = '\0'; // null terminate tag attribute name - q = *(s += strspn(s, EZXML_WS "=")); - if (q == '"' || q == '\'') { // attribute value - attr[l + 1] = ++s; - while (*s && *s != q) s++; - if (*s) *(s++) = '\0'; // null terminate attribute val - else { - ezxml_free_attr(attr); - return ezxml_err(root, d, "missing %c", q); - } - - for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j +=3); - attr[l + 1] = ezxml_decode(attr[l + 1], root->ent, (a - && a[j]) ? *a[j + 2] : ' '); - if (attr[l + 1] < d || attr[l + 1] > s) - attr[l + 3][l / 2] = EZXML_TXTM; // value malloced - } - } - while (isspace(*s)) s++; - } - - if (*s == '/') { // self closing tag - *(s++) = '\0'; - if ((*s && *s != '>') || (! *s && e != '>')) { - if (l) ezxml_free_attr(attr); - return ezxml_err(root, d, "missing >"); - } - ezxml_open_tag(root, d, attr); - ezxml_close_tag(root, d, s); - } - else if ((q = *s) == '>' || (! *s && e == '>')) { // open tag - *s = '\0'; // temporarily null terminate tag name - ezxml_open_tag(root, d, attr); - *s = q; - } - else { - if (l) ezxml_free_attr(attr); - return ezxml_err(root, d, "missing >"); - } - } - else if (*s == '/') { // close tag - s += strcspn(d = s + 1, EZXML_WS ">") + 1; - if (! (q = *s) && e != '>') return ezxml_err(root, d, "missing >"); - *s = '\0'; // temporarily null terminate tag name - if (ezxml_close_tag(root, d, s)) return &root->xml; - if (isspace(*s = q)) s += strspn(s, EZXML_WS); - } - else if (! strncmp(s, "!--", 3)) { // xml comment - if (! (s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) || - (! *s && e != '>')) return ezxml_err(root, d, "unclosed Yes -// 0 --> No -int AnySkypeusers(void) -{ - HANDLE hContact; - DBVARIANT dbv; - int tCompareResult; - - // already on list? - for (hContact=db_find_first(); - hContact != NULL; - hContact=db_find_next(hContact)) - { - // GETCONTACTBASEPROTO doesn't work on not loaded protocol, therefore get - // protocol from DB - if (db_get_s(hContact, "Protocol", "p", &dbv)) continue; - tCompareResult = !strcmp(dbv.pszVal, SKYPE_PROTONAME); - db_free(&dbv); - if (tCompareResult) return 1; - } - return 0; -} - - -/*void UpgradeName(char *OldName) -{ - DBCONTACTENUMSETTINGS cns; - DBCONTACTWRITESETTING cws; - DBVARIANT dbv; - HANDLE hContact=NULL; - struct PLUGINDI pdi; - - LOG(("Updating old database settings if there are any...")); - cns.pfnEnumProc=EnumOldPluginName; - cns.lParam=(LPARAM)&pdi; - cns.szModule=OldName; - cns.ofsSettings=0; - - hContact = db_find_first(); - - for ( ;; ) { - memset(&pdi,0,sizeof(pdi)); - CallService(MS_DB_CONTACT_ENUMSETTINGS,(WPARAM)hContact,(LPARAM)&cns); - // Upgrade Protocol settings to new string - if (pdi.szSettings) { - int i; - - LOG(("We're currently upgrading...")); - for (i=0;i 0 && !Miranda_Terminated()) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - UnregisterClass (WndClass.lpszClassName, hInst); - LOG (("Messagepump stopped.")); -} - -// DLL Stuff // - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) -{ - mirandaVersion = mirVersion; - - return &pluginInfo; -} - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MUUID_SKYPE_CALL, MIID_LAST}; - -extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - UNREFERENCED_PARAMETER(fdwReason); - UNREFERENCED_PARAMETER(lpvReserved); - - hInst = hinstDLL; - return TRUE; -} - - -int PreShutdown(WPARAM wParam, LPARAM lParam) { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - PostThreadMessage(msgPumpThreadId, WM_QUIT, 0, 0); - return 0; -} - -extern "C" int __declspec(dllexport) Load(void) -{ - DWORD Buffsize; - HKEY MyKey; - BOOL SkypeInstalled; - BOOL UseCustomCommand; - WSADATA wsaData; - char path[MAX_PATH]; - - mir_getLP(&pluginInfo); - - // RM: commented so it will always use predefined name - or was this really needed? - ///GetModuleFileNameA( hInst, path, sizeof( path )); - ///_splitpath (path, NULL, NULL, SKYPE_PROTONAME, NULL); - ///CharUpperA( SKYPE_PROTONAME ); - - InitializeCriticalSection(&RingAndEndcallMutex); - InitializeCriticalSection(&QueryThreadMutex); - InitializeCriticalSection(&TimeMutex); - - -#ifdef _DEBUG - init_debug(); -#endif - - LOG(("Load: Skype Plugin loading...")); - - // We need to upgrade SKYPE_PROTOCOL internal name to Skype if not already done -/* if (!db_get_b(NULL, SKYPE_PROTONAME, "UpgradeDone", 0)) - UpgradeName("SKYPE_PROTOCOL");*/ - - // Initialisation of Skype MsgQueue must be done because of Cleanup in end and - // Mutex is also initialized here. - LOG(("SkypeMsgInit initializing Skype MSG-queue")); - if (SkypeMsgInit()==-1) { - OUTPUT(_T("Memory allocation error on startup.")); - return 0; - } - - // On first run on new profile, ask user, if he wants to enable the plugin in - // this profile - // --> Fixing Issue #0000006 from bugtracker. - if (!db_get_b(NULL, SKYPE_PROTONAME, "FirstRun", 0)) { - db_set_b(NULL, SKYPE_PROTONAME, "FirstRun", 1); - if (AnySkypeusers()==0) // First run, it seems :) - if (MessageBox(NULL, TranslateT("This seems to be the first time that you're running the Skype protocol plugin. Do you want to enable the protocol for this Miranda-Profile? (If you chose NO, you can always enable it in the plugin options later."), _T("Welcome!"), MB_ICONQUESTION|MB_YESNO)==IDNO) { - char path[MAX_PATH], *filename; - GetModuleFileNameA(hInst, path, sizeof(path)); - if (filename = strrchr(path,'\\')+1) - db_set_b(NULL,"PluginDisable",filename,1); - return 0; - } - } - - - // Check if Skype is installed - SkypeInstalled=TRUE; - UseCustomCommand = (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); - UseSockets = (BOOL)db_get_b(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0); - - if (!UseSockets && !UseCustomCommand) - { - if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - { - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - { - SkypeInstalled=FALSE; - } - } - - Buffsize=sizeof(skype_path); - - if (SkypeInstalled==FALSE || RegQueryValueExA(MyKey, "SkypePath", NULL, NULL, (unsigned char *)skype_path, &Buffsize)!=ERROR_SUCCESS) - { - //OUTPUT("Skype was not found installed :( \nMaybe you are using portable skype."); - RegCloseKey(MyKey); - skype_path[0]=0; - //return 0; - } - RegCloseKey(MyKey); - } - WSAStartup(MAKEWORD(2,2), &wsaData); - - // Start Skype connection - if (!(ControlAPIAttach=RegisterWindowMessage(_T("SkypeControlAPIAttach"))) || !(ControlAPIDiscover=RegisterWindowMessage(_T("SkypeControlAPIDiscover")))) - { - OUTPUT(_T("Cannot register Window message.")); - return 0; - } - - SkypeMsgReceived=CreateSemaphore(NULL, 0, MAX_MSGS, NULL); - if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || - !(MessagePumpReady=CreateEvent(NULL, FALSE, FALSE, NULL)) || -#ifdef SKYPEBUG_OFFLN - !(GotUserstatus=CreateEvent(NULL, TRUE, FALSE, NULL)) || -#endif - !(hBuddyAdded=CreateEvent(NULL, FALSE, FALSE, NULL)) || - !(FetchMessageEvent=CreateEvent(NULL, FALSE, TRUE, NULL))) { - OUTPUT(_T("Unable to create Mutex!")); - return 0; - } - - /* Register the module */ - PROTOCOLDESCRIPTOR pd = { PROTOCOLDESCRIPTOR_V3_SIZE }; - pd.szName = SKYPE_PROTONAME; - pd.type = PROTOTYPE_PROTOCOL; - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); - - VoiceServiceInit(); - - CreateServices(); - HookEvents(); - InitVSApi(); - MsgList_Init(); - - HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); - - // Startup Message-pump - pthread_create (( pThreadFunc )MsgPump, NULL); - WaitForSingleObject(MessagePumpReady, INFINITE); - return 0; -} - - - -extern "C" int __declspec( dllexport ) Unload(void) -{ - BOOL UseCustomCommand = db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); - BOOL Shutdown = db_get_b(NULL, SKYPE_PROTONAME, "Shutdown", 0); - - LOG (("Unload started")); - - if ( Shutdown && ((skype_path && skype_path[0]) ||UseCustomCommand) ) { - - if(UseCustomCommand) - { - DBVARIANT dbv; - if(!db_get_s(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) - { - char szAbsolutePath[MAX_PATH]; - - TranslateMirandaRelativePathToAbsolute(dbv.pszVal, szAbsolutePath, FALSE); - _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); - LOG (("Unload Sent /shutdown to %s", szAbsolutePath)); - db_free(&dbv); - } - } - else - { - _spawnl(_P_NOWAIT, skype_path, skype_path, "/SHUTDOWN", NULL); - LOG (("Unload Sent /shutdown to %s", skype_path)); - } - - } - SkypeMsgCleanup(); - //WSACleanup(); - FreeVSApi(); - UnhookEvents(); - UnhookEvent(hChatEvent); - UnhookEvent (hChatMenu); - UnhookEvent (hEvInitChat); - DestroyHookableEvent(hInitChat); - VoiceServiceExit(); - GCExit(); - MsgList_Exit(); - - CloseHandle(SkypeReady); - CloseHandle(SkypeMsgReceived); -#ifdef SKYPEBUG_OFFLN - CloseHandle(GotUserstatus); -#endif - CloseHandle(MessagePumpReady); - CloseHandle(hBuddyAdded); - CloseHandle(FetchMessageEvent); - - DeleteCriticalSection(&RingAndEndcallMutex); - DeleteCriticalSection(&QueryThreadMutex); - - SkypeRegisterProxy (0, 0); - LOG (("Unload: Shutdown complete")); -#ifdef _DEBUG - end_debug(); -#endif - DeleteCriticalSection(&TimeMutex); - return 0; -} - diff --git a/protocols/SkypeClassic/skype.h b/protocols/SkypeClassic/skype.h deleted file mode 100644 index b5afb7e8f1..0000000000 --- a/protocols/SkypeClassic/skype.h +++ /dev/null @@ -1,181 +0,0 @@ -#pragma once - -#define _CRT_SECURE_NO_DEPRECATE 1 -#define TEXT_LEN 1024 -#define CP_ACP 0 - -#define code_page CP_ACP; -#define MIRANDA_CUSTOM_LP - - -// System includes -#include -#include -#include -#include -#include -#include "resource.h" -#include -#include -#include -#include -#include "util.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter - -// Miranda Includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#pragma warning (pop) - -// MyDetails defines - -// wParam=NULL -// lParam=(char *) new nickname - do not free -// return=0 for sucess -#define PS_SETMYNICKNAME "/SetNickname" - -// Optional, default value is 1024 -// wParam=NULL -// lParam=NULL -// return= <=0 for error, >0 the max length of the nick -#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength" - -// wParam=(char *)Buffer to file name -// lParam=(int)Buffer size -// return=0 for sucess -#define PS_GETMYAVATAR "/GetMyAvatar" - -// wParam=0 -// lParam=(const char *)Avatar file name -// return=0 for sucess -#define PS_SETMYAVATAR "/SetMyAvatar" - - -// Program defines -#define SKYPE_NAME "Username" -#define SKYPE_PROTO "PROTOCOL 7" -#define SKYPE_PROTONAME g_szProtoName // Name of our protocol, taken from .DLL name -#define MAX_MSGS 128 // Maximum messages in queue -#define MAX_USERLEN 32 // Maximum length of a username in Skype -#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available -#define USEPOPUP 1 // Use the popup-plugin? -#define TIMEOUT_MSGSEND 60000 // Stolen from msgdialog.c -#define MAX_MSG_AGE 30 // Maximum age in seconds before a Message from queue gets trashed -#define SKYPEBUG_OFFLN 1 // Activate fix for the SkypeAPI Offline-Bug - -// Program hooks -typedef struct { - char ChatNew[MAXMODULELABELLENGTH]; - char SetAvatar[MAXMODULELABELLENGTH]; - char SendFile[MAXMODULELABELLENGTH]; - char HoldCall[MAXMODULELABELLENGTH]; - char AnswerCall[MAXMODULELABELLENGTH]; - char ImportHistory[MAXMODULELABELLENGTH]; - char AddUser[MAXMODULELABELLENGTH]; - char SkypeOutCallUser[MAXMODULELABELLENGTH]; - char CallHangupUser[MAXMODULELABELLENGTH]; - char CallUser[MAXMODULELABELLENGTH]; -} SKYPE_SVCNAMES; -#define SKYPE_CALL g_svcNames.CallUser -#define SKYPE_CALLHANGUP g_svcNames.CallHangupUser -#define SKYPEOUT_CALL g_svcNames.SkypeOutCallUser -#define SKYPE_ADDUSER g_svcNames.AddUser -#define SKYPE_IMPORTHISTORY g_svcNames.ImportHistory -#define SKYPE_ANSWERCALL g_svcNames.AnswerCall -#define SKYPE_HOLDCALL g_svcNames.HoldCall -#define SKYPE_SENDFILE g_svcNames.SendFile -#define SKYPE_SETAVATAR g_svcNames.SetAvatar -#define SKYPE_CHATNEW g_svcNames.ChatNew -#define EVENTTYPE_CALL 2000 - -#define WM_COPYDATALOCAL WM_USER+100 // WM_COPYDATA for local window communication, needed due to Win98 bug - -#ifndef __SKYPESVC_C__ -extern SKYPE_SVCNAMES g_svcNames; -#endif - -// Skype API Communication services -#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg" -#define SKYPE_REGPROXY "/RegisterProxySvc" - -#define MUUID_SKYPE_CALL { 0x245241eb, 0x178c, 0x4b3f, { 0x91, 0xa, 0x4c, 0x4d, 0xf0, 0xa0, 0xc3, 0xb6 } } - - -// Common used code-pieces -#define OUTPUT(a) ShowMessage(IDI_ERRORS, a, 1); -#define OUTPUTA(a) ShowMessageA(IDI_ERRORS, a, 1); - -typedef void ( __cdecl* pThreadFunc )( void* ); - -// Prototypes - -void __cdecl SkypeSystemInit(char *); -void __cdecl MsgPump (char *dummy); -void PingPong(void); -void CheckIfApiIsResponding(char *); -void TellError(DWORD err); -int ShowMessage(int, TCHAR*, int); -#ifdef _UNICODE -int ShowMessageA(int iconID, char *lpzText, int mustShow); -#else -#define ShowMessageA ShowMessage -#endif -void EndCallThread(char *); -void GetInfoThread(HANDLE); -int OnDetailsInit( WPARAM, LPARAM ); -INT_PTR SkypeGetAvatarInfo(WPARAM wParam,LPARAM lParam); -INT_PTR SkypeGetAvatarCaps(WPARAM wParam,LPARAM lParam); -INT_PTR SkypeGetAwayMessage(WPARAM wParam,LPARAM lParam); -int HookContactAdded(WPARAM wParam, LPARAM lParam); -int HookContactDeleted(WPARAM wParam, LPARAM lParam); -INT_PTR ImportHistory(WPARAM wParam, LPARAM lParam); -int CreateTopToolbarButton(WPARAM wParam, LPARAM lParam); -int OnModulesLoaded(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetStatus(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetStatus(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetInfo(WPARAM wParam,LPARAM lParam); -INT_PTR SkypeAddToList(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeBasicSearch(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSendMessage(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeRecvMessage(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeUserIsTyping(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSendAuthRequest(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeRecvAuth(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAuthAllow(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAuthDeny(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAddToListByEvent(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeRegisterProxy(WPARAM wParam, LPARAM lParam); -time_t SkypeTime(time_t *timer); -void MessageSendWatchThread(void*); -int OkToExit(WPARAM wParam, LPARAM lParam); -int MirandaExit(WPARAM wParam, LPARAM lParam); -int __stdcall EnterBitmapFileName( char* szDest ); -void CleanupNicknames(char *dummy); -int InitVSApi(); -int FreeVSApi(); -HANDLE GetMetaHandle(DWORD dwId); -void LaunchSkypeAndSetStatusThread(void *newStatus); - -// Structs - -typedef struct { - char *SkypeSetting; - char *MirandaSetting; -} settings_map; diff --git a/protocols/SkypeClassic/skypeapi.cpp b/protocols/SkypeClassic/skypeapi.cpp deleted file mode 100644 index 966972f8fe..0000000000 --- a/protocols/SkypeClassic/skypeapi.cpp +++ /dev/null @@ -1,1706 +0,0 @@ -/* - * SkypeAPI - All more or less important functions that deal with Skype - */ - -#include "skype.h" -#include "skypeapi.h" -#include "utf8.h" -#include "debug.h" -#include "contacts.h" -#include "skypeproxy.h" -#include "pthread.h" -#include "gchat.h" -#include "alogon.h" -#include "msgq.h" -#include -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -#include -#include -#pragma warning (push) -#include - -#pragma warning (disable: 4706) // assignment within conditional expression - -// Imported Globals -extern HWND hSkypeWnd, g_hWnd; -extern BOOL SkypeInitialized, UseSockets, MirandaShuttingDown, bIsImoproxy; -extern int SkypeStatus, receivers; -extern HANDLE SkypeReady, SkypeMsgReceived, httbButton; -extern UINT ControlAPIAttach, ControlAPIDiscover; -extern LONG AttachStatus; -extern HINSTANCE hInst; -extern PLUGININFOEX pluginInfo; -extern HANDLE hProtocolAvatarsFolder, hHookSkypeApiRcv; -extern char DefaultAvatarsFolder[MAX_PATH+1], *pszProxyCallout, protocol, g_szProtoName[]; - -// -> Skype Message Queue functions // - -static TYP_MSGQ SkypeMsgs, SkypeSendQueue; - -status_map status_codes[] = { - {ID_STATUS_AWAY, "AWAY"}, - {ID_STATUS_NA, "NA"}, - {ID_STATUS_DND, "DND"}, - {ID_STATUS_ONLINE, "ONLINE"}, - {ID_STATUS_FREECHAT, "SKYPEME"}, // Unfortunately Skype API tells us userstatus ONLINE, if we are free for chat - {ID_STATUS_OFFLINE, "OFFLINE"}, - {ID_STATUS_INVISIBLE, "INVISIBLE"}, - {ID_STATUS_CONNECTING, "CONNECTING"}, - {0, NULL} -}; - -//status_map - - -static CRITICAL_SECTION ConnectMutex; -static BOOL rcvThreadRunning=FALSE, isConnecting = FALSE; -static SOCKET ClientSocket=INVALID_SOCKET; -static HANDLE SkypeMsgToSend=NULL; - -static char *m_szSendBuf = NULL; -static DWORD m_iBufSize = 0; - - -static int _ConnectToSkypeAPI(char *path, BOOL bStart); - - -/* SkypeReceivedMessage - * - * Purpose: Hook to be called when a message is received, if some caller is - * using our internal I/O services. - * Params : wParam - Not used - * lParam - COPYDATASTRUCT like in WM_COPYDATA - * Returns: Result from SendMessage - */ -INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam) { - return SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, lParam); -} - -/* - * Skype via Socket --> Skype2Socket connection - */ - -void rcvThread(char *dummy) { - unsigned int length; - char *buf; - COPYDATASTRUCT CopyData; - int rcv; - - if (!UseSockets) return; - rcvThreadRunning=TRUE; - for ( ;; ) { - if (ClientSocket==INVALID_SOCKET) { - rcvThreadRunning=FALSE; - return; - } - LOG(("rcvThread Receiving from socket..")); - if ((rcv=recv(ClientSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || rcv==0) { - rcvThreadRunning=FALSE; - if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} - else {LOG(("rcvThread lost connection, graceful shutdown"));} - return; - } - LOG(("rcvThread Received length, recieving message..")); - buf=(char *)calloc(1, length+1); - if ((rcv = recv(ClientSocket, buf, length, 0))==SOCKET_ERROR || rcv==0) { - rcvThreadRunning=FALSE; - if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} - else {LOG(("rcvThread lost connection, graceful shutdown"));} - free(buf); - return; - } - LOG(("Received message: %s", buf)); - - CopyData.dwData=0; - CopyData.lpData=buf; - CopyData.cbData=(DWORD)strlen(buf)+1; - if (!SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, (LPARAM)&CopyData)) - { - LOG(("SendMessage failed: %08X", GetLastError())); - } - free(buf); - } -} - -void sendThread(char *dummy) { - COPYDATASTRUCT CopyData; - LRESULT SendResult; - int oldstatus; - unsigned int length; - char *szMsg; - - while (SkypeMsgToSend) { - if (WaitForSingleObject(SkypeMsgToSend, INFINITE) != WAIT_OBJECT_0) return; - if (!(szMsg = MsgQ_Get(&SkypeSendQueue))) continue; - length=(unsigned int)strlen(szMsg); - - if (UseSockets) { - if (send(ClientSocket, (char *)&length, sizeof(length), 0) != SOCKET_ERROR && - send(ClientSocket, szMsg, length, 0) != SOCKET_ERROR) { - free (szMsg); - continue; - } - SendResult = 0; - } else { - CopyData.dwData=0; - CopyData.lpData=szMsg; - CopyData.cbData=length+1; - - // Internal comm channel - if (pszProxyCallout) { - CallService (pszProxyCallout, 0, (LPARAM)&CopyData); - free(szMsg); - continue; - } - - // If this didn't work, proceed with normal Skype API - if (!hSkypeWnd) - { - LOG(("SkypeSend: DAMN! No Skype window handle! :(")); - } - SendResult=SendMessage(hSkypeWnd, WM_COPYDATA, (WPARAM)g_hWnd, (LPARAM)&CopyData); - LOG(("SkypeSend: SendMessage returned %d", SendResult)); - free(szMsg); - } - if (!SendResult) { - SkypeInitialized=FALSE; - AttachStatus=-1; - ResetEvent(SkypeReady); - if (g_hWnd) KillTimer (g_hWnd, 1); - if (SkypeStatus!=ID_STATUS_OFFLINE) { - // Go offline - logoff_contacts(FALSE); - oldstatus=SkypeStatus; - InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); - ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); - } - // Reconnect to Skype - ResetEvent(SkypeReady); - pthread_create(LaunchSkypeAndSetStatusThread, (void *)ID_STATUS_ONLINE); - WaitForSingleObject (SkypeReady, 10000); - // SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - } - } -} - - -/* - * Skype Messagequeue - Implemented as a linked list - */ - -/* SkypeMsgInit - * - * Purpose: Initializes the Skype Message queue and API - * Returns: 0 - Success - * -1 - Memory allocation failure - */ -int SkypeMsgInit(void) { - - MsgQ_Init(&SkypeMsgs); - MsgQ_Init(&SkypeSendQueue); - InitializeCriticalSection(&ConnectMutex); - if (SkypeMsgToSend=CreateSemaphore(NULL, 0, MAX_MSGS, NULL)) { - if (m_szSendBuf = (char*)malloc(m_iBufSize=512)) { - if (_beginthread(( pThreadFunc )sendThread, 0, NULL)!=-1) - return 0; - free(m_szSendBuf); - } - CloseHandle (SkypeMsgToSend); - } - return -1; -} - -/* SkypeMsgAdd - * - * Purpose: Add Message to linked list - * Params : msg - Message to add to queue - * Returns: 0 - Success - * -1 - Memory allocation failure - */ -int SkypeMsgAdd(char *msg) { - return MsgQ_Add(&SkypeMsgs, msg)?0:-1; -} - -/* SkypeMsgCleanup - * - * Purpose: Clean up the whole MESSagequeue - free() all - */ -void SkypeMsgCleanup(void) { - int i; - - LOG(("SkypeMsgCleanup Cleaning up message queue..")); - if (receivers>1) - { - LOG (("SkypeMsgCleanup Releasing %d receivers", receivers)); - for (i=0;i %s", szMsg)); - - // Fake PING-PONG, as PING-PONG is not supported by Skype2Socket - if ((UseSockets || bIsImoproxy) && !strcmp(szMsg, "PING")) { - CopyData.dwData=0; - CopyData.lpData="PONG"; - CopyData.cbData=5; - SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, (LPARAM)&CopyData); - return 0; - } - - if (UseSockets && ClientSocket==INVALID_SOCKET) return -1; - if (!MsgQ_Add(&SkypeSendQueue, szMsg) || !ReleaseSemaphore(SkypeMsgToSend, 1, NULL)) - return -1; - return 0; -} - -/* SkypeSend - * - * Purpose: Sends the specified message to the Skype API. - * If it fails, try to reconnect zu the Skype API - * Params: use like sprintf without first param (dest. buffer) - * Returns: 0 - Success - * -1 - Failure - */ -int SkypeSend(char *szFmt, ...) { - char *pNewBuf; - va_list ap; - size_t iLen; - - // 0.0.0.17+ - Build message-String from supplied parameter list - // so the user doesn't have to care about memory allocation any more. - // 0.0.0.47+ - No more restrictions apply to the format string. - // The temporary buffer remains allocated during the session and gets - // dynamically expanded when needed. This makes sense, as this function - // is used very often and therefore it is faster to not allocate - // memory on every send. - if (!m_szSendBuf && !(m_szSendBuf=(char*)malloc(m_iBufSize=512))) return -1; - do - { - va_start(ap, szFmt); - iLen = _vsnprintf(m_szSendBuf, m_iBufSize, szFmt, ap); - va_end(ap); - if (iLen == -1) - { - if (!(pNewBuf = (char*)realloc (m_szSendBuf, m_iBufSize*2))) - { - iLen = strlen (m_szSendBuf); - break; - } - m_szSendBuf = pNewBuf; - m_iBufSize*=2; - } - } while (iLen == -1); - - return __sendMsg(m_szSendBuf); -} - -/* SkypeRcvTime - * - * Purpose: Wait, until either the message "what" is received or maxwait-Time has passed - * or there was an error and return it - * Params : what - Wait for this string-part at the beginning of a received string - * If the first character of the string is NULL, the rest after the NULL - * character will be searched in the entire received message-string. - * You can tokenize the string by using NULL characters. - * You HAVE TO end the string with a extra \0, otherwise the tokenizer - * will run amok in memory! - * st - The message timestamp must be newer or equal to st. - * Set to 0, if you do not need this and want the first message of this - * kind in the queue. - * maxwait - Wait this time before returning, if nothing was received, - * can be INFINITE - * Returns: The received message containing "what" or a ERROR-Message or NULL if - * time is up and nothing was received - * Warning: Don't forget to free() return value! - */ -char *SkypeRcvTime(char *what, time_t st, DWORD maxwait) { - char *msg, *token=NULL; - struct MsgQueue *ptr; - int j; - DWORD dwWaitStat; - BOOL bChatMsg = FALSE, bIsChatMsg = FALSE; - - LOG (("SkypeRcv - Requesting answer: %s", what)); - if (what) bChatMsg = strncmp(what, "CHATMESSAGE", 11)==0; - do { - EnterCriticalSection(&SkypeMsgs.cs); - // First, search for the requested message. On second run, also accept an ERROR - for (j=0; j<2; j++) - { - for (ptr=SkypeMsgs.l.tqh_first; ptr; ptr=ptr->l.tqe_next) { - if (what && what[0]==0) { - // Tokenizer syntax active - token=what+1; - while (*token) { - if (!strstr (ptr->message, token)) { - token=NULL; - break; - } - token+=strlen(token)+1; - } - } - - //if (j==1) {LOG(("SkypeRcv compare %s (%lu) -- %s (%lu)", ptr->message, ptr->tReceived, what, st));} - if ((st == 0 || ptr->tReceived >= st) && - (what==NULL || token || (what[0] && !strncmp(ptr->message, what, strlen(what))) || - (bIsChatMsg = (j==1 && bChatMsg && !strncmp(ptr->message, what+4, strlen(what+4)))) || - (j==1 && !strncmp(ptr->message, "ERROR", 5)))) - { - msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); - LOG(("1) InterlockedDecrement ((long *)&receivers); // receivers--; - if (receivers>1) {LOG (("SkypeRcv: %d receivers still waiting", receivers));} - - } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); - InterlockedDecrement ((long *)&receivers); - LOG(("message, what)); - pCurMsg = ptr->message; - bIsError = FALSE; - if (*what && !strncmp(pCurMsg, what, iLenWhat)) { - // Now we received a MESSAGE with an identifier. So this one is definitely for us - // However the status can be SENDING instead of SENT and next message with this number - // isn't using the ID anymore, so we have to save the ID as new identifier for message recognition - pCurMsg+=iLenWhat; - if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) - strncpy (msgid, pCurMsg, pMsg-pCurMsg); - else if (strncmp (pCurMsg, "ERROR", 5) == 0) bIsError = TRUE; - } - - if ((*msgid && strncmp (pCurMsg, msgid, strlen(msgid)) == 0) || - (!*what && ptr->tReceived >= st && - (strncmp(pCurMsg, "MESSAGE", 7) == 0 || strncmp(pCurMsg, "CHATMESSAGE", 11) == 0 ) - ) || bIsError || - (ptr->tReceived >= st && ptr->tReceived <=st+1 && - (bIsError=(strncmp(pCurMsg, "ERROR 26", 8)==0 || strncmp(pCurMsg, "ERROR 43", 8)==0)) - ) ) - { - bProcess = bIsError; - if (!bIsError) { - if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) { - pMsg++; - if (strncmp (pMsg, "STATUS ", 7) == 0) { - pMsg+=7; - if (strcmp (pMsg, "SENDING") == 0) { - // Remove dat shit - struct MsgQueue *ptr_=ptr->l.tqe_next; - - free(MsgQ_RemoveMsg(&SkypeMsgs, ptr)); - ptr=ptr_; - continue; - } - bProcess = (strcmp (pMsg, "SENT") == 0 || strcmp (pMsg, "QUEUED") == 0 || - strcmp (pMsg, "FAILED") == 0 || strcmp (pMsg, "IGNORED") == 0 || - strcmp (pMsg, "SENDING") == 0); - } - } - } - if (bProcess) { - msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); - LOG(("l.tqe_next; - } - LeaveCriticalSection(&SkypeMsgs.cs); - InterlockedIncrement ((long *)&receivers); //receivers++; - dwWaitStat = WaitForSingleObject(SkypeMsgReceived, maxwait); - if (receivers>1) InterlockedDecrement ((long *)&receivers); // receivers--; - if (receivers>1) {LOG (("SkypeRcvMsg: %d receivers still waiting", receivers));} - - } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); - InterlockedDecrement ((long *)&receivers); - LOG((" Answer %s", str, ptr)); - return ptr; -} - -char *SkypeGetID(char *szWhat, char *szWho, char *szProperty) { - char szID[16]={0}; - static DWORD dwId = 0; - - if (protocol>=4 || bIsImoproxy) sprintf (szID, "#G%d ", dwId++); - return __SkypeGet (szID, szWhat, szWho, szProperty); -} - -char *SkypeGet(char *szWhat, char *szWho, char *szProperty) { - return __SkypeGet ("", szWhat, szWho, szProperty); -} - -#ifdef _UNICODE -WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty) { - char *ptszWho = (char*)make_utf8_string(szWho); - char *pRet = SkypeGet (szWhat, ptszWho, szProperty); - free (ptszWho); - if (pRet) { - WCHAR *ptr = make_unicode_string((const unsigned char*)pRet); - free (pRet); - return ptr; - } - return NULL; -} -#endif - -char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty) { - char *ret = SkypeGet(szWhat, szWho, szProperty); - if (ret && !strncmp(ret, "ERROR", 5)) { - free (ret); - return NULL; - } - return ret; -} - -#ifdef _UNICODE -WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty) { - WCHAR *ret = SkypeGetW(szWhat, szWho, szProperty); - if (ret && !_tcsncmp(ret, _T("ERROR"), 5)) { - free (ret); - return NULL; - } - return ret; -} -#endif - - -/* SkypeGetProfile - * - * Issues a SET PROFILE szProperty szValue and waits until the answer is received - * Returns the answer or NULL on failure - * BEWARE: Don't forget to free() return value! - * - * For example: SkypeGetProfile("FULLNAME", "Tweety"); -*/ -char *SkypeGetProfile(char *szProperty) { - return SkypeGet ("PROFILE", "", szProperty); -} - -/* SkypeSetProfile - * - * -*/ -int SkypeSetProfile(char *szProperty, char *szValue) { - return SkypeSend("SET PROFILE %s %s", szProperty, szValue); -} - -/* SkypeMsgCollectGarbage - * - * Purpose: Runs the garbage collector on the Skype Message-Queue to throw out old - * messages which may unnecessarily eat up memory. - * Params : age - Time in seconds. Messages older than this value will be - * thrown out. - * Returns: 0 - No messages were thrown out - * >0 - n messages were thrown out - */ -int SkypeMsgCollectGarbage(time_t age) { - return MsgQ_CollectGarbage(&SkypeMsgs, age); -} - - -/* SkypeCall - * - * Purpose: Give a Skype call to the given User in wParam - * or hangs up existing call - * (hangUp is moved over to SkypeCallHangup) - * Params : wParam - Handle to the User to be called - * lParam - Can be NULL - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - char *msg=0; - int res; - - if (!db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - res = -1; // no direct return, because dbv needs to be freed - } else { - if (db_get_s((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; - msg=(char *)malloc(strlen(dbv.pszVal)+6); - strcpy(msg, "CALL "); - strcat(msg, dbv.pszVal); - res=SkypeSend(msg); - } - db_free(&dbv); - free(msg); - return res; -} - -/* SkypeCallHangup - * - * Prupose: Hangs up the existing call to the given User - * in wParam. - * - * Params : wParam - Handle to the User to be called - * lParam - Can be NULL - * - * Returns: 0 - Success - * -1 - Failure - * - */ -INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - char *msg=0; - int res = -1; - - if (!db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - msg=(char *)malloc(strlen(dbv.pszVal)+21); - sprintf(msg, "SET %s STATUS FINISHED", dbv.pszVal); - //sprintf(msg, "ALTER CALL %s HANGUP", dbv.pszVal); - res=SkypeSend(msg); -#if _DEBUG - db_unset((HANDLE)wParam, SKYPE_PROTONAME, "CallId"); -#endif - //} else { - // if (db_get((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; - // msg=(char *)malloc(strlen(dbv.pszVal)+6); - // strcpy(msg, "CALL "); - // strcat(msg, dbv.pszVal); - // res=SkypeSend(msg); - } - db_free(&dbv); - free(msg); - return res; -} - -/* FixNumber - * - * Purpose: Eliminates all non-numeric chars from the given phonenumber - * Params : p - Pointer to the buffer with the number - */ -static void FixNumber(char *p) { - unsigned int i; - - for (i=0;i<=strlen(p);i++) - if ((p[i]<'0' || p[i]>'9')) - if (p[i]) { - memmove(p+i, p+i+1, strlen(p+i)); - i--; - } else break; -} - - -/* DialDlgProc - * - * Purpose: Dialog procedure for the Dial-Dialog - */ -static INT_PTR CALLBACK DialDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static HANDLE hContact; - static unsigned int entries=0; - BOOL TempAdded=FALSE; - char number[64], *msg, *ptr=NULL; - - switch (uMsg){ - case WM_INITDIALOG: - hContact=(HANDLE)lParam; - Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); - TranslateDialogDefault(hwndDlg); - - if (lParam) { - DBVARIANT dbv; - BOOL bDialNow=TRUE; - - if (!db_get(hContact,"UserInfo","MyPhone1",&dbv)) { - int j; - char idstr[16]; - - // Multiple phone numbers, select one - bDialNow=FALSE; - db_free(&dbv); - for(j=0;;j++) { - sprintf(idstr,"MyPhone%d",j); - if(db_get_s(hContact,"UserInfo",idstr,&dbv)) break; - FixNumber(dbv.pszVal+1); // Leave + alone - SendDlgItemMessage(hwndDlg,IDC_NUMBER,CB_ADDSTRING,0,(LPARAM)dbv.pszVal); - db_free(&dbv); - } - } - if (db_get_s(hContact,SKYPE_PROTONAME,"SkypeOutNr",&dbv)) { - db_get_s(hContact,"UserInfo","MyPhone0",&dbv); - FixNumber(dbv.pszVal+1); - } - SetDlgItemTextA(hwndDlg, IDC_NUMBER, dbv.pszVal); - db_free(&dbv); - if (bDialNow) PostMessage(hwndDlg, WM_COMMAND, IDDIAL, 0); - } else { - DBVARIANT dbv; - char number[64]; - - for (entries=0;entriesMAX_ENTRIES) entries=MAX_ENTRIES; - for (i=entries;i>0;i--) { - sprintf(buf, "LastNumber%d", i-1); - if (!db_get_s(NULL, SKYPE_PROTONAME, buf, &dbv)) { - sprintf(buf, "LastNumber%d", i); - db_set_s(NULL, SKYPE_PROTONAME, buf, dbv.pszVal); - db_free(&dbv); - } else break; - } - db_set_s(NULL, SKYPE_PROTONAME, "LastNumber0", number); - } - TempAdded=TRUE; - } - if (!db_set_s(hContact, SKYPE_PROTONAME, "SkypeOutNr", number)) { - msg=(char *)malloc(strlen(number)+6); - strcpy(msg, "CALL "); - strcat(msg, number); - if (SkypeSend(msg) || (ptr=SkypeRcv("ERROR", 500))) { - db_unset(hContact, SKYPE_PROTONAME, "SkypeOutNr"); - if (ptr) { - OUTPUTA(ptr); - free(ptr); - } - if (TempAdded) CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); - } - free(msg); - } - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - } - break; - case WM_DESTROY: - Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); - if (httbButton) CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)httbButton, TTBST_RELEASED); - break; - } - return FALSE; -} - -/* CallstatDlgProc - * - * Purpose: Dialog procedure for the CallStatus Dialog - */ -static INT_PTR CALLBACK CallstatDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static int selected; - static DBVARIANT dbv, dbv2={0}; - - switch (uMsg){ - case WM_INITDIALOG: - { - HANDLE hContact; - char *szProto; - - if (!db_get_s((HANDLE)lParam, SKYPE_PROTONAME, "CallId", &dbv)) { - - // Check, if another call is in progress - for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && hContact!=(HANDLE)lParam && - db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 && - !db_get_s(hContact, SKYPE_PROTONAME, "CallId", &dbv2)) - { - if (db_get_b(hContact, SKYPE_PROTONAME, "OnHold", 0)) { - db_free(&dbv2); - continue; - } else break; - } - } - - if (dbv2.pszVal) - { - char buf[256], buf2[256]; - char *szOtherCaller=(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); - - Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); - TranslateDialogDefault(hwndDlg); - SendMessage(hwndDlg, WM_COMMAND, IDC_JOIN, 0); - - GetWindowTextA(hwndDlg, buf, sizeof(buf)); - _snprintf(buf2, sizeof(buf), buf, CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)lParam,0)); - SetWindowTextA(hwndDlg, buf2); - - GetDlgItemTextA(hwndDlg, IDC_JOIN, buf, sizeof(buf)); - _snprintf(buf2, sizeof(buf), buf, szOtherCaller); - SetDlgItemTextA(hwndDlg, IDC_JOIN, buf2); - - GetDlgItemTextA(hwndDlg, IDC_HOLD, buf, sizeof(buf)); - _snprintf(buf2, sizeof(buf), buf, szOtherCaller); - SetDlgItemTextA(hwndDlg, IDC_HOLD, buf2); - - return TRUE; - } - - // No other call in progress, no need for this Dlg., just answer the call - SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); - testfor ("ERROR", 200); - db_free(&dbv); - } - DestroyWindow(hwndDlg); - break; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_JOIN: - case IDC_HOLD: - case IDC_HANGUP: - CheckRadioButton(hwndDlg, IDC_JOIN, IDC_HANGUP, (selected=LOWORD(wParam))); - break; - case IDOK: - { - char *szIdCall2; - - switch (selected) { - case IDC_JOIN: - if (szIdCall2=strchr(dbv2.pszVal, ' ')) - SkypeSend("SET %s JOIN_CONFERENCE%s", dbv.pszVal, szIdCall2); - break; - case IDC_HOLD: - SkypeSend("SET %s STATUS ONHOLD", dbv2.pszVal); - SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); - break; - case IDC_HANGUP: - SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); - break; - } - - db_free(&dbv); - db_free(&dbv2); - DestroyWindow(hwndDlg); - break; - } - } - break; - case WM_DESTROY: - Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); - break; - } - return FALSE; -} - - -/* SkypeOutCallErrorCheck - * - * Purpose: Checks, if an error has occured after call and - * if so, hangs up the call - * This procedure is a seperate thread to not block the core - * while waiting for "ERROR" - * Params : szCallId - ID of the call - */ -void SkypeOutCallErrorCheck(char *szCallId) { - if (testfor("ERROR", 500)) EndCallThread(szCallId); -} - -/* SkypeOutCall - * - * Purpose: Give a SkypeOut call to the given User in wParam - * or hangs up existing call - * The user's record is searched for Phone-number entries. - * If there is more than 1 entry, the Dial-Dialog is shown - * Params : wParam - Handle to the User to be called - * If NULL, the dial-dialog is shown - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - int res = -1; - - if (wParam && !db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - res=SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); - pthread_create(( pThreadFunc )SkypeOutCallErrorCheck, _strdup(dbv.pszVal)); - db_free(&dbv); - } else if (!CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIAL), NULL, DialDlgProc, (LPARAM)wParam)) return -1; - return res; -} - -/* SkypeHoldCall - * - * Purpose: Put the call to the User given in wParam on Hold or Resumes it - * Params : wParam - Handle to the User - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - int retval; - - LOG(("SkypeHoldCall started")); - if (!wParam || db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) - return -1; - retval = SkypeSend ("SET %s STATUS %s", dbv.pszVal, - db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)?"INPROGRESS":"ONHOLD"); - db_free(&dbv); - return retval; -} - -/* SkypeAnswerCall - * - * Purpose: Answer a Skype-call when a user double-clicks on - * The incoming-call-Symbol. Works for both, Skype and SkypeOut-calls - * Params : wParam - Not used - * lParam - CLISTEVENT* - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam) { - - LOG(("SkypeAnswerCall started")); - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CALLSTAT), NULL, CallstatDlgProc, (LPARAM)((CLISTEVENT*)lParam)->hContact); - return 0; -} -/* SkypeSetNick - * - * Purpose: Set Full Name in profile - * Params : wParam=0 - * lParam=(LPARAM)(const char*)Nick text - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam) { - int retval = -1; - char *Nick = NULL; - - if (wParam & SMNN_UNICODE) - { - db_set_ws(0, SKYPE_PROTONAME, "Nick", (WCHAR*)lParam); - if (AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && - !(Nick = (char*)make_utf8_string((WCHAR*)lParam))) return -1; - } - else - { - db_set_s(0, SKYPE_PROTONAME, "Nick", (char*)lParam); - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && - utf8_encode((const char *)lParam, &Nick) == -1 ) return -1; - } - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) - retval = SkypeSend("SET PROFILE FULLNAME %s", Nick); - if (Nick) free (Nick); - - return retval; - -} -/* SkypeSetAwayMessage - * - * Purpose: Set Mood message in profile - * Params : wParam=status mode - * lParam=(LPARAM)(const char*)message text - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam) { - int retval = -1; - char *Mood = NULL; - - if (!lParam) lParam=(LPARAM)""; - if(utf8_encode((const char *)lParam, &Mood) == -1 ) return -1; - db_set_s(NULL, SKYPE_PROTONAME, "MoodText", (const char *)lParam); - - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) - retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); - free (Mood); - - return retval; -} -INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam) { - int retval = -1; - char *Mood = NULL; - - if (!lParam) lParam=(LPARAM)""; - if (!(Mood = (char*)make_utf8_string((WCHAR*)lParam))) return -1; - db_set_ws(NULL, SKYPE_PROTONAME, "MoodText", (WCHAR*)lParam); - - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) - retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); - free (Mood); - - return retval; -} - -/* SkypeSetAvatar - * - * Purpose: Set user avatar in profile - * Params : wParam=0 - * lParam=(LPARAM)(const char*)filename - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam) { - char *filename = (char *) lParam, *ext; - char AvatarFile[MAX_PATH+1], OldAvatarFile[1024]; - char *ptr = NULL; - int ret; - char command[500]; - DBVARIANT dbv = {0}; - BOOL hasOldAvatar = (db_get_s(NULL, SKYPE_PROTONAME, "AvatarFile", &dbv) == 0 && dbv.type == DBVT_ASCIIZ); - size_t len; - - if (AttachStatus != SKYPECONTROLAPI_ATTACH_SUCCESS) - return -3; - - if (filename == NULL) - return -1; - len = strlen(filename); - if (len < 4) - return -1; - - ext = &filename[len-4]; - if (_stricmp(ext, ".jpg")==0 || _stricmp(ext-1, ".jpeg")==0) - ext = "jpg"; - else if (_stricmp(ext, ".png")==0) - ext = "png"; - else - return -2; - - FoldersGetCustomPath(hProtocolAvatarsFolder, AvatarFile, sizeof(AvatarFile), DefaultAvatarsFolder); - if (!*AvatarFile) strcpy (AvatarFile, DefaultAvatarsFolder); - mir_snprintf(AvatarFile, sizeof(AvatarFile), "%s\\%s avatar.%s", AvatarFile, SKYPE_PROTONAME, ext); - - // Backup old file - if (hasOldAvatar) - { - strncpy(OldAvatarFile, dbv.pszVal, sizeof(OldAvatarFile)-4); - OldAvatarFile[sizeof(OldAvatarFile)-5] = '\0'; - strcat(OldAvatarFile, "_old"); - DeleteFileA(OldAvatarFile); - if (!MoveFileA(dbv.pszVal, OldAvatarFile)) - { - db_free(&dbv); - return -3; - } - } - - // Copy new file - if (!CopyFileA(filename, AvatarFile, FALSE)) - { - if (hasOldAvatar) - { - MoveFileA(OldAvatarFile, dbv.pszVal); - db_free(&dbv); - } - return -3; - } - - // Try to set with skype - mir_snprintf(command, sizeof(command), "SET AVATAR 1 %s", AvatarFile); - if (SkypeSend(command) || (ptr = SkypeRcv(command+4, INFINITE)) == NULL || !strncmp(ptr, "ERROR", 5)) - { - DeleteFileA(AvatarFile); - - if (hasOldAvatar) - MoveFileA(OldAvatarFile, dbv.pszVal); - - ret = -4; - } - else - { - if (hasOldAvatar) - DeleteFileA(OldAvatarFile); - - db_set_s(NULL, SKYPE_PROTONAME, "AvatarFile", AvatarFile); - - ret = 0; - } - - if (ptr != NULL) - free(ptr); - - if (hasOldAvatar) - db_free(&dbv); - - return ret; -} - - -/* SkypeSendFile - * - * Purpose: Opens the Skype-dialog to send a file - * Params : wParam - Handle to the User - * lParam - Not used - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - int retval; - - if (!wParam || db_get_s((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) - return -1; - retval=SkypeSend("OPEN FILETRANSFER %s", dbv.pszVal); - db_free(&dbv); - return retval; -} - -/* SkypeChatCreate - * - * Purpose: Creates a groupchat with the user - * Params : wParam - Handle to the User - * lParam - Not used - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - HANDLE hContact=(HANDLE)wParam; - char *ptr, *ptr2; - - if (!hContact || db_get_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) - return -1; - // Flush old messages - while (testfor("\0CHAT \0 STATUS \0", 0)); - if (SkypeSend("CHAT CREATE %s", dbv.pszVal) || !(ptr=SkypeRcv ("\0CHAT \0 STATUS \0", INFINITE))) - { - db_free(&dbv); - return -1; - } - db_free(&dbv); - if (ptr2=strstr (ptr, "STATUS")) { - *(ptr2-1)=0; - ChatStart (ptr+5, FALSE); - } - free(ptr); - return 0; -} - -/* SkypeAdduserDlg - * - * Purpose: Show Skype's Add user Dialog - */ -INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam) { - SkypeSend("OPEN ADDAFRIEND"); - return 0; -} - -/* SkypeFlush - * - * Purpose: Flush the Skype Message-List - */ -void SkypeFlush(void) { - char *ptr; - - while ((ptr=SkypeRcv(NULL, 0))!=NULL) free(ptr); -} - -/* SkypeStatusToMiranda - * - * Purpose: Converts the specified Skype-Status mode to the corresponding Miranda-Status mode - * Params : s - Skype Status - * Returns: The correct Status - * 0 - Nothing found - */ -int SkypeStatusToMiranda(char *s) { - int i; - if (!strcmp("SKYPEOUT", s)) return db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); - for(i=0; status_codes[i].szStat; i++) - if (!strcmp(status_codes[i].szStat, s)) - return status_codes[i].id; - return 0; -} - -/* MirandaStatusToSkype - * - * Purpose: Converts the specified Miranda-Status mode to the corresponding Skype-Status mode - * Params : id - Miranda Status - * Returns: The correct Status - * NULL - Nothing found - */ -char *MirandaStatusToSkype(int id) { - int i; - if (db_get_b(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) { - switch (id) - { - case ID_STATUS_NA: return "AWAY"; - case ID_STATUS_FREECHAT: return "ONLINE"; - } - } - for(i=0; status_codes[i].szStat; i++) - if (status_codes[i].id==id) - return status_codes[i].szStat; - return NULL; -} - -/* GetSkypeErrorMsg - * - * Purpose: Get a human-readable Error-Message for the supplied Skype Error-Message - * Params : str - Skype Error-Message string - * Returns: Human-readable Error Message or NULL, if nothing was found - * Warning: Don't forget to free() return value - */ -char *GetSkypeErrorMsg(char *str) { - char *pos, *reason, *msg; - - LOG (("GetSkypeErrorMsg received error: %s", str)); - if (!strncmp(str, "ERROR", 5)) { - reason=_strdup(str); - return reason; - } - if ((pos=strstr(str, "FAILURE")) ) { - switch(atoi(pos+14)) { - case MISC_ERROR: msg="Misc. Error"; break; - case USER_NOT_FOUND: msg="User does not exist, check username"; break; - case USER_NOT_ONLINE: msg="Trying to send IM to an user, who is not online"; break; - case USER_BLOCKED: msg="IM blocked by recipient"; break; - case TYPE_UNSUPPORTED: msg="Type unsupported"; break; - case SENDER_NOT_FRIEND: msg="Sending IM message to user, who has not added you to friendslist and has chosen 'only people in my friendslist can start IM'"; break; - case SENDER_NOT_AUTHORIZED: msg="Sending IM message to user, who has not authorized you and has chosen 'only people whom I have authorized can start IM'"; break; - default: msg="Unknown error"; - } - reason=(char *)malloc(strlen(pos)+strlen(msg)+3); - sprintf (reason, "%s: %s", pos, msg); - return reason; - } - return NULL; -} - -/* testfor - * - * Purpose: Wait, until the given Message-Fragment is received from Skype within - * the given amount of time - * Params : see SkypeRcv - * Returns: TRUE - Message was received within the given amount of time - * FALSE- nope, sorry - */ -BOOL testfor(char *what, DWORD maxwait) { - char *res; - - if ((res=SkypeRcv(what, maxwait))==NULL) return FALSE; - free(res); - return TRUE; -} - -char SendSkypeproxyCommand(char command) { - int length=0; - char reply=0; - BOOL res; - - res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR - || send(ClientSocket, (char *)&command, sizeof(command), 0)==SOCKET_ERROR - || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; - if (res) - return -1; - else - return reply; -} - -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : path - Path to the Skype application - * iStart - Need to start skype for status change. - * 1 = Normal start if Skype not running - * 2 = Forced startp code execution no matter what - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -int ConnectToSkypeAPI(char *path, int iStart) { - static int iRet = -1; // last request result - static volatile long newRequest = TRUE; - - InterlockedExchange(&newRequest, TRUE); // place new request - EnterCriticalSection(&ConnectMutex); // Prevent reentrance - if (iRet == -1 || newRequest) - { - iRet = _ConnectToSkypeAPI(path, iStart); - InterlockedExchange(&newRequest, FALSE); // every thread which is waiting for connect mutex will get our result as well.. but subsequent calls will set this value to true and call _Connect again - } - LeaveCriticalSection(&ConnectMutex); - return iRet; -} - -void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces) { - *szAbsolutePath = 0; - CallService (MS_UTILS_PATHTOABSOLUTE, (WPARAM)(*cszPath ? cszPath : ".\\"), (LPARAM)szAbsolutePath); - if(fQuoteSpaces && strchr((LPCSTR)szAbsolutePath, ' ')){ - memmove (szAbsolutePath+1, szAbsolutePath, strlen(szAbsolutePath)+1); - *szAbsolutePath='"'; - strcat (szAbsolutePath, "\""); - } - - TRACEA(szAbsolutePath); -} - -static int my_spawnv(const char *cmdname, const char *const *argv, PROCESS_INFORMATION *pi) -{ - int i, iLen=0; - char *CommandLine; - STARTUPINFOA si={0}; - BOOL bRet; - - memset (pi, 0, sizeof(PROCESS_INFORMATION)); - for (i=0; argv[i]; i++) iLen+=strlen(argv[i])+1; - if (!(CommandLine = (char*)calloc(1, iLen))) return -1; - for (i=0; argv[i]; i++) { - if (i) strcat (CommandLine, " "); - strcat (CommandLine, argv[i]); - } - si.cb = sizeof(si); - - bRet = CreateProcessA( cmdname,CommandLine,NULL,NULL,FALSE,0,NULL,NULL,&si,pi); - free(CommandLine); - if (!bRet) return -1; - return (DWORD)pi->hProcess; -} - -static int _ConnectToSkypeAPI(char *path, int iStart) { - BOOL SkypeLaunched=FALSE; - BOOL UseCustomCommand = db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); - int counter=0, i, j, maxattempts=db_get_w(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10); - char *args[16], *pFree = NULL; - char *SkypeOptions[]={"/notray", "/nosplash", "/minimized", "/removable", "/datapath:", "/secondary"}; - const int SkypeDefaults[]={0, 1, 1, 0, 0}; - - char szAbsolutePath[MAX_PATH]; - - LOG(("ConnectToSkypeAPI started.")); - if (UseSockets) - { - SOCKADDR_IN service; - DBVARIANT dbv; - long inet; - struct hostent *hp; - - LOG(("ConnectToSkypeAPI: Connecting to Skype2socket socket...")); - if ((ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) return -1; - - if (!db_get_s(NULL, SKYPE_PROTONAME, "Host", &dbv)) { - if ((inet=inet_addr(dbv.pszVal))==-1) { - if (hp=gethostbyname(dbv.pszVal)) - memcpy(&inet, hp->h_addr, sizeof(inet)); - else { - OUTPUT(_T("Cannot resolve host!")); - db_free(&dbv); - return -1; - } - } - db_free(&dbv); - } else { - OUTPUT(_T("Cannot find valid host to connect to.")); - return -1; - } - - service.sin_family = AF_INET; - service.sin_addr.s_addr = inet; - service.sin_port = htons((unsigned short)db_get_w(NULL, SKYPE_PROTONAME, "Port", 1401)); - - if ( connect( ClientSocket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR) return -1; - - if (db_get_b(NULL, SKYPE_PROTONAME, "RequiresPassword", 0) && !db_get_s(NULL, SKYPE_PROTONAME, "Password", &dbv)) - { - char reply=0; - - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); - if ((reply=SendSkypeproxyCommand(AUTHENTICATE))==-1) - { - db_free(&dbv); - return -1; - } - if (!reply) { - OUTPUT(_T("Authentication is not supported/needed for this Skypeproxy server. It will be disabled.")); - db_set_b(NULL, SKYPE_PROTONAME, "RequiresPassword", 0); - } else { - unsigned int length=(unsigned int)strlen(dbv.pszVal); - BOOL res; - res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR - || send(ClientSocket, dbv.pszVal, length, 0)==SOCKET_ERROR - || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; - if (res) - { - db_free(&dbv); - return -1; - } - if (!reply) - { - OUTPUT(_T("Authentication failed for this server, connection was not successful. Verify that your password is correct!")); - db_free(&dbv); - return -1; - } - } - db_free(&dbv); - } - else - { - char reply=0; - - if ((reply=SendSkypeproxyCommand(CAPABILITIES))==-1) return -1; - if (reply&USE_AUTHENTICATION) { - OUTPUT(_T("The server you specified requires authentication, but you have not supplied a password for it. Check the Skype plugin settings and try again.")); - return -1; - } - } - - - if (!rcvThreadRunning) - if(_beginthread(( pThreadFunc )rcvThread, 0, NULL)==-1) return -1; - - AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; - return 0; - } - - if (pszProxyCallout) - { - if (SkypeSend("SET USERSTATUS ONLINE")==-1) - { - AttachStatus=SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE; - return -1; - } - for ( ;; ) { - char *ptr = SkypeRcv ("CONNSTATUS", INFINITE); - if (!ptr) - { - AttachStatus=SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE; - return -1; - } - - if (strcmp (ptr+11, "CONNECTING")) - { - free (ptr); - break; - } - free (ptr); - } - - AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; - return 0; - } - - do - { - int retval; - /* To initiate communication, Client should broadcast windows message - ('SkypeControlAPIDiscover') to all windows in the system, specifying its own - window handle in wParam parameter. - */ - if (iStart != 2 || counter) - { - LOG(("ConnectToSkypeAPI sending discover message.. hWnd=%08X", (long)g_hWnd)); - retval=SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - LOG(("ConnectToSkypeAPI sent discover message returning %d", retval)); - } - - /* In response, Skype responds with - message 'SkypeControlAPIAttach' to the handle specified, and indicates - connection status - SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. - If there is no answer after 3 seconds, launch Skype as it's propably - not running. - */ - if (iStart == 2 || (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION)) - { - if (iStart != 2 && g_hWnd==NULL) - { - LOG(("ConnectToSkypeAPI: hWnd of SkypeDispatchWindow not yet set..")); - continue; - } - if ((iStart == 2 || !SkypeLaunched) && (path || UseCustomCommand)) - { - static PROCESS_INFORMATION pi={0}; - DWORD dwExitStatus = 0; - - if ((!pi.hProcess || !GetExitCodeProcess(pi.hProcess, &dwExitStatus) || dwExitStatus != STILL_ACTIVE) && - (db_get_b(NULL, SKYPE_PROTONAME, "StartSkype", 1) || iStart)) - { - LOG(("ConnectToSkypeAPI Starting Skype, as it's not running")); - - j=1; - for (i=0; i=maxattempts && AttachStatus==-1) - { - int oldstatus=SkypeStatus; - InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); - ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); - OUTPUT(_T("ERROR: Skype not running / too old / working!")); - return -1; - } - } - } - LOG(("Attachstatus %d", AttachStatus)); - } while (AttachStatus==SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE || AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); - - while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); - LOG(("Attachstatus %d", AttachStatus)); - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { - int oldstatus; - - switch(AttachStatus) { - case SKYPECONTROLAPI_ATTACH_REFUSED: - OUTPUT(_T("Skype refused the connection :(")); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - OUTPUT(_T("The Skype API is not available")); - break; - default: - LOG(("ERROR: AttachStatus: %d", AttachStatus)); - OUTPUT(_T("Wheee, Skype won't let me use the API. :(")); - } - oldstatus=SkypeStatus; - InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); - ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); - return -1; - } - - return 0; -} - -/* CloseSkypeAPI - * Purpose: Closes existing api connection - * Params: path - Path to the Skype application; could be NULL when using proxy - * Returns: always 0 - */ -int CloseSkypeAPI(char *skypePath) -{ - char szAbsolutePath[MAX_PATH]; - - logoff_contacts(TRUE); - if (UseSockets) - { - if (ClientSocket != INVALID_SOCKET) - { - closesocket(ClientSocket); - ClientSocket = INVALID_SOCKET; - } - } - else { - if (!pszProxyCallout) - { - if (AttachStatus!=-1) - { - // it was crashing when the skype-network-proxy is used (imo2sproxy for imo.im) and skype-path is empty - // now, with the "UseSockets" check and the skypePath[0] != 0 check its fixed - if (skypePath != NULL && skypePath[0] != 0) { - TranslateMirandaRelativePathToAbsolute(skypePath, szAbsolutePath, FALSE); - _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); - } - } - } - } - SkypeInitialized=FALSE; - ResetEvent(SkypeReady); - AttachStatus=-1; - if (g_hWnd) KillTimer (g_hWnd, 1); - return 0; -} -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : path - Path to the Skype application - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -//int __connectAPI(char *path) { -// int retval; -// -// EnterCriticalSection(&ConnectMutex); -// if (AttachStatus!=-1) { -// LeaveCriticalSection(&ConnectMutex); -// return -1; -// } -// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_CONNECTING); -// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, SkypeStatus); -// retval=__connectAPI(path); -// if (retval==-1) { -// logoff_contacts(); -// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_OFFLINE); -// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_CONNECTING, SkypeStatus); -// } -// LeaveCriticalSection(&ConnectMutex); -// return retval; -//} diff --git a/protocols/SkypeClassic/skypeapi.h b/protocols/SkypeClassic/skypeapi.h deleted file mode 100644 index fa4f5139a1..0000000000 --- a/protocols/SkypeClassic/skypeapi.h +++ /dev/null @@ -1,69 +0,0 @@ -// Skype API defines -#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 -#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 -#define SKYPECONTROLAPI_ATTACH_REFUSED 2 -#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 -#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 - -#define MISC_ERROR 1 -#define USER_NOT_FOUND 2 -#define USER_NOT_ONLINE 3 -#define USER_BLOCKED 4 -#define TYPE_UNSUPPORTED 5 -#define SENDER_NOT_FRIEND 6 -#define SENDER_NOT_AUTHORIZED 7 - -#define MAX_ENTRIES 128 // Max. 128 number-Entries in Dial-dlg. - -typedef struct { - int id; - char *szStat; -} status_map; - -// Prototypes -int SkypeMsgInit(void); -int SkypeMsgAdd(char *msg); -void SkypeMsgCleanup(void); -char *SkypeMsgGet(void); -int SkypeSend(char*, ...); -char *SkypeRcv(char *what, DWORD maxwait); -char *SkypeRcvTime(char *what, time_t st, DWORD maxwait); -char *SkypeRcvMsg(char *what, time_t st, HANDLE hContact, DWORD maxwait); -INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeHup(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam); -void SkypeFlush(void); -int SkypeStatusToMiranda(char *s); -char *MirandaStatusToSkype(int id); -char *GetSkypeErrorMsg(char *str); -BOOL testfor(char *what, DWORD maxwait); -int ConnectToSkypeAPI(char *path, BOOL bStart); -int CloseSkypeAPI(char *skypePath); -INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam); -int SkypeMsgCollectGarbage(time_t age); -INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam); -int SkypeSetProfile(char *szProperty, char *szValue); -char *SkypeGet(char *szWhat, char *szWho, char *szProperty); -char *SkypeGetID(char *szWhat, char *szWho, char *szProperty); -char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty); -#ifdef _UNICODE -WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty); -WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty); -#define SkypeGetT SkypeGetW -#define SkypeGetErrT SkypeGetErrW -#else -#define SkypeGetT SkypeGet -#define SkypeGetErrT SkypeGetErr -#endif -char *SkypeGetProfile(char *szProperty); -void SetUserNamePassword(); -INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam); diff --git a/protocols/SkypeClassic/skypeopt.cpp b/protocols/SkypeClassic/skypeopt.cpp deleted file mode 100644 index 078770d1a6..0000000000 --- a/protocols/SkypeClassic/skypeopt.cpp +++ /dev/null @@ -1,968 +0,0 @@ -#include "skype.h" -#include "skypeopt.h" -#include "pthread.h" -#include "gchat.h" -#include "skypeprofile.h" -#if(WINVER >= 0x0500) -#include "uxtheme.h" -#define HAVE_UXTHEMES -#endif - -#ifdef SKYPE_AUTO_DETECTION -#include "ezxml/ezxml.c" -#endif - -#ifdef UNICODE -#include "utf8.h" -#endif - -#pragma warning (disable: 4706) // assignment within conditional expression - -// VC6 SDK defines -#ifndef BIF_SHAREABLE -#define BIF_SHAREABLE 0x8000 // sharable resources displayed (remote shares, requires BIF_USENEWUI) -#endif -#ifndef BIF_NEWDIALOGSTYLE -#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize -#endif // Caller needs to call OleInitialize() before using this API -#ifndef BIF_NONEWFOLDERBUTTON -#define BIF_NONEWFOLDERBUTTON 0x0200 // Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE. -#endif - - -extern HINSTANCE hInst; -extern char protocol, g_szProtoName[]; -extern BOOL SkypeInitialized, bProtocolSet, bIsImoproxy; -extern DWORD mirandaVersion; - -BOOL showPopup, showPopupErr, popupWindowColor, popupWindowColorErr; -unsigned int popupBackColor, popupBackColorErr; -unsigned int popupTextColor, popupTextColorErr; -int popupTimeSec, popupTimeSecErr; -POPUPDATAT InCallPopup; -POPUPDATAT ErrorPopup; - -static SkypeProfile myProfile; -static HBITMAP hAvatar = NULL; - -extern BOOL PopupServiceExists; -extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD); - -int RegisterOptions(WPARAM wParam, LPARAM lParam) { - OPTIONSDIALOGPAGE odp; - - UNREFERENCED_PARAMETER(lParam); - - ZeroMemory(&odp, sizeof(odp)); - odp.cbSize = sizeof(odp); - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszGroup = "Network"; - odp.pszTitle = SKYPE_PROTONAME; - odp.pfnDlgProc = OptionsDlgProc; - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - - if(PopupServiceExists) - { - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUP); - odp.pszGroup = "Popups"; - odp.pfnDlgProc = OptPopupDlgProc; - Options_AddPage(wParam, &odp); - } - - return 0; -} - -INT_PTR CALLBACK OptPopupDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static RECT r; - - switch ( msg ) - { - case WM_INITDIALOG: - TranslateDialogDefault( hwnd ); - // Message Popup - popupTimeSec = db_get_dw(NULL, SKYPE_PROTONAME, "popupTimeSec", 4); - popupTextColor = db_get_dw(NULL, SKYPE_PROTONAME, "popupTextColor", GetSysColor(COLOR_WINDOWTEXT)); - popupBackColor = db_get_dw(NULL, SKYPE_PROTONAME, "popupBackColor", GetSysColor(COLOR_BTNFACE)); - popupWindowColor = db_get_b(NULL, SKYPE_PROTONAME, "popupWindowColor", FALSE); - showPopup = db_get_b(NULL, SKYPE_PROTONAME, "showPopup", TRUE); - // ERROR Message Popup - popupTimeSecErr = db_get_dw(NULL, SKYPE_PROTONAME, "popupTimeSecErr", 4); - popupTextColorErr = db_get_dw(NULL, SKYPE_PROTONAME, "popupTextColorErr", GetSysColor(COLOR_WINDOWTEXT)); - popupBackColorErr = db_get_dw(NULL, SKYPE_PROTONAME, "popupBackColorErr", GetSysColor(COLOR_BTNFACE)); - popupWindowColorErr = db_get_b(NULL, SKYPE_PROTONAME, "popupWindowColorErr", FALSE); - showPopupErr = db_get_b(NULL, SKYPE_PROTONAME, "showPopupErr", TRUE); - - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); - CheckDlgButton(hwnd, IDC_POPUPINCOMING, (WPARAM) showPopup); - CheckDlgButton(hwnd, IDC_USEWINCOLORS, (WPARAM) popupWindowColor); - CheckDlgButton(hwnd, IDC_POPUPERROR, (WPARAM) showPopupErr); - CheckDlgButton(hwnd, IDC_USEWINCOLORSERR, (WPARAM) popupWindowColorErr); - SendDlgItemMessage(hwnd, IDC_POPUPTIME, EM_SETLIMITTEXT, 3, 0L); - SetDlgItemInt(hwnd, IDC_POPUPTIME, popupTimeSec,FALSE); - SendDlgItemMessage(hwnd, IDC_POPUPTIMEERR, EM_SETLIMITTEXT, 3, 0L); - SetDlgItemInt(hwnd, IDC_POPUPTIMEERR, popupTimeSecErr,FALSE); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETCOLOUR,0, popupBackColor); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETCOLOUR,0, popupTextColor); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETCOLOUR,0, popupBackColorErr); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETCOLOUR,0, popupTextColorErr); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); - - - return TRUE; - break; - - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) - { - case 0: - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - db_set_dw(NULL, SKYPE_PROTONAME, "popupBackColor", popupBackColor); - db_set_dw(NULL, SKYPE_PROTONAME, "popupTextColor", popupTextColor); - db_set_dw(NULL, SKYPE_PROTONAME, "popupTimeSec", popupTimeSec); - db_set_b(NULL, SKYPE_PROTONAME, "popupWindowColor", (BYTE)popupWindowColor); - db_set_b(NULL, SKYPE_PROTONAME, "showPopup", (BYTE)showPopup); - db_set_dw(NULL, SKYPE_PROTONAME, "popupBackColorErr", popupBackColorErr); - db_set_dw(NULL, SKYPE_PROTONAME, "popupTextColorErr", popupTextColorErr); - db_set_dw(NULL, SKYPE_PROTONAME, "popupTimeSecErr", popupTimeSecErr); - db_set_b(NULL, SKYPE_PROTONAME, "popupWindowColorErr", (BYTE)popupWindowColorErr); - db_set_b(NULL, SKYPE_PROTONAME, "showPopupErr", (BYTE)showPopupErr); - break; - } - } - break; - - - - case WM_COMMAND: - switch( LOWORD( wParam )) - { - case IDC_PREVIEW: - { - HANDLE hContact; - TCHAR * lpzContactName; - - hContact = db_find_first(); - lpzContactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR); - InCallPopup.lchContact = hContact; - InCallPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); - InCallPopup.colorBack = ! popupWindowColor ? popupBackColor : GetSysColor(COLOR_BTNFACE); - InCallPopup.colorText = ! popupWindowColor ? popupTextColor : GetSysColor(COLOR_WINDOWTEXT); - InCallPopup.iSeconds = popupTimeSec; - InCallPopup.PluginData = (void *)1; - - lstrcpy(InCallPopup.lptzText, TranslateT("Incoming Skype Call")); - - lstrcpy(InCallPopup.lptzContactName, lpzContactName); - - CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&InCallPopup,0); - - - break; - } - case IDC_PREVIEWERR: - ErrorPopup.lchContact = NULL; - ErrorPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); - ErrorPopup.colorBack = ! popupWindowColorErr ? popupBackColorErr : GetSysColor(COLOR_BTNFACE); - ErrorPopup.colorText = ! popupWindowColorErr ? popupTextColorErr : GetSysColor(COLOR_WINDOWTEXT); - ErrorPopup.iSeconds = popupTimeSecErr; - ErrorPopup.PluginData = (void *)1; - - lstrcpy(ErrorPopup.lptzText, TranslateT("Preview Error Message")); - - lstrcpy(ErrorPopup.lptzContactName, _T("Error Message")); - - - CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&ErrorPopup,0); - - break; - - case IDC_POPUPTIME: - case IDC_POPUPTIMEERR: - { - BOOL Translated; - popupTimeSec = GetDlgItemInt(hwnd,IDC_POPUPTIME,&Translated,FALSE); - popupTimeSecErr = GetDlgItemInt(hwnd,IDC_POPUPTIMEERR,&Translated,FALSE); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - } - case IDC_POPUPTEXTCOLOR: - case IDC_POPUPBACKCOLOR: - case IDC_POPUPTEXTCOLORERR: - case IDC_POPUPBACKCOLORERR: - popupBackColor = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLOR,CPM_GETCOLOUR,0,0); - popupTextColor = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLOR,CPM_GETCOLOUR,0,0); - popupBackColorErr = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLORERR,CPM_GETCOLOUR,0,0); - popupTextColorErr = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLORERR,CPM_GETCOLOUR,0,0); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_USEWINCOLORS: - popupWindowColor = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORS)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_POPUPINCOMING: - showPopup = (IsDlgButtonChecked(hwnd,IDC_POPUPINCOMING)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_USEWINCOLORSERR: - popupWindowColorErr = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORSERR)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_POPUPERROR: - showPopupErr = (IsDlgButtonChecked(hwnd,IDC_POPUPERROR)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - } - - break; - - case WM_DESTROY: - break; - } - - return 0; -} - -INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int iInit = TRUE; - - UNREFERENCED_PARAMETER(wParam); - - switch(msg) - { - case WM_INITDIALOG: - { - TCITEM tci; - RECT rcClient; - GetClientRect(hwnd, &rcClient); - - iInit = TRUE; - tci.mask = TCIF_PARAM|TCIF_TEXT; - tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_DEFAULT), hwnd, OptionsDefaultDlgProc); - tci.pszText = TranslateT("Skype default"); - TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci); - MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); -#ifdef HAVE_UXTHEMES - if(MyEnableThemeDialogTexture) - MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); -#endif - - tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_ADVANCED),hwnd,OptionsAdvancedDlgProc); - tci.pszText = TranslateT("Skype advanced"); - TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 1, &tci); - MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); - ShowWindow((HWND)tci.lParam, SW_HIDE); -#ifdef HAVE_UXTHEMES - if(MyEnableThemeDialogTexture) - MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); -#endif - - tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_PROXY),hwnd,OptionsProxyDlgProc); - tci.pszText = TranslateT("Skype proxy"); - TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 2, &tci); - MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); - ShowWindow((HWND)tci.lParam, SW_HIDE); -#ifdef HAVE_UXTHEMES - if(MyEnableThemeDialogTexture) - MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); -#endif - - iInit = FALSE; - return FALSE; - } - - case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0); - if(!iInit) - SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); - break; - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - { - TCITEM tci; - int i,count; - tci.mask = TCIF_PARAM; - count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB)); - for (i=0;icode) - { - case TCN_SELCHANGING: - { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); - ShowWindow((HWND)tci.lParam,SW_HIDE); - } - break; - case TCN_SELCHANGE: - { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); - ShowWindow((HWND)tci.lParam,SW_SHOW); - } - break; - } - break; - - } - break; - } - return FALSE; -} - -INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - const int Skype2SocketControls[]={ IDC_STATIC_HOST, IDC_HOST, IDC_STATIC_PORT, IDC_PORT, IDC_REQPASS, IDC_PASSWORD, IDC_STATIC_RESTART }; - static BOOL initDlg=FALSE; - DBVARIANT dbv; - int i; - - switch (uMsg){ - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - if (!db_get_s(NULL, SKYPE_PROTONAME, "Host", &dbv)) { - SetDlgItemTextA(hwndDlg, IDC_HOST, dbv.pszVal); - db_free(&dbv); - } else SetDlgItemText(hwndDlg, IDC_HOST, _T("localhost")); - SendDlgItemMessage(hwndDlg, IDC_PORT, EM_SETLIMITTEXT, 5, 0L); - SetDlgItemInt(hwndDlg, IDC_PORT, db_get_w(NULL, SKYPE_PROTONAME, "Port", 1401), FALSE); - CheckDlgButton(hwndDlg, IDC_REQPASS, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "RequiresPassword", 0)); - CheckDlgButton(hwndDlg, IDC_USES2S, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0)); - if (!db_get_s(NULL, SKYPE_PROTONAME, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal); - db_free(&dbv); - } - SendMessage(hwndDlg, WM_COMMAND, IDC_USES2S, 0); - SendMessage(hwndDlg, WM_COMMAND, IDC_REQPASS, 0); - initDlg=FALSE; - return TRUE; - case WM_NOTIFY: { - NMHDR* nmhdr = (NMHDR*)lParam; - - switch (nmhdr->code){ - case PSN_APPLY: - case PSN_KILLACTIVE: - { - char buf[1024]; - GetDlgItemTextA(hwndDlg, IDC_HOST, buf, sizeof(buf)); - db_set_s(NULL, SKYPE_PROTONAME, "Host", buf); - db_set_w(NULL, SKYPE_PROTONAME, "Port", (unsigned short)GetDlgItemInt(hwndDlg, IDC_PORT, NULL, FALSE)); - db_set_b(NULL, SKYPE_PROTONAME, "RequiresPassword", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REQPASS), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "UseSkype2Socket", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USES2S), BM_GETCHECK,0,0))); - ZeroMemory(buf, sizeof(buf)); - GetDlgItemTextA(hwndDlg, IDC_PASSWORD, buf, sizeof(buf)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buf), (LPARAM)buf); - db_set_s(NULL, SKYPE_PROTONAME, "Password", buf); - return TRUE; - } - } - break; - } - case WM_COMMAND: { - switch (LOWORD(wParam)) { - case IDC_USES2S: - for (i=0; i=5)) { - CheckDlgButton(hwndDlg, IDC_GROUPCHAT, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0)); - CheckDlgButton(hwndDlg, IDC_GROUPCHATREAD, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "MarkGroupchatRead", 0)); - } else { - EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHAT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), FALSE); - } - -#ifdef USEPOPUP - if (ServiceExists(MS_POPUP_ADDPOPUP)) - CheckDlgButton(hwndDlg, IDC_USEPOPUP, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UsePopup", 0)); - else -#endif - EnableWindow(GetDlgItem(hwndDlg, IDC_USEPOPUP), FALSE); - - j=db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); - for(i=0;icode){ - case PSN_APPLY: - case PSN_KILLACTIVE: - db_set_b (NULL, SKYPE_PROTONAME, "EnableMenu", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_ENABLEMENU), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "UsePopup", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USEPOPUP), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "UseGroupchat", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHAT), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "MarkGroupchatRead", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "SuppressErrors", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOERRORS), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "KeepState", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_KEEPSTATE), BM_GETCHECK,0,0))); - db_set_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETITEMDATA,SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETCURSEL,0,0),0)); - db_set_b (NULL, SKYPE_PROTONAME, "UseTimeZonePatch", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_TIMEZONE), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "IgnoreTimeZones", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_IGNTZ), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "ShowDefaultSkypeAvatar", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWDEFAULTAVATAR), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "SuppressCallSummaryMessage", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SUPPRESSCALLSUMMARYMESSAGE), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "NoSkype3Stats", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSKYPE3STATS), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "ShowFullname", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWFULLNAME), BM_GETCHECK,0,0))); - return TRUE; - } - break; - } - case WM_COMMAND: { - switch (LOWORD(wParam)) { - case IDC_CLEANUP: - pthread_create(( pThreadFunc )CleanupNicknames, NULL); - break; - } - if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return 0; -} - -static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) -{ - UNREFERENCED_PARAMETER(lParam); - - switch (uMsg) - { - case BFFM_INITIALIZED: - { - // Set initial directory. -#ifdef UNICODE - wchar_t* wszInitFolder = make_unicode_string((const unsigned char*)lpData); - SendMessage(hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)wszInitFolder); - free(wszInitFolder); -#else - SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData); -#endif - break; - } - } - return 0; -} - -INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static BOOL initDlg=FALSE; - static int skypeLaunchControls[]={IDC_NOSPLASH,IDC_MINIMIZED,IDC_NOTRAY,IDC_REMOVEABLE,IDC_SECONDARY,IDC_DATAPATHO,IDC_CUSTOMCOMMAND,IDC_STATIC_PATHINFO}; - - switch (uMsg){ - case WM_INITDIALOG: - { - DBVARIANT dbv; - BOOL startSkype; - int i; - - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - startSkype=db_get_b(NULL, SKYPE_PROTONAME, "StartSkype", 1); - - CheckDlgButton(hwndDlg, IDC_STARTSKYPE, (BYTE)startSkype); - CheckDlgButton(hwndDlg, IDC_NOSPLASH, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "nosplash", 1)); - CheckDlgButton(hwndDlg, IDC_MINIMIZED, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "minimized", 1)); - CheckDlgButton(hwndDlg, IDC_NOTRAY, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "notray", 0)); - CheckDlgButton(hwndDlg, IDC_REMOVEABLE, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "removable", 0)); - CheckDlgButton(hwndDlg, IDC_SECONDARY, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "secondary", 0)); - CheckDlgButton(hwndDlg, IDC_DATAPATHO, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "datapath:", 0)); - CheckDlgButton(hwndDlg, IDC_SHUTDOWN, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "Shutdown", 0)); - CheckDlgButton(hwndDlg, IDC_UNLOADOFFLINE, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UnloadOnOffline", 0)); - - CheckDlgButton(hwndDlg, IDC_CUSTOMCOMMAND, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0)); - SendDlgItemMessage(hwndDlg, IDC_COMMANDLINE, EM_SETLIMITTEXT, MAX_PATH-1, 0L); - if(!db_get_s(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) - { - SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), dbv.pszVal); - db_free(&dbv); - } - - SendDlgItemMessage(hwndDlg, IDC_DATAPATH, EM_SETLIMITTEXT, MAX_PATH-1, 0L); - if(!db_get_s(NULL,SKYPE_PROTONAME,"datapath",&dbv)) - { - SetWindowTextA(GetDlgItem(hwndDlg, IDC_DATAPATH), dbv.pszVal); - db_free(&dbv); - } - - for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) - EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - - // LoginUserName - if(!db_get_ts(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) - { - SetWindowText(GetDlgItem(hwndDlg, IDC_USERNAME), dbv.ptszVal); - db_free(&dbv); - } - - // LoginPassword - if(!db_get_ts(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) - { - SetWindowText(GetDlgItem(hwndDlg, IDC_PASSWORD), dbv.ptszVal); - db_free(&dbv); - } - - SendDlgItemMessage(hwndDlg, IDC_CONNATTEMPTS, EM_SETLIMITTEXT, 3, 0L); - SetDlgItemInt (hwndDlg, IDC_CONNATTEMPTS, db_get_w(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10), FALSE); - SendMessage(hwndDlg, WM_COMMAND, IDC_STARTSKYPE, 0); - initDlg=FALSE; - return TRUE; - } - case WM_NOTIFY: { - NMHDR* nmhdr = (NMHDR*)lParam; - - switch (nmhdr->code){ - case PSN_APPLY: - case PSN_KILLACTIVE: - { - char text[500]; - TCHAR wtext[500]; - char szRelativePath[MAX_PATH]; - - db_set_b (NULL, SKYPE_PROTONAME, "StartSkype", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "nosplash", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSPLASH), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "minimized", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_MINIMIZED), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "notray", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOTRAY), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "Shutdown", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHUTDOWN), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "UnloadOnOffline", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_UNLOADOFFLINE), BM_GETCHECK,0,0))); - db_set_w (NULL, SKYPE_PROTONAME, "ConnectionAttempts", (unsigned short)GetDlgItemInt(hwndDlg, IDC_CONNATTEMPTS, NULL, FALSE)); - db_set_b (NULL, SKYPE_PROTONAME, "UseCustomCommand", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "datapath:", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "removable", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REMOVEABLE), BM_GETCHECK,0,0))); - db_set_b (NULL, SKYPE_PROTONAME, "secondary", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY), BM_GETCHECK,0,0))); - - GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,text,sizeof(text)); - strncpy(szRelativePath, text, sizeof(szRelativePath)-1); - CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); - db_set_s(NULL, SKYPE_PROTONAME, "CommandLine", szRelativePath); - - GetDlgItemTextA(hwndDlg,IDC_DATAPATH,text,sizeof(text)); - strncpy(szRelativePath, text, sizeof(szRelativePath)-1); - CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); - db_set_s(NULL, SKYPE_PROTONAME, "datapath", szRelativePath); - - // LoginUserName - GetDlgItemText(hwndDlg,IDC_USERNAME,wtext,sizeof(wtext)/sizeof(TCHAR)); - db_set_ts(NULL, SKYPE_PROTONAME, "LoginUserName", wtext); - - // LoginPassword - GetDlgItemText(hwndDlg,IDC_PASSWORD,wtext,sizeof(wtext)/sizeof(TCHAR)); - db_set_ts(NULL, SKYPE_PROTONAME, "LoginPassword", wtext); - - return TRUE; - } - } - break; - } - case WM_COMMAND: { - switch (LOWORD(wParam)) { - BOOL startSkype; - int i; - case IDC_STARTSKYPE: - startSkype=SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0); - - for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) - EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - break; - case IDC_CLEANUP: - pthread_create(( pThreadFunc )CleanupNicknames, NULL); - break; - case IDC_DATAPATHO: - EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - break; - case IDC_CUSTOMCOMMAND: - EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - break; - case IDC_BROWSECMDL: - { - OPENFILENAMEA ofn={0}; - BOOL gofnResult; - char szFileName[MAX_PATH]; - char szAbsolutePath[MAX_PATH]; - - ofn.lStructSize=sizeof(ofn); - ofn.hwndOwner=hwndDlg; - ofn.lpstrFilter="Executable files (*.exe)\0*.exe\0All files (*.*)\0*.*\0"; - ofn.nMaxFile=sizeof(szFileName); - ofn.lpstrDefExt="exe"; - ofn.lpstrFile=szFileName; - ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING; - - GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,szFileName,sizeof(szFileName)); - TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); - strcpy (szFileName, szAbsolutePath); - - if (!(gofnResult = GetOpenFileNameA(&ofn)) && CommDlgExtendedError() == FNERR_INVALIDFILENAME){ - strcpy(szFileName, ".\\Skype.exe"); - TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); - strcpy (szFileName, szAbsolutePath); - gofnResult = GetOpenFileNameA(&ofn); - } - - if(gofnResult) - SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), szFileName); - - break; - } - case IDC_BROWSEDP: - { - BROWSEINFOA bi={0}; - LPITEMIDLIST pidl; - char szFileName[MAX_PATH]; - char szAbsolutePath[MAX_PATH]; - - GetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName, MAX_PATH); - - TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); - bi.hwndOwner = hwndDlg; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_SHAREABLE | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON; - bi.lpfn = BrowseCallbackProc; - bi.lParam = (LPARAM)szAbsolutePath; - - if ( (pidl = SHBrowseForFolderA (&bi)) ) { - if (SHGetPathFromIDListA (pidl, szFileName)) - SetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName); - CoTaskMemFree (pidl); - } - break; - } - -#ifdef SKYPE_AUTO_DETECTION - case IDC_AUTODETECTION: - DoAutoDetect(hwndDlg); - break; -#endif - } - if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// OnDetailsInit - initializes user info dialog pages. - -int OnDetailsInit( WPARAM wParam, LPARAM lParam ) -{ - OPTIONSDIALOGPAGE odp = {0}; - HANDLE hContact = ( HANDLE )lParam; - - odp.cbSize = sizeof(odp); - odp.hIcon = NULL; - odp.hInstance = hInst; - - if ( hContact == NULL ) { - - char szTitle[256]; - - if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 27) && !bIsImoproxy) - { - mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Avatar" )); - - odp.pfnDlgProc = AvatarDlgProc; - odp.position = 1900000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETAVATAR); - odp.pszTitle = szTitle; - UserInfo_AddPage(wParam, &odp); - } - - mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Details" )); - - odp.pfnDlgProc = DetailsDlgProc; - odp.position = 1900000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETDETAILS); - odp.pszTitle = szTitle; - UserInfo_AddPage(wParam, &odp); - } - - return 0; -} - -/*AvatarDlgProc -* -* For setting the skype avatar -* -*/ -INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static RECT r; - - UNREFERENCED_PARAMETER(lParam); - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - - hAvatar = NULL; - if(ServiceExists(MS_AV_GETMYAVATAR)){ - struct avatarCacheEntry *ace = (struct avatarCacheEntry *)CallService(MS_AV_GETMYAVATAR, 0,(LPARAM) SKYPE_PROTONAME); - if (ace!=NULL) { - hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )ace->szFilename); - if ( hAvatar != NULL ) - SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); - } - } - - - - return TRUE; - - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_SETAVATAR: - { - char szFileName[ MAX_PATH ]; - if ( EnterBitmapFileName( szFileName ) != ERROR_SUCCESS ) - return FALSE; - - hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )szFileName); - if ( hAvatar != NULL ){ - SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); - CallService(SKYPE_SETAVATAR, 0, ( LPARAM )szFileName); - } - break; - } - case IDC_DELETEAVATAR: - if ( hAvatar != NULL ) { - DeleteObject( hAvatar ); - hAvatar = NULL; - CallService(SKYPE_SETAVATAR, 0, 0); - } - db_unset( NULL, SKYPE_PROTONAME, "AvatarFile" ); - InvalidateRect( hwndDlg, NULL, TRUE ); - break; - } } - break; - - case WM_DESTROY: - if ( hAvatar != NULL ) - DeleteObject( hAvatar ); - break; - } - - return 0; -} - -/*DetailsDlgProc -* -* For setting the skype infos -* -*/ -INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int sexM = 0,sexF = 0, sex; - - UNREFERENCED_PARAMETER(lParam); - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - - ZeroMemory (&myProfile, sizeof(myProfile)); - SkypeProfile_Load(&myProfile); - if(SkypeInitialized) - SkypeProfile_LoadFromSkype(&myProfile); - - SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)_T("")); - sexM = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("MALE")); - sexF = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("FEMALE")); - - switch(myProfile.Sex) { - case 0x4D: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexM, 0); break; - case 0x46: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexF, 0); break; - } - - SetDlgItemText(hwndDlg, IDC_FULLNAME, myProfile.FullName); - SetDlgItemTextA(hwndDlg, IDC_HOMEPAGE, myProfile.HomePage); - SetDlgItemTextA(hwndDlg, IDC_HOMEPHONE, myProfile.HomePhone); - SetDlgItemTextA(hwndDlg, IDC_OFFICEPHONE, myProfile.OfficePhone); - SetDlgItemText(hwndDlg, IDC_CITY, myProfile.City); - SetDlgItemText(hwndDlg, IDC_PROVINCE, myProfile.Province); - DateTime_SetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), GDT_VALID, &myProfile.Birthday); - return TRUE; - - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_SAVEDETAILS: - GetDlgItemText(hwndDlg,IDC_FULLNAME,myProfile.FullName,sizeof(myProfile.FullName)/sizeof(TCHAR)); - GetDlgItemTextA(hwndDlg,IDC_HOMEPAGE,myProfile.HomePage,sizeof(myProfile.HomePage)/sizeof(TCHAR)); - GetDlgItemTextA(hwndDlg,IDC_HOMEPHONE,myProfile.HomePhone,sizeof(myProfile.HomePhone)/sizeof(TCHAR)); - GetDlgItemTextA(hwndDlg,IDC_OFFICEPHONE,myProfile.OfficePhone,sizeof(myProfile.OfficePhone)/sizeof(TCHAR)); - GetDlgItemText(hwndDlg,IDC_CITY,myProfile.City,sizeof(myProfile.City)/sizeof(TCHAR)); - GetDlgItemText(hwndDlg,IDC_PROVINCE,myProfile.Province,sizeof(myProfile.Province)/sizeof(TCHAR)); - sex = SendMessage(GetDlgItem(hwndDlg,IDC_SEX),CB_GETCURSEL,0,0); - - myProfile.Sex = 0; - if(sex == sexF) myProfile.Sex = 0x46; else - if(sex == sexM) myProfile.Sex = 0x4D; - DateTime_GetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), &myProfile.Birthday); - - SkypeProfile_Save(&myProfile); - if(SkypeInitialized) - SkypeProfile_SaveToSkype(&myProfile); - break; - } - } - break; - - case WM_DESTROY: - if ( hAvatar != NULL ) - DeleteObject( hAvatar ); - break; - } - - return 0; -} - -#ifdef SKYPE_AUTO_DETECTION -/** - * DoAutoDetect - * @param dlg The default option dialog handle - */ -void DoAutoDetect(HWND dlg) -{ - char basePath[MAX_PATH]; - char fileName[MAX_PATH]; - char tmpUser[255]; - ezxml_t f1, acc; - - if (FAILED(SHGetFolderPath(dlg,CSIDL_APPDATA,NULL,0,basePath))) - { - OUTPUT("Error in retrieving appdata path!"); - return; - } - - strcat(basePath,"\\Skype\\"); - sprintf (fileName, "%s\\shared.xml", basePath); - - if (f1 = ezxml_parse_file(fileName)) - { - if (acc = ezxml_get(f1, "Lib", 0, "Account", 0, "Default", -1)) - { - if (GetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),tmpUser,sizeof(tmpUser))) - SetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),acc->txt); - /* Can't find this stuff in current Skype verions?? - sprintf (fileName, "%s\\%s\\config.xml", basePath, acc->txt); - if ((acc = ezxml_get(f1, "UI", 0, "Messages", 0, "OpenWindowInCompactMode", -1)) && *acc->txt!='0') - { - ezxml_set_txt (acc, "0"); - // ezXML doesn't supprot saving yet - } - */ - } - ezxml_free(f1); - } - else - { - OUTPUT("Failed to open skypes configuration files!"); - return; - } -} -#endif diff --git a/protocols/SkypeClassic/skypeopt.h b/protocols/SkypeClassic/skypeopt.h deleted file mode 100644 index 23aa7a5212..0000000000 --- a/protocols/SkypeClassic/skypeopt.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * RegisterOptions - * - * This function tells Miranda to add the configuration section of this plugin in - * the Options-dialog. - */ -int RegisterOptions(WPARAM wParam, LPARAM lParam); -/* - * OptionsDlgProc - * - * This callback function is called, when the options dialog in Miranda is shown - * The function contains all necessary stuff to process the options in the dialog - * and store them in the database, when changed, and fill out the settings-dialog - * correctly according to the current settings - */ -INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK OptionsAdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK OptPopupDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -/* -* Procedure to call when the option page is asked -* -*/ -int OnDetailsInit( WPARAM wParam, LPARAM lParam ); - -/* -* Dialog to change avatar in user details. -* -* -*/ -INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -/* -* Dialog to change infos in user details. -* -* -*/ -INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -/* - * Helper functions - * - */ -void DoAutoDetect(HWND dlg); - -; \ No newline at end of file diff --git a/protocols/SkypeClassic/skypeprofile.cpp b/protocols/SkypeClassic/skypeprofile.cpp deleted file mode 100644 index 168dbfa97c..0000000000 --- a/protocols/SkypeClassic/skypeprofile.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#pragma warning (disable: 4706) // assignment within conditional expression - -#include "skypeprofile.h" -#include "skypeapi.h" -#include "utf8.h" - -extern char g_szProtoName[]; - -void SkypeProfile_Save(SkypeProfile *pstProf) -{ - db_set_b(NULL, SKYPE_PROTONAME, "Gender", pstProf->Sex); - db_set_s(NULL, SKYPE_PROTONAME, "HomePhone", pstProf->HomePhone); - db_set_s(NULL, SKYPE_PROTONAME, "OfficePhone", pstProf->OfficePhone); - db_set_s(NULL, SKYPE_PROTONAME, "HomePage", pstProf->HomePage); - db_set_ts(NULL, SKYPE_PROTONAME, "Nick", pstProf->FullName); - db_set_ts(NULL, SKYPE_PROTONAME, "City", pstProf->City); - db_set_ts(NULL, SKYPE_PROTONAME, "Province", pstProf->Province); - db_set_w(NULL, SKYPE_PROTONAME, "BirthYear", (WORD)pstProf->Birthday.wYear); - db_set_b(NULL, SKYPE_PROTONAME, "BirthMonth", (BYTE)pstProf->Birthday.wMonth); - db_set_b(NULL, SKYPE_PROTONAME, "BirthDay", (BYTE)pstProf->Birthday.wDay); -} - -void SkypeProfile_Load(SkypeProfile *pstProf) -{ - DBVARIANT dbv; - - pstProf->Sex = (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "Gender", 0); - pstProf->Birthday.wYear = (WORD)db_get_w(NULL, SKYPE_PROTONAME, "BirthYear", 1900); - pstProf->Birthday.wMonth = (WORD)db_get_b(NULL, SKYPE_PROTONAME, "BirthMonth", 01); - pstProf->Birthday.wDay = (WORD)db_get_b(NULL, SKYPE_PROTONAME, "BirthDay", 01); - if(!db_get_ts(NULL,SKYPE_PROTONAME,"Nick",&dbv)) - { - _tcsncpy (pstProf->FullName, dbv.ptszVal, sizeof(pstProf->FullName)/sizeof(TCHAR)); - db_free(&dbv); - } - if(!db_get_s(NULL,SKYPE_PROTONAME,"HomePage",&dbv)) - { - strncpy (pstProf->HomePage, dbv.pszVal, sizeof(pstProf->HomePage)); - db_free(&dbv); - } - if(!db_get_ts(NULL,SKYPE_PROTONAME,"Province",&dbv)) - { - _tcsncpy (pstProf->Province, dbv.ptszVal, sizeof(pstProf->Province)/sizeof(TCHAR)); - db_free(&dbv); - } - if(!db_get_ts(NULL,SKYPE_PROTONAME,"City",&dbv)) - { - _tcsncpy (pstProf->City, dbv.ptszVal, sizeof(pstProf->City)/sizeof(TCHAR)); - db_free(&dbv); - } - if(!db_get_s(NULL,SKYPE_PROTONAME,"OfficePhone",&dbv)) - { - strncpy (pstProf->OfficePhone, dbv.pszVal, sizeof(pstProf->OfficePhone)); - db_free(&dbv); - } - if(!db_get_s(NULL,SKYPE_PROTONAME,"HomePhone",&dbv)) - { - strncpy (pstProf->HomePhone, dbv.pszVal, sizeof(pstProf->HomePhone)); - db_free(&dbv); - } -} - -static void LoadSaveSkype(SkypeProfile *pstProf, BOOL bSet) -{ -#pragma warning (push) -#pragma warning (disable: 4204) // nonstandard extension used : non-constant aggregate initializer -#define ENTRY(x,y) {x, pstProf->y, sizeof(pstProf->y)/sizeof(pstProf->y[0]), sizeof(pstProf->y[0])} - const struct { - char *pszSetting; - LPVOID lpDest; - int iSize; - char cType; - } astSettings[] = { - ENTRY("FULLNAME", FullName), - ENTRY("PHONE_HOME", HomePhone), - ENTRY("PHONE_OFFICE", OfficePhone), - ENTRY("HOMEPAGE", HomePage), - ENTRY("CITY", City), - ENTRY("PROVINCE", Province) - }; -#pragma warning (pop) -#undef ENTRY - char *ptr; - int i; - - if (bSet) { - char *pBuf, szBirthday[16]; - for (i=0; iSex) - { - case 0x4D: SkypeSetProfile ("SEX", "MALE"); break; - case 0x46: SkypeSetProfile ("SEX", "FEMALE"); break; - } - sprintf (szBirthday, "%04d%02d%02d", pstProf->Birthday.wYear, pstProf->Birthday.wMonth, pstProf->Birthday.wDay); - SkypeSetProfile ("BIRTHDAY", szBirthday); - } else { - for (i=0; iSex=0x4D; else - if (!_stricmp(ptr, "FEMALE")) pstProf->Sex=0x46; - free (ptr); - } - if (ptr=SkypeGetProfile("BIRTHDAY")) - { - if (*ptr != '0') - sscanf(ptr, "%04hd%02hd%02hd", &pstProf->Birthday.wYear, &pstProf->Birthday.wMonth, - &pstProf->Birthday.wDay); - free(ptr); - } - } -} - -void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf) -{ - LoadSaveSkype (pstProf, FALSE); -} - -void SkypeProfile_SaveToSkype(SkypeProfile *pstProf) -{ - LoadSaveSkype (pstProf, TRUE); -} \ No newline at end of file diff --git a/protocols/SkypeClassic/skypeprofile.h b/protocols/SkypeClassic/skypeprofile.h deleted file mode 100644 index 5902f865c3..0000000000 --- a/protocols/SkypeClassic/skypeprofile.h +++ /dev/null @@ -1,33 +0,0 @@ -// System includes -#include -#include -#include -#include -#include -#include "resource.h" -#include "skype.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -// Miranda database access -#include -#include -#pragma warning (pop) - -typedef struct -{ - TCHAR FullName[256]; - char HomePhone[256]; - char OfficePhone[256]; - char HomePage[256]; - TCHAR City[256]; - TCHAR Province[256]; - BYTE Sex; - SYSTEMTIME Birthday; -} SkypeProfile; - -void SkypeProfile_Load(SkypeProfile *pstProf); -void SkypeProfile_Save(SkypeProfile *pstProf); -void SkypeProfile_Free(SkypeProfile *pstProf); -void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf); -void SkypeProfile_SaveToSkype(SkypeProfile *pstProf); diff --git a/protocols/SkypeClassic/skypeproxy.h b/protocols/SkypeClassic/skypeproxy.h deleted file mode 100644 index 8e1490803e..0000000000 --- a/protocols/SkypeClassic/skypeproxy.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Commands for command mode of Skype proxy */ - -#define AUTHENTICATE 0x01 -#define CAPABILITIES 0x02 - -/* Capabilities flags of Skypeproxy */ -#define USE_AUTHENTICATION 0x01 \ No newline at end of file diff --git a/protocols/SkypeClassic/skypeproxy/skypeproxy.c b/protocols/SkypeClassic/skypeproxy/skypeproxy.c deleted file mode 100644 index fff9c1b916..0000000000 --- a/protocols/SkypeClassic/skypeproxy/skypeproxy.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - -Purpose -======= -This program opens a connection on a local TCP/IP port and sends/ -receives Skype-API calls on it so that you can remote-control -Skype over a network. -Note, that there are currently NO SECURITY mechanisms, so don't -use this over an untrusted network! - -Author -====== -This program was written by leecher in 2005 (mailto:leecher@dose.0wnz.at) -Please give feedback at http://forum.skype.com/viewtopic.php?t=16187 - -Protocol -======== -Basic protocol structure ------------------------- -Sender and receiver have the same protocol: - - [(UINT)Length of message][(char[])Message] - -The Length is so that you can malloc() enough space for the data buffer -to receive the next message. - -A special case is, if the [Length of message] is 0. In this case the -client tells the server that he wants to switch to command mode. - -Command mode ------------- -The server expects - - [(char)Command] - -next. Currently the following commands are supported: - - CAPABILITIES - returns the Server's capabilities - AUTHENTICATE - Starts the authentification process - -CAPABILITIES ------------- -The server returns - - [(char)Capabilities] - -where this currently can be the following: - - USE_AUTHENTICATION - The server supports and requires authentication - -AUTHENTICATE ------------- -The server returns - - [(char)0x01] - -if authentication is supported AND needed (skypeproxy started with -k switch) or - - [(char)0x00] - -if this is not the case. -If 0x01 was returned the server next expects a normal message -(see "Basic protocol structure) containing the password. -If the authentication was successful, the server replies with - - [(char)0x01] - -otherwise with - - [(char)0x00] - -PLEASE NOTE THAT THE AUTHENTICATION CURRENTLY IS PLAIN TEXT. SO DON'T -USE THIS PROGRAM OVER AN UNTRUSTED NETWORK, OTHERWISE THERE MAY BE THE -POSSIBILITY THAT SOMEONE SNIFFS YOUR PASSWORD! - -Code example ------------- - -SOCKET MySocket; - -int SendPacket(char *szSkypeMessage) { - unsigned int length=strlen(szSkypeMsg); - - if (send(MySocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || - send(MySocket, szSkypeMsg, length, 0)==SOCKET_ERROR) - return -1; - return 0; -} - -// don't forget to free() the return value on my Heap!! -char *ReceivePacket(void) { - unsigned int lenght, received; - char *buf; - - if ((received=recv(MySocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || - received==0) - return NULL; - if (!(buf=calloc(1, length+1))) return NULL; - if (recv(MySocket, buf, length, 0)==SOCKET_ERROR) { - free(buf); - return NULL; - } - return buf; -} - - -License -======= -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -History -======== -V1.0alpha - First preview release -V1.0 - Implemented killing & restarting Skype process when it dies - - BUGFIX: SendMessage() is a blocking call, if Skype hangs our app hangs too -> Fixed - - Added command line parsing. - - Renamed from Skype2Socket to skypeproxy - - Added authentication feature. -*/ - -#include -#include -#include -#include -#include "skypeproxy.h" - -UINT ControlAPIAttach, ControlAPIDiscover; -HWND hSkypeWnd=NULL, hWnd; -HANDLE SkypeReady, ServerThreadBye; -LONG AttachStatus=-1; -int exitcode=EXIT_SUCCESS; -char skype_path[MAX_PATH], *password=NULL; -BYTE WatchDog=1; -BOOL WatchDogRunning=FALSE, Authenticated=FALSE; -SOCKET ListenSocket, AcceptSocket; - - -void bail_out(int i) { - OUTPUT("Got termination signal, bailing out."); - if (i==1) exitcode=EXIT_FAILURE; - PostMessage(hWnd, WM_QUIT, 0, 0); -} - -BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) { - DWORD dwID ; - - GetWindowThreadProcessId(hwnd, &dwID) ; - if(dwID == (DWORD)lParam) - PostMessage(hwnd, WM_CLOSE, 0, 0) ; // May you be so kind to quit, please? - - return TRUE ; -} - -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : ForceRestart - Kill Skype if it's running before restarting - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -void ConnectToSkypeAPI(void *ForceRestart) { - BOOL SkypeLaunched=FALSE; - int counter=0, i, j; - char *args[5]; - char *SkypeOptions[]={"/notray", "/nosplash", "/minimized"}; - char *szFuncName="ConnectToSkypeAPI"; - - ResetEvent(SkypeReady); - AttachStatus=-1; - if ((BOOL)ForceRestart) { - HANDLE hProc; - DWORD dwPID=0; - - if (!hSkypeWnd) { - OUTPUT("I can't kill Skype, as I don't even have its window handle!"); - return; - } - GetWindowThreadProcessId(hSkypeWnd, &dwPID); - LOG(("%s: Shutting down Skype as it was not behaving the way it should...", szFuncName)); - if (hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID)) { - - // Try to shutdown Skype the nice way by asking it to close - EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID); - - if(WaitForSingleObject(hProc, 10000)!=WAIT_OBJECT_0) { - // Try it the hard way by killing it - LOG(("%s: I tried it the nice way, but you were not listening! Now DIIIIEEE!", szFuncName)); - if (!TerminateProcess(hProc,0)) { - OUTPUT("Argh, process refused to die, it's too mighty for me, I've given up"); - CloseHandle(hProc); - return; - } - LOG(("%s: Process killed! >:)", szFuncName)); - } - CloseHandle(hProc); - } - } - do { - /* To initiate communication, Client should broadcast windows message - ('SkypeControlAPIDiscover') to all windows in the system, specifying its own - window handle in wParam parameter. - */ - LOG(("%s: Sending discover message..", szFuncName)); - SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - LOG(("%s: Discover message sent, waiting for Skype to become ready..", szFuncName)); - - /* In response, Skype responds with - message 'SkypeControlAPIAttach' to the handle specified, and indicates - connection status - SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. - If there is no answer after 3 seconds, launch Skype as it's propably - not running. - */ - if (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && - AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) - { - if (hWnd==NULL) { - LOG(("%s: hWnd of SkypeDispatchWindow not yet set..", szFuncName)); - continue; - } - if (!SkypeLaunched && skype_path) { - LOG(("%s: Starting Skype, as it's not running", szFuncName)); - args[0]=skype_path; - j=1; - for (i=0; i<3; i++) { - args[j]=SkypeOptions[i]; - LOG(("%s: Using Skype parameter: ", szFuncName, args[j])); - j++; - } - args[j]=NULL; - _spawnv(_P_NOWAIT, skype_path, args); - ResetEvent(SkypeReady); - SkypeLaunched=TRUE; - LOG(("%s: Skype process started.", szFuncName)); - // Skype launching iniciated, keep sending Discover messages until it responds. - continue; - } else { - LOG(("%s: Check if Skype was launchable..", szFuncName)); - if (!skype_path) { - OUTPUT("There was no correct path for Skype application"); - bail_out(1); - return; - } - LOG("%s: Trying to attach: #%d", szFuncName, counter)); - counter++; - if (counter==5) { - OUTPUT("ERROR: Skype not running / too old / working!"); - bail_out(1); - return; - } - } - } - LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); - } while (AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); - - while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); - LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { - switch(AttachStatus) { - case SKYPECONTROLAPI_ATTACH_REFUSED: - OUTPUT("Skype refused the connection :("); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - OUTPUT("The Skype API is not available"); - break; - default: - LOG(("%s: ERROR: AttachStatus: %d", szFuncName, AttachStatus)); - OUTPUT("Wheee, Skype won't let me use the API. :("); - } - bail_out(1); - return; - } - OUTPUT("Attached to Skype successfully."); - if (!WatchDogRunning) - if (_beginthread(WatchDogTimer, 0, NULL)==-1) { - OUTPUT("Cannot start Watchdog."); - bail_out(1); - } - return; -} - -void SkypeSend(char *szMsg) { - COPYDATASTRUCT CopyData; - int count=0; - - if (!hSkypeWnd) { - LOG(("SkypeSend: DAMN! No Skype window handle! :(")); - return; - } - if (strcmp(szMsg, "PING")) {LOG(("> %s", szMsg));} - CopyData.dwData=0; - CopyData.lpData=szMsg; - CopyData.cbData=strlen(szMsg)+1; - while (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { - count++; - LOG(("SkypeSend: failed, try #%d", count)); - if (count==5) { - OUTPUT("Sending message to Skype failed too often."); - OUTPUT("Skype may have died unexpectedly, I will try to restart it."); - ConnectToSkypeAPI((void *)TRUE); - OUTPUT("Restart complete. Trying to deliver message one more time."); - if (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { - OUTPUT("It still failed. Skype seems to be completely f*cked up. I've given up. Bye.."); - bail_out(1); - break; - } else { - OUTPUT("Now it worked! :)"); - break; - } - } - Sleep(1000); - } -} - -void ServerThread(char *dummy) { - unsigned int length, received; - char *buf, command, reply; - - LOG(("ServerThread started")); - AcceptSocket=INVALID_SOCKET; - while( AcceptSocket == INVALID_SOCKET) { - if ((AcceptSocket = accept( ListenSocket, NULL, NULL ))==INVALID_SOCKET) { - LOG(("ServerThread: Byebye...")); - SetEvent(ServerThreadBye); - bail_out(1); - return; - } - OUTPUT("Connection by client"); - while(1) { - if ((received=recv(AcceptSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || - received==0) - { - OUTPUT("Connection was closed by client. See ya soon! :)"); - break; - } - // Command mode - if (length==0) { - reply=0; - if (recv(AcceptSocket, (char *)&command, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } -#ifdef USE_AUTHENTICATION - if (command==AUTHENTICATE) - if (password) reply=0x01; // Ok, go ahead - else command=0; -#endif - if (command==CAPABILITIES) - reply=password?USE_AUTHENTICATION:0; - - if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } - continue; - } - // Normal Skype API-call - if (!(buf=calloc(1, length+1))) { - OUTPUT("Out of memory error while allocating buffer space."); - break; - } - if (recv(AcceptSocket, buf, length, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - free(buf); - break; - } - switch (command) { -#ifdef USE_AUTHENTICATION - case 0x01: // Compare hash - if (password && !strcmp(password, buf)) Authenticated=TRUE; - else Authenticated=FALSE; - if (Authenticated) { - OUTPUT("User authenticated succesfully."); - reply=1; - } else { - OUTPUT("User authentication failed!! (Intruder?)"); - reply=0; - } - if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } - command=0; - break; -#endif - default: -#ifdef USE_AUTHENTICATION - if (password && !Authenticated) break; -#endif - SkypeSend(buf); - } - command=0; - free(buf); - } - AcceptSocket=INVALID_SOCKET; -#ifdef USE_AUTHENTICATION - Authenticated=FALSE; -#endif - } -} - - -void WatchDogTimer(char *dummy) { - LOG(("WatchDogTimer started")); - WatchDogRunning=TRUE; - while (1) { - Sleep(PING_INTERVAL); - if (!WatchDog) { - OUTPUT("Ouch.. It seems that Skype has died unexpectedly. Trying to restart."); - ConnectToSkypeAPI((void *)TRUE); - } - WatchDog=0; - SkypeSend("PING"); - } -} - -LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) -{ - PCOPYDATASTRUCT CopyData; - char *szSkypeMsg=NULL; - - switch (message) - { - case WM_COPYDATA: -// LOG("WM_COPYDATA", "start"); - if(hSkypeWnd==(HWND)wParam) { - CopyData=(PCOPYDATASTRUCT)lParam; - szSkypeMsg=strdup(CopyData->lpData); - ReplyMessage(1); - if (!strcmp(szSkypeMsg, "PONG")) { - WatchDog=1; - break; - } // Hide PING-PONG - LOG(("< %s", szSkypeMsg)); - if (!strcmp(szSkypeMsg, "USERSTATUS LOGGEDOUT")) { - OUTPUT("Skype shut down gracefully. I'll leave too, bye.. :)"); - bail_out(1); - } -#ifdef USE_AUTHENTICATION - if (password && !Authenticated) break; -#endif - if (AcceptSocket!=INVALID_SOCKET) { - unsigned int length=strlen(szSkypeMsg); - - if (send(AcceptSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || - send(AcceptSocket, szSkypeMsg, length, 0)==SOCKET_ERROR) - OUTPUT("Cannot send to client :("); - } - } - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - if(message==ControlAPIAttach) { - // Skype responds with Attach to the discover-message - AttachStatus=lParam; - if (AttachStatus==SKYPECONTROLAPI_ATTACH_SUCCESS) - hSkypeWnd=(HWND)wParam; // Skype gave us the communication window handle - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_API_AVAILABLE) - SetEvent(SkypeReady); - break; - } - return (DefWindowProc(hWnd, message, wParam, lParam)); - } -// LOG("WM_COPYDATA", "exit"); - if (szSkypeMsg) free(szSkypeMsg); - return 1; -} - - -void TellError(DWORD err) { - LPVOID lpMsgBuf; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); - MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); - LocalFree( lpMsgBuf ); - return; -} - -int main(int argc, char *argv[]) { - DWORD Buffsize; - HKEY MyKey; - BOOL SkypeInstalled=TRUE; - MSG Message; - WNDCLASS WndClass; - SOCKADDR_IN service; - WSADATA wsaData; - int ExitCode=STILL_ACTIVE; - unsigned short BindPort=1401; - char BindIP[16]="0.0.0.0"; - - printf("Skypeproxy V1.0, by leecher 2005 \n\n"); - - if (argc>1) { - int i; - - if (!stricmp(argv[1], "-h") || !stricmp(argv[1], "--help") || !stricmp(argv[1], "/?")) { - printf("Usage: %s [-i BindIP] [-p BindPort]", argv[0]); -#ifdef USE_AUTHENTICATION - printf(" [-k Password]"); -#endif - printf("\n\n"); - return EXIT_SUCCESS; - } - for (i=0;ii+1) - strncpy(BindIP, argv[i+1], sizeof(BindIP)); - if (!stricmp(argv[i], "-p") && argc>i+1) - if (!(BindPort=atoi(argv[i+1]))) { - OUTPUT("ERROR: Cannot convert port to int. bye.."); - return EXIT_FAILURE; - } -#ifdef USE_AUTHENTICATION - if (!stricmp(argv[i], "-k") && argc>i+1) - password=strdup(argv[i+1]); -#endif - } - } - - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS || - RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - SkypeInstalled=FALSE; - Buffsize=sizeof(skype_path); - if (SkypeInstalled==FALSE || - RegQueryValueEx(MyKey, "SkypePath", NULL, NULL, skype_path, &Buffsize)!=ERROR_SUCCESS) { - OUTPUT("Skype was not found on this machine :("); - RegCloseKey(MyKey); - skype_path[0]=0; - return EXIT_FAILURE; - } - RegCloseKey(MyKey); - - if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { - OUTPUT("Error at loading windows sockets."); - return EXIT_FAILURE; - } - - if ((ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { - printf("* Error at creating socket(): Error %d", WSAGetLastError()); - return EXIT_FAILURE; - } - - service.sin_family = AF_INET; - service.sin_addr.s_addr = inet_addr(BindIP); - service.sin_port = htons(BindPort); - - printf("* Binding to interface %s, Port %d..", BindIP, BindPort); - if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR || - listen( ListenSocket, 1 ) == SOCKET_ERROR) - { - OUTPUT("Failed."); - closesocket(ListenSocket); - return EXIT_FAILURE; - } - printf("OK\n"); - - - if (!(ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach")) || - !(ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover"))) { - OUTPUT("Cannot register Windows message."); - closesocket(ListenSocket); - return EXIT_FAILURE; - } - - // Create window class - hSkypeWnd=NULL; - WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; - WndClass.lpfnWndProc = (WNDPROC)WndProc; - WndClass.cbClsExtra = 0; - WndClass.cbWndExtra = 0; - WndClass.hInstance = NULL; - WndClass.hIcon = NULL; - WndClass.hCursor = NULL; - WndClass.hbrBackground = NULL; - WndClass.lpszMenuName = NULL; - WndClass.lpszClassName = "SkypeApiDispatchWindow"; - RegisterClass(&WndClass); - // Do not check the retval of RegisterClass, because on non-unicode - // win98 it will fail, as it is a stub that returns false() there - - // Create main window - hWnd=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, - "SkypeApiDispatchWindow", "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, 0); - - if (!hWnd) { - OUTPUT("Cannot create window."); - TellError(GetLastError()); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - return EXIT_FAILURE; - } - ShowWindow(hWnd, 0); - UpdateWindow(hWnd); - - if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || - !(ServerThreadBye=CreateEvent(NULL, TRUE, FALSE, NULL))) { - OUTPUT("Unable to create Mutex!"); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - return EXIT_FAILURE; - } - - if (_beginthread(ConnectToSkypeAPI, 0, (void *)FALSE)==-1 || - _beginthread(ServerThread, 0, NULL)==-1) { - OUTPUT("Cannot create thread. Bye.."); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - CloseHandle(SkypeReady); - return EXIT_FAILURE; - } - - signal(SIGINT, &bail_out); - LOG(("Startup: Messagepump started.\nPress CTRL+C to terminate\n")); - - while (GetMessage(&Message, hWnd, 0, 0)) - { - TranslateMessage(&Message); - DispatchMessage(&Message); - } - - LOG(("Shutdown: Messagepump stopped")); - - if (password) free(password); - if (AcceptSocket != INVALID_SOCKET) closesocket(AcceptSocket); - closesocket(ListenSocket); - LOG(("Shutdown: Waiting for serverthread to quit...")); - if (WaitForSingleObject(ServerThreadBye, 3000)==WAIT_TIMEOUT) - {OUTPUT("Serverthread didn't terminate correctly, shutting down anyway...");} - else - {LOG(("ServerThread terminated"));} - CloseHandle(WndClass.hInstance); - CloseHandle(SkypeReady); - return exitcode; -} \ No newline at end of file diff --git a/protocols/SkypeClassic/skypeproxy/skypeproxy.h b/protocols/SkypeClassic/skypeproxy/skypeproxy.h deleted file mode 100644 index 8ce122990b..0000000000 --- a/protocols/SkypeClassic/skypeproxy/skypeproxy.h +++ /dev/null @@ -1,36 +0,0 @@ -/*** Skype API ***/ -//Messages -#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 -#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 -#define SKYPECONTROLAPI_ATTACH_REFUSED 2 -#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 -#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 - -// Errors -#define MISC_ERROR 1 -#define USER_NOT_FOUND 2 -#define USER_NOT_ONLINE 3 -#define USER_BLOCKED 4 -#define TYPE_UNSUPPORTED 5 -#define SENDER_NOT_FRIEND 6 -#define SENDER_NOT_AUTHORIZED 7 - - -/*** Debugging macros ***/ -#define OUTPUT(a) printf("* %s\n", a); -#define LOG(a, b) printf("- %s: %s\n", a, b); -#define LOGL(a, b) printf("- %s: %d\n", a, b); - -/*** Program settings ***/ -#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available -#define USE_AUTHENTICATION 0x01 // Program supports authentication -> Comment to disable! - -/*** Commands ***/ -#define AUTHENTICATE 0x01 -#define CAPABILITIES 0x02 - -/*** Sockets ***/ -#pragma comment(lib, "ws2_32") - -/*** Prototypes ***/ -void WatchDogTimer(char *); \ No newline at end of file diff --git a/protocols/SkypeClassic/skypesvc.cpp b/protocols/SkypeClassic/skypesvc.cpp deleted file mode 100644 index bc8131b2c8..0000000000 --- a/protocols/SkypeClassic/skypesvc.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#define __SKYPESVC_C__ -#include "skype.h" -#include "skypesvc.h" -#include "skypeapi.h" -#include "skypeopt.h" -#include "contacts.h" -#include "m_toptoolbar.h" - -// Exports -SKYPE_SVCNAMES g_svcNames; - -//From skype.c -extern char protocol, g_szProtoName[]; -extern HINSTANCE hInst; -extern DWORD mirandaVersion; -static HANDLE m_hPrebuildCMenu=NULL, m_hStatusHookContact=NULL, m_hContactDeleted=NULL, - m_hHookModulesLoaded=NULL, m_hHookOkToExit=NULL, m_hOptHook=NULL, m_hHookMirandaExit=NULL, - m_hTTBModuleLoadedHook = NULL, m_hHookOnUserInfoInit = NULL; - -void CreateProtoService(const char* szService, MIRANDASERVICE svc) -{ - char str[MAXMODULELABELLENGTH]; - _snprintf(str, sizeof(str), "%s%s", SKYPE_PROTONAME, szService); - CreateServiceFunction(str, svc); -} - -#define CreateServiceName(srvce) _snprintf (g_svcNames.##srvce, sizeof(g_svcNames.##srvce), "%s/"#srvce, SKYPE_PROTONAME); - -void CreateServices(void) -{ - CreateServiceName(ChatNew); - CreateServiceName(SetAvatar); - CreateServiceName(SendFile); - CreateServiceName(HoldCall); - CreateServiceName(AnswerCall); - CreateServiceName(ImportHistory); - CreateServiceName(AddUser); - CreateServiceName(SkypeOutCallUser); - CreateServiceName(CallHangupUser); - CreateServiceName(CallUser); - - CreateServiceFunction(SKYPE_CALL, SkypeCall); - CreateServiceFunction(SKYPE_CALLHANGUP, SkypeCallHangup); - CreateServiceFunction(SKYPEOUT_CALL, SkypeOutCall); - CreateServiceFunction(SKYPE_HOLDCALL, SkypeHoldCall); - CreateServiceFunction(SKYPE_ADDUSER, SkypeAdduserDlg); - CreateServiceFunction(SKYPE_IMPORTHISTORY, ImportHistory); - CreateServiceFunction(SKYPE_ANSWERCALL, SkypeAnswerCall); - CreateServiceFunction(SKYPE_SENDFILE, SkypeSendFile); - CreateServiceFunction(SKYPE_SETAVATAR, SkypeSetAvatar); - - CreateProtoService(PS_GETCAPS, SkypeGetCaps); - CreateProtoService(PS_GETNAME, SkypeGetName); - CreateProtoService(PS_LOADICON, SkypeLoadIcon); - CreateProtoService(PS_SETSTATUS, SkypeSetStatus); - CreateProtoService(PS_GETSTATUS, SkypeGetStatus); - CreateProtoService(PS_ADDTOLIST, SkypeAddToList); - CreateProtoService(PS_ADDTOLISTBYEVENT, SkypeAddToListByEvent); - CreateProtoService(PS_BASICSEARCH, SkypeBasicSearch); - - CreateProtoService(PSS_GETINFO, SkypeGetInfo); - CreateProtoService(PSS_MESSAGE, SkypeSendMessage); - CreateProtoService(PSR_MESSAGE, SkypeRecvMessage); - CreateProtoService(PSS_USERISTYPING, SkypeUserIsTyping); - CreateProtoService(PSS_AUTHREQUEST, SkypeSendAuthRequest); - CreateProtoService(PSR_AUTH, SkypeRecvAuth); - CreateProtoService(PS_AUTHALLOW, SkypeAuthAllow); - CreateProtoService(PS_AUTHDENY, SkypeAuthDeny); - - CreateProtoService(PS_GETAVATARINFO, SkypeGetAvatarInfo); - CreateProtoService(PS_GETAVATARCAPS, SkypeGetAvatarCaps); - CreateProtoService(PS_GETMYAVATAR, SkypeGetAvatar); - CreateProtoService(PS_SETMYAVATAR, SkypeSetAvatar); - - CreateProtoService(PS_SETAWAYMSG, SkypeSetAwayMessage); - CreateProtoService(PS_SETAWAYMSGW, SkypeSetAwayMessageW); - CreateProtoService(PSS_GETAWAYMSG, SkypeGetAwayMessage); - CreateProtoService(PS_SETMYNICKNAME, SkypeSetNick); - - CreateProtoService(PSS_SKYPEAPIMSG, SkypeReceivedAPIMessage); - CreateProtoService(SKYPE_REGPROXY, SkypeRegisterProxy); -} - -void HookEvents(void) -{ - m_hPrebuildCMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); - - //HookEvent(ME_CLIST_DOUBLECLICKED, ClistDblClick); - m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions); - m_hStatusHookContact = HookEvent(ME_DB_CONTACT_ADDED,HookContactAdded); - m_hContactDeleted = HookEvent( ME_DB_CONTACT_DELETED, HookContactDeleted ); - m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - m_hHookMirandaExit = HookEvent(ME_SYSTEM_OKTOEXIT, MirandaExit); - m_hHookOkToExit = HookEvent(ME_SYSTEM_PRESHUTDOWN, OkToExit); -} - -void HookEventsLoaded(void) -{ - // We cannot check for the TTB-service before this event gets fired... :-/ - m_hTTBModuleLoadedHook = HookEvent(ME_TTB_MODULELOADED, CreateTopToolbarButton); - m_hHookOnUserInfoInit = HookEvent( ME_USERINFO_INITIALISE, OnDetailsInit ); -} - -void UnhookEvents(void) -{ - UnhookEvent(m_hOptHook); - UnhookEvent(m_hTTBModuleLoadedHook); - UnhookEvent(m_hHookOnUserInfoInit); - UnhookEvent(m_hStatusHookContact); - UnhookEvent(m_hContactDeleted); - UnhookEvent(m_hHookModulesLoaded); - UnhookEvent(m_hPrebuildCMenu); - UnhookEvent(m_hHookOkToExit); - UnhookEvent(m_hHookMirandaExit); - //UnhookEvent(ClistDblClick); -} - -INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam) { - int ret = 0; - - UNREFERENCED_PARAMETER(lParam); - - switch (wParam) { - case PFLAGNUM_1: - ret = PF1_BASICSEARCH | PF1_IM | PF1_MODEMSG; // | PF1_AUTHREQ; - if (protocol>=5) ret |= PF1_ADDSEARCHRES; - break; - - case PFLAGNUM_2: - ret = PF2_ONLINE | PF2_SHORTAWAY | PF2_INVISIBLE | PF2_HEAVYDND; -#ifdef MAPDND - ret |= PF2_LIGHTDND | PF2_HEAVYDND; -#endif - if (!db_get_b(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) - ret |= PF2_LONGAWAY | PF2_FREECHAT; - break; - - case PFLAGNUM_3: - ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE; - break; - - case PFLAGNUM_4: - ret = PF4_FORCEAUTH | PF4_FORCEADDED | PF4_AVATARS | PF4_SUPPORTTYPING /* Not really, but libgaim compat. */; - if (mirandaVersion >= 0x070000) ret |= PF4_IMSENDUTF; - break; - case PFLAG_UNIQUEIDTEXT: - ret = (INT_PTR)Translate("Skype name"); - break; - case PFLAG_UNIQUEIDSETTING: - ret = (INT_PTR) SKYPE_NAME; - break; - } - return ret; -} - -INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam) -{ - if (lParam) - { - strncpy((char *)lParam, SKYPE_PROTONAME, wParam); - return 0; // Success - } - return 1; // Failure -} - - -INT_PTR SkypeLoadIcon(WPARAM wParam,LPARAM lParam) -{ - UINT id; - - UNREFERENCED_PARAMETER(lParam); - - switch(wParam&0xFFFF) { - case PLI_PROTOCOL: id=IDI_SKYPE; break; // IDI_MAIN is the main icon for the protocol - default: return (int)(HICON)NULL; - } - return (int)LoadImage(hInst,MAKEINTRESOURCE(id),IMAGE_ICON,GetSystemMetrics(wParam&PLIF_SMALL?SM_CXSMICON:SM_CXICON),GetSystemMetrics(wParam&PLIF_SMALL?SM_CYSMICON:SM_CYICON),0); -} - -INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam) -{ DBVARIANT dbv; - if (!db_get_s(NULL,SKYPE_PROTONAME, "AvatarFile", &dbv)){ - lstrcpynA((char*)wParam, dbv.pszVal, (int)lParam); - db_free(&dbv); - } - return 0; -} diff --git a/protocols/SkypeClassic/skypesvc.h b/protocols/SkypeClassic/skypesvc.h deleted file mode 100644 index 74c8cd37bf..0000000000 --- a/protocols/SkypeClassic/skypesvc.h +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include -#include "resource.h" - -void CreateProtoService(const char* szService, MIRANDASERVICE svc); -void HookEvents(void); -void HookEventsLoaded(void); -void UnhookEvents(void); -void CreateServices(void); -INT_PTR SkypeLoadIcon(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam); -/* SkypeGetAvatar - * - * Purpose: Return the avatar file name - * Params : wParam=0 - * lParam=0 - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam); \ No newline at end of file diff --git a/protocols/SkypeClassic/src/alogon.cpp b/protocols/SkypeClassic/src/alogon.cpp new file mode 100644 index 0000000000..8002d495fc --- /dev/null +++ b/protocols/SkypeClassic/src/alogon.cpp @@ -0,0 +1,129 @@ +#include "skype.h" +#include "debug.h" + +extern char g_szProtoName[]; +extern HANDLE SkypeReady; + +/** + * Purpose: Retrieves class name from window + * + * Note: This is some sort of hack to return static local variable, + * but it works :) + */ +static const TCHAR* getClassName(HWND wnd) +{ + static TCHAR className[256]; + + *className=0; + GetClassName(wnd, &className[0], sizeof(className)/sizeof(className[0])); + return className; +} + +/** + * Purpose: Finds a window + * + * Note: This function relies on Skype window placement. + * It should work for Skype 3.x + */ +static HWND findWindow(HWND parent, const TCHAR* childClassName) +{ + // Get child window + // This window is not combo box or edit box + HWND wnd = GetWindow(parent, GW_CHILD); + while(wnd != NULL && _tcscmp(getClassName(wnd), childClassName) != 0) + wnd = GetWindow(wnd, GW_HWNDNEXT); + + return wnd; +} + +static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) +{ + DWORD dwPID; + const TCHAR *lpszClassName; + + + GetWindowThreadProcessId(hWnd,&dwPID); + if (lParam != 0 && dwPID != (DWORD)lParam) return TRUE; + lpszClassName = getClassName(hWnd); + if(_tcscmp(lpszClassName, _T("tSkMainForm.UnicodeClass")) == 0 || + _tcscmp(lpszClassName, _T("TLoginForm.UnicodeClass")) == 0) + { + HWND loginControl = GetWindow(hWnd, GW_CHILD); + + LOG(("setUserNamePasswordThread: Skype window found!")); + + // Sleep for some time, while Skype is loading + // It loads slowly :( + //Sleep(5000); + LOG (("TLoginControl = %S", getClassName(loginControl))); + + // Check for login control + if(_tcscmp(getClassName(loginControl), _T("TLoginControl")) == 0) + { + // Find user name window + HWND userName = findWindow(loginControl, _T("TNavigableTntComboBox.UnicodeClass")); + HWND password = findWindow(loginControl, _T("TNavigableTntEdit.UnicodeClass")); + + LOG (("userName=%08X; password=%08X", userName, password)); + if (userName && password) + { + // Set user name and password + DBVARIANT dbv; + + if(!db_get_ws(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) + { + SendMessageW(userName, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); + db_free(&dbv); + } + + if(!db_get_ws(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) + { + SendMessageW(password, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); + db_free(&dbv); + SendMessageW(password, WM_CHAR, 13, 0); + } + + + SendMessageW(hWnd, + WM_COMMAND, + 0x4a8, // sign-in button; WARNING: This ID can change during newer Skype versions + (LPARAM)findWindow(loginControl, _T("TTntButton.UnicodeClass"))); + } + return FALSE; + } + + } + return TRUE; +} + +DWORD WINAPI setUserNamePasswordThread(LPVOID lpDummy) +{ + DWORD dwPid = (DWORD)lpDummy; + HANDLE mutex = CreateMutex(NULL, TRUE, _T("setUserNamePasswordMutex")); + + // Check double entrance + if(GetLastError() == ERROR_ALREADY_EXISTS) + return 0; + + WaitForSingleObject(SkypeReady, 5000); + EnumWindows (EnumWindowsProc, dwPid); + + ReleaseMutex(mutex); + CloseHandle(mutex); + return 0; +} + +/** + * Purpose: Finds Skype window and sets user name and password. + * + * Note: This function relies on Skype window placement. + * It should work for Skype 3.x + */ +void setUserNamePassword(int dwPid) +{ + DWORD threadId; + CreateThread(NULL, 0, &setUserNamePasswordThread, (LPVOID)dwPid, 0, &threadId); + + // Give time to thread + Sleep(100); +} diff --git a/protocols/SkypeClassic/src/alogon.h b/protocols/SkypeClassic/src/alogon.h new file mode 100644 index 0000000000..00d2e7e703 --- /dev/null +++ b/protocols/SkypeClassic/src/alogon.h @@ -0,0 +1 @@ +void setUserNamePassword(int dwPid); diff --git a/protocols/SkypeClassic/src/contacts.cpp b/protocols/SkypeClassic/src/contacts.cpp new file mode 100644 index 0000000000..8e25ae7c9d --- /dev/null +++ b/protocols/SkypeClassic/src/contacts.cpp @@ -0,0 +1,419 @@ +/* + * Contactlist management functions + */ + +#include "skype.h" +#include "skypeapi.h" +#include "debug.h" +#include "pthread.h" +#include "gchat.h" +#include "voiceservice.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +#include +#pragma warning (pop) + +#pragma warning (disable: 4706) // assignment within conditional expression + +// Imported Globals +extern HINSTANCE hInst; +extern BOOL bSkypeOut, bIsImoproxy; +extern char protocol, g_szProtoName[]; + +// Handles +static HANDLE hMenuCallItem, hMenuCallHangup, hMenuSkypeOutCallItem, hMenuHoldCallItem, hMenuFileTransferItem, hMenuChatInitItem; + +// Check if alpha blending icons are supported +// Seems to be not neccessary +/* +BOOL SupportAlphaIcons(void) { + HANDLE hMod; + DLLVERSIONINFO tDVI={0}; + BOOL retval=FALSE; + FARPROC pDllGetVersion; + + if (!(hMod=LoadLibrary("comctl32.dll"))) return FALSE; + if (pDllGetVersion=GetProcAddress(hMod, "DllGetVersion")) { + tDVI.cbSize=sizeof(tDVI); + if (!pDllGetVersion ((DLLVERSIONINFO *)&tDVI)) { + if (GetDeviceCaps(GetDC(NULL), BITSPIXEL)*GetDeviceCaps(GetDC(NULL), PLANES)>=32 && + tDVI.dwMajorVersion>=6) + retval=TRUE; + } + } + FreeLibrary(hMod); + return retval; +} +*/ + +CLISTMENUITEM CallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Call (Skype)"); + mi.pszService=SKYPE_CALL; + + return mi; +} + +CLISTMENUITEM SkypeOutCallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_HIDDEN|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALLSKYPEOUT)); + mi.ptszName=LPGENT("Call using SkypeOut"); + mi.pszService=SKYPEOUT_CALL; + + return mi; +} + +CLISTMENUITEM HupItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Hang up call (Skype)"); + mi.pszService=SKYPE_CALLHANGUP; + + return mi; +} + +CLISTMENUITEM SkypeOutHupItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); + mi.ptszName=LPGENT("Hang up SkypeOut call"); + mi.pszService=SKYPEOUT_CALL; + return mi; +} + +CLISTMENUITEM HoldCallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HOLD)); + mi.ptszName=LPGENT("Hold call"); + mi.pszService=SKYPE_HOLDCALL; + return mi; +} + +CLISTMENUITEM ResumeCallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_RESUME)); + mi.ptszName=LPGENT("Resume call"); + mi.pszService=SKYPE_HOLDCALL; + return mi; +} + +CLISTMENUITEM FileTransferItem(void) { + CLISTMENUITEM mi={0}; + + // Stolen from file.c of Miranda core + mi.cbSize=sizeof(mi); + mi.position=-2000020000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE); + mi.ptszName=LPGENT("&File"); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.pszService=SKYPE_SENDFILE; + return mi; +} + +CLISTMENUITEM ChatInitItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000020000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon( hInst, MAKEINTRESOURCE( IDI_INVITE )); + mi.ptszName=LPGENT("&Open groupchat"); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.pszService=SKYPE_CHATNEW; + return mi; +} + +HANDLE add_contextmenu(HANDLE hContact) { + CLISTMENUITEM mi; + + UNREFERENCED_PARAMETER(hContact); + + if (!HasVoiceService()) { + mi=CallItem(); + hMenuCallItem=Menu_AddContactMenuItem(&mi); + mi=HupItem(); + hMenuCallHangup=Menu_AddContactMenuItem(&mi); + } + + mi=SkypeOutCallItem(); + hMenuSkypeOutCallItem=Menu_AddContactMenuItem(&mi); + + if (!HasVoiceService()) { + mi=HoldCallItem(); + hMenuHoldCallItem=Menu_AddContactMenuItem(&mi); + } + + // We cannot use flag PF1_FILESEND for sending files, as Skype opens its own + // sendfile-Dialog. + mi=FileTransferItem(); + hMenuFileTransferItem=Menu_AddContactMenuItem(&mi); + + mi=ChatInitItem(); + hMenuChatInitItem=Menu_AddContactMenuItem(&mi); + + + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Import Skype history"); + mi.pszService=SKYPE_IMPORTHISTORY; + return Menu_AddContactMenuItem(&mi); +} + +HANDLE add_mainmenu(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ADD)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Add Skype contact"); + mi.pszService=SKYPE_ADDUSER; + return Menu_AddMainMenuItem(&mi); + +} + +int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + CLISTMENUITEM mi; + char *szProto; + BOOL callAvailable = FALSE; + BOOL hangupAvailable = FALSE; + + UNREFERENCED_PARAMETER(lParam); + + if (!(szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0))) return 0; + + if (!HasVoiceService()) { + // Clear hold-Item in case it exists + mi=HoldCallItem(); + mi.flags|=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); + } + + if (!strcmp(szProto, SKYPE_PROTONAME)) { + if (!HasVoiceService()) { + if (!db_get((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + if (db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)) + mi=ResumeCallItem(); else mi=HoldCallItem(); + mi.flags=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); + + callAvailable = FALSE; + hangupAvailable = TRUE; + + db_free(&dbv); + } else { callAvailable = TRUE; hangupAvailable = FALSE; } + + if (db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)!=0) { + callAvailable = FALSE; + hangupAvailable = FALSE; + } + + mi = CallItem(); + mi.flags |= CMIM_ALL | (!callAvailable?CMIF_HIDDEN:0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallItem,(LPARAM)&mi); + + mi = HupItem(); + mi.flags |= CMIM_ALL | (!hangupAvailable?CMIF_HIDDEN:0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallHangup,(LPARAM)&mi); + } + + // Clear SkypeOut menu in case it exists + mi=SkypeOutCallItem(); + mi.flags|=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); + + // File sending and groupchat-creation works starting with protocol version 5 + if (protocol>=5) { + mi=FileTransferItem(); + if (db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) + mi.flags ^= CMIF_HIDDEN; + mi.flags |= CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuFileTransferItem,(LPARAM)&mi); + } + + if (protocol>=5 || bIsImoproxy) { + mi=ChatInitItem(); + if (db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0) && + db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) + mi.flags ^= CMIF_HIDDEN; + mi.flags |= CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuChatInitItem,(LPARAM)&mi); + } + + } else if (bSkypeOut) { + if (!db_get((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + mi=SkypeOutHupItem(); + db_free(&dbv); + } else { + mi=SkypeOutCallItem(); + if(!db_get((HANDLE)wParam,"UserInfo","MyPhone0",&dbv)) { + db_free(&dbv); + mi.flags=0; + } + } + mi.flags|=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); + } + + return 0; +} + +/* +int ClistDblClick(WPARAM wParam, LPARAM lParam) { + char *szProto; + + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, wParam, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && + db_get_w((HANDLE)wParam, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)==ID_STATUS_ONTHEPHONE) { + SkypeCall(wParam, 0); + } + + return 0; +} +*/ + +HANDLE find_contact(char *name) { + char *szProto; + int tCompareResult; + HANDLE hContact; + DBVARIANT dbv; + + // already on list? + for (hContact=(HANDLE)db_find_first();hContact != NULL;hContact=db_find_next(hContact)) + { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) + { + if (db_get_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; + tCompareResult = strcmp(dbv.pszVal, name); + db_free(&dbv); + if (tCompareResult) continue; + return hContact; // already there, return handle + } + } + return NULL; +} +HANDLE find_contactT(TCHAR *name) { + char *szProto; + int tCompareResult; + HANDLE hContact; + DBVARIANT dbv; + + // already on list? + for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) + { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) + { + if (db_get_ts(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; + tCompareResult = _tcscmp(dbv.ptszVal, name); + db_free(&dbv); + if (tCompareResult) continue; + return hContact; // already there, return handle + } + } + return NULL; +} + + +HANDLE add_contact(char *name, DWORD flags) { + HANDLE hContact; + + // already on list? + if (hContact=find_contact(name)) { + if (!(flags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 1)) { + db_unset( hContact, "CList", "NotOnList" ); + db_unset( hContact, "CList", "Hidden" ); + } + LOG(("add_contact: Found %s", name)); + return hContact; // already there, return handle + } + // no, so add + + LOG(("add_contact: Adding %s", name)); + hContact=(HANDLE)CallServiceSync(MS_DB_CONTACT_ADD, 0, 0); + if (hContact) { + if (CallServiceSync(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact,(LPARAM)SKYPE_PROTONAME)!=0) { + LOG(("add_contact: Ouch! MS_PROTO_ADDTOCONTACT failed for some reason")); + CallServiceSync(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + return NULL; + } + if (name[0]) db_set_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, name); + + if (flags & PALF_TEMPORARY ) { + db_set_b(hContact, "CList", "NotOnList", 1); + db_set_b(hContact, "CList", "Hidden", 1); + } + if (name[0]) { + SkypeSend("GET USER %s DISPLAYNAME", name); + } else {LOG(("add_contact: Info: The contact added has no name."));} + } else {LOG(("add_contact: Ouch! MS_DB_CONTACT_ADD failed for some reason"));} + LOG(("add_contact succeeded")); + return hContact; +} + +void logoff_contacts(BOOL bCleanup) { + HANDLE hContact; + char *szProto; + DBVARIANT dbv={0}; + + LOG(("logoff_contacts: Logging off contacts.")); + for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME)) + { + if (db_get_w(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) + db_set_w(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE); + + db_unset(hContact, SKYPE_PROTONAME, "CallId"); + if (db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==1) + { + if (db_get_ts(hContact, SKYPE_PROTONAME, "ChatRoomID", &dbv)) continue; + RemChat (dbv.ptszVal); + db_free(&dbv); + } + if (db_get_s(hContact, SKYPE_PROTONAME, "Typing_Stream", &dbv) == 0) + { + if (bCleanup) SkypeSend ("ALTER APPLICATION libpurple_typing DISCONNECT %s", dbv.pszVal); + db_free(&dbv); + db_unset(hContact, SKYPE_PROTONAME, "Typing_Stream"); + } + + } + } + if (bCleanup && (protocol>=5 || bIsImoproxy)) SkypeSend ("DELETE APPLICATION libpurple_typing"); +} diff --git a/protocols/SkypeClassic/src/contacts.h b/protocols/SkypeClassic/src/contacts.h new file mode 100644 index 0000000000..35a400c3e9 --- /dev/null +++ b/protocols/SkypeClassic/src/contacts.h @@ -0,0 +1,11 @@ +// Prototypes +HANDLE add_contextmenu(HANDLE hContact); +HANDLE find_contact(char *name); +HANDLE find_contactT(TCHAR *name); +HANDLE add_contact(char *name, DWORD flags); +HANDLE add_mainmenu(void); +CLISTMENUITEM HupItem(void); +CLISTMENUITEM CallItem(void); +void logoff_contacts(BOOL bCleanup); +int PrebuildContactMenu(WPARAM, LPARAM); +//int ClistDblClick(WPARAM, LPARAM); \ No newline at end of file diff --git a/protocols/SkypeClassic/src/debug.cpp b/protocols/SkypeClassic/src/debug.cpp new file mode 100644 index 0000000000..a5d7067e8e --- /dev/null +++ b/protocols/SkypeClassic/src/debug.cpp @@ -0,0 +1,75 @@ +#ifndef _DEBUG +#pragma warning (disable: 4206) // nonstandard extension used : translation unit is empty +#else +#include "debug.h" + +#define WIN32_LEAN_AND_MEAN +//#include +#include +//#include +#include "skype.h" +#include +#include + +#define INITBUF 1024 /* Initial size of buffer */ + +#pragma warning (disable: 4706) // assignment within conditional expression + +extern char g_szProtoName[]; + +static CRITICAL_SECTION m_WriteFileMutex; +static FILE *m_fpLogFile = NULL; +static char *m_szLogBuf = NULL; +static DWORD m_iBufSize = 0; + +void init_debug(void) { + char *p; + char logfile[MAX_PATH]; + + ZeroMemory(logfile, sizeof(logfile)); + p=logfile+GetModuleFileNameA(NULL, logfile, sizeof(logfile)); + if (!(p=strrchr (logfile, '\\'))) p=logfile; else p++; + sprintf (p, "%s_log.txt", SKYPE_PROTONAME); + m_szLogBuf = calloc (1, (m_iBufSize = INITBUF)); + m_fpLogFile = fopen(logfile, "a"); + InitializeCriticalSection(&m_WriteFileMutex); +} + +void end_debug (void) { + if (m_szLogBuf) free (m_szLogBuf); + if (m_fpLogFile) fclose (m_fpLogFile); + DeleteCriticalSection(&m_WriteFileMutex); +} + +void do_log(const char *pszFormat, ...) { + char *ct, *pNewBuf; + va_list ap; + time_t lt; + int iLen; + + if (!m_szLogBuf || !m_fpLogFile) return; + EnterCriticalSection(&m_WriteFileMutex); + time(<); + ct=ctime(<); + ct[strlen(ct)-1]=0; + do + { + va_start(ap, pszFormat); + iLen = _vsnprintf(m_szLogBuf, m_iBufSize, pszFormat, ap); + va_end(ap); + if (iLen == -1) + { + if (!(pNewBuf = (char*)realloc (m_szLogBuf, m_iBufSize*2))) + { + iLen = strlen (m_szLogBuf); + break; + } + m_szLogBuf = pNewBuf; + m_iBufSize*=2; + } + } while (iLen == -1); + fprintf (m_fpLogFile, sizeof(time_t) == sizeof(int) ? "%s (%ld) [%08X] %s\n" : "%s (%lld) [%08X] %s\n", ct, lt, GetCurrentThreadId(), m_szLogBuf); + fflush (m_fpLogFile); + LeaveCriticalSection(&m_WriteFileMutex); +} +#endif \ No newline at end of file diff --git a/protocols/SkypeClassic/src/debug.h b/protocols/SkypeClassic/src/debug.h new file mode 100644 index 0000000000..9582246251 --- /dev/null +++ b/protocols/SkypeClassic/src/debug.h @@ -0,0 +1,23 @@ +//#define DEBUG_RELEASE 1 + +#ifdef DEBUG_RELEASE + #define _DEBUG 1 +#endif + +#ifdef _DEBUG + void init_debug(void); + void end_debug (void); + void do_log(const char *pszFormat, ...); + #define DEBUG_OUT(a) OUTPUT(a) + #define TRACE(a) OutputDebugString(a) + #define TRACEA(a) OutputDebugStringA(a) + #define TRACEW(a) OutputDebugStringW(a) + #define LOG(a) do_log a +#else + #define DEBUG_OUT(a) + #define LOG(a) + #define TRACE(a) + #define TRACEA(a) + #define TRACEW(a) +#endif + diff --git a/protocols/SkypeClassic/src/ezxml/ezxml.c b/protocols/SkypeClassic/src/ezxml/ezxml.c new file mode 100644 index 0000000000..24c02fbd70 --- /dev/null +++ b/protocols/SkypeClassic/src/ezxml/ezxml.c @@ -0,0 +1,1033 @@ +/* ezxml.c + * + * Copyright 2004-2006 Aaron Voisine + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if defined(WIN32) || defined(_WIN32) +#include +#ifndef EZXML_NOMMAP +#define EZXML_NOMMAP +#endif +#endif + +#include +#include +#include +#include +#include +#if !defined(WIN32) && !defined(_WIN32) +#include +#endif +#include +#ifndef EZXML_NOMMAP +#include +#endif // EZXML_NOMMAP +#include +#include "ezxml.h" + +#if defined(WIN32) || defined(_WIN32) +#define vsnprintf _vsnprintf +#define snprintf _snprintf +#define open _open +#define read _read +#define write _write +#define close _close +#endif + +#define EZXML_WS "\t\r\n " // whitespace +#define EZXML_ERRL 128 // maximum error string length + +typedef struct ezxml_root *ezxml_root_t; +struct ezxml_root { // additional data for the root tag + struct ezxml xml; // is a super-struct built on top of ezxml struct + ezxml_t cur; // current xml tree insertion point + char *m; // original xml string + size_t len; // length of allocated memory for mmap, -1 for malloc + char *u; // UTF-8 conversion of string if original was UTF-16 + char *s; // start of work area + char *e; // end of work area + char **ent; // general entities (ampersand sequences) + char ***attr; // default attributes + char ***pi; // processing instructions + short standalone; // non-zero if + char err[EZXML_ERRL]; // error string +}; + +char *EZXML_NIL[] = { NULL }; // empty, null terminated array of strings + +// returns the first child tag with the given name or NULL if not found +ezxml_t ezxml_child(ezxml_t xml, const char *name) +{ + xml = (xml) ? xml->child : NULL; + while (xml && strcmp(name, xml->name)) xml = xml->sibling; + return xml; +} + +// returns the Nth tag with the same name in the same subsection or NULL if not +// found +ezxml_t ezxml_idx(ezxml_t xml, int idx) +{ + for (; xml && idx; idx--) xml = xml->next; + return xml; +} + +// returns the value of the requested tag attribute or NULL if not found +const char *ezxml_attr(ezxml_t xml, const char *attr) +{ + int i = 0, j = 1; + ezxml_root_t root = (ezxml_root_t)xml; + + if (! xml || ! xml->attr) return NULL; + while (xml->attr[i] && strcmp(attr, xml->attr[i])) i += 2; + if (xml->attr[i]) return xml->attr[i + 1]; // found attribute + + while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag + for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++); + if (! root->attr[i]) return NULL; // no matching default attributes + while (root->attr[i][j] && strcmp(attr, root->attr[i][j])) j += 3; + return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; // found default +} + +// same as ezxml_get but takes an already initialized va_list +ezxml_t ezxml_vget(ezxml_t xml, va_list ap) +{ + char *name = va_arg(ap, char *); + int idx = -1; + + if (name && *name) { + idx = va_arg(ap, int); + xml = ezxml_child(xml, name); + } + return (idx < 0) ? xml : ezxml_vget(ezxml_idx(xml, idx), ap); +} + +// Traverses the xml tree to retrieve a specific subtag. Takes a variable +// length list of tag names and indexes. The argument list must be terminated +// by either an index of -1 or an empty string tag name. Example: +// title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1); +// This retrieves the title of the 3rd book on the 1st shelf of library. +// Returns NULL if not found. +ezxml_t ezxml_get(ezxml_t xml, ...) +{ + va_list ap; + ezxml_t r; + + va_start(ap, xml); + r = ezxml_vget(xml, ap); + va_end(ap); + return r; +} + +// returns a null terminated array of processing instructions for the given +// target +const char **ezxml_pi(ezxml_t xml, const char *target) +{ + ezxml_root_t root = (ezxml_root_t)xml; + int i = 0; + + if (! root) return (const char **)EZXML_NIL; + while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag + while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target + return (const char **)((root->pi[i]) ? root->pi[i] + 1 : EZXML_NIL); +} + +// set an error string and return root +ezxml_t ezxml_err(ezxml_root_t root, char *s, const char *err, ...) +{ + va_list ap; + int line = 1; + char *t, fmt[EZXML_ERRL]; + + for (t = root->s; t < s; t++) if (*t == '\n') line++; + snprintf(fmt, EZXML_ERRL, "[error near line %d]: %s", line, err); + + va_start(ap, err); + vsnprintf(root->err, EZXML_ERRL, fmt, ap); + va_end(ap); + + return &root->xml; +} + +// Recursively decodes entity and character references and normalizes new lines +// ent is a null terminated array of alternating entity names and values. set t +// to '&' for general entity decoding, '%' for parameter entity decoding, 'c' +// for cdata sections, ' ' for attribute normalization, or '*' for non-cdata +// attribute normalization. Returns s, or if the decoded string is longer than +// s, returns a malloced string that must be freed. +char *ezxml_decode(char *s, char **ent, char t) +{ + char *e, *r = s, *m = s; + long b, c, d, l; + + for (; *s; s++) { // normalize line endings + while (*s == '\r') { + *(s++) = '\n'; + if (*s == '\n') memmove(s, (s + 1), strlen(s)); + } + } + + for (s = r; ; ) { + while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace(*s)) s++; + + if (! *s) break; + else if (t != 'c' && ! strncmp(s, "&#", 2)) { // character reference + if (s[2] == 'x') c = strtol(s + 3, &e, 16); // base 16 + else c = strtol(s + 2, &e, 10); // base 10 + if (! c || *e != ';') { s++; continue; } // not a character ref + + if (c < 0x80) *(s++) = c; // US-ASCII subset + else { // multi-byte UTF-8 sequence + for (b = 0, d = c; d; d /= 2) b++; // number of bits in c + b = (b - 2) / 5; // number of bytes in payload + *(s++) = (0xFF << (7 - b)) | (c >> (6 * b)); // head + while (b) *(s++) = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload + } + + memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';'))); + } + else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) || + (*s == '%' && t == '%')) { // entity reference + for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); + b += 2); // find entity in entity list + + if (ent[b++]) { // found a match + if ((c = strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) { + l = (d = (s - r)) + c + strlen(e); // new length + r = (r == m) ? strcpy(malloc(l), r) : realloc(r, l); + e = strchr((s = r + d), ';'); // fix up pointers + } + + memmove(s + c, e + 1, strlen(e)); // shift rest of string + strncpy(s, ent[b], c); // copy in replacement text + } + else s++; // not a known entity + } + else if ((t == ' ' || t == '*') && isspace(*s)) *(s++) = ' '; + else s++; // no decoding needed + } + + if (t == '*') { // normalize spaces for non-cdata attributes + for (s = r; *s; s++) { + if ((l = strspn(s, " "))) memmove(s, s + l, strlen(s + l) + 1); + while (*s && *s != ' ') s++; + } + if (--s >= r && *s == ' ') *s = '\0'; // trim any trailing space + } + return r; +} + +// called when parser finds start of new tag +void ezxml_open_tag(ezxml_root_t root, char *name, char **attr) +{ + ezxml_t xml = root->cur; + + if (xml->name) xml = ezxml_add_child(xml, name, strlen(xml->txt)); + else xml->name = name; // first open tag + + xml->attr = attr; + root->cur = xml; // update tag insertion point +} + +// called when parser finds character content between open and closing tag +void ezxml_char_content(ezxml_root_t root, char *s, size_t len, char t) +{ + ezxml_t xml = root->cur; + char *m = s; + size_t l; + + if (! xml || ! xml->name || ! len) return; // sanity check + + s[len] = '\0'; // null terminate text (calling functions anticipate this) + len = strlen(s = ezxml_decode(s, root->ent, t)) + 1; + + if (! *(xml->txt)) xml->txt = s; // initial character content + else { // allocate our own memory and make a copy + xml->txt = (xml->flags & EZXML_TXTM) // allocate some space + ? realloc(xml->txt, (l = strlen(xml->txt)) + len) + : strcpy(malloc((l = strlen(xml->txt)) + len), xml->txt); + strcpy(xml->txt + l, s); // add new char content + if (s != m) free(s); // free s if it was malloced by ezxml_decode() + } + + if (xml->txt != m) ezxml_set_flag(xml, EZXML_TXTM); +} + +// called when parser finds closing tag +ezxml_t ezxml_close_tag(ezxml_root_t root, char *name, char *s) +{ + if (! root->cur || ! root->cur->name || strcmp(name, root->cur->name)) + return ezxml_err(root, s, "unexpected closing tag ", name); + + root->cur = root->cur->parent; + return NULL; +} + +// checks for circular entity references, returns non-zero if no circular +// references are found, zero otherwise +int ezxml_ent_ok(char *name, char *s, char **ent) +{ + int i; + + for (; ; s++) { + while (*s && *s != '&') s++; // find next entity reference + if (! *s) return 1; + if (! strncmp(s + 1, name, strlen(name))) return 0; // circular ref. + for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i])); i += 2); + if (ent[i] && ! ezxml_ent_ok(name, ent[i + 1], ent)) return 0; + } +} + +// called when the parser finds a processing instruction +void ezxml_proc_inst(ezxml_root_t root, char *s, size_t len) +{ + int i = 0, j = 1; + char *target = s; + + s[len] = '\0'; // null terminate instruction + if (*(s += strcspn(s, EZXML_WS))) { + *s = '\0'; // null terminate target + s += strspn(s + 1, EZXML_WS) + 1; // skip whitespace after target + } + + if (! strcmp(target, "xml")) { // + if ((s = strstr(s, "standalone")) && ! strncmp(s + strspn(s + 10, + EZXML_WS "='\"") + 10, "yes", 3)) root->standalone = 1; + return; + } + + if (! root->pi[0]) *(root->pi = malloc(sizeof(char **))) = NULL; //first pi + + while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target + if (! root->pi[i]) { // new target + root->pi = realloc(root->pi, sizeof(char **) * (i + 2)); + root->pi[i] = malloc(sizeof(char *) * 3); + root->pi[i][0] = target; + root->pi[i][1] = (char *)(root->pi[i + 1] = NULL); // terminate pi list + root->pi[i][2] = strdup(""); // empty document position list + } + + while (root->pi[i][j]) j++; // find end of instruction list for this target + root->pi[i] = realloc(root->pi[i], sizeof(char *) * (j + 3)); + root->pi[i][j + 2] = realloc(root->pi[i][j + 1], j + 1); + strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<"); + root->pi[i][j + 1] = NULL; // null terminate pi list for this target + root->pi[i][j] = s; // set instruction +} + +// called when the parser finds an internal doctype subset +short ezxml_internal_dtd(ezxml_root_t root, char *s, size_t len) +{ + char q, *c, *t, *n = NULL, *v, **ent, **pe; + int i, j; + + pe = memcpy(malloc(sizeof(EZXML_NIL)), EZXML_NIL, sizeof(EZXML_NIL)); + + for (s[len] = '\0'; s; ) { + while (*s && *s != '<' && *s != '%') s++; // find next declaration + + if (! *s) break; + else if (! strncmp(s, "'); + continue; + } + + for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++); + ent = realloc(ent, (i + 3) * sizeof(char *)); // space for next ent + if (*c == '%') pe = ent; + else root->ent = ent; + + *(++s) = '\0'; // null terminate name + if ((s = strchr(v, q))) *(s++) = '\0'; // null terminate value + ent[i + 1] = ezxml_decode(v, pe, '%'); // set value + ent[i + 2] = NULL; // null terminate entity list + if (! ezxml_ent_ok(n, ent[i + 1], ent)) { // circular reference + if (ent[i + 1] != v) free(ent[i + 1]); + ezxml_err(root, v, "circular entity declaration &%s", n); + break; + } + else ent[i] = n; // set entity name + } + else if (! strncmp(s, "")) == '>') continue; + else *s = '\0'; // null terminate tag name + for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0]); i++); + + while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') { + if (*(s = n + strcspn(n, EZXML_WS))) *s = '\0'; // attr name + else { ezxml_err(root, t, "malformed ") - 1; + if (*c == ' ') continue; // cdata is default, nothing to do + v = NULL; + } + else if ((*s == '"' || *s == '\'') && // default value + (s = strchr(v = s + 1, *s))) *s = '\0'; + else { ezxml_err(root, t, "malformed attr[i]) { // new tag name + root->attr = (! i) ? malloc(2 * sizeof(char **)) + : realloc(root->attr, + (i + 2) * sizeof(char **)); + root->attr[i] = malloc(2 * sizeof(char *)); + root->attr[i][0] = t; // set tag name + root->attr[i][1] = (char *)(root->attr[i + 1] = NULL); + } + + for (j = 1; root->attr[i][j]; j += 3); // find end of list + root->attr[i] = realloc(root->attr[i], + (j + 4) * sizeof(char *)); + + root->attr[i][j + 3] = NULL; // null terminate list + root->attr[i][j + 2] = c; // is it cdata? + root->attr[i][j + 1] = (v) ? ezxml_decode(v, root->ent, *c) + : NULL; + root->attr[i][j] = n; // attribute name + } + } + else if (! strncmp(s, ""); // comments + else if (! strncmp(s, ""))) + ezxml_proc_inst(root, c, s++ - c); + } + else if (*s == '<') s = strchr(s, '>'); // skip other declarations + else if (*(s++) == '%' && ! root->standalone) break; + } + + free(pe); + return ! *root->err; +} + +// Converts a UTF-16 string to UTF-8. Returns a new string that must be freed +// or NULL if no conversion was needed. +char *ezxml_str2utf8(char **s, size_t *len) +{ + char *u; + size_t l = 0, sl, max = *len; + long c, d; + int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1; + + if (be == -1) return NULL; // not UTF-16 + + u = malloc(max); + for (sl = 2; sl < *len - 1; sl += 2) { + c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) //UTF-16BE + : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); //UTF-16LE + if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { // high-half + d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) + : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); + c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000; + } + + while (l + 6 > max) u = realloc(u, max += EZXML_BUFSIZE); + if (c < 0x80) u[l++] = c; // US-ASCII subset + else { // multi-byte UTF-8 sequence + for (b = 0, d = c; d; d /= 2) b++; // bits in c + b = (b - 2) / 5; // bytes in payload + u[l++] = (0xFF << (7 - b)) | (c >> (6 * b)); // head + while (b) u[l++] = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload + } + } + return *s = realloc(u, *len = l); +} + +// frees a tag attribute list +void ezxml_free_attr(char **attr) { + int i = 0; + char *m; + + if (! attr || attr == EZXML_NIL) return; // nothing to free + while (attr[i]) i += 2; // find end of attribute list + m = attr[i + 1]; // list of which names and values are malloced + for (i = 0; m[i]; i++) { + if (m[i] & EZXML_NAMEM) free(attr[i * 2]); + if (m[i] & EZXML_TXTM) free(attr[(i * 2) + 1]); + } + free(m); + free(attr); +} + +// parse the given xml string and return an ezxml structure +ezxml_t ezxml_parse_str(char *s, size_t len) +{ + ezxml_root_t root = (ezxml_root_t)ezxml_new(NULL); + char q, e, *d, **attr, **a = NULL; // initialize a to avoid compile warning + int l, i, j; + + root->m = s; + if (! len) return ezxml_err(root, NULL, "root tag missing"); + root->u = ezxml_str2utf8(&s, &len); // convert utf-16 to utf-8 + root->e = (root->s = s) + len; // record start and end of work area + + e = s[len - 1]; // save end char + s[len - 1] = '\0'; // turn end char into null terminator + + while (*s && *s != '<') s++; // find first tag + if (! *s) return ezxml_err(root, s, "root tag missing"); + + for (; ; ) { + attr = (char **)EZXML_NIL; + d = ++s; + + if (isalpha(*s) || *s == '_' || *s == ':' || *s < '\0') { // new tag + if (! root->cur) + return ezxml_err(root, d, "markup outside of root element"); + + s += strcspn(s, EZXML_WS "/>"); + while (isspace(*s)) *(s++) = '\0'; // null terminate tag name + + if (*s && *s != '/' && *s != '>') // find tag in default attr list + for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++); + + for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { // new attrib + attr = (l) ? realloc(attr, (l + 4) * sizeof(char *)) + : malloc(4 * sizeof(char *)); // allocate space + attr[l + 3] = (l) ? realloc(attr[l + 1], (l / 2) + 2) + : malloc(2); // mem for list of maloced vals + strcpy(attr[l + 3] + (l / 2), " "); // value is not malloced + attr[l + 2] = NULL; // null terminate list + attr[l + 1] = ""; // temporary attribute value + attr[l] = s; // set attribute name + + s += strcspn(s, EZXML_WS "=/>"); + if (*s == '=' || isspace(*s)) { + *(s++) = '\0'; // null terminate tag attribute name + q = *(s += strspn(s, EZXML_WS "=")); + if (q == '"' || q == '\'') { // attribute value + attr[l + 1] = ++s; + while (*s && *s != q) s++; + if (*s) *(s++) = '\0'; // null terminate attribute val + else { + ezxml_free_attr(attr); + return ezxml_err(root, d, "missing %c", q); + } + + for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j +=3); + attr[l + 1] = ezxml_decode(attr[l + 1], root->ent, (a + && a[j]) ? *a[j + 2] : ' '); + if (attr[l + 1] < d || attr[l + 1] > s) + attr[l + 3][l / 2] = EZXML_TXTM; // value malloced + } + } + while (isspace(*s)) s++; + } + + if (*s == '/') { // self closing tag + *(s++) = '\0'; + if ((*s && *s != '>') || (! *s && e != '>')) { + if (l) ezxml_free_attr(attr); + return ezxml_err(root, d, "missing >"); + } + ezxml_open_tag(root, d, attr); + ezxml_close_tag(root, d, s); + } + else if ((q = *s) == '>' || (! *s && e == '>')) { // open tag + *s = '\0'; // temporarily null terminate tag name + ezxml_open_tag(root, d, attr); + *s = q; + } + else { + if (l) ezxml_free_attr(attr); + return ezxml_err(root, d, "missing >"); + } + } + else if (*s == '/') { // close tag + s += strcspn(d = s + 1, EZXML_WS ">") + 1; + if (! (q = *s) && e != '>') return ezxml_err(root, d, "missing >"); + *s = '\0'; // temporarily null terminate tag name + if (ezxml_close_tag(root, d, s)) return &root->xml; + if (isspace(*s = q)) s += strspn(s, EZXML_WS); + } + else if (! strncmp(s, "!--", 3)) { // xml comment + if (! (s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) || + (! *s && e != '>')) return ezxml_err(root, d, "unclosed Yes +// 0 --> No +int AnySkypeusers(void) +{ + HANDLE hContact; + DBVARIANT dbv; + int tCompareResult; + + // already on list? + for (hContact=db_find_first(); + hContact != NULL; + hContact=db_find_next(hContact)) + { + // GETCONTACTBASEPROTO doesn't work on not loaded protocol, therefore get + // protocol from DB + if (db_get_s(hContact, "Protocol", "p", &dbv)) continue; + tCompareResult = !strcmp(dbv.pszVal, SKYPE_PROTONAME); + db_free(&dbv); + if (tCompareResult) return 1; + } + return 0; +} + + +/*void UpgradeName(char *OldName) +{ + DBCONTACTENUMSETTINGS cns; + DBCONTACTWRITESETTING cws; + DBVARIANT dbv; + HANDLE hContact=NULL; + struct PLUGINDI pdi; + + LOG(("Updating old database settings if there are any...")); + cns.pfnEnumProc=EnumOldPluginName; + cns.lParam=(LPARAM)&pdi; + cns.szModule=OldName; + cns.ofsSettings=0; + + hContact = db_find_first(); + + for ( ;; ) { + memset(&pdi,0,sizeof(pdi)); + CallService(MS_DB_CONTACT_ENUMSETTINGS,(WPARAM)hContact,(LPARAM)&cns); + // Upgrade Protocol settings to new string + if (pdi.szSettings) { + int i; + + LOG(("We're currently upgrading...")); + for (i=0;i 0 && !Miranda_Terminated()) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + UnregisterClass (WndClass.lpszClassName, hInst); + LOG (("Messagepump stopped.")); +} + +// DLL Stuff // + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) +{ + mirandaVersion = mirVersion; + + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MUUID_SKYPE_CALL, MIID_LAST}; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + UNREFERENCED_PARAMETER(fdwReason); + UNREFERENCED_PARAMETER(lpvReserved); + + hInst = hinstDLL; + return TRUE; +} + + +int PreShutdown(WPARAM wParam, LPARAM lParam) { + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + PostThreadMessage(msgPumpThreadId, WM_QUIT, 0, 0); + return 0; +} + +extern "C" int __declspec(dllexport) Load(void) +{ + DWORD Buffsize; + HKEY MyKey; + BOOL SkypeInstalled; + BOOL UseCustomCommand; + WSADATA wsaData; + char path[MAX_PATH]; + + mir_getLP(&pluginInfo); + + // RM: commented so it will always use predefined name - or was this really needed? + ///GetModuleFileNameA( hInst, path, sizeof( path )); + ///_splitpath (path, NULL, NULL, SKYPE_PROTONAME, NULL); + ///CharUpperA( SKYPE_PROTONAME ); + + InitializeCriticalSection(&RingAndEndcallMutex); + InitializeCriticalSection(&QueryThreadMutex); + InitializeCriticalSection(&TimeMutex); + + +#ifdef _DEBUG + init_debug(); +#endif + + LOG(("Load: Skype Plugin loading...")); + + // We need to upgrade SKYPE_PROTOCOL internal name to Skype if not already done +/* if (!db_get_b(NULL, SKYPE_PROTONAME, "UpgradeDone", 0)) + UpgradeName("SKYPE_PROTOCOL");*/ + + // Initialisation of Skype MsgQueue must be done because of Cleanup in end and + // Mutex is also initialized here. + LOG(("SkypeMsgInit initializing Skype MSG-queue")); + if (SkypeMsgInit()==-1) { + OUTPUT(_T("Memory allocation error on startup.")); + return 0; + } + + // On first run on new profile, ask user, if he wants to enable the plugin in + // this profile + // --> Fixing Issue #0000006 from bugtracker. + if (!db_get_b(NULL, SKYPE_PROTONAME, "FirstRun", 0)) { + db_set_b(NULL, SKYPE_PROTONAME, "FirstRun", 1); + if (AnySkypeusers()==0) // First run, it seems :) + if (MessageBox(NULL, TranslateT("This seems to be the first time that you're running the Skype protocol plugin. Do you want to enable the protocol for this Miranda-Profile? (If you chose NO, you can always enable it in the plugin options later."), _T("Welcome!"), MB_ICONQUESTION|MB_YESNO)==IDNO) { + char path[MAX_PATH], *filename; + GetModuleFileNameA(hInst, path, sizeof(path)); + if (filename = strrchr(path,'\\')+1) + db_set_b(NULL,"PluginDisable",filename,1); + return 0; + } + } + + + // Check if Skype is installed + SkypeInstalled=TRUE; + UseCustomCommand = (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); + UseSockets = (BOOL)db_get_b(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0); + + if (!UseSockets && !UseCustomCommand) + { + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) + { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) + { + SkypeInstalled=FALSE; + } + } + + Buffsize=sizeof(skype_path); + + if (SkypeInstalled==FALSE || RegQueryValueExA(MyKey, "SkypePath", NULL, NULL, (unsigned char *)skype_path, &Buffsize)!=ERROR_SUCCESS) + { + //OUTPUT("Skype was not found installed :( \nMaybe you are using portable skype."); + RegCloseKey(MyKey); + skype_path[0]=0; + //return 0; + } + RegCloseKey(MyKey); + } + WSAStartup(MAKEWORD(2,2), &wsaData); + + // Start Skype connection + if (!(ControlAPIAttach=RegisterWindowMessage(_T("SkypeControlAPIAttach"))) || !(ControlAPIDiscover=RegisterWindowMessage(_T("SkypeControlAPIDiscover")))) + { + OUTPUT(_T("Cannot register Window message.")); + return 0; + } + + SkypeMsgReceived=CreateSemaphore(NULL, 0, MAX_MSGS, NULL); + if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || + !(MessagePumpReady=CreateEvent(NULL, FALSE, FALSE, NULL)) || +#ifdef SKYPEBUG_OFFLN + !(GotUserstatus=CreateEvent(NULL, TRUE, FALSE, NULL)) || +#endif + !(hBuddyAdded=CreateEvent(NULL, FALSE, FALSE, NULL)) || + !(FetchMessageEvent=CreateEvent(NULL, FALSE, TRUE, NULL))) { + OUTPUT(_T("Unable to create Mutex!")); + return 0; + } + + /* Register the module */ + PROTOCOLDESCRIPTOR pd = { PROTOCOLDESCRIPTOR_V3_SIZE }; + pd.szName = SKYPE_PROTONAME; + pd.type = PROTOTYPE_PROTOCOL; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + VoiceServiceInit(); + + CreateServices(); + HookEvents(); + InitVSApi(); + MsgList_Init(); + + HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + + // Startup Message-pump + pthread_create (( pThreadFunc )MsgPump, NULL); + WaitForSingleObject(MessagePumpReady, INFINITE); + return 0; +} + + + +extern "C" int __declspec( dllexport ) Unload(void) +{ + BOOL UseCustomCommand = db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); + BOOL Shutdown = db_get_b(NULL, SKYPE_PROTONAME, "Shutdown", 0); + + LOG (("Unload started")); + + if ( Shutdown && ((skype_path && skype_path[0]) ||UseCustomCommand) ) { + + if(UseCustomCommand) + { + DBVARIANT dbv; + if(!db_get_s(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) + { + char szAbsolutePath[MAX_PATH]; + + TranslateMirandaRelativePathToAbsolute(dbv.pszVal, szAbsolutePath, FALSE); + _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); + LOG (("Unload Sent /shutdown to %s", szAbsolutePath)); + db_free(&dbv); + } + } + else + { + _spawnl(_P_NOWAIT, skype_path, skype_path, "/SHUTDOWN", NULL); + LOG (("Unload Sent /shutdown to %s", skype_path)); + } + + } + SkypeMsgCleanup(); + //WSACleanup(); + FreeVSApi(); + UnhookEvents(); + UnhookEvent(hChatEvent); + UnhookEvent (hChatMenu); + UnhookEvent (hEvInitChat); + DestroyHookableEvent(hInitChat); + VoiceServiceExit(); + GCExit(); + MsgList_Exit(); + + CloseHandle(SkypeReady); + CloseHandle(SkypeMsgReceived); +#ifdef SKYPEBUG_OFFLN + CloseHandle(GotUserstatus); +#endif + CloseHandle(MessagePumpReady); + CloseHandle(hBuddyAdded); + CloseHandle(FetchMessageEvent); + + DeleteCriticalSection(&RingAndEndcallMutex); + DeleteCriticalSection(&QueryThreadMutex); + + SkypeRegisterProxy (0, 0); + LOG (("Unload: Shutdown complete")); +#ifdef _DEBUG + end_debug(); +#endif + DeleteCriticalSection(&TimeMutex); + return 0; +} + diff --git a/protocols/SkypeClassic/src/skype.h b/protocols/SkypeClassic/src/skype.h new file mode 100644 index 0000000000..3c7fd2b927 --- /dev/null +++ b/protocols/SkypeClassic/src/skype.h @@ -0,0 +1,183 @@ +#pragma once + +#define _CRT_SECURE_NO_DEPRECATE 1 +#define TEXT_LEN 1024 +#define CP_ACP 0 + +#define code_page CP_ACP; +#define MIRANDA_CUSTOM_LP + + +// System includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "resource.h" +#include "version.h" +#include "util.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter + +// Miranda Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma warning (pop) + +// MyDetails defines + +// wParam=NULL +// lParam=(char *) new nickname - do not free +// return=0 for sucess +#define PS_SETMYNICKNAME "/SetNickname" + +// Optional, default value is 1024 +// wParam=NULL +// lParam=NULL +// return= <=0 for error, >0 the max length of the nick +#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength" + +// wParam=(char *)Buffer to file name +// lParam=(int)Buffer size +// return=0 for sucess +#define PS_GETMYAVATAR "/GetMyAvatar" + +// wParam=0 +// lParam=(const char *)Avatar file name +// return=0 for sucess +#define PS_SETMYAVATAR "/SetMyAvatar" + + +// Program defines +#define SKYPE_NAME "Username" +#define SKYPE_PROTO "PROTOCOL 7" +#define SKYPE_PROTONAME g_szProtoName // Name of our protocol, taken from .DLL name +#define MAX_MSGS 128 // Maximum messages in queue +#define MAX_USERLEN 32 // Maximum length of a username in Skype +#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available +#define USEPOPUP 1 // Use the popup-plugin? +#define TIMEOUT_MSGSEND 60000 // Stolen from msgdialog.c +#define MAX_MSG_AGE 30 // Maximum age in seconds before a Message from queue gets trashed +#define SKYPEBUG_OFFLN 1 // Activate fix for the SkypeAPI Offline-Bug + +// Program hooks +typedef struct { + char ChatNew[MAXMODULELABELLENGTH]; + char SetAvatar[MAXMODULELABELLENGTH]; + char SendFile[MAXMODULELABELLENGTH]; + char HoldCall[MAXMODULELABELLENGTH]; + char AnswerCall[MAXMODULELABELLENGTH]; + char ImportHistory[MAXMODULELABELLENGTH]; + char AddUser[MAXMODULELABELLENGTH]; + char SkypeOutCallUser[MAXMODULELABELLENGTH]; + char CallHangupUser[MAXMODULELABELLENGTH]; + char CallUser[MAXMODULELABELLENGTH]; +} SKYPE_SVCNAMES; +#define SKYPE_CALL g_svcNames.CallUser +#define SKYPE_CALLHANGUP g_svcNames.CallHangupUser +#define SKYPEOUT_CALL g_svcNames.SkypeOutCallUser +#define SKYPE_ADDUSER g_svcNames.AddUser +#define SKYPE_IMPORTHISTORY g_svcNames.ImportHistory +#define SKYPE_ANSWERCALL g_svcNames.AnswerCall +#define SKYPE_HOLDCALL g_svcNames.HoldCall +#define SKYPE_SENDFILE g_svcNames.SendFile +#define SKYPE_SETAVATAR g_svcNames.SetAvatar +#define SKYPE_CHATNEW g_svcNames.ChatNew +#define EVENTTYPE_CALL 2000 + +#define WM_COPYDATALOCAL WM_USER+100 // WM_COPYDATA for local window communication, needed due to Win98 bug + +#ifndef __SKYPESVC_C__ +extern SKYPE_SVCNAMES g_svcNames; +#endif + +// Skype API Communication services +#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg" +#define SKYPE_REGPROXY "/RegisterProxySvc" + +#define MUUID_SKYPE_CALL { 0x245241eb, 0x178c, 0x4b3f, { 0x91, 0xa, 0x4c, 0x4d, 0xf0, 0xa0, 0xc3, 0xb6 } } + + +// Common used code-pieces +#define OUTPUT(a) ShowMessage(IDI_ERRORS, a, 1); +#define OUTPUTA(a) ShowMessageA(IDI_ERRORS, a, 1); + +typedef void ( __cdecl* pThreadFunc )( void* ); + +// Prototypes + +void __cdecl SkypeSystemInit(char *); +void __cdecl MsgPump (char *dummy); +void PingPong(void); +void CheckIfApiIsResponding(char *); +void TellError(DWORD err); +int ShowMessage(int, TCHAR*, int); +#ifdef _UNICODE +int ShowMessageA(int iconID, char *lpzText, int mustShow); +#else +#define ShowMessageA ShowMessage +#endif +void EndCallThread(char *); +void GetInfoThread(HANDLE); +int OnDetailsInit( WPARAM, LPARAM ); +INT_PTR SkypeGetAvatarInfo(WPARAM wParam,LPARAM lParam); +INT_PTR SkypeGetAvatarCaps(WPARAM wParam,LPARAM lParam); +INT_PTR SkypeGetAwayMessage(WPARAM wParam,LPARAM lParam); +int HookContactAdded(WPARAM wParam, LPARAM lParam); +int HookContactDeleted(WPARAM wParam, LPARAM lParam); +INT_PTR ImportHistory(WPARAM wParam, LPARAM lParam); +int CreateTopToolbarButton(WPARAM wParam, LPARAM lParam); +int OnModulesLoaded(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetStatus(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetStatus(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetInfo(WPARAM wParam,LPARAM lParam); +INT_PTR SkypeAddToList(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeBasicSearch(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSendMessage(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeRecvMessage(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeUserIsTyping(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSendAuthRequest(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeRecvAuth(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAuthAllow(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAuthDeny(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAddToListByEvent(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeRegisterProxy(WPARAM wParam, LPARAM lParam); +time_t SkypeTime(time_t *timer); +void MessageSendWatchThread(void*); +int OkToExit(WPARAM wParam, LPARAM lParam); +int MirandaExit(WPARAM wParam, LPARAM lParam); +int __stdcall EnterBitmapFileName( char* szDest ); +void CleanupNicknames(char *dummy); +int InitVSApi(); +int FreeVSApi(); +HANDLE GetMetaHandle(DWORD dwId); +void LaunchSkypeAndSetStatusThread(void *newStatus); + +// Structs + +typedef struct { + char *SkypeSetting; + char *MirandaSetting; +} settings_map; diff --git a/protocols/SkypeClassic/src/skypeapi.cpp b/protocols/SkypeClassic/src/skypeapi.cpp new file mode 100644 index 0000000000..966972f8fe --- /dev/null +++ b/protocols/SkypeClassic/src/skypeapi.cpp @@ -0,0 +1,1706 @@ +/* + * SkypeAPI - All more or less important functions that deal with Skype + */ + +#include "skype.h" +#include "skypeapi.h" +#include "utf8.h" +#include "debug.h" +#include "contacts.h" +#include "skypeproxy.h" +#include "pthread.h" +#include "gchat.h" +#include "alogon.h" +#include "msgq.h" +#include +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +#include +#include +#pragma warning (push) +#include + +#pragma warning (disable: 4706) // assignment within conditional expression + +// Imported Globals +extern HWND hSkypeWnd, g_hWnd; +extern BOOL SkypeInitialized, UseSockets, MirandaShuttingDown, bIsImoproxy; +extern int SkypeStatus, receivers; +extern HANDLE SkypeReady, SkypeMsgReceived, httbButton; +extern UINT ControlAPIAttach, ControlAPIDiscover; +extern LONG AttachStatus; +extern HINSTANCE hInst; +extern PLUGININFOEX pluginInfo; +extern HANDLE hProtocolAvatarsFolder, hHookSkypeApiRcv; +extern char DefaultAvatarsFolder[MAX_PATH+1], *pszProxyCallout, protocol, g_szProtoName[]; + +// -> Skype Message Queue functions // + +static TYP_MSGQ SkypeMsgs, SkypeSendQueue; + +status_map status_codes[] = { + {ID_STATUS_AWAY, "AWAY"}, + {ID_STATUS_NA, "NA"}, + {ID_STATUS_DND, "DND"}, + {ID_STATUS_ONLINE, "ONLINE"}, + {ID_STATUS_FREECHAT, "SKYPEME"}, // Unfortunately Skype API tells us userstatus ONLINE, if we are free for chat + {ID_STATUS_OFFLINE, "OFFLINE"}, + {ID_STATUS_INVISIBLE, "INVISIBLE"}, + {ID_STATUS_CONNECTING, "CONNECTING"}, + {0, NULL} +}; + +//status_map + + +static CRITICAL_SECTION ConnectMutex; +static BOOL rcvThreadRunning=FALSE, isConnecting = FALSE; +static SOCKET ClientSocket=INVALID_SOCKET; +static HANDLE SkypeMsgToSend=NULL; + +static char *m_szSendBuf = NULL; +static DWORD m_iBufSize = 0; + + +static int _ConnectToSkypeAPI(char *path, BOOL bStart); + + +/* SkypeReceivedMessage + * + * Purpose: Hook to be called when a message is received, if some caller is + * using our internal I/O services. + * Params : wParam - Not used + * lParam - COPYDATASTRUCT like in WM_COPYDATA + * Returns: Result from SendMessage + */ +INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam) { + return SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, lParam); +} + +/* + * Skype via Socket --> Skype2Socket connection + */ + +void rcvThread(char *dummy) { + unsigned int length; + char *buf; + COPYDATASTRUCT CopyData; + int rcv; + + if (!UseSockets) return; + rcvThreadRunning=TRUE; + for ( ;; ) { + if (ClientSocket==INVALID_SOCKET) { + rcvThreadRunning=FALSE; + return; + } + LOG(("rcvThread Receiving from socket..")); + if ((rcv=recv(ClientSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || rcv==0) { + rcvThreadRunning=FALSE; + if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} + else {LOG(("rcvThread lost connection, graceful shutdown"));} + return; + } + LOG(("rcvThread Received length, recieving message..")); + buf=(char *)calloc(1, length+1); + if ((rcv = recv(ClientSocket, buf, length, 0))==SOCKET_ERROR || rcv==0) { + rcvThreadRunning=FALSE; + if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} + else {LOG(("rcvThread lost connection, graceful shutdown"));} + free(buf); + return; + } + LOG(("Received message: %s", buf)); + + CopyData.dwData=0; + CopyData.lpData=buf; + CopyData.cbData=(DWORD)strlen(buf)+1; + if (!SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, (LPARAM)&CopyData)) + { + LOG(("SendMessage failed: %08X", GetLastError())); + } + free(buf); + } +} + +void sendThread(char *dummy) { + COPYDATASTRUCT CopyData; + LRESULT SendResult; + int oldstatus; + unsigned int length; + char *szMsg; + + while (SkypeMsgToSend) { + if (WaitForSingleObject(SkypeMsgToSend, INFINITE) != WAIT_OBJECT_0) return; + if (!(szMsg = MsgQ_Get(&SkypeSendQueue))) continue; + length=(unsigned int)strlen(szMsg); + + if (UseSockets) { + if (send(ClientSocket, (char *)&length, sizeof(length), 0) != SOCKET_ERROR && + send(ClientSocket, szMsg, length, 0) != SOCKET_ERROR) { + free (szMsg); + continue; + } + SendResult = 0; + } else { + CopyData.dwData=0; + CopyData.lpData=szMsg; + CopyData.cbData=length+1; + + // Internal comm channel + if (pszProxyCallout) { + CallService (pszProxyCallout, 0, (LPARAM)&CopyData); + free(szMsg); + continue; + } + + // If this didn't work, proceed with normal Skype API + if (!hSkypeWnd) + { + LOG(("SkypeSend: DAMN! No Skype window handle! :(")); + } + SendResult=SendMessage(hSkypeWnd, WM_COPYDATA, (WPARAM)g_hWnd, (LPARAM)&CopyData); + LOG(("SkypeSend: SendMessage returned %d", SendResult)); + free(szMsg); + } + if (!SendResult) { + SkypeInitialized=FALSE; + AttachStatus=-1; + ResetEvent(SkypeReady); + if (g_hWnd) KillTimer (g_hWnd, 1); + if (SkypeStatus!=ID_STATUS_OFFLINE) { + // Go offline + logoff_contacts(FALSE); + oldstatus=SkypeStatus; + InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); + ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); + } + // Reconnect to Skype + ResetEvent(SkypeReady); + pthread_create(LaunchSkypeAndSetStatusThread, (void *)ID_STATUS_ONLINE); + WaitForSingleObject (SkypeReady, 10000); + // SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); + } + } +} + + +/* + * Skype Messagequeue - Implemented as a linked list + */ + +/* SkypeMsgInit + * + * Purpose: Initializes the Skype Message queue and API + * Returns: 0 - Success + * -1 - Memory allocation failure + */ +int SkypeMsgInit(void) { + + MsgQ_Init(&SkypeMsgs); + MsgQ_Init(&SkypeSendQueue); + InitializeCriticalSection(&ConnectMutex); + if (SkypeMsgToSend=CreateSemaphore(NULL, 0, MAX_MSGS, NULL)) { + if (m_szSendBuf = (char*)malloc(m_iBufSize=512)) { + if (_beginthread(( pThreadFunc )sendThread, 0, NULL)!=-1) + return 0; + free(m_szSendBuf); + } + CloseHandle (SkypeMsgToSend); + } + return -1; +} + +/* SkypeMsgAdd + * + * Purpose: Add Message to linked list + * Params : msg - Message to add to queue + * Returns: 0 - Success + * -1 - Memory allocation failure + */ +int SkypeMsgAdd(char *msg) { + return MsgQ_Add(&SkypeMsgs, msg)?0:-1; +} + +/* SkypeMsgCleanup + * + * Purpose: Clean up the whole MESSagequeue - free() all + */ +void SkypeMsgCleanup(void) { + int i; + + LOG(("SkypeMsgCleanup Cleaning up message queue..")); + if (receivers>1) + { + LOG (("SkypeMsgCleanup Releasing %d receivers", receivers)); + for (i=0;i %s", szMsg)); + + // Fake PING-PONG, as PING-PONG is not supported by Skype2Socket + if ((UseSockets || bIsImoproxy) && !strcmp(szMsg, "PING")) { + CopyData.dwData=0; + CopyData.lpData="PONG"; + CopyData.cbData=5; + SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, (LPARAM)&CopyData); + return 0; + } + + if (UseSockets && ClientSocket==INVALID_SOCKET) return -1; + if (!MsgQ_Add(&SkypeSendQueue, szMsg) || !ReleaseSemaphore(SkypeMsgToSend, 1, NULL)) + return -1; + return 0; +} + +/* SkypeSend + * + * Purpose: Sends the specified message to the Skype API. + * If it fails, try to reconnect zu the Skype API + * Params: use like sprintf without first param (dest. buffer) + * Returns: 0 - Success + * -1 - Failure + */ +int SkypeSend(char *szFmt, ...) { + char *pNewBuf; + va_list ap; + size_t iLen; + + // 0.0.0.17+ - Build message-String from supplied parameter list + // so the user doesn't have to care about memory allocation any more. + // 0.0.0.47+ - No more restrictions apply to the format string. + // The temporary buffer remains allocated during the session and gets + // dynamically expanded when needed. This makes sense, as this function + // is used very often and therefore it is faster to not allocate + // memory on every send. + if (!m_szSendBuf && !(m_szSendBuf=(char*)malloc(m_iBufSize=512))) return -1; + do + { + va_start(ap, szFmt); + iLen = _vsnprintf(m_szSendBuf, m_iBufSize, szFmt, ap); + va_end(ap); + if (iLen == -1) + { + if (!(pNewBuf = (char*)realloc (m_szSendBuf, m_iBufSize*2))) + { + iLen = strlen (m_szSendBuf); + break; + } + m_szSendBuf = pNewBuf; + m_iBufSize*=2; + } + } while (iLen == -1); + + return __sendMsg(m_szSendBuf); +} + +/* SkypeRcvTime + * + * Purpose: Wait, until either the message "what" is received or maxwait-Time has passed + * or there was an error and return it + * Params : what - Wait for this string-part at the beginning of a received string + * If the first character of the string is NULL, the rest after the NULL + * character will be searched in the entire received message-string. + * You can tokenize the string by using NULL characters. + * You HAVE TO end the string with a extra \0, otherwise the tokenizer + * will run amok in memory! + * st - The message timestamp must be newer or equal to st. + * Set to 0, if you do not need this and want the first message of this + * kind in the queue. + * maxwait - Wait this time before returning, if nothing was received, + * can be INFINITE + * Returns: The received message containing "what" or a ERROR-Message or NULL if + * time is up and nothing was received + * Warning: Don't forget to free() return value! + */ +char *SkypeRcvTime(char *what, time_t st, DWORD maxwait) { + char *msg, *token=NULL; + struct MsgQueue *ptr; + int j; + DWORD dwWaitStat; + BOOL bChatMsg = FALSE, bIsChatMsg = FALSE; + + LOG (("SkypeRcv - Requesting answer: %s", what)); + if (what) bChatMsg = strncmp(what, "CHATMESSAGE", 11)==0; + do { + EnterCriticalSection(&SkypeMsgs.cs); + // First, search for the requested message. On second run, also accept an ERROR + for (j=0; j<2; j++) + { + for (ptr=SkypeMsgs.l.tqh_first; ptr; ptr=ptr->l.tqe_next) { + if (what && what[0]==0) { + // Tokenizer syntax active + token=what+1; + while (*token) { + if (!strstr (ptr->message, token)) { + token=NULL; + break; + } + token+=strlen(token)+1; + } + } + + //if (j==1) {LOG(("SkypeRcv compare %s (%lu) -- %s (%lu)", ptr->message, ptr->tReceived, what, st));} + if ((st == 0 || ptr->tReceived >= st) && + (what==NULL || token || (what[0] && !strncmp(ptr->message, what, strlen(what))) || + (bIsChatMsg = (j==1 && bChatMsg && !strncmp(ptr->message, what+4, strlen(what+4)))) || + (j==1 && !strncmp(ptr->message, "ERROR", 5)))) + { + msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); + LOG(("1) InterlockedDecrement ((long *)&receivers); // receivers--; + if (receivers>1) {LOG (("SkypeRcv: %d receivers still waiting", receivers));} + + } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); + InterlockedDecrement ((long *)&receivers); + LOG(("message, what)); + pCurMsg = ptr->message; + bIsError = FALSE; + if (*what && !strncmp(pCurMsg, what, iLenWhat)) { + // Now we received a MESSAGE with an identifier. So this one is definitely for us + // However the status can be SENDING instead of SENT and next message with this number + // isn't using the ID anymore, so we have to save the ID as new identifier for message recognition + pCurMsg+=iLenWhat; + if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) + strncpy (msgid, pCurMsg, pMsg-pCurMsg); + else if (strncmp (pCurMsg, "ERROR", 5) == 0) bIsError = TRUE; + } + + if ((*msgid && strncmp (pCurMsg, msgid, strlen(msgid)) == 0) || + (!*what && ptr->tReceived >= st && + (strncmp(pCurMsg, "MESSAGE", 7) == 0 || strncmp(pCurMsg, "CHATMESSAGE", 11) == 0 ) + ) || bIsError || + (ptr->tReceived >= st && ptr->tReceived <=st+1 && + (bIsError=(strncmp(pCurMsg, "ERROR 26", 8)==0 || strncmp(pCurMsg, "ERROR 43", 8)==0)) + ) ) + { + bProcess = bIsError; + if (!bIsError) { + if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) { + pMsg++; + if (strncmp (pMsg, "STATUS ", 7) == 0) { + pMsg+=7; + if (strcmp (pMsg, "SENDING") == 0) { + // Remove dat shit + struct MsgQueue *ptr_=ptr->l.tqe_next; + + free(MsgQ_RemoveMsg(&SkypeMsgs, ptr)); + ptr=ptr_; + continue; + } + bProcess = (strcmp (pMsg, "SENT") == 0 || strcmp (pMsg, "QUEUED") == 0 || + strcmp (pMsg, "FAILED") == 0 || strcmp (pMsg, "IGNORED") == 0 || + strcmp (pMsg, "SENDING") == 0); + } + } + } + if (bProcess) { + msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); + LOG(("l.tqe_next; + } + LeaveCriticalSection(&SkypeMsgs.cs); + InterlockedIncrement ((long *)&receivers); //receivers++; + dwWaitStat = WaitForSingleObject(SkypeMsgReceived, maxwait); + if (receivers>1) InterlockedDecrement ((long *)&receivers); // receivers--; + if (receivers>1) {LOG (("SkypeRcvMsg: %d receivers still waiting", receivers));} + + } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); + InterlockedDecrement ((long *)&receivers); + LOG((" Answer %s", str, ptr)); + return ptr; +} + +char *SkypeGetID(char *szWhat, char *szWho, char *szProperty) { + char szID[16]={0}; + static DWORD dwId = 0; + + if (protocol>=4 || bIsImoproxy) sprintf (szID, "#G%d ", dwId++); + return __SkypeGet (szID, szWhat, szWho, szProperty); +} + +char *SkypeGet(char *szWhat, char *szWho, char *szProperty) { + return __SkypeGet ("", szWhat, szWho, szProperty); +} + +#ifdef _UNICODE +WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty) { + char *ptszWho = (char*)make_utf8_string(szWho); + char *pRet = SkypeGet (szWhat, ptszWho, szProperty); + free (ptszWho); + if (pRet) { + WCHAR *ptr = make_unicode_string((const unsigned char*)pRet); + free (pRet); + return ptr; + } + return NULL; +} +#endif + +char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty) { + char *ret = SkypeGet(szWhat, szWho, szProperty); + if (ret && !strncmp(ret, "ERROR", 5)) { + free (ret); + return NULL; + } + return ret; +} + +#ifdef _UNICODE +WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty) { + WCHAR *ret = SkypeGetW(szWhat, szWho, szProperty); + if (ret && !_tcsncmp(ret, _T("ERROR"), 5)) { + free (ret); + return NULL; + } + return ret; +} +#endif + + +/* SkypeGetProfile + * + * Issues a SET PROFILE szProperty szValue and waits until the answer is received + * Returns the answer or NULL on failure + * BEWARE: Don't forget to free() return value! + * + * For example: SkypeGetProfile("FULLNAME", "Tweety"); +*/ +char *SkypeGetProfile(char *szProperty) { + return SkypeGet ("PROFILE", "", szProperty); +} + +/* SkypeSetProfile + * + * +*/ +int SkypeSetProfile(char *szProperty, char *szValue) { + return SkypeSend("SET PROFILE %s %s", szProperty, szValue); +} + +/* SkypeMsgCollectGarbage + * + * Purpose: Runs the garbage collector on the Skype Message-Queue to throw out old + * messages which may unnecessarily eat up memory. + * Params : age - Time in seconds. Messages older than this value will be + * thrown out. + * Returns: 0 - No messages were thrown out + * >0 - n messages were thrown out + */ +int SkypeMsgCollectGarbage(time_t age) { + return MsgQ_CollectGarbage(&SkypeMsgs, age); +} + + +/* SkypeCall + * + * Purpose: Give a Skype call to the given User in wParam + * or hangs up existing call + * (hangUp is moved over to SkypeCallHangup) + * Params : wParam - Handle to the User to be called + * lParam - Can be NULL + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + char *msg=0; + int res; + + if (!db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + res = -1; // no direct return, because dbv needs to be freed + } else { + if (db_get_s((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; + msg=(char *)malloc(strlen(dbv.pszVal)+6); + strcpy(msg, "CALL "); + strcat(msg, dbv.pszVal); + res=SkypeSend(msg); + } + db_free(&dbv); + free(msg); + return res; +} + +/* SkypeCallHangup + * + * Prupose: Hangs up the existing call to the given User + * in wParam. + * + * Params : wParam - Handle to the User to be called + * lParam - Can be NULL + * + * Returns: 0 - Success + * -1 - Failure + * + */ +INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + char *msg=0; + int res = -1; + + if (!db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + msg=(char *)malloc(strlen(dbv.pszVal)+21); + sprintf(msg, "SET %s STATUS FINISHED", dbv.pszVal); + //sprintf(msg, "ALTER CALL %s HANGUP", dbv.pszVal); + res=SkypeSend(msg); +#if _DEBUG + db_unset((HANDLE)wParam, SKYPE_PROTONAME, "CallId"); +#endif + //} else { + // if (db_get((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; + // msg=(char *)malloc(strlen(dbv.pszVal)+6); + // strcpy(msg, "CALL "); + // strcat(msg, dbv.pszVal); + // res=SkypeSend(msg); + } + db_free(&dbv); + free(msg); + return res; +} + +/* FixNumber + * + * Purpose: Eliminates all non-numeric chars from the given phonenumber + * Params : p - Pointer to the buffer with the number + */ +static void FixNumber(char *p) { + unsigned int i; + + for (i=0;i<=strlen(p);i++) + if ((p[i]<'0' || p[i]>'9')) + if (p[i]) { + memmove(p+i, p+i+1, strlen(p+i)); + i--; + } else break; +} + + +/* DialDlgProc + * + * Purpose: Dialog procedure for the Dial-Dialog + */ +static INT_PTR CALLBACK DialDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static HANDLE hContact; + static unsigned int entries=0; + BOOL TempAdded=FALSE; + char number[64], *msg, *ptr=NULL; + + switch (uMsg){ + case WM_INITDIALOG: + hContact=(HANDLE)lParam; + Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); + TranslateDialogDefault(hwndDlg); + + if (lParam) { + DBVARIANT dbv; + BOOL bDialNow=TRUE; + + if (!db_get(hContact,"UserInfo","MyPhone1",&dbv)) { + int j; + char idstr[16]; + + // Multiple phone numbers, select one + bDialNow=FALSE; + db_free(&dbv); + for(j=0;;j++) { + sprintf(idstr,"MyPhone%d",j); + if(db_get_s(hContact,"UserInfo",idstr,&dbv)) break; + FixNumber(dbv.pszVal+1); // Leave + alone + SendDlgItemMessage(hwndDlg,IDC_NUMBER,CB_ADDSTRING,0,(LPARAM)dbv.pszVal); + db_free(&dbv); + } + } + if (db_get_s(hContact,SKYPE_PROTONAME,"SkypeOutNr",&dbv)) { + db_get_s(hContact,"UserInfo","MyPhone0",&dbv); + FixNumber(dbv.pszVal+1); + } + SetDlgItemTextA(hwndDlg, IDC_NUMBER, dbv.pszVal); + db_free(&dbv); + if (bDialNow) PostMessage(hwndDlg, WM_COMMAND, IDDIAL, 0); + } else { + DBVARIANT dbv; + char number[64]; + + for (entries=0;entriesMAX_ENTRIES) entries=MAX_ENTRIES; + for (i=entries;i>0;i--) { + sprintf(buf, "LastNumber%d", i-1); + if (!db_get_s(NULL, SKYPE_PROTONAME, buf, &dbv)) { + sprintf(buf, "LastNumber%d", i); + db_set_s(NULL, SKYPE_PROTONAME, buf, dbv.pszVal); + db_free(&dbv); + } else break; + } + db_set_s(NULL, SKYPE_PROTONAME, "LastNumber0", number); + } + TempAdded=TRUE; + } + if (!db_set_s(hContact, SKYPE_PROTONAME, "SkypeOutNr", number)) { + msg=(char *)malloc(strlen(number)+6); + strcpy(msg, "CALL "); + strcat(msg, number); + if (SkypeSend(msg) || (ptr=SkypeRcv("ERROR", 500))) { + db_unset(hContact, SKYPE_PROTONAME, "SkypeOutNr"); + if (ptr) { + OUTPUTA(ptr); + free(ptr); + } + if (TempAdded) CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + } + free(msg); + } + case IDCANCEL: + DestroyWindow(hwndDlg); + break; + } + break; + case WM_DESTROY: + Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); + if (httbButton) CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)httbButton, TTBST_RELEASED); + break; + } + return FALSE; +} + +/* CallstatDlgProc + * + * Purpose: Dialog procedure for the CallStatus Dialog + */ +static INT_PTR CALLBACK CallstatDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static int selected; + static DBVARIANT dbv, dbv2={0}; + + switch (uMsg){ + case WM_INITDIALOG: + { + HANDLE hContact; + char *szProto; + + if (!db_get_s((HANDLE)lParam, SKYPE_PROTONAME, "CallId", &dbv)) { + + // Check, if another call is in progress + for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && hContact!=(HANDLE)lParam && + db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 && + !db_get_s(hContact, SKYPE_PROTONAME, "CallId", &dbv2)) + { + if (db_get_b(hContact, SKYPE_PROTONAME, "OnHold", 0)) { + db_free(&dbv2); + continue; + } else break; + } + } + + if (dbv2.pszVal) + { + char buf[256], buf2[256]; + char *szOtherCaller=(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); + + Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); + TranslateDialogDefault(hwndDlg); + SendMessage(hwndDlg, WM_COMMAND, IDC_JOIN, 0); + + GetWindowTextA(hwndDlg, buf, sizeof(buf)); + _snprintf(buf2, sizeof(buf), buf, CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)lParam,0)); + SetWindowTextA(hwndDlg, buf2); + + GetDlgItemTextA(hwndDlg, IDC_JOIN, buf, sizeof(buf)); + _snprintf(buf2, sizeof(buf), buf, szOtherCaller); + SetDlgItemTextA(hwndDlg, IDC_JOIN, buf2); + + GetDlgItemTextA(hwndDlg, IDC_HOLD, buf, sizeof(buf)); + _snprintf(buf2, sizeof(buf), buf, szOtherCaller); + SetDlgItemTextA(hwndDlg, IDC_HOLD, buf2); + + return TRUE; + } + + // No other call in progress, no need for this Dlg., just answer the call + SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); + testfor ("ERROR", 200); + db_free(&dbv); + } + DestroyWindow(hwndDlg); + break; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_JOIN: + case IDC_HOLD: + case IDC_HANGUP: + CheckRadioButton(hwndDlg, IDC_JOIN, IDC_HANGUP, (selected=LOWORD(wParam))); + break; + case IDOK: + { + char *szIdCall2; + + switch (selected) { + case IDC_JOIN: + if (szIdCall2=strchr(dbv2.pszVal, ' ')) + SkypeSend("SET %s JOIN_CONFERENCE%s", dbv.pszVal, szIdCall2); + break; + case IDC_HOLD: + SkypeSend("SET %s STATUS ONHOLD", dbv2.pszVal); + SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); + break; + case IDC_HANGUP: + SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); + break; + } + + db_free(&dbv); + db_free(&dbv2); + DestroyWindow(hwndDlg); + break; + } + } + break; + case WM_DESTROY: + Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); + break; + } + return FALSE; +} + + +/* SkypeOutCallErrorCheck + * + * Purpose: Checks, if an error has occured after call and + * if so, hangs up the call + * This procedure is a seperate thread to not block the core + * while waiting for "ERROR" + * Params : szCallId - ID of the call + */ +void SkypeOutCallErrorCheck(char *szCallId) { + if (testfor("ERROR", 500)) EndCallThread(szCallId); +} + +/* SkypeOutCall + * + * Purpose: Give a SkypeOut call to the given User in wParam + * or hangs up existing call + * The user's record is searched for Phone-number entries. + * If there is more than 1 entry, the Dial-Dialog is shown + * Params : wParam - Handle to the User to be called + * If NULL, the dial-dialog is shown + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + int res = -1; + + if (wParam && !db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + res=SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); + pthread_create(( pThreadFunc )SkypeOutCallErrorCheck, _strdup(dbv.pszVal)); + db_free(&dbv); + } else if (!CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIAL), NULL, DialDlgProc, (LPARAM)wParam)) return -1; + return res; +} + +/* SkypeHoldCall + * + * Purpose: Put the call to the User given in wParam on Hold or Resumes it + * Params : wParam - Handle to the User + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + int retval; + + LOG(("SkypeHoldCall started")); + if (!wParam || db_get_s((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) + return -1; + retval = SkypeSend ("SET %s STATUS %s", dbv.pszVal, + db_get_b((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)?"INPROGRESS":"ONHOLD"); + db_free(&dbv); + return retval; +} + +/* SkypeAnswerCall + * + * Purpose: Answer a Skype-call when a user double-clicks on + * The incoming-call-Symbol. Works for both, Skype and SkypeOut-calls + * Params : wParam - Not used + * lParam - CLISTEVENT* + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam) { + + LOG(("SkypeAnswerCall started")); + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CALLSTAT), NULL, CallstatDlgProc, (LPARAM)((CLISTEVENT*)lParam)->hContact); + return 0; +} +/* SkypeSetNick + * + * Purpose: Set Full Name in profile + * Params : wParam=0 + * lParam=(LPARAM)(const char*)Nick text + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam) { + int retval = -1; + char *Nick = NULL; + + if (wParam & SMNN_UNICODE) + { + db_set_ws(0, SKYPE_PROTONAME, "Nick", (WCHAR*)lParam); + if (AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && + !(Nick = (char*)make_utf8_string((WCHAR*)lParam))) return -1; + } + else + { + db_set_s(0, SKYPE_PROTONAME, "Nick", (char*)lParam); + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && + utf8_encode((const char *)lParam, &Nick) == -1 ) return -1; + } + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) + retval = SkypeSend("SET PROFILE FULLNAME %s", Nick); + if (Nick) free (Nick); + + return retval; + +} +/* SkypeSetAwayMessage + * + * Purpose: Set Mood message in profile + * Params : wParam=status mode + * lParam=(LPARAM)(const char*)message text + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam) { + int retval = -1; + char *Mood = NULL; + + if (!lParam) lParam=(LPARAM)""; + if(utf8_encode((const char *)lParam, &Mood) == -1 ) return -1; + db_set_s(NULL, SKYPE_PROTONAME, "MoodText", (const char *)lParam); + + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) + retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); + free (Mood); + + return retval; +} +INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam) { + int retval = -1; + char *Mood = NULL; + + if (!lParam) lParam=(LPARAM)""; + if (!(Mood = (char*)make_utf8_string((WCHAR*)lParam))) return -1; + db_set_ws(NULL, SKYPE_PROTONAME, "MoodText", (WCHAR*)lParam); + + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) + retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); + free (Mood); + + return retval; +} + +/* SkypeSetAvatar + * + * Purpose: Set user avatar in profile + * Params : wParam=0 + * lParam=(LPARAM)(const char*)filename + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam) { + char *filename = (char *) lParam, *ext; + char AvatarFile[MAX_PATH+1], OldAvatarFile[1024]; + char *ptr = NULL; + int ret; + char command[500]; + DBVARIANT dbv = {0}; + BOOL hasOldAvatar = (db_get_s(NULL, SKYPE_PROTONAME, "AvatarFile", &dbv) == 0 && dbv.type == DBVT_ASCIIZ); + size_t len; + + if (AttachStatus != SKYPECONTROLAPI_ATTACH_SUCCESS) + return -3; + + if (filename == NULL) + return -1; + len = strlen(filename); + if (len < 4) + return -1; + + ext = &filename[len-4]; + if (_stricmp(ext, ".jpg")==0 || _stricmp(ext-1, ".jpeg")==0) + ext = "jpg"; + else if (_stricmp(ext, ".png")==0) + ext = "png"; + else + return -2; + + FoldersGetCustomPath(hProtocolAvatarsFolder, AvatarFile, sizeof(AvatarFile), DefaultAvatarsFolder); + if (!*AvatarFile) strcpy (AvatarFile, DefaultAvatarsFolder); + mir_snprintf(AvatarFile, sizeof(AvatarFile), "%s\\%s avatar.%s", AvatarFile, SKYPE_PROTONAME, ext); + + // Backup old file + if (hasOldAvatar) + { + strncpy(OldAvatarFile, dbv.pszVal, sizeof(OldAvatarFile)-4); + OldAvatarFile[sizeof(OldAvatarFile)-5] = '\0'; + strcat(OldAvatarFile, "_old"); + DeleteFileA(OldAvatarFile); + if (!MoveFileA(dbv.pszVal, OldAvatarFile)) + { + db_free(&dbv); + return -3; + } + } + + // Copy new file + if (!CopyFileA(filename, AvatarFile, FALSE)) + { + if (hasOldAvatar) + { + MoveFileA(OldAvatarFile, dbv.pszVal); + db_free(&dbv); + } + return -3; + } + + // Try to set with skype + mir_snprintf(command, sizeof(command), "SET AVATAR 1 %s", AvatarFile); + if (SkypeSend(command) || (ptr = SkypeRcv(command+4, INFINITE)) == NULL || !strncmp(ptr, "ERROR", 5)) + { + DeleteFileA(AvatarFile); + + if (hasOldAvatar) + MoveFileA(OldAvatarFile, dbv.pszVal); + + ret = -4; + } + else + { + if (hasOldAvatar) + DeleteFileA(OldAvatarFile); + + db_set_s(NULL, SKYPE_PROTONAME, "AvatarFile", AvatarFile); + + ret = 0; + } + + if (ptr != NULL) + free(ptr); + + if (hasOldAvatar) + db_free(&dbv); + + return ret; +} + + +/* SkypeSendFile + * + * Purpose: Opens the Skype-dialog to send a file + * Params : wParam - Handle to the User + * lParam - Not used + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + int retval; + + if (!wParam || db_get_s((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return -1; + retval=SkypeSend("OPEN FILETRANSFER %s", dbv.pszVal); + db_free(&dbv); + return retval; +} + +/* SkypeChatCreate + * + * Purpose: Creates a groupchat with the user + * Params : wParam - Handle to the User + * lParam - Not used + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + HANDLE hContact=(HANDLE)wParam; + char *ptr, *ptr2; + + if (!hContact || db_get_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return -1; + // Flush old messages + while (testfor("\0CHAT \0 STATUS \0", 0)); + if (SkypeSend("CHAT CREATE %s", dbv.pszVal) || !(ptr=SkypeRcv ("\0CHAT \0 STATUS \0", INFINITE))) + { + db_free(&dbv); + return -1; + } + db_free(&dbv); + if (ptr2=strstr (ptr, "STATUS")) { + *(ptr2-1)=0; + ChatStart (ptr+5, FALSE); + } + free(ptr); + return 0; +} + +/* SkypeAdduserDlg + * + * Purpose: Show Skype's Add user Dialog + */ +INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam) { + SkypeSend("OPEN ADDAFRIEND"); + return 0; +} + +/* SkypeFlush + * + * Purpose: Flush the Skype Message-List + */ +void SkypeFlush(void) { + char *ptr; + + while ((ptr=SkypeRcv(NULL, 0))!=NULL) free(ptr); +} + +/* SkypeStatusToMiranda + * + * Purpose: Converts the specified Skype-Status mode to the corresponding Miranda-Status mode + * Params : s - Skype Status + * Returns: The correct Status + * 0 - Nothing found + */ +int SkypeStatusToMiranda(char *s) { + int i; + if (!strcmp("SKYPEOUT", s)) return db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); + for(i=0; status_codes[i].szStat; i++) + if (!strcmp(status_codes[i].szStat, s)) + return status_codes[i].id; + return 0; +} + +/* MirandaStatusToSkype + * + * Purpose: Converts the specified Miranda-Status mode to the corresponding Skype-Status mode + * Params : id - Miranda Status + * Returns: The correct Status + * NULL - Nothing found + */ +char *MirandaStatusToSkype(int id) { + int i; + if (db_get_b(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) { + switch (id) + { + case ID_STATUS_NA: return "AWAY"; + case ID_STATUS_FREECHAT: return "ONLINE"; + } + } + for(i=0; status_codes[i].szStat; i++) + if (status_codes[i].id==id) + return status_codes[i].szStat; + return NULL; +} + +/* GetSkypeErrorMsg + * + * Purpose: Get a human-readable Error-Message for the supplied Skype Error-Message + * Params : str - Skype Error-Message string + * Returns: Human-readable Error Message or NULL, if nothing was found + * Warning: Don't forget to free() return value + */ +char *GetSkypeErrorMsg(char *str) { + char *pos, *reason, *msg; + + LOG (("GetSkypeErrorMsg received error: %s", str)); + if (!strncmp(str, "ERROR", 5)) { + reason=_strdup(str); + return reason; + } + if ((pos=strstr(str, "FAILURE")) ) { + switch(atoi(pos+14)) { + case MISC_ERROR: msg="Misc. Error"; break; + case USER_NOT_FOUND: msg="User does not exist, check username"; break; + case USER_NOT_ONLINE: msg="Trying to send IM to an user, who is not online"; break; + case USER_BLOCKED: msg="IM blocked by recipient"; break; + case TYPE_UNSUPPORTED: msg="Type unsupported"; break; + case SENDER_NOT_FRIEND: msg="Sending IM message to user, who has not added you to friendslist and has chosen 'only people in my friendslist can start IM'"; break; + case SENDER_NOT_AUTHORIZED: msg="Sending IM message to user, who has not authorized you and has chosen 'only people whom I have authorized can start IM'"; break; + default: msg="Unknown error"; + } + reason=(char *)malloc(strlen(pos)+strlen(msg)+3); + sprintf (reason, "%s: %s", pos, msg); + return reason; + } + return NULL; +} + +/* testfor + * + * Purpose: Wait, until the given Message-Fragment is received from Skype within + * the given amount of time + * Params : see SkypeRcv + * Returns: TRUE - Message was received within the given amount of time + * FALSE- nope, sorry + */ +BOOL testfor(char *what, DWORD maxwait) { + char *res; + + if ((res=SkypeRcv(what, maxwait))==NULL) return FALSE; + free(res); + return TRUE; +} + +char SendSkypeproxyCommand(char command) { + int length=0; + char reply=0; + BOOL res; + + res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR + || send(ClientSocket, (char *)&command, sizeof(command), 0)==SOCKET_ERROR + || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; + if (res) + return -1; + else + return reply; +} + +/* ConnectToSkypeAPI + * + * Purpose: Establish a connection to the Skype API + * Params : path - Path to the Skype application + * iStart - Need to start skype for status change. + * 1 = Normal start if Skype not running + * 2 = Forced startp code execution no matter what + * Returns: 0 - Connecting succeeded + * -1 - Something went wrong + */ +int ConnectToSkypeAPI(char *path, int iStart) { + static int iRet = -1; // last request result + static volatile long newRequest = TRUE; + + InterlockedExchange(&newRequest, TRUE); // place new request + EnterCriticalSection(&ConnectMutex); // Prevent reentrance + if (iRet == -1 || newRequest) + { + iRet = _ConnectToSkypeAPI(path, iStart); + InterlockedExchange(&newRequest, FALSE); // every thread which is waiting for connect mutex will get our result as well.. but subsequent calls will set this value to true and call _Connect again + } + LeaveCriticalSection(&ConnectMutex); + return iRet; +} + +void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces) { + *szAbsolutePath = 0; + CallService (MS_UTILS_PATHTOABSOLUTE, (WPARAM)(*cszPath ? cszPath : ".\\"), (LPARAM)szAbsolutePath); + if(fQuoteSpaces && strchr((LPCSTR)szAbsolutePath, ' ')){ + memmove (szAbsolutePath+1, szAbsolutePath, strlen(szAbsolutePath)+1); + *szAbsolutePath='"'; + strcat (szAbsolutePath, "\""); + } + + TRACEA(szAbsolutePath); +} + +static int my_spawnv(const char *cmdname, const char *const *argv, PROCESS_INFORMATION *pi) +{ + int i, iLen=0; + char *CommandLine; + STARTUPINFOA si={0}; + BOOL bRet; + + memset (pi, 0, sizeof(PROCESS_INFORMATION)); + for (i=0; argv[i]; i++) iLen+=strlen(argv[i])+1; + if (!(CommandLine = (char*)calloc(1, iLen))) return -1; + for (i=0; argv[i]; i++) { + if (i) strcat (CommandLine, " "); + strcat (CommandLine, argv[i]); + } + si.cb = sizeof(si); + + bRet = CreateProcessA( cmdname,CommandLine,NULL,NULL,FALSE,0,NULL,NULL,&si,pi); + free(CommandLine); + if (!bRet) return -1; + return (DWORD)pi->hProcess; +} + +static int _ConnectToSkypeAPI(char *path, int iStart) { + BOOL SkypeLaunched=FALSE; + BOOL UseCustomCommand = db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); + int counter=0, i, j, maxattempts=db_get_w(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10); + char *args[16], *pFree = NULL; + char *SkypeOptions[]={"/notray", "/nosplash", "/minimized", "/removable", "/datapath:", "/secondary"}; + const int SkypeDefaults[]={0, 1, 1, 0, 0}; + + char szAbsolutePath[MAX_PATH]; + + LOG(("ConnectToSkypeAPI started.")); + if (UseSockets) + { + SOCKADDR_IN service; + DBVARIANT dbv; + long inet; + struct hostent *hp; + + LOG(("ConnectToSkypeAPI: Connecting to Skype2socket socket...")); + if ((ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) return -1; + + if (!db_get_s(NULL, SKYPE_PROTONAME, "Host", &dbv)) { + if ((inet=inet_addr(dbv.pszVal))==-1) { + if (hp=gethostbyname(dbv.pszVal)) + memcpy(&inet, hp->h_addr, sizeof(inet)); + else { + OUTPUT(_T("Cannot resolve host!")); + db_free(&dbv); + return -1; + } + } + db_free(&dbv); + } else { + OUTPUT(_T("Cannot find valid host to connect to.")); + return -1; + } + + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet; + service.sin_port = htons((unsigned short)db_get_w(NULL, SKYPE_PROTONAME, "Port", 1401)); + + if ( connect( ClientSocket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR) return -1; + + if (db_get_b(NULL, SKYPE_PROTONAME, "RequiresPassword", 0) && !db_get_s(NULL, SKYPE_PROTONAME, "Password", &dbv)) + { + char reply=0; + + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + if ((reply=SendSkypeproxyCommand(AUTHENTICATE))==-1) + { + db_free(&dbv); + return -1; + } + if (!reply) { + OUTPUT(_T("Authentication is not supported/needed for this Skypeproxy server. It will be disabled.")); + db_set_b(NULL, SKYPE_PROTONAME, "RequiresPassword", 0); + } else { + unsigned int length=(unsigned int)strlen(dbv.pszVal); + BOOL res; + res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR + || send(ClientSocket, dbv.pszVal, length, 0)==SOCKET_ERROR + || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; + if (res) + { + db_free(&dbv); + return -1; + } + if (!reply) + { + OUTPUT(_T("Authentication failed for this server, connection was not successful. Verify that your password is correct!")); + db_free(&dbv); + return -1; + } + } + db_free(&dbv); + } + else + { + char reply=0; + + if ((reply=SendSkypeproxyCommand(CAPABILITIES))==-1) return -1; + if (reply&USE_AUTHENTICATION) { + OUTPUT(_T("The server you specified requires authentication, but you have not supplied a password for it. Check the Skype plugin settings and try again.")); + return -1; + } + } + + + if (!rcvThreadRunning) + if(_beginthread(( pThreadFunc )rcvThread, 0, NULL)==-1) return -1; + + AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; + return 0; + } + + if (pszProxyCallout) + { + if (SkypeSend("SET USERSTATUS ONLINE")==-1) + { + AttachStatus=SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE; + return -1; + } + for ( ;; ) { + char *ptr = SkypeRcv ("CONNSTATUS", INFINITE); + if (!ptr) + { + AttachStatus=SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE; + return -1; + } + + if (strcmp (ptr+11, "CONNECTING")) + { + free (ptr); + break; + } + free (ptr); + } + + AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; + return 0; + } + + do + { + int retval; + /* To initiate communication, Client should broadcast windows message + ('SkypeControlAPIDiscover') to all windows in the system, specifying its own + window handle in wParam parameter. + */ + if (iStart != 2 || counter) + { + LOG(("ConnectToSkypeAPI sending discover message.. hWnd=%08X", (long)g_hWnd)); + retval=SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); + LOG(("ConnectToSkypeAPI sent discover message returning %d", retval)); + } + + /* In response, Skype responds with + message 'SkypeControlAPIAttach' to the handle specified, and indicates + connection status + SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. + If there is no answer after 3 seconds, launch Skype as it's propably + not running. + */ + if (iStart == 2 || (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION)) + { + if (iStart != 2 && g_hWnd==NULL) + { + LOG(("ConnectToSkypeAPI: hWnd of SkypeDispatchWindow not yet set..")); + continue; + } + if ((iStart == 2 || !SkypeLaunched) && (path || UseCustomCommand)) + { + static PROCESS_INFORMATION pi={0}; + DWORD dwExitStatus = 0; + + if ((!pi.hProcess || !GetExitCodeProcess(pi.hProcess, &dwExitStatus) || dwExitStatus != STILL_ACTIVE) && + (db_get_b(NULL, SKYPE_PROTONAME, "StartSkype", 1) || iStart)) + { + LOG(("ConnectToSkypeAPI Starting Skype, as it's not running")); + + j=1; + for (i=0; i=maxattempts && AttachStatus==-1) + { + int oldstatus=SkypeStatus; + InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); + ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); + OUTPUT(_T("ERROR: Skype not running / too old / working!")); + return -1; + } + } + } + LOG(("Attachstatus %d", AttachStatus)); + } while (AttachStatus==SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE || AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); + + while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); + LOG(("Attachstatus %d", AttachStatus)); + if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { + int oldstatus; + + switch(AttachStatus) { + case SKYPECONTROLAPI_ATTACH_REFUSED: + OUTPUT(_T("Skype refused the connection :(")); + break; + case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: + OUTPUT(_T("The Skype API is not available")); + break; + default: + LOG(("ERROR: AttachStatus: %d", AttachStatus)); + OUTPUT(_T("Wheee, Skype won't let me use the API. :(")); + } + oldstatus=SkypeStatus; + InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); + ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); + return -1; + } + + return 0; +} + +/* CloseSkypeAPI + * Purpose: Closes existing api connection + * Params: path - Path to the Skype application; could be NULL when using proxy + * Returns: always 0 + */ +int CloseSkypeAPI(char *skypePath) +{ + char szAbsolutePath[MAX_PATH]; + + logoff_contacts(TRUE); + if (UseSockets) + { + if (ClientSocket != INVALID_SOCKET) + { + closesocket(ClientSocket); + ClientSocket = INVALID_SOCKET; + } + } + else { + if (!pszProxyCallout) + { + if (AttachStatus!=-1) + { + // it was crashing when the skype-network-proxy is used (imo2sproxy for imo.im) and skype-path is empty + // now, with the "UseSockets" check and the skypePath[0] != 0 check its fixed + if (skypePath != NULL && skypePath[0] != 0) { + TranslateMirandaRelativePathToAbsolute(skypePath, szAbsolutePath, FALSE); + _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); + } + } + } + } + SkypeInitialized=FALSE; + ResetEvent(SkypeReady); + AttachStatus=-1; + if (g_hWnd) KillTimer (g_hWnd, 1); + return 0; +} +/* ConnectToSkypeAPI + * + * Purpose: Establish a connection to the Skype API + * Params : path - Path to the Skype application + * Returns: 0 - Connecting succeeded + * -1 - Something went wrong + */ +//int __connectAPI(char *path) { +// int retval; +// +// EnterCriticalSection(&ConnectMutex); +// if (AttachStatus!=-1) { +// LeaveCriticalSection(&ConnectMutex); +// return -1; +// } +// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_CONNECTING); +// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, SkypeStatus); +// retval=__connectAPI(path); +// if (retval==-1) { +// logoff_contacts(); +// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_OFFLINE); +// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_CONNECTING, SkypeStatus); +// } +// LeaveCriticalSection(&ConnectMutex); +// return retval; +//} diff --git a/protocols/SkypeClassic/src/skypeapi.h b/protocols/SkypeClassic/src/skypeapi.h new file mode 100644 index 0000000000..fa4f5139a1 --- /dev/null +++ b/protocols/SkypeClassic/src/skypeapi.h @@ -0,0 +1,69 @@ +// Skype API defines +#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 +#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 +#define SKYPECONTROLAPI_ATTACH_REFUSED 2 +#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 +#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 + +#define MISC_ERROR 1 +#define USER_NOT_FOUND 2 +#define USER_NOT_ONLINE 3 +#define USER_BLOCKED 4 +#define TYPE_UNSUPPORTED 5 +#define SENDER_NOT_FRIEND 6 +#define SENDER_NOT_AUTHORIZED 7 + +#define MAX_ENTRIES 128 // Max. 128 number-Entries in Dial-dlg. + +typedef struct { + int id; + char *szStat; +} status_map; + +// Prototypes +int SkypeMsgInit(void); +int SkypeMsgAdd(char *msg); +void SkypeMsgCleanup(void); +char *SkypeMsgGet(void); +int SkypeSend(char*, ...); +char *SkypeRcv(char *what, DWORD maxwait); +char *SkypeRcvTime(char *what, time_t st, DWORD maxwait); +char *SkypeRcvMsg(char *what, time_t st, HANDLE hContact, DWORD maxwait); +INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeHup(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam); +void SkypeFlush(void); +int SkypeStatusToMiranda(char *s); +char *MirandaStatusToSkype(int id); +char *GetSkypeErrorMsg(char *str); +BOOL testfor(char *what, DWORD maxwait); +int ConnectToSkypeAPI(char *path, BOOL bStart); +int CloseSkypeAPI(char *skypePath); +INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam); +int SkypeMsgCollectGarbage(time_t age); +INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam); +int SkypeSetProfile(char *szProperty, char *szValue); +char *SkypeGet(char *szWhat, char *szWho, char *szProperty); +char *SkypeGetID(char *szWhat, char *szWho, char *szProperty); +char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty); +#ifdef _UNICODE +WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty); +WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty); +#define SkypeGetT SkypeGetW +#define SkypeGetErrT SkypeGetErrW +#else +#define SkypeGetT SkypeGet +#define SkypeGetErrT SkypeGetErr +#endif +char *SkypeGetProfile(char *szProperty); +void SetUserNamePassword(); +INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam); diff --git a/protocols/SkypeClassic/src/skypeopt.cpp b/protocols/SkypeClassic/src/skypeopt.cpp new file mode 100644 index 0000000000..078770d1a6 --- /dev/null +++ b/protocols/SkypeClassic/src/skypeopt.cpp @@ -0,0 +1,968 @@ +#include "skype.h" +#include "skypeopt.h" +#include "pthread.h" +#include "gchat.h" +#include "skypeprofile.h" +#if(WINVER >= 0x0500) +#include "uxtheme.h" +#define HAVE_UXTHEMES +#endif + +#ifdef SKYPE_AUTO_DETECTION +#include "ezxml/ezxml.c" +#endif + +#ifdef UNICODE +#include "utf8.h" +#endif + +#pragma warning (disable: 4706) // assignment within conditional expression + +// VC6 SDK defines +#ifndef BIF_SHAREABLE +#define BIF_SHAREABLE 0x8000 // sharable resources displayed (remote shares, requires BIF_USENEWUI) +#endif +#ifndef BIF_NEWDIALOGSTYLE +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +#endif // Caller needs to call OleInitialize() before using this API +#ifndef BIF_NONEWFOLDERBUTTON +#define BIF_NONEWFOLDERBUTTON 0x0200 // Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE. +#endif + + +extern HINSTANCE hInst; +extern char protocol, g_szProtoName[]; +extern BOOL SkypeInitialized, bProtocolSet, bIsImoproxy; +extern DWORD mirandaVersion; + +BOOL showPopup, showPopupErr, popupWindowColor, popupWindowColorErr; +unsigned int popupBackColor, popupBackColorErr; +unsigned int popupTextColor, popupTextColorErr; +int popupTimeSec, popupTimeSecErr; +POPUPDATAT InCallPopup; +POPUPDATAT ErrorPopup; + +static SkypeProfile myProfile; +static HBITMAP hAvatar = NULL; + +extern BOOL PopupServiceExists; +extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD); + +int RegisterOptions(WPARAM wParam, LPARAM lParam) { + OPTIONSDIALOGPAGE odp; + + UNREFERENCED_PARAMETER(lParam); + + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszGroup = "Network"; + odp.pszTitle = SKYPE_PROTONAME; + odp.pfnDlgProc = OptionsDlgProc; + odp.flags = ODPF_BOLDGROUPS; + Options_AddPage(wParam, &odp); + + if(PopupServiceExists) + { + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUP); + odp.pszGroup = "Popups"; + odp.pfnDlgProc = OptPopupDlgProc; + Options_AddPage(wParam, &odp); + } + + return 0; +} + +INT_PTR CALLBACK OptPopupDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static RECT r; + + switch ( msg ) + { + case WM_INITDIALOG: + TranslateDialogDefault( hwnd ); + // Message Popup + popupTimeSec = db_get_dw(NULL, SKYPE_PROTONAME, "popupTimeSec", 4); + popupTextColor = db_get_dw(NULL, SKYPE_PROTONAME, "popupTextColor", GetSysColor(COLOR_WINDOWTEXT)); + popupBackColor = db_get_dw(NULL, SKYPE_PROTONAME, "popupBackColor", GetSysColor(COLOR_BTNFACE)); + popupWindowColor = db_get_b(NULL, SKYPE_PROTONAME, "popupWindowColor", FALSE); + showPopup = db_get_b(NULL, SKYPE_PROTONAME, "showPopup", TRUE); + // ERROR Message Popup + popupTimeSecErr = db_get_dw(NULL, SKYPE_PROTONAME, "popupTimeSecErr", 4); + popupTextColorErr = db_get_dw(NULL, SKYPE_PROTONAME, "popupTextColorErr", GetSysColor(COLOR_WINDOWTEXT)); + popupBackColorErr = db_get_dw(NULL, SKYPE_PROTONAME, "popupBackColorErr", GetSysColor(COLOR_BTNFACE)); + popupWindowColorErr = db_get_b(NULL, SKYPE_PROTONAME, "popupWindowColorErr", FALSE); + showPopupErr = db_get_b(NULL, SKYPE_PROTONAME, "showPopupErr", TRUE); + + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); + CheckDlgButton(hwnd, IDC_POPUPINCOMING, (WPARAM) showPopup); + CheckDlgButton(hwnd, IDC_USEWINCOLORS, (WPARAM) popupWindowColor); + CheckDlgButton(hwnd, IDC_POPUPERROR, (WPARAM) showPopupErr); + CheckDlgButton(hwnd, IDC_USEWINCOLORSERR, (WPARAM) popupWindowColorErr); + SendDlgItemMessage(hwnd, IDC_POPUPTIME, EM_SETLIMITTEXT, 3, 0L); + SetDlgItemInt(hwnd, IDC_POPUPTIME, popupTimeSec,FALSE); + SendDlgItemMessage(hwnd, IDC_POPUPTIMEERR, EM_SETLIMITTEXT, 3, 0L); + SetDlgItemInt(hwnd, IDC_POPUPTIMEERR, popupTimeSecErr,FALSE); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETCOLOUR,0, popupBackColor); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETCOLOUR,0, popupTextColor); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETCOLOUR,0, popupBackColorErr); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETCOLOUR,0, popupTextColorErr); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); + + + return TRUE; + break; + + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) + { + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + db_set_dw(NULL, SKYPE_PROTONAME, "popupBackColor", popupBackColor); + db_set_dw(NULL, SKYPE_PROTONAME, "popupTextColor", popupTextColor); + db_set_dw(NULL, SKYPE_PROTONAME, "popupTimeSec", popupTimeSec); + db_set_b(NULL, SKYPE_PROTONAME, "popupWindowColor", (BYTE)popupWindowColor); + db_set_b(NULL, SKYPE_PROTONAME, "showPopup", (BYTE)showPopup); + db_set_dw(NULL, SKYPE_PROTONAME, "popupBackColorErr", popupBackColorErr); + db_set_dw(NULL, SKYPE_PROTONAME, "popupTextColorErr", popupTextColorErr); + db_set_dw(NULL, SKYPE_PROTONAME, "popupTimeSecErr", popupTimeSecErr); + db_set_b(NULL, SKYPE_PROTONAME, "popupWindowColorErr", (BYTE)popupWindowColorErr); + db_set_b(NULL, SKYPE_PROTONAME, "showPopupErr", (BYTE)showPopupErr); + break; + } + } + break; + + + + case WM_COMMAND: + switch( LOWORD( wParam )) + { + case IDC_PREVIEW: + { + HANDLE hContact; + TCHAR * lpzContactName; + + hContact = db_find_first(); + lpzContactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR); + InCallPopup.lchContact = hContact; + InCallPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); + InCallPopup.colorBack = ! popupWindowColor ? popupBackColor : GetSysColor(COLOR_BTNFACE); + InCallPopup.colorText = ! popupWindowColor ? popupTextColor : GetSysColor(COLOR_WINDOWTEXT); + InCallPopup.iSeconds = popupTimeSec; + InCallPopup.PluginData = (void *)1; + + lstrcpy(InCallPopup.lptzText, TranslateT("Incoming Skype Call")); + + lstrcpy(InCallPopup.lptzContactName, lpzContactName); + + CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&InCallPopup,0); + + + break; + } + case IDC_PREVIEWERR: + ErrorPopup.lchContact = NULL; + ErrorPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); + ErrorPopup.colorBack = ! popupWindowColorErr ? popupBackColorErr : GetSysColor(COLOR_BTNFACE); + ErrorPopup.colorText = ! popupWindowColorErr ? popupTextColorErr : GetSysColor(COLOR_WINDOWTEXT); + ErrorPopup.iSeconds = popupTimeSecErr; + ErrorPopup.PluginData = (void *)1; + + lstrcpy(ErrorPopup.lptzText, TranslateT("Preview Error Message")); + + lstrcpy(ErrorPopup.lptzContactName, _T("Error Message")); + + + CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&ErrorPopup,0); + + break; + + case IDC_POPUPTIME: + case IDC_POPUPTIMEERR: + { + BOOL Translated; + popupTimeSec = GetDlgItemInt(hwnd,IDC_POPUPTIME,&Translated,FALSE); + popupTimeSecErr = GetDlgItemInt(hwnd,IDC_POPUPTIMEERR,&Translated,FALSE); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + } + case IDC_POPUPTEXTCOLOR: + case IDC_POPUPBACKCOLOR: + case IDC_POPUPTEXTCOLORERR: + case IDC_POPUPBACKCOLORERR: + popupBackColor = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLOR,CPM_GETCOLOUR,0,0); + popupTextColor = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLOR,CPM_GETCOLOUR,0,0); + popupBackColorErr = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLORERR,CPM_GETCOLOUR,0,0); + popupTextColorErr = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLORERR,CPM_GETCOLOUR,0,0); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_USEWINCOLORS: + popupWindowColor = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORS)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_POPUPINCOMING: + showPopup = (IsDlgButtonChecked(hwnd,IDC_POPUPINCOMING)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_USEWINCOLORSERR: + popupWindowColorErr = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORSERR)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_POPUPERROR: + showPopupErr = (IsDlgButtonChecked(hwnd,IDC_POPUPERROR)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + } + + break; + + case WM_DESTROY: + break; + } + + return 0; +} + +INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int iInit = TRUE; + + UNREFERENCED_PARAMETER(wParam); + + switch(msg) + { + case WM_INITDIALOG: + { + TCITEM tci; + RECT rcClient; + GetClientRect(hwnd, &rcClient); + + iInit = TRUE; + tci.mask = TCIF_PARAM|TCIF_TEXT; + tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_DEFAULT), hwnd, OptionsDefaultDlgProc); + tci.pszText = TranslateT("Skype default"); + TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci); + MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); +#ifdef HAVE_UXTHEMES + if(MyEnableThemeDialogTexture) + MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); +#endif + + tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_ADVANCED),hwnd,OptionsAdvancedDlgProc); + tci.pszText = TranslateT("Skype advanced"); + TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 1, &tci); + MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); +#ifdef HAVE_UXTHEMES + if(MyEnableThemeDialogTexture) + MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); +#endif + + tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_PROXY),hwnd,OptionsProxyDlgProc); + tci.pszText = TranslateT("Skype proxy"); + TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 2, &tci); + MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); +#ifdef HAVE_UXTHEMES + if(MyEnableThemeDialogTexture) + MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); +#endif + + iInit = FALSE; + return FALSE; + } + + case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0); + if(!iInit) + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + break; + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + TCITEM tci; + int i,count; + tci.mask = TCIF_PARAM; + count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB)); + for (i=0;icode) + { + case TCN_SELCHANGING: + { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_HIDE); + } + break; + case TCN_SELCHANGE: + { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_SHOW); + } + break; + } + break; + + } + break; + } + return FALSE; +} + +INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + const int Skype2SocketControls[]={ IDC_STATIC_HOST, IDC_HOST, IDC_STATIC_PORT, IDC_PORT, IDC_REQPASS, IDC_PASSWORD, IDC_STATIC_RESTART }; + static BOOL initDlg=FALSE; + DBVARIANT dbv; + int i; + + switch (uMsg){ + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + if (!db_get_s(NULL, SKYPE_PROTONAME, "Host", &dbv)) { + SetDlgItemTextA(hwndDlg, IDC_HOST, dbv.pszVal); + db_free(&dbv); + } else SetDlgItemText(hwndDlg, IDC_HOST, _T("localhost")); + SendDlgItemMessage(hwndDlg, IDC_PORT, EM_SETLIMITTEXT, 5, 0L); + SetDlgItemInt(hwndDlg, IDC_PORT, db_get_w(NULL, SKYPE_PROTONAME, "Port", 1401), FALSE); + CheckDlgButton(hwndDlg, IDC_REQPASS, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "RequiresPassword", 0)); + CheckDlgButton(hwndDlg, IDC_USES2S, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0)); + if (!db_get_s(NULL, SKYPE_PROTONAME, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal); + db_free(&dbv); + } + SendMessage(hwndDlg, WM_COMMAND, IDC_USES2S, 0); + SendMessage(hwndDlg, WM_COMMAND, IDC_REQPASS, 0); + initDlg=FALSE; + return TRUE; + case WM_NOTIFY: { + NMHDR* nmhdr = (NMHDR*)lParam; + + switch (nmhdr->code){ + case PSN_APPLY: + case PSN_KILLACTIVE: + { + char buf[1024]; + GetDlgItemTextA(hwndDlg, IDC_HOST, buf, sizeof(buf)); + db_set_s(NULL, SKYPE_PROTONAME, "Host", buf); + db_set_w(NULL, SKYPE_PROTONAME, "Port", (unsigned short)GetDlgItemInt(hwndDlg, IDC_PORT, NULL, FALSE)); + db_set_b(NULL, SKYPE_PROTONAME, "RequiresPassword", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REQPASS), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "UseSkype2Socket", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USES2S), BM_GETCHECK,0,0))); + ZeroMemory(buf, sizeof(buf)); + GetDlgItemTextA(hwndDlg, IDC_PASSWORD, buf, sizeof(buf)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buf), (LPARAM)buf); + db_set_s(NULL, SKYPE_PROTONAME, "Password", buf); + return TRUE; + } + } + break; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDC_USES2S: + for (i=0; i=5)) { + CheckDlgButton(hwndDlg, IDC_GROUPCHAT, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0)); + CheckDlgButton(hwndDlg, IDC_GROUPCHATREAD, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "MarkGroupchatRead", 0)); + } else { + EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHAT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), FALSE); + } + +#ifdef USEPOPUP + if (ServiceExists(MS_POPUP_ADDPOPUP)) + CheckDlgButton(hwndDlg, IDC_USEPOPUP, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UsePopup", 0)); + else +#endif + EnableWindow(GetDlgItem(hwndDlg, IDC_USEPOPUP), FALSE); + + j=db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); + for(i=0;icode){ + case PSN_APPLY: + case PSN_KILLACTIVE: + db_set_b (NULL, SKYPE_PROTONAME, "EnableMenu", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_ENABLEMENU), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "UsePopup", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USEPOPUP), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "UseGroupchat", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHAT), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "MarkGroupchatRead", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "SuppressErrors", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOERRORS), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "KeepState", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_KEEPSTATE), BM_GETCHECK,0,0))); + db_set_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETITEMDATA,SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETCURSEL,0,0),0)); + db_set_b (NULL, SKYPE_PROTONAME, "UseTimeZonePatch", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_TIMEZONE), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "IgnoreTimeZones", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_IGNTZ), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "ShowDefaultSkypeAvatar", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWDEFAULTAVATAR), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "SuppressCallSummaryMessage", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SUPPRESSCALLSUMMARYMESSAGE), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "NoSkype3Stats", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSKYPE3STATS), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "ShowFullname", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWFULLNAME), BM_GETCHECK,0,0))); + return TRUE; + } + break; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDC_CLEANUP: + pthread_create(( pThreadFunc )CleanupNicknames, NULL); + break; + } + if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + return 0; +} + +static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + UNREFERENCED_PARAMETER(lParam); + + switch (uMsg) + { + case BFFM_INITIALIZED: + { + // Set initial directory. +#ifdef UNICODE + wchar_t* wszInitFolder = make_unicode_string((const unsigned char*)lpData); + SendMessage(hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)wszInitFolder); + free(wszInitFolder); +#else + SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData); +#endif + break; + } + } + return 0; +} + +INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static BOOL initDlg=FALSE; + static int skypeLaunchControls[]={IDC_NOSPLASH,IDC_MINIMIZED,IDC_NOTRAY,IDC_REMOVEABLE,IDC_SECONDARY,IDC_DATAPATHO,IDC_CUSTOMCOMMAND,IDC_STATIC_PATHINFO}; + + switch (uMsg){ + case WM_INITDIALOG: + { + DBVARIANT dbv; + BOOL startSkype; + int i; + + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + startSkype=db_get_b(NULL, SKYPE_PROTONAME, "StartSkype", 1); + + CheckDlgButton(hwndDlg, IDC_STARTSKYPE, (BYTE)startSkype); + CheckDlgButton(hwndDlg, IDC_NOSPLASH, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "nosplash", 1)); + CheckDlgButton(hwndDlg, IDC_MINIMIZED, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "minimized", 1)); + CheckDlgButton(hwndDlg, IDC_NOTRAY, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "notray", 0)); + CheckDlgButton(hwndDlg, IDC_REMOVEABLE, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "removable", 0)); + CheckDlgButton(hwndDlg, IDC_SECONDARY, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "secondary", 0)); + CheckDlgButton(hwndDlg, IDC_DATAPATHO, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "datapath:", 0)); + CheckDlgButton(hwndDlg, IDC_SHUTDOWN, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "Shutdown", 0)); + CheckDlgButton(hwndDlg, IDC_UNLOADOFFLINE, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UnloadOnOffline", 0)); + + CheckDlgButton(hwndDlg, IDC_CUSTOMCOMMAND, (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0)); + SendDlgItemMessage(hwndDlg, IDC_COMMANDLINE, EM_SETLIMITTEXT, MAX_PATH-1, 0L); + if(!db_get_s(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) + { + SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), dbv.pszVal); + db_free(&dbv); + } + + SendDlgItemMessage(hwndDlg, IDC_DATAPATH, EM_SETLIMITTEXT, MAX_PATH-1, 0L); + if(!db_get_s(NULL,SKYPE_PROTONAME,"datapath",&dbv)) + { + SetWindowTextA(GetDlgItem(hwndDlg, IDC_DATAPATH), dbv.pszVal); + db_free(&dbv); + } + + for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) + EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + + // LoginUserName + if(!db_get_ts(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) + { + SetWindowText(GetDlgItem(hwndDlg, IDC_USERNAME), dbv.ptszVal); + db_free(&dbv); + } + + // LoginPassword + if(!db_get_ts(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) + { + SetWindowText(GetDlgItem(hwndDlg, IDC_PASSWORD), dbv.ptszVal); + db_free(&dbv); + } + + SendDlgItemMessage(hwndDlg, IDC_CONNATTEMPTS, EM_SETLIMITTEXT, 3, 0L); + SetDlgItemInt (hwndDlg, IDC_CONNATTEMPTS, db_get_w(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10), FALSE); + SendMessage(hwndDlg, WM_COMMAND, IDC_STARTSKYPE, 0); + initDlg=FALSE; + return TRUE; + } + case WM_NOTIFY: { + NMHDR* nmhdr = (NMHDR*)lParam; + + switch (nmhdr->code){ + case PSN_APPLY: + case PSN_KILLACTIVE: + { + char text[500]; + TCHAR wtext[500]; + char szRelativePath[MAX_PATH]; + + db_set_b (NULL, SKYPE_PROTONAME, "StartSkype", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "nosplash", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSPLASH), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "minimized", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_MINIMIZED), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "notray", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOTRAY), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "Shutdown", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHUTDOWN), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "UnloadOnOffline", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_UNLOADOFFLINE), BM_GETCHECK,0,0))); + db_set_w (NULL, SKYPE_PROTONAME, "ConnectionAttempts", (unsigned short)GetDlgItemInt(hwndDlg, IDC_CONNATTEMPTS, NULL, FALSE)); + db_set_b (NULL, SKYPE_PROTONAME, "UseCustomCommand", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "datapath:", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "removable", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REMOVEABLE), BM_GETCHECK,0,0))); + db_set_b (NULL, SKYPE_PROTONAME, "secondary", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY), BM_GETCHECK,0,0))); + + GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,text,sizeof(text)); + strncpy(szRelativePath, text, sizeof(szRelativePath)-1); + CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); + db_set_s(NULL, SKYPE_PROTONAME, "CommandLine", szRelativePath); + + GetDlgItemTextA(hwndDlg,IDC_DATAPATH,text,sizeof(text)); + strncpy(szRelativePath, text, sizeof(szRelativePath)-1); + CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); + db_set_s(NULL, SKYPE_PROTONAME, "datapath", szRelativePath); + + // LoginUserName + GetDlgItemText(hwndDlg,IDC_USERNAME,wtext,sizeof(wtext)/sizeof(TCHAR)); + db_set_ts(NULL, SKYPE_PROTONAME, "LoginUserName", wtext); + + // LoginPassword + GetDlgItemText(hwndDlg,IDC_PASSWORD,wtext,sizeof(wtext)/sizeof(TCHAR)); + db_set_ts(NULL, SKYPE_PROTONAME, "LoginPassword", wtext); + + return TRUE; + } + } + break; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + BOOL startSkype; + int i; + case IDC_STARTSKYPE: + startSkype=SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0); + + for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) + EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + break; + case IDC_CLEANUP: + pthread_create(( pThreadFunc )CleanupNicknames, NULL); + break; + case IDC_DATAPATHO: + EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + break; + case IDC_CUSTOMCOMMAND: + EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + break; + case IDC_BROWSECMDL: + { + OPENFILENAMEA ofn={0}; + BOOL gofnResult; + char szFileName[MAX_PATH]; + char szAbsolutePath[MAX_PATH]; + + ofn.lStructSize=sizeof(ofn); + ofn.hwndOwner=hwndDlg; + ofn.lpstrFilter="Executable files (*.exe)\0*.exe\0All files (*.*)\0*.*\0"; + ofn.nMaxFile=sizeof(szFileName); + ofn.lpstrDefExt="exe"; + ofn.lpstrFile=szFileName; + ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING; + + GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,szFileName,sizeof(szFileName)); + TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); + strcpy (szFileName, szAbsolutePath); + + if (!(gofnResult = GetOpenFileNameA(&ofn)) && CommDlgExtendedError() == FNERR_INVALIDFILENAME){ + strcpy(szFileName, ".\\Skype.exe"); + TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); + strcpy (szFileName, szAbsolutePath); + gofnResult = GetOpenFileNameA(&ofn); + } + + if(gofnResult) + SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), szFileName); + + break; + } + case IDC_BROWSEDP: + { + BROWSEINFOA bi={0}; + LPITEMIDLIST pidl; + char szFileName[MAX_PATH]; + char szAbsolutePath[MAX_PATH]; + + GetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName, MAX_PATH); + + TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); + bi.hwndOwner = hwndDlg; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_SHAREABLE | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON; + bi.lpfn = BrowseCallbackProc; + bi.lParam = (LPARAM)szAbsolutePath; + + if ( (pidl = SHBrowseForFolderA (&bi)) ) { + if (SHGetPathFromIDListA (pidl, szFileName)) + SetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName); + CoTaskMemFree (pidl); + } + break; + } + +#ifdef SKYPE_AUTO_DETECTION + case IDC_AUTODETECTION: + DoAutoDetect(hwndDlg); + break; +#endif + } + if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// OnDetailsInit - initializes user info dialog pages. + +int OnDetailsInit( WPARAM wParam, LPARAM lParam ) +{ + OPTIONSDIALOGPAGE odp = {0}; + HANDLE hContact = ( HANDLE )lParam; + + odp.cbSize = sizeof(odp); + odp.hIcon = NULL; + odp.hInstance = hInst; + + if ( hContact == NULL ) { + + char szTitle[256]; + + if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 27) && !bIsImoproxy) + { + mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Avatar" )); + + odp.pfnDlgProc = AvatarDlgProc; + odp.position = 1900000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETAVATAR); + odp.pszTitle = szTitle; + UserInfo_AddPage(wParam, &odp); + } + + mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Details" )); + + odp.pfnDlgProc = DetailsDlgProc; + odp.position = 1900000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETDETAILS); + odp.pszTitle = szTitle; + UserInfo_AddPage(wParam, &odp); + } + + return 0; +} + +/*AvatarDlgProc +* +* For setting the skype avatar +* +*/ +INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static RECT r; + + UNREFERENCED_PARAMETER(lParam); + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + + hAvatar = NULL; + if(ServiceExists(MS_AV_GETMYAVATAR)){ + struct avatarCacheEntry *ace = (struct avatarCacheEntry *)CallService(MS_AV_GETMYAVATAR, 0,(LPARAM) SKYPE_PROTONAME); + if (ace!=NULL) { + hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )ace->szFilename); + if ( hAvatar != NULL ) + SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); + } + } + + + + return TRUE; + + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_SETAVATAR: + { + char szFileName[ MAX_PATH ]; + if ( EnterBitmapFileName( szFileName ) != ERROR_SUCCESS ) + return FALSE; + + hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )szFileName); + if ( hAvatar != NULL ){ + SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); + CallService(SKYPE_SETAVATAR, 0, ( LPARAM )szFileName); + } + break; + } + case IDC_DELETEAVATAR: + if ( hAvatar != NULL ) { + DeleteObject( hAvatar ); + hAvatar = NULL; + CallService(SKYPE_SETAVATAR, 0, 0); + } + db_unset( NULL, SKYPE_PROTONAME, "AvatarFile" ); + InvalidateRect( hwndDlg, NULL, TRUE ); + break; + } } + break; + + case WM_DESTROY: + if ( hAvatar != NULL ) + DeleteObject( hAvatar ); + break; + } + + return 0; +} + +/*DetailsDlgProc +* +* For setting the skype infos +* +*/ +INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int sexM = 0,sexF = 0, sex; + + UNREFERENCED_PARAMETER(lParam); + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + + ZeroMemory (&myProfile, sizeof(myProfile)); + SkypeProfile_Load(&myProfile); + if(SkypeInitialized) + SkypeProfile_LoadFromSkype(&myProfile); + + SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)_T("")); + sexM = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("MALE")); + sexF = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("FEMALE")); + + switch(myProfile.Sex) { + case 0x4D: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexM, 0); break; + case 0x46: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexF, 0); break; + } + + SetDlgItemText(hwndDlg, IDC_FULLNAME, myProfile.FullName); + SetDlgItemTextA(hwndDlg, IDC_HOMEPAGE, myProfile.HomePage); + SetDlgItemTextA(hwndDlg, IDC_HOMEPHONE, myProfile.HomePhone); + SetDlgItemTextA(hwndDlg, IDC_OFFICEPHONE, myProfile.OfficePhone); + SetDlgItemText(hwndDlg, IDC_CITY, myProfile.City); + SetDlgItemText(hwndDlg, IDC_PROVINCE, myProfile.Province); + DateTime_SetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), GDT_VALID, &myProfile.Birthday); + return TRUE; + + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_SAVEDETAILS: + GetDlgItemText(hwndDlg,IDC_FULLNAME,myProfile.FullName,sizeof(myProfile.FullName)/sizeof(TCHAR)); + GetDlgItemTextA(hwndDlg,IDC_HOMEPAGE,myProfile.HomePage,sizeof(myProfile.HomePage)/sizeof(TCHAR)); + GetDlgItemTextA(hwndDlg,IDC_HOMEPHONE,myProfile.HomePhone,sizeof(myProfile.HomePhone)/sizeof(TCHAR)); + GetDlgItemTextA(hwndDlg,IDC_OFFICEPHONE,myProfile.OfficePhone,sizeof(myProfile.OfficePhone)/sizeof(TCHAR)); + GetDlgItemText(hwndDlg,IDC_CITY,myProfile.City,sizeof(myProfile.City)/sizeof(TCHAR)); + GetDlgItemText(hwndDlg,IDC_PROVINCE,myProfile.Province,sizeof(myProfile.Province)/sizeof(TCHAR)); + sex = SendMessage(GetDlgItem(hwndDlg,IDC_SEX),CB_GETCURSEL,0,0); + + myProfile.Sex = 0; + if(sex == sexF) myProfile.Sex = 0x46; else + if(sex == sexM) myProfile.Sex = 0x4D; + DateTime_GetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), &myProfile.Birthday); + + SkypeProfile_Save(&myProfile); + if(SkypeInitialized) + SkypeProfile_SaveToSkype(&myProfile); + break; + } + } + break; + + case WM_DESTROY: + if ( hAvatar != NULL ) + DeleteObject( hAvatar ); + break; + } + + return 0; +} + +#ifdef SKYPE_AUTO_DETECTION +/** + * DoAutoDetect + * @param dlg The default option dialog handle + */ +void DoAutoDetect(HWND dlg) +{ + char basePath[MAX_PATH]; + char fileName[MAX_PATH]; + char tmpUser[255]; + ezxml_t f1, acc; + + if (FAILED(SHGetFolderPath(dlg,CSIDL_APPDATA,NULL,0,basePath))) + { + OUTPUT("Error in retrieving appdata path!"); + return; + } + + strcat(basePath,"\\Skype\\"); + sprintf (fileName, "%s\\shared.xml", basePath); + + if (f1 = ezxml_parse_file(fileName)) + { + if (acc = ezxml_get(f1, "Lib", 0, "Account", 0, "Default", -1)) + { + if (GetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),tmpUser,sizeof(tmpUser))) + SetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),acc->txt); + /* Can't find this stuff in current Skype verions?? + sprintf (fileName, "%s\\%s\\config.xml", basePath, acc->txt); + if ((acc = ezxml_get(f1, "UI", 0, "Messages", 0, "OpenWindowInCompactMode", -1)) && *acc->txt!='0') + { + ezxml_set_txt (acc, "0"); + // ezXML doesn't supprot saving yet + } + */ + } + ezxml_free(f1); + } + else + { + OUTPUT("Failed to open skypes configuration files!"); + return; + } +} +#endif diff --git a/protocols/SkypeClassic/src/skypeopt.h b/protocols/SkypeClassic/src/skypeopt.h new file mode 100644 index 0000000000..23aa7a5212 --- /dev/null +++ b/protocols/SkypeClassic/src/skypeopt.h @@ -0,0 +1,49 @@ +/* + * RegisterOptions + * + * This function tells Miranda to add the configuration section of this plugin in + * the Options-dialog. + */ +int RegisterOptions(WPARAM wParam, LPARAM lParam); +/* + * OptionsDlgProc + * + * This callback function is called, when the options dialog in Miranda is shown + * The function contains all necessary stuff to process the options in the dialog + * and store them in the database, when changed, and fill out the settings-dialog + * correctly according to the current settings + */ +INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK OptionsAdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK OptPopupDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +/* +* Procedure to call when the option page is asked +* +*/ +int OnDetailsInit( WPARAM wParam, LPARAM lParam ); + +/* +* Dialog to change avatar in user details. +* +* +*/ +INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +/* +* Dialog to change infos in user details. +* +* +*/ +INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +/* + * Helper functions + * + */ +void DoAutoDetect(HWND dlg); + +; \ No newline at end of file diff --git a/protocols/SkypeClassic/src/skypeprofile.cpp b/protocols/SkypeClassic/src/skypeprofile.cpp new file mode 100644 index 0000000000..168dbfa97c --- /dev/null +++ b/protocols/SkypeClassic/src/skypeprofile.cpp @@ -0,0 +1,145 @@ +#pragma warning (disable: 4706) // assignment within conditional expression + +#include "skypeprofile.h" +#include "skypeapi.h" +#include "utf8.h" + +extern char g_szProtoName[]; + +void SkypeProfile_Save(SkypeProfile *pstProf) +{ + db_set_b(NULL, SKYPE_PROTONAME, "Gender", pstProf->Sex); + db_set_s(NULL, SKYPE_PROTONAME, "HomePhone", pstProf->HomePhone); + db_set_s(NULL, SKYPE_PROTONAME, "OfficePhone", pstProf->OfficePhone); + db_set_s(NULL, SKYPE_PROTONAME, "HomePage", pstProf->HomePage); + db_set_ts(NULL, SKYPE_PROTONAME, "Nick", pstProf->FullName); + db_set_ts(NULL, SKYPE_PROTONAME, "City", pstProf->City); + db_set_ts(NULL, SKYPE_PROTONAME, "Province", pstProf->Province); + db_set_w(NULL, SKYPE_PROTONAME, "BirthYear", (WORD)pstProf->Birthday.wYear); + db_set_b(NULL, SKYPE_PROTONAME, "BirthMonth", (BYTE)pstProf->Birthday.wMonth); + db_set_b(NULL, SKYPE_PROTONAME, "BirthDay", (BYTE)pstProf->Birthday.wDay); +} + +void SkypeProfile_Load(SkypeProfile *pstProf) +{ + DBVARIANT dbv; + + pstProf->Sex = (BYTE)db_get_b(NULL, SKYPE_PROTONAME, "Gender", 0); + pstProf->Birthday.wYear = (WORD)db_get_w(NULL, SKYPE_PROTONAME, "BirthYear", 1900); + pstProf->Birthday.wMonth = (WORD)db_get_b(NULL, SKYPE_PROTONAME, "BirthMonth", 01); + pstProf->Birthday.wDay = (WORD)db_get_b(NULL, SKYPE_PROTONAME, "BirthDay", 01); + if(!db_get_ts(NULL,SKYPE_PROTONAME,"Nick",&dbv)) + { + _tcsncpy (pstProf->FullName, dbv.ptszVal, sizeof(pstProf->FullName)/sizeof(TCHAR)); + db_free(&dbv); + } + if(!db_get_s(NULL,SKYPE_PROTONAME,"HomePage",&dbv)) + { + strncpy (pstProf->HomePage, dbv.pszVal, sizeof(pstProf->HomePage)); + db_free(&dbv); + } + if(!db_get_ts(NULL,SKYPE_PROTONAME,"Province",&dbv)) + { + _tcsncpy (pstProf->Province, dbv.ptszVal, sizeof(pstProf->Province)/sizeof(TCHAR)); + db_free(&dbv); + } + if(!db_get_ts(NULL,SKYPE_PROTONAME,"City",&dbv)) + { + _tcsncpy (pstProf->City, dbv.ptszVal, sizeof(pstProf->City)/sizeof(TCHAR)); + db_free(&dbv); + } + if(!db_get_s(NULL,SKYPE_PROTONAME,"OfficePhone",&dbv)) + { + strncpy (pstProf->OfficePhone, dbv.pszVal, sizeof(pstProf->OfficePhone)); + db_free(&dbv); + } + if(!db_get_s(NULL,SKYPE_PROTONAME,"HomePhone",&dbv)) + { + strncpy (pstProf->HomePhone, dbv.pszVal, sizeof(pstProf->HomePhone)); + db_free(&dbv); + } +} + +static void LoadSaveSkype(SkypeProfile *pstProf, BOOL bSet) +{ +#pragma warning (push) +#pragma warning (disable: 4204) // nonstandard extension used : non-constant aggregate initializer +#define ENTRY(x,y) {x, pstProf->y, sizeof(pstProf->y)/sizeof(pstProf->y[0]), sizeof(pstProf->y[0])} + const struct { + char *pszSetting; + LPVOID lpDest; + int iSize; + char cType; + } astSettings[] = { + ENTRY("FULLNAME", FullName), + ENTRY("PHONE_HOME", HomePhone), + ENTRY("PHONE_OFFICE", OfficePhone), + ENTRY("HOMEPAGE", HomePage), + ENTRY("CITY", City), + ENTRY("PROVINCE", Province) + }; +#pragma warning (pop) +#undef ENTRY + char *ptr; + int i; + + if (bSet) { + char *pBuf, szBirthday[16]; + for (i=0; iSex) + { + case 0x4D: SkypeSetProfile ("SEX", "MALE"); break; + case 0x46: SkypeSetProfile ("SEX", "FEMALE"); break; + } + sprintf (szBirthday, "%04d%02d%02d", pstProf->Birthday.wYear, pstProf->Birthday.wMonth, pstProf->Birthday.wDay); + SkypeSetProfile ("BIRTHDAY", szBirthday); + } else { + for (i=0; iSex=0x4D; else + if (!_stricmp(ptr, "FEMALE")) pstProf->Sex=0x46; + free (ptr); + } + if (ptr=SkypeGetProfile("BIRTHDAY")) + { + if (*ptr != '0') + sscanf(ptr, "%04hd%02hd%02hd", &pstProf->Birthday.wYear, &pstProf->Birthday.wMonth, + &pstProf->Birthday.wDay); + free(ptr); + } + } +} + +void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf) +{ + LoadSaveSkype (pstProf, FALSE); +} + +void SkypeProfile_SaveToSkype(SkypeProfile *pstProf) +{ + LoadSaveSkype (pstProf, TRUE); +} \ No newline at end of file diff --git a/protocols/SkypeClassic/src/skypeprofile.h b/protocols/SkypeClassic/src/skypeprofile.h new file mode 100644 index 0000000000..5902f865c3 --- /dev/null +++ b/protocols/SkypeClassic/src/skypeprofile.h @@ -0,0 +1,33 @@ +// System includes +#include +#include +#include +#include +#include +#include "resource.h" +#include "skype.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +// Miranda database access +#include +#include +#pragma warning (pop) + +typedef struct +{ + TCHAR FullName[256]; + char HomePhone[256]; + char OfficePhone[256]; + char HomePage[256]; + TCHAR City[256]; + TCHAR Province[256]; + BYTE Sex; + SYSTEMTIME Birthday; +} SkypeProfile; + +void SkypeProfile_Load(SkypeProfile *pstProf); +void SkypeProfile_Save(SkypeProfile *pstProf); +void SkypeProfile_Free(SkypeProfile *pstProf); +void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf); +void SkypeProfile_SaveToSkype(SkypeProfile *pstProf); diff --git a/protocols/SkypeClassic/src/skypeproxy.h b/protocols/SkypeClassic/src/skypeproxy.h new file mode 100644 index 0000000000..8e1490803e --- /dev/null +++ b/protocols/SkypeClassic/src/skypeproxy.h @@ -0,0 +1,7 @@ +/* Commands for command mode of Skype proxy */ + +#define AUTHENTICATE 0x01 +#define CAPABILITIES 0x02 + +/* Capabilities flags of Skypeproxy */ +#define USE_AUTHENTICATION 0x01 \ No newline at end of file diff --git a/protocols/SkypeClassic/src/skypeproxy/skypeproxy.c b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.c new file mode 100644 index 0000000000..fff9c1b916 --- /dev/null +++ b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.c @@ -0,0 +1,651 @@ +/* + +Purpose +======= +This program opens a connection on a local TCP/IP port and sends/ +receives Skype-API calls on it so that you can remote-control +Skype over a network. +Note, that there are currently NO SECURITY mechanisms, so don't +use this over an untrusted network! + +Author +====== +This program was written by leecher in 2005 (mailto:leecher@dose.0wnz.at) +Please give feedback at http://forum.skype.com/viewtopic.php?t=16187 + +Protocol +======== +Basic protocol structure +------------------------ +Sender and receiver have the same protocol: + + [(UINT)Length of message][(char[])Message] + +The Length is so that you can malloc() enough space for the data buffer +to receive the next message. + +A special case is, if the [Length of message] is 0. In this case the +client tells the server that he wants to switch to command mode. + +Command mode +------------ +The server expects + + [(char)Command] + +next. Currently the following commands are supported: + + CAPABILITIES - returns the Server's capabilities + AUTHENTICATE - Starts the authentification process + +CAPABILITIES +------------ +The server returns + + [(char)Capabilities] + +where this currently can be the following: + + USE_AUTHENTICATION - The server supports and requires authentication + +AUTHENTICATE +------------ +The server returns + + [(char)0x01] + +if authentication is supported AND needed (skypeproxy started with -k switch) or + + [(char)0x00] + +if this is not the case. +If 0x01 was returned the server next expects a normal message +(see "Basic protocol structure) containing the password. +If the authentication was successful, the server replies with + + [(char)0x01] + +otherwise with + + [(char)0x00] + +PLEASE NOTE THAT THE AUTHENTICATION CURRENTLY IS PLAIN TEXT. SO DON'T +USE THIS PROGRAM OVER AN UNTRUSTED NETWORK, OTHERWISE THERE MAY BE THE +POSSIBILITY THAT SOMEONE SNIFFS YOUR PASSWORD! + +Code example +------------ + +SOCKET MySocket; + +int SendPacket(char *szSkypeMessage) { + unsigned int length=strlen(szSkypeMsg); + + if (send(MySocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || + send(MySocket, szSkypeMsg, length, 0)==SOCKET_ERROR) + return -1; + return 0; +} + +// don't forget to free() the return value on my Heap!! +char *ReceivePacket(void) { + unsigned int lenght, received; + char *buf; + + if ((received=recv(MySocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || + received==0) + return NULL; + if (!(buf=calloc(1, length+1))) return NULL; + if (recv(MySocket, buf, length, 0)==SOCKET_ERROR) { + free(buf); + return NULL; + } + return buf; +} + + +License +======= +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +History +======== +V1.0alpha - First preview release +V1.0 - Implemented killing & restarting Skype process when it dies + - BUGFIX: SendMessage() is a blocking call, if Skype hangs our app hangs too -> Fixed + - Added command line parsing. + - Renamed from Skype2Socket to skypeproxy + - Added authentication feature. +*/ + +#include +#include +#include +#include +#include "skypeproxy.h" + +UINT ControlAPIAttach, ControlAPIDiscover; +HWND hSkypeWnd=NULL, hWnd; +HANDLE SkypeReady, ServerThreadBye; +LONG AttachStatus=-1; +int exitcode=EXIT_SUCCESS; +char skype_path[MAX_PATH], *password=NULL; +BYTE WatchDog=1; +BOOL WatchDogRunning=FALSE, Authenticated=FALSE; +SOCKET ListenSocket, AcceptSocket; + + +void bail_out(int i) { + OUTPUT("Got termination signal, bailing out."); + if (i==1) exitcode=EXIT_FAILURE; + PostMessage(hWnd, WM_QUIT, 0, 0); +} + +BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) { + DWORD dwID ; + + GetWindowThreadProcessId(hwnd, &dwID) ; + if(dwID == (DWORD)lParam) + PostMessage(hwnd, WM_CLOSE, 0, 0) ; // May you be so kind to quit, please? + + return TRUE ; +} + +/* ConnectToSkypeAPI + * + * Purpose: Establish a connection to the Skype API + * Params : ForceRestart - Kill Skype if it's running before restarting + * Returns: 0 - Connecting succeeded + * -1 - Something went wrong + */ +void ConnectToSkypeAPI(void *ForceRestart) { + BOOL SkypeLaunched=FALSE; + int counter=0, i, j; + char *args[5]; + char *SkypeOptions[]={"/notray", "/nosplash", "/minimized"}; + char *szFuncName="ConnectToSkypeAPI"; + + ResetEvent(SkypeReady); + AttachStatus=-1; + if ((BOOL)ForceRestart) { + HANDLE hProc; + DWORD dwPID=0; + + if (!hSkypeWnd) { + OUTPUT("I can't kill Skype, as I don't even have its window handle!"); + return; + } + GetWindowThreadProcessId(hSkypeWnd, &dwPID); + LOG(("%s: Shutting down Skype as it was not behaving the way it should...", szFuncName)); + if (hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID)) { + + // Try to shutdown Skype the nice way by asking it to close + EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID); + + if(WaitForSingleObject(hProc, 10000)!=WAIT_OBJECT_0) { + // Try it the hard way by killing it + LOG(("%s: I tried it the nice way, but you were not listening! Now DIIIIEEE!", szFuncName)); + if (!TerminateProcess(hProc,0)) { + OUTPUT("Argh, process refused to die, it's too mighty for me, I've given up"); + CloseHandle(hProc); + return; + } + LOG(("%s: Process killed! >:)", szFuncName)); + } + CloseHandle(hProc); + } + } + do { + /* To initiate communication, Client should broadcast windows message + ('SkypeControlAPIDiscover') to all windows in the system, specifying its own + window handle in wParam parameter. + */ + LOG(("%s: Sending discover message..", szFuncName)); + SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); + LOG(("%s: Discover message sent, waiting for Skype to become ready..", szFuncName)); + + /* In response, Skype responds with + message 'SkypeControlAPIAttach' to the handle specified, and indicates + connection status + SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. + If there is no answer after 3 seconds, launch Skype as it's propably + not running. + */ + if (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && + AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) + { + if (hWnd==NULL) { + LOG(("%s: hWnd of SkypeDispatchWindow not yet set..", szFuncName)); + continue; + } + if (!SkypeLaunched && skype_path) { + LOG(("%s: Starting Skype, as it's not running", szFuncName)); + args[0]=skype_path; + j=1; + for (i=0; i<3; i++) { + args[j]=SkypeOptions[i]; + LOG(("%s: Using Skype parameter: ", szFuncName, args[j])); + j++; + } + args[j]=NULL; + _spawnv(_P_NOWAIT, skype_path, args); + ResetEvent(SkypeReady); + SkypeLaunched=TRUE; + LOG(("%s: Skype process started.", szFuncName)); + // Skype launching iniciated, keep sending Discover messages until it responds. + continue; + } else { + LOG(("%s: Check if Skype was launchable..", szFuncName)); + if (!skype_path) { + OUTPUT("There was no correct path for Skype application"); + bail_out(1); + return; + } + LOG("%s: Trying to attach: #%d", szFuncName, counter)); + counter++; + if (counter==5) { + OUTPUT("ERROR: Skype not running / too old / working!"); + bail_out(1); + return; + } + } + } + LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); + } while (AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); + + while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); + LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); + if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { + switch(AttachStatus) { + case SKYPECONTROLAPI_ATTACH_REFUSED: + OUTPUT("Skype refused the connection :("); + break; + case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: + OUTPUT("The Skype API is not available"); + break; + default: + LOG(("%s: ERROR: AttachStatus: %d", szFuncName, AttachStatus)); + OUTPUT("Wheee, Skype won't let me use the API. :("); + } + bail_out(1); + return; + } + OUTPUT("Attached to Skype successfully."); + if (!WatchDogRunning) + if (_beginthread(WatchDogTimer, 0, NULL)==-1) { + OUTPUT("Cannot start Watchdog."); + bail_out(1); + } + return; +} + +void SkypeSend(char *szMsg) { + COPYDATASTRUCT CopyData; + int count=0; + + if (!hSkypeWnd) { + LOG(("SkypeSend: DAMN! No Skype window handle! :(")); + return; + } + if (strcmp(szMsg, "PING")) {LOG(("> %s", szMsg));} + CopyData.dwData=0; + CopyData.lpData=szMsg; + CopyData.cbData=strlen(szMsg)+1; + while (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { + count++; + LOG(("SkypeSend: failed, try #%d", count)); + if (count==5) { + OUTPUT("Sending message to Skype failed too often."); + OUTPUT("Skype may have died unexpectedly, I will try to restart it."); + ConnectToSkypeAPI((void *)TRUE); + OUTPUT("Restart complete. Trying to deliver message one more time."); + if (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { + OUTPUT("It still failed. Skype seems to be completely f*cked up. I've given up. Bye.."); + bail_out(1); + break; + } else { + OUTPUT("Now it worked! :)"); + break; + } + } + Sleep(1000); + } +} + +void ServerThread(char *dummy) { + unsigned int length, received; + char *buf, command, reply; + + LOG(("ServerThread started")); + AcceptSocket=INVALID_SOCKET; + while( AcceptSocket == INVALID_SOCKET) { + if ((AcceptSocket = accept( ListenSocket, NULL, NULL ))==INVALID_SOCKET) { + LOG(("ServerThread: Byebye...")); + SetEvent(ServerThreadBye); + bail_out(1); + return; + } + OUTPUT("Connection by client"); + while(1) { + if ((received=recv(AcceptSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || + received==0) + { + OUTPUT("Connection was closed by client. See ya soon! :)"); + break; + } + // Command mode + if (length==0) { + reply=0; + if (recv(AcceptSocket, (char *)&command, 1, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + break; + } +#ifdef USE_AUTHENTICATION + if (command==AUTHENTICATE) + if (password) reply=0x01; // Ok, go ahead + else command=0; +#endif + if (command==CAPABILITIES) + reply=password?USE_AUTHENTICATION:0; + + if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + break; + } + continue; + } + // Normal Skype API-call + if (!(buf=calloc(1, length+1))) { + OUTPUT("Out of memory error while allocating buffer space."); + break; + } + if (recv(AcceptSocket, buf, length, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + free(buf); + break; + } + switch (command) { +#ifdef USE_AUTHENTICATION + case 0x01: // Compare hash + if (password && !strcmp(password, buf)) Authenticated=TRUE; + else Authenticated=FALSE; + if (Authenticated) { + OUTPUT("User authenticated succesfully."); + reply=1; + } else { + OUTPUT("User authentication failed!! (Intruder?)"); + reply=0; + } + if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + break; + } + command=0; + break; +#endif + default: +#ifdef USE_AUTHENTICATION + if (password && !Authenticated) break; +#endif + SkypeSend(buf); + } + command=0; + free(buf); + } + AcceptSocket=INVALID_SOCKET; +#ifdef USE_AUTHENTICATION + Authenticated=FALSE; +#endif + } +} + + +void WatchDogTimer(char *dummy) { + LOG(("WatchDogTimer started")); + WatchDogRunning=TRUE; + while (1) { + Sleep(PING_INTERVAL); + if (!WatchDog) { + OUTPUT("Ouch.. It seems that Skype has died unexpectedly. Trying to restart."); + ConnectToSkypeAPI((void *)TRUE); + } + WatchDog=0; + SkypeSend("PING"); + } +} + +LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) +{ + PCOPYDATASTRUCT CopyData; + char *szSkypeMsg=NULL; + + switch (message) + { + case WM_COPYDATA: +// LOG("WM_COPYDATA", "start"); + if(hSkypeWnd==(HWND)wParam) { + CopyData=(PCOPYDATASTRUCT)lParam; + szSkypeMsg=strdup(CopyData->lpData); + ReplyMessage(1); + if (!strcmp(szSkypeMsg, "PONG")) { + WatchDog=1; + break; + } // Hide PING-PONG + LOG(("< %s", szSkypeMsg)); + if (!strcmp(szSkypeMsg, "USERSTATUS LOGGEDOUT")) { + OUTPUT("Skype shut down gracefully. I'll leave too, bye.. :)"); + bail_out(1); + } +#ifdef USE_AUTHENTICATION + if (password && !Authenticated) break; +#endif + if (AcceptSocket!=INVALID_SOCKET) { + unsigned int length=strlen(szSkypeMsg); + + if (send(AcceptSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || + send(AcceptSocket, szSkypeMsg, length, 0)==SOCKET_ERROR) + OUTPUT("Cannot send to client :("); + } + } + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + if(message==ControlAPIAttach) { + // Skype responds with Attach to the discover-message + AttachStatus=lParam; + if (AttachStatus==SKYPECONTROLAPI_ATTACH_SUCCESS) + hSkypeWnd=(HWND)wParam; // Skype gave us the communication window handle + if (AttachStatus!=SKYPECONTROLAPI_ATTACH_API_AVAILABLE) + SetEvent(SkypeReady); + break; + } + return (DefWindowProc(hWnd, message, wParam, lParam)); + } +// LOG("WM_COPYDATA", "exit"); + if (szSkypeMsg) free(szSkypeMsg); + return 1; +} + + +void TellError(DWORD err) { + LPVOID lpMsgBuf; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); + MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); + LocalFree( lpMsgBuf ); + return; +} + +int main(int argc, char *argv[]) { + DWORD Buffsize; + HKEY MyKey; + BOOL SkypeInstalled=TRUE; + MSG Message; + WNDCLASS WndClass; + SOCKADDR_IN service; + WSADATA wsaData; + int ExitCode=STILL_ACTIVE; + unsigned short BindPort=1401; + char BindIP[16]="0.0.0.0"; + + printf("Skypeproxy V1.0, by leecher 2005 \n\n"); + + if (argc>1) { + int i; + + if (!stricmp(argv[1], "-h") || !stricmp(argv[1], "--help") || !stricmp(argv[1], "/?")) { + printf("Usage: %s [-i BindIP] [-p BindPort]", argv[0]); +#ifdef USE_AUTHENTICATION + printf(" [-k Password]"); +#endif + printf("\n\n"); + return EXIT_SUCCESS; + } + for (i=0;ii+1) + strncpy(BindIP, argv[i+1], sizeof(BindIP)); + if (!stricmp(argv[i], "-p") && argc>i+1) + if (!(BindPort=atoi(argv[i+1]))) { + OUTPUT("ERROR: Cannot convert port to int. bye.."); + return EXIT_FAILURE; + } +#ifdef USE_AUTHENTICATION + if (!stricmp(argv[i], "-k") && argc>i+1) + password=strdup(argv[i+1]); +#endif + } + } + + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS || + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) + SkypeInstalled=FALSE; + Buffsize=sizeof(skype_path); + if (SkypeInstalled==FALSE || + RegQueryValueEx(MyKey, "SkypePath", NULL, NULL, skype_path, &Buffsize)!=ERROR_SUCCESS) { + OUTPUT("Skype was not found on this machine :("); + RegCloseKey(MyKey); + skype_path[0]=0; + return EXIT_FAILURE; + } + RegCloseKey(MyKey); + + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { + OUTPUT("Error at loading windows sockets."); + return EXIT_FAILURE; + } + + if ((ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { + printf("* Error at creating socket(): Error %d", WSAGetLastError()); + return EXIT_FAILURE; + } + + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(BindIP); + service.sin_port = htons(BindPort); + + printf("* Binding to interface %s, Port %d..", BindIP, BindPort); + if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR || + listen( ListenSocket, 1 ) == SOCKET_ERROR) + { + OUTPUT("Failed."); + closesocket(ListenSocket); + return EXIT_FAILURE; + } + printf("OK\n"); + + + if (!(ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach")) || + !(ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover"))) { + OUTPUT("Cannot register Windows message."); + closesocket(ListenSocket); + return EXIT_FAILURE; + } + + // Create window class + hSkypeWnd=NULL; + WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; + WndClass.lpfnWndProc = (WNDPROC)WndProc; + WndClass.cbClsExtra = 0; + WndClass.cbWndExtra = 0; + WndClass.hInstance = NULL; + WndClass.hIcon = NULL; + WndClass.hCursor = NULL; + WndClass.hbrBackground = NULL; + WndClass.lpszMenuName = NULL; + WndClass.lpszClassName = "SkypeApiDispatchWindow"; + RegisterClass(&WndClass); + // Do not check the retval of RegisterClass, because on non-unicode + // win98 it will fail, as it is a stub that returns false() there + + // Create main window + hWnd=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, + "SkypeApiDispatchWindow", "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, 0); + + if (!hWnd) { + OUTPUT("Cannot create window."); + TellError(GetLastError()); + closesocket(ListenSocket); + CloseHandle(WndClass.hInstance); + return EXIT_FAILURE; + } + ShowWindow(hWnd, 0); + UpdateWindow(hWnd); + + if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || + !(ServerThreadBye=CreateEvent(NULL, TRUE, FALSE, NULL))) { + OUTPUT("Unable to create Mutex!"); + closesocket(ListenSocket); + CloseHandle(WndClass.hInstance); + return EXIT_FAILURE; + } + + if (_beginthread(ConnectToSkypeAPI, 0, (void *)FALSE)==-1 || + _beginthread(ServerThread, 0, NULL)==-1) { + OUTPUT("Cannot create thread. Bye.."); + closesocket(ListenSocket); + CloseHandle(WndClass.hInstance); + CloseHandle(SkypeReady); + return EXIT_FAILURE; + } + + signal(SIGINT, &bail_out); + LOG(("Startup: Messagepump started.\nPress CTRL+C to terminate\n")); + + while (GetMessage(&Message, hWnd, 0, 0)) + { + TranslateMessage(&Message); + DispatchMessage(&Message); + } + + LOG(("Shutdown: Messagepump stopped")); + + if (password) free(password); + if (AcceptSocket != INVALID_SOCKET) closesocket(AcceptSocket); + closesocket(ListenSocket); + LOG(("Shutdown: Waiting for serverthread to quit...")); + if (WaitForSingleObject(ServerThreadBye, 3000)==WAIT_TIMEOUT) + {OUTPUT("Serverthread didn't terminate correctly, shutting down anyway...");} + else + {LOG(("ServerThread terminated"));} + CloseHandle(WndClass.hInstance); + CloseHandle(SkypeReady); + return exitcode; +} \ No newline at end of file diff --git a/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h new file mode 100644 index 0000000000..8ce122990b --- /dev/null +++ b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h @@ -0,0 +1,36 @@ +/*** Skype API ***/ +//Messages +#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 +#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 +#define SKYPECONTROLAPI_ATTACH_REFUSED 2 +#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 +#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 + +// Errors +#define MISC_ERROR 1 +#define USER_NOT_FOUND 2 +#define USER_NOT_ONLINE 3 +#define USER_BLOCKED 4 +#define TYPE_UNSUPPORTED 5 +#define SENDER_NOT_FRIEND 6 +#define SENDER_NOT_AUTHORIZED 7 + + +/*** Debugging macros ***/ +#define OUTPUT(a) printf("* %s\n", a); +#define LOG(a, b) printf("- %s: %s\n", a, b); +#define LOGL(a, b) printf("- %s: %d\n", a, b); + +/*** Program settings ***/ +#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available +#define USE_AUTHENTICATION 0x01 // Program supports authentication -> Comment to disable! + +/*** Commands ***/ +#define AUTHENTICATE 0x01 +#define CAPABILITIES 0x02 + +/*** Sockets ***/ +#pragma comment(lib, "ws2_32") + +/*** Prototypes ***/ +void WatchDogTimer(char *); \ No newline at end of file diff --git a/protocols/SkypeClassic/src/skypesvc.cpp b/protocols/SkypeClassic/src/skypesvc.cpp new file mode 100644 index 0000000000..bc8131b2c8 --- /dev/null +++ b/protocols/SkypeClassic/src/skypesvc.cpp @@ -0,0 +1,187 @@ +#define __SKYPESVC_C__ +#include "skype.h" +#include "skypesvc.h" +#include "skypeapi.h" +#include "skypeopt.h" +#include "contacts.h" +#include "m_toptoolbar.h" + +// Exports +SKYPE_SVCNAMES g_svcNames; + +//From skype.c +extern char protocol, g_szProtoName[]; +extern HINSTANCE hInst; +extern DWORD mirandaVersion; +static HANDLE m_hPrebuildCMenu=NULL, m_hStatusHookContact=NULL, m_hContactDeleted=NULL, + m_hHookModulesLoaded=NULL, m_hHookOkToExit=NULL, m_hOptHook=NULL, m_hHookMirandaExit=NULL, + m_hTTBModuleLoadedHook = NULL, m_hHookOnUserInfoInit = NULL; + +void CreateProtoService(const char* szService, MIRANDASERVICE svc) +{ + char str[MAXMODULELABELLENGTH]; + _snprintf(str, sizeof(str), "%s%s", SKYPE_PROTONAME, szService); + CreateServiceFunction(str, svc); +} + +#define CreateServiceName(srvce) _snprintf (g_svcNames.##srvce, sizeof(g_svcNames.##srvce), "%s/"#srvce, SKYPE_PROTONAME); + +void CreateServices(void) +{ + CreateServiceName(ChatNew); + CreateServiceName(SetAvatar); + CreateServiceName(SendFile); + CreateServiceName(HoldCall); + CreateServiceName(AnswerCall); + CreateServiceName(ImportHistory); + CreateServiceName(AddUser); + CreateServiceName(SkypeOutCallUser); + CreateServiceName(CallHangupUser); + CreateServiceName(CallUser); + + CreateServiceFunction(SKYPE_CALL, SkypeCall); + CreateServiceFunction(SKYPE_CALLHANGUP, SkypeCallHangup); + CreateServiceFunction(SKYPEOUT_CALL, SkypeOutCall); + CreateServiceFunction(SKYPE_HOLDCALL, SkypeHoldCall); + CreateServiceFunction(SKYPE_ADDUSER, SkypeAdduserDlg); + CreateServiceFunction(SKYPE_IMPORTHISTORY, ImportHistory); + CreateServiceFunction(SKYPE_ANSWERCALL, SkypeAnswerCall); + CreateServiceFunction(SKYPE_SENDFILE, SkypeSendFile); + CreateServiceFunction(SKYPE_SETAVATAR, SkypeSetAvatar); + + CreateProtoService(PS_GETCAPS, SkypeGetCaps); + CreateProtoService(PS_GETNAME, SkypeGetName); + CreateProtoService(PS_LOADICON, SkypeLoadIcon); + CreateProtoService(PS_SETSTATUS, SkypeSetStatus); + CreateProtoService(PS_GETSTATUS, SkypeGetStatus); + CreateProtoService(PS_ADDTOLIST, SkypeAddToList); + CreateProtoService(PS_ADDTOLISTBYEVENT, SkypeAddToListByEvent); + CreateProtoService(PS_BASICSEARCH, SkypeBasicSearch); + + CreateProtoService(PSS_GETINFO, SkypeGetInfo); + CreateProtoService(PSS_MESSAGE, SkypeSendMessage); + CreateProtoService(PSR_MESSAGE, SkypeRecvMessage); + CreateProtoService(PSS_USERISTYPING, SkypeUserIsTyping); + CreateProtoService(PSS_AUTHREQUEST, SkypeSendAuthRequest); + CreateProtoService(PSR_AUTH, SkypeRecvAuth); + CreateProtoService(PS_AUTHALLOW, SkypeAuthAllow); + CreateProtoService(PS_AUTHDENY, SkypeAuthDeny); + + CreateProtoService(PS_GETAVATARINFO, SkypeGetAvatarInfo); + CreateProtoService(PS_GETAVATARCAPS, SkypeGetAvatarCaps); + CreateProtoService(PS_GETMYAVATAR, SkypeGetAvatar); + CreateProtoService(PS_SETMYAVATAR, SkypeSetAvatar); + + CreateProtoService(PS_SETAWAYMSG, SkypeSetAwayMessage); + CreateProtoService(PS_SETAWAYMSGW, SkypeSetAwayMessageW); + CreateProtoService(PSS_GETAWAYMSG, SkypeGetAwayMessage); + CreateProtoService(PS_SETMYNICKNAME, SkypeSetNick); + + CreateProtoService(PSS_SKYPEAPIMSG, SkypeReceivedAPIMessage); + CreateProtoService(SKYPE_REGPROXY, SkypeRegisterProxy); +} + +void HookEvents(void) +{ + m_hPrebuildCMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); + + //HookEvent(ME_CLIST_DOUBLECLICKED, ClistDblClick); + m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions); + m_hStatusHookContact = HookEvent(ME_DB_CONTACT_ADDED,HookContactAdded); + m_hContactDeleted = HookEvent( ME_DB_CONTACT_DELETED, HookContactDeleted ); + m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + m_hHookMirandaExit = HookEvent(ME_SYSTEM_OKTOEXIT, MirandaExit); + m_hHookOkToExit = HookEvent(ME_SYSTEM_PRESHUTDOWN, OkToExit); +} + +void HookEventsLoaded(void) +{ + // We cannot check for the TTB-service before this event gets fired... :-/ + m_hTTBModuleLoadedHook = HookEvent(ME_TTB_MODULELOADED, CreateTopToolbarButton); + m_hHookOnUserInfoInit = HookEvent( ME_USERINFO_INITIALISE, OnDetailsInit ); +} + +void UnhookEvents(void) +{ + UnhookEvent(m_hOptHook); + UnhookEvent(m_hTTBModuleLoadedHook); + UnhookEvent(m_hHookOnUserInfoInit); + UnhookEvent(m_hStatusHookContact); + UnhookEvent(m_hContactDeleted); + UnhookEvent(m_hHookModulesLoaded); + UnhookEvent(m_hPrebuildCMenu); + UnhookEvent(m_hHookOkToExit); + UnhookEvent(m_hHookMirandaExit); + //UnhookEvent(ClistDblClick); +} + +INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam) { + int ret = 0; + + UNREFERENCED_PARAMETER(lParam); + + switch (wParam) { + case PFLAGNUM_1: + ret = PF1_BASICSEARCH | PF1_IM | PF1_MODEMSG; // | PF1_AUTHREQ; + if (protocol>=5) ret |= PF1_ADDSEARCHRES; + break; + + case PFLAGNUM_2: + ret = PF2_ONLINE | PF2_SHORTAWAY | PF2_INVISIBLE | PF2_HEAVYDND; +#ifdef MAPDND + ret |= PF2_LIGHTDND | PF2_HEAVYDND; +#endif + if (!db_get_b(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) + ret |= PF2_LONGAWAY | PF2_FREECHAT; + break; + + case PFLAGNUM_3: + ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE; + break; + + case PFLAGNUM_4: + ret = PF4_FORCEAUTH | PF4_FORCEADDED | PF4_AVATARS | PF4_SUPPORTTYPING /* Not really, but libgaim compat. */; + if (mirandaVersion >= 0x070000) ret |= PF4_IMSENDUTF; + break; + case PFLAG_UNIQUEIDTEXT: + ret = (INT_PTR)Translate("Skype name"); + break; + case PFLAG_UNIQUEIDSETTING: + ret = (INT_PTR) SKYPE_NAME; + break; + } + return ret; +} + +INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam) +{ + if (lParam) + { + strncpy((char *)lParam, SKYPE_PROTONAME, wParam); + return 0; // Success + } + return 1; // Failure +} + + +INT_PTR SkypeLoadIcon(WPARAM wParam,LPARAM lParam) +{ + UINT id; + + UNREFERENCED_PARAMETER(lParam); + + switch(wParam&0xFFFF) { + case PLI_PROTOCOL: id=IDI_SKYPE; break; // IDI_MAIN is the main icon for the protocol + default: return (int)(HICON)NULL; + } + return (int)LoadImage(hInst,MAKEINTRESOURCE(id),IMAGE_ICON,GetSystemMetrics(wParam&PLIF_SMALL?SM_CXSMICON:SM_CXICON),GetSystemMetrics(wParam&PLIF_SMALL?SM_CYSMICON:SM_CYICON),0); +} + +INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam) +{ DBVARIANT dbv; + if (!db_get_s(NULL,SKYPE_PROTONAME, "AvatarFile", &dbv)){ + lstrcpynA((char*)wParam, dbv.pszVal, (int)lParam); + db_free(&dbv); + } + return 0; +} diff --git a/protocols/SkypeClassic/src/skypesvc.h b/protocols/SkypeClassic/src/skypesvc.h new file mode 100644 index 0000000000..74c8cd37bf --- /dev/null +++ b/protocols/SkypeClassic/src/skypesvc.h @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include "resource.h" + +void CreateProtoService(const char* szService, MIRANDASERVICE svc); +void HookEvents(void); +void HookEventsLoaded(void); +void UnhookEvents(void); +void CreateServices(void); +INT_PTR SkypeLoadIcon(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam); +/* SkypeGetAvatar + * + * Purpose: Return the avatar file name + * Params : wParam=0 + * lParam=0 + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam); \ No newline at end of file diff --git a/protocols/SkypeClassic/src/utf8.cpp b/protocols/SkypeClassic/src/utf8.cpp new file mode 100644 index 0000000000..8ae746e871 --- /dev/null +++ b/protocols/SkypeClassic/src/utf8.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2001 Peter Harris + * Copyright (C) 2001 Edmund Grimley Evans + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Convert a string between UTF-8 and the locale's charset. + */ + +#include +#include + +#include "utf8.h" + +#ifdef _WIN32 + + /* Thanks to Peter Harris for this win32 + * code. + */ + +#include +#include + +unsigned char *make_utf8_string(const wchar_t *unicode) +{ + int size = 0, index = 0, out_index = 0; + unsigned char *out; + unsigned short c; + + /* first calculate the size of the target string */ + c = unicode[index++]; + while(c) { + if(c < 0x0080) { + size += 1; + } else if(c < 0x0800) { + size += 2; + } else { + size += 3; + } + c = unicode[index++]; + } + + out = (unsigned char *) malloc(size + 1); + if (out == NULL) + return NULL; + index = 0; + + c = unicode[index++]; + while(c) + { + if(c < 0x080) { + out[out_index++] = (unsigned char)c; + } else if(c < 0x800) { + #pragma warning (suppress: 4244) // conversion from 'int' to 'unsigned char', possible loss of data + out[out_index++] = 0xc0 | (c >> 6); + out[out_index++] = 0x80 | (c & 0x3f); + } else { + out[out_index++] = 0xe0 | (c >> 12); + out[out_index++] = 0x80 | ((c >> 6) & 0x3f); + out[out_index++] = 0x80 | (c & 0x3f); + } + c = unicode[index++]; + } + out[out_index] = 0x00; + + return out; +} + +wchar_t *make_unicode_string(const unsigned char *utf8) +{ + int size = 0, index = 0, out_index = 0; + wchar_t *out; + unsigned char c; + + /* first calculate the size of the target string */ + c = utf8[index++]; + while(c) { + if((c & 0x80) == 0) { + index += 0; + } else if((c & 0xe0) == 0xe0) { + index += 2; + } else { + index += 1; + } + size += 1; + c = utf8[index++]; + } + + out = (wchar_t *) malloc((size + 1) * sizeof(wchar_t)); + if (out == NULL) + return NULL; + index = 0; + + c = utf8[index++]; + while(c) + { + if((c & 0x80) == 0) { + out[out_index++] = c; + } else if((c & 0xe0) == 0xe0) { + out[out_index] = (c & 0x1F) << 12; + c = utf8[index++]; + out[out_index] |= (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } else { + out[out_index] = (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + c = utf8[index++]; + } + out[out_index] = 0; + + return out; +} + +int utf8_encode(const char *from, char **to) +{ + wchar_t *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), NULL, 0); + + if(wchars == 0) + { +// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); + return -1; + } + + unicode = (wchar_t *) calloc(wchars + 1, sizeof(unsigned short)); + if(unicode == NULL) + { +// fprintf(stderr, "Out of memory processing string to UTF8\n"); + return -1; + } + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), unicode, wchars); + if(err != wchars) + { + free(unicode); +// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); + return -1; + } + + /* On NT-based windows systems, we could use WideCharToMultiByte(), but + * MS doesn't actually have a consistent API across win32. + */ + *to = (char *) make_utf8_string(unicode); + + free(unicode); + return 0; +} + +int utf8_decode(const char *from, char **to) +{ + wchar_t *unicode; + int chars, err; +// LPCPINFO lpCPInfo; + + /* On NT-based windows systems, we could use MultiByteToWideChar(CP_UTF8), but + * MS doesn't actually have a consistent API across win32. + */ + unicode = make_unicode_string( (const unsigned char *)from); + if(unicode == NULL) + { + fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); + return -1; + } + + //if(GetCPInfo(CP_ACP,lpCPInfo)) + { + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + } + /*else + { + chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + }*/ + + if(chars == 0) + { + fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); + free(unicode); + return -1; + } + + *to = (char *) calloc(chars + 1, sizeof(unsigned char)); + if(*to == NULL) + { + fprintf(stderr, "Out of memory processing string to local charset\n"); + free(unicode); + return -1; + } + + //err = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + if(err != chars) + { + fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); + free(unicode); + free(*to); + *to = NULL; + return -1; + } + + free(unicode); + return 0; +} + +#ifndef _UNICODE +char *make_tchar_string(const unsigned char *utf8) { + char *ret; + if (utf8_decode((const char*)utf8, &ret)==-1) return NULL; + return ret; +} +#endif + +#else /* End win32. Rest is for real operating systems */ + + +#ifdef HAVE_LANGINFO_CODESET +#include +#endif + +int iconvert(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen); + +static char *current_charset = "BIG-5"; /* means "US-ASCII" */ + +void convert_set_charset(const char *charset) +{ + + if (!charset) + charset = getenv("CHARSET"); + +#ifdef HAVE_LANGINFO_CODESET + if (!charset) + charset = nl_langinfo(CODESET); +#endif + + free(current_charset); + current_charset = 0; + if (charset && *charset) + current_charset = _strdup(charset); +} + +static int convert_buffer(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen) +{ + int ret = -1; + +#ifdef HAVE_ICONV + ret = iconvert(fromcode, tocode, from, fromlen, to, tolen); + if (ret != -1) + return ret; +#endif + +#ifndef HAVE_ICONV /* should be ifdef USE_CHARSET_CONVERT */ + ret = charset_convert(fromcode, tocode, from, fromlen, to, tolen); + if (ret != -1) + return ret; +#endif + + return ret; +} + +static int convert_string(const char *fromcode, const char *tocode, + const char *from, char **to, char replace) +{ + int ret; + size_t fromlen; + char *s; + + fromlen = lstrlen(from); + ret = convert_buffer(fromcode, tocode, from, fromlen, to, 0); + if (ret == -2) + return -1; + if (ret != -1) + return ret; + + s = malloc(fromlen + 1); + if (!s) + return -1; + lstrcpy(s, from); + *to = s; + for (; *s; s++) + if (*s & ~0x7f) + *s = replace; + return 3; +} + +int utf8_encode(const char *from, char **to) +{ + char *charset; + + if (!current_charset) + convert_set_charset(0); + charset = current_charset ? current_charset : "US-ASCII"; + return convert_string(charset, "UTF-8", from, to, '#'); +} + +int utf8_decode(const char *from, char **to) +{ + char *charset; + + if(*from == 0) { + *to = malloc(1); + **to = 0; + return 1; + } + + if (!current_charset) + convert_set_charset(0); + charset = current_charset ? current_charset : "US-ASCII"; + return convert_string("UTF-8", charset, from, to, '?'); +} + +#endif diff --git a/protocols/SkypeClassic/src/utf8.h b/protocols/SkypeClassic/src/utf8.h new file mode 100644 index 0000000000..70c533deca --- /dev/null +++ b/protocols/SkypeClassic/src/utf8.h @@ -0,0 +1,47 @@ +/* + * Convert a string between UTF-8 and the locale's charset. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * + * If the locale's charset is not set explicitly then it is + * obtained using nl_langinfo(CODESET), where available, the + * environment variable CHARSET, or assumed to be US-ASCII. + * + * Return value of conversion functions: + * + * -1 : memory allocation failed + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ + +#ifndef __UTF8_H +#define __UTF8_H + +#ifdef __cplusplus +extern "C" { +#endif + +void convert_set_charset(const char *charset); + +int utf8_encode(const char *from, char **to); +int utf8_decode(const char *from, char **to); +wchar_t *make_unicode_string(const unsigned char *utf8); +unsigned char *make_utf8_string(const wchar_t *unicode); +#ifdef _UNICODE +#define make_tchar_string make_unicode_string +// Helpers for strings that only can contain 7bit chars to not make unneccessary memory allocation +#define make_nonutf_tchar_string(x) make_tchar_string(x) +#define free_nonutf_tchar_string(x) if(x) free(x); +#else +char *make_tchar_string(const unsigned char *utf8); +#define make_nonutf_tchar_string(x) (char*)x +#define free_nonutf_tchar_string(x) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __UTF8_H */ diff --git a/protocols/SkypeClassic/src/util.cpp b/protocols/SkypeClassic/src/util.cpp new file mode 100644 index 0000000000..ce5ad9c756 --- /dev/null +++ b/protocols/SkypeClassic/src/util.cpp @@ -0,0 +1,57 @@ +#include + +char * __cdecl strtok_r ( + char * string, + const char * control, + char **nextoken + ) +{ + unsigned char *str; + const unsigned char *ctrl = (const unsigned char*)control; + + unsigned char map[32]; + int count; + + /* Clear control map */ + for (count = 0; count < 32; count++) + map[count] = 0; + + /* Set bits in delimiter table */ + do { + map[*ctrl >> 3] |= (1 << (*ctrl & 7)); + } while (*ctrl++); + + /* Initialize str. If string is NULL, set str to the saved + * pointer (i.e., continue breaking tokens out of the string + * from the last strtok call) */ + if (string) + str = (unsigned char*)string; + else + str = (unsigned char*)(*nextoken); + + /* Find beginning of token (skip over leading delimiters). Note that + * there is no token iff this loop sets str to point to the terminal + * null (*str == '\0') */ + while ( (map[*str >> 3] & (1 << (*str & 7))) && *str ) + str++; + + string = (char*)str; + + /* Find the end of the token. If it is not the end of the string, + * put a null there. */ + for ( ; *str ; str++ ) + if ( map[*str >> 3] & (1 << (*str & 7)) ) { + *str++ = '\0'; + break; + } + + /* Update nextoken (or the corresponding field in the per-thread data + * structure */ + *nextoken = (char*)str; + + /* Determine if a token has been found. */ + if ( string == (char*)str ) + return NULL; + else + return string; +} diff --git a/protocols/SkypeClassic/src/util.h b/protocols/SkypeClassic/src/util.h new file mode 100644 index 0000000000..181f5d1878 --- /dev/null +++ b/protocols/SkypeClassic/src/util.h @@ -0,0 +1,7 @@ +char * __cdecl strtok_r ( + char * string, + const char * control, + char **nextoken + ); + +void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces); diff --git a/protocols/SkypeClassic/src/version.h b/protocols/SkypeClassic/src/version.h new file mode 100644 index 0000000000..2e8a2547b5 --- /dev/null +++ b/protocols/SkypeClassic/src/version.h @@ -0,0 +1,20 @@ +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 54 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM + +#define __STRINGIFY_IMPL(x) #x +#define __STRINGIFY(x) __STRINGIFY_IMPL(x) +#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS) + +#define __PLUGIN_NAME "Skype Protocol (Classic)" +#define __INTERNAL_NAME "SkypeClassic" +#define __FILENAME "SkypeClassic.dll" +#define __DESCRIPTION "Skype protocol support for Miranda NG. Classic implemetation which requires running original Skype client." +#define __AUTHOR "leecher - tweety - jls17" +#define __AUTHOREMAIL "leecher@dose.0wnz.at - tweety@user.berlios.de" +#define __AUTHORWEB "http://miranda-ng.org/p/SkypeClassic/" +#define __COPYRIGHT "© 2004-2012 leecher - tweety" diff --git a/protocols/SkypeClassic/src/voiceservice.cpp b/protocols/SkypeClassic/src/voiceservice.cpp new file mode 100644 index 0000000000..2a22bbe86c --- /dev/null +++ b/protocols/SkypeClassic/src/voiceservice.cpp @@ -0,0 +1,156 @@ +#include "skype.h" +#include "skypeapi.h" +#include "skypesvc.h" +#include "voiceservice.h" +#include + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +#include +#pragma warning (pop) + +HANDLE hVoiceNotify = NULL; +BOOL has_voice_service = FALSE; + +extern char g_szProtoName[]; + + +BOOL HasVoiceService() +{ + return has_voice_service; +} + +void NofifyVoiceService(HANDLE hContact, char *callId, int state) +{ + VOICE_CALL vc = {0}; + vc.cbSize = sizeof(vc); + vc.szModule = SKYPE_PROTONAME; + vc.id = callId; + vc.flags = VOICE_CALL_CONTACT; + vc.state = state; + vc.hContact = hContact; + NotifyEventHooks(hVoiceNotify, (WPARAM) &vc, 0); +} + +static INT_PTR VoiceGetInfo(WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + return VOICE_SUPPORTED | VOICE_CALL_CONTACT | VOICE_CAN_HOLD; +} + +static HANDLE FindContactByCallId(char *callId) +{ + HANDLE hContact; + int iCmpRes; + for (hContact = db_find_first(); + hContact != NULL; + hContact = db_find_next(hContact)) + { + char *szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + + DBVARIANT dbv; + if (szProto != NULL + && !strcmp(szProto, SKYPE_PROTONAME) + && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 + && !db_get_s(hContact, SKYPE_PROTONAME, "CallId", &dbv)) + { + iCmpRes = strcmp(callId, dbv.pszVal); + db_free(&dbv); + if (iCmpRes == 0) return hContact; + } + } + + return NULL; +} + +static INT_PTR VoiceCall(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (db_get_s((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return -1; + + SkypeSend("CALL %s", dbv.pszVal); + db_free (&dbv); + + return 0; +} + +static INT_PTR VoiceAnswer(WPARAM wParam, LPARAM lParam) +{ + char *callId = (char *) wParam; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (FindContactByCallId(callId) == NULL) + return -1; + + SkypeSend("SET %s STATUS INPROGRESS", callId); + testfor("ERROR", 200); + + return 0; +} + +static INT_PTR VoiceDrop(WPARAM wParam, LPARAM lParam) +{ + char *callId = (char *) wParam; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (FindContactByCallId(callId) == NULL) + return -1; + + SkypeSend("SET %s STATUS FINISHED", callId); + + return 0; +} + +static INT_PTR VoiceHold(WPARAM wParam, LPARAM lParam) +{ + char *callId = (char *) wParam; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (FindContactByCallId(callId) == NULL) + return -1; + + SkypeSend("SET %s STATUS ONHOLD", callId); + + return 0; +} + +void VoiceServiceInit() +{ + // leecher, 26.03.2011: Did this ever work in the old versions?? + char szEvent[MAXMODULELABELLENGTH]; + + _snprintf (szEvent, sizeof(szEvent), "%s%s", SKYPE_PROTONAME, PE_VOICE_CALL_STATE); + hVoiceNotify = CreateHookableEvent( szEvent ); + CreateProtoService( PS_VOICE_GETINFO, VoiceGetInfo ); + CreateProtoService( PS_VOICE_CALL, VoiceCall ); + CreateProtoService( PS_VOICE_ANSWERCALL, VoiceAnswer ); + CreateProtoService( PS_VOICE_DROPCALL, VoiceDrop ); + CreateProtoService( PS_VOICE_HOLDCALL, VoiceHold ); +} + +void VoiceServiceExit() +{ + DestroyHookableEvent(hVoiceNotify); +} + +void VoiceServiceModulesLoaded() +{ + has_voice_service = ServiceExists(MS_VOICESERVICE_REGISTER); +} \ No newline at end of file diff --git a/protocols/SkypeClassic/src/voiceservice.h b/protocols/SkypeClassic/src/voiceservice.h new file mode 100644 index 0000000000..0ffbd6d9ca --- /dev/null +++ b/protocols/SkypeClassic/src/voiceservice.h @@ -0,0 +1,18 @@ +#ifndef _VOICESERVICE_H_ +#define _VOICESERVICE_H_ + +#pragma warning (push) +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union +#include +#pragma warning (pop) + +BOOL HasVoiceService(); +void VoiceServiceInit(); +void VoiceServiceExit(); +void VoiceServiceModulesLoaded(); +void NofifyVoiceService(HANDLE hContact, char *callId, int state) ; + + + +#endif // _VOICESERVICE_H_ + diff --git a/protocols/SkypeClassic/utf8.cpp b/protocols/SkypeClassic/utf8.cpp deleted file mode 100644 index 8ae746e871..0000000000 --- a/protocols/SkypeClassic/utf8.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2001 Peter Harris - * Copyright (C) 2001 Edmund Grimley Evans - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Convert a string between UTF-8 and the locale's charset. - */ - -#include -#include - -#include "utf8.h" - -#ifdef _WIN32 - - /* Thanks to Peter Harris for this win32 - * code. - */ - -#include -#include - -unsigned char *make_utf8_string(const wchar_t *unicode) -{ - int size = 0, index = 0, out_index = 0; - unsigned char *out; - unsigned short c; - - /* first calculate the size of the target string */ - c = unicode[index++]; - while(c) { - if(c < 0x0080) { - size += 1; - } else if(c < 0x0800) { - size += 2; - } else { - size += 3; - } - c = unicode[index++]; - } - - out = (unsigned char *) malloc(size + 1); - if (out == NULL) - return NULL; - index = 0; - - c = unicode[index++]; - while(c) - { - if(c < 0x080) { - out[out_index++] = (unsigned char)c; - } else if(c < 0x800) { - #pragma warning (suppress: 4244) // conversion from 'int' to 'unsigned char', possible loss of data - out[out_index++] = 0xc0 | (c >> 6); - out[out_index++] = 0x80 | (c & 0x3f); - } else { - out[out_index++] = 0xe0 | (c >> 12); - out[out_index++] = 0x80 | ((c >> 6) & 0x3f); - out[out_index++] = 0x80 | (c & 0x3f); - } - c = unicode[index++]; - } - out[out_index] = 0x00; - - return out; -} - -wchar_t *make_unicode_string(const unsigned char *utf8) -{ - int size = 0, index = 0, out_index = 0; - wchar_t *out; - unsigned char c; - - /* first calculate the size of the target string */ - c = utf8[index++]; - while(c) { - if((c & 0x80) == 0) { - index += 0; - } else if((c & 0xe0) == 0xe0) { - index += 2; - } else { - index += 1; - } - size += 1; - c = utf8[index++]; - } - - out = (wchar_t *) malloc((size + 1) * sizeof(wchar_t)); - if (out == NULL) - return NULL; - index = 0; - - c = utf8[index++]; - while(c) - { - if((c & 0x80) == 0) { - out[out_index++] = c; - } else if((c & 0xe0) == 0xe0) { - out[out_index] = (c & 0x1F) << 12; - c = utf8[index++]; - out[out_index] |= (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } else { - out[out_index] = (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } - c = utf8[index++]; - } - out[out_index] = 0; - - return out; -} - -int utf8_encode(const char *from, char **to) -{ - wchar_t *unicode; - int wchars, err; - - wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), NULL, 0); - - if(wchars == 0) - { -// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); - return -1; - } - - unicode = (wchar_t *) calloc(wchars + 1, sizeof(unsigned short)); - if(unicode == NULL) - { -// fprintf(stderr, "Out of memory processing string to UTF8\n"); - return -1; - } - - err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), unicode, wchars); - if(err != wchars) - { - free(unicode); -// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); - return -1; - } - - /* On NT-based windows systems, we could use WideCharToMultiByte(), but - * MS doesn't actually have a consistent API across win32. - */ - *to = (char *) make_utf8_string(unicode); - - free(unicode); - return 0; -} - -int utf8_decode(const char *from, char **to) -{ - wchar_t *unicode; - int chars, err; -// LPCPINFO lpCPInfo; - - /* On NT-based windows systems, we could use MultiByteToWideChar(CP_UTF8), but - * MS doesn't actually have a consistent API across win32. - */ - unicode = make_unicode_string( (const unsigned char *)from); - if(unicode == NULL) - { - fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); - return -1; - } - - //if(GetCPInfo(CP_ACP,lpCPInfo)) - { - - chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); - } - /*else - { - chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); - }*/ - - if(chars == 0) - { - fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); - free(unicode); - return -1; - } - - *to = (char *) calloc(chars + 1, sizeof(unsigned char)); - if(*to == NULL) - { - fprintf(stderr, "Out of memory processing string to local charset\n"); - free(unicode); - return -1; - } - - //err = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); - err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); - if(err != chars) - { - fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); - free(unicode); - free(*to); - *to = NULL; - return -1; - } - - free(unicode); - return 0; -} - -#ifndef _UNICODE -char *make_tchar_string(const unsigned char *utf8) { - char *ret; - if (utf8_decode((const char*)utf8, &ret)==-1) return NULL; - return ret; -} -#endif - -#else /* End win32. Rest is for real operating systems */ - - -#ifdef HAVE_LANGINFO_CODESET -#include -#endif - -int iconvert(const char *fromcode, const char *tocode, - const char *from, size_t fromlen, - char **to, size_t *tolen); - -static char *current_charset = "BIG-5"; /* means "US-ASCII" */ - -void convert_set_charset(const char *charset) -{ - - if (!charset) - charset = getenv("CHARSET"); - -#ifdef HAVE_LANGINFO_CODESET - if (!charset) - charset = nl_langinfo(CODESET); -#endif - - free(current_charset); - current_charset = 0; - if (charset && *charset) - current_charset = _strdup(charset); -} - -static int convert_buffer(const char *fromcode, const char *tocode, - const char *from, size_t fromlen, - char **to, size_t *tolen) -{ - int ret = -1; - -#ifdef HAVE_ICONV - ret = iconvert(fromcode, tocode, from, fromlen, to, tolen); - if (ret != -1) - return ret; -#endif - -#ifndef HAVE_ICONV /* should be ifdef USE_CHARSET_CONVERT */ - ret = charset_convert(fromcode, tocode, from, fromlen, to, tolen); - if (ret != -1) - return ret; -#endif - - return ret; -} - -static int convert_string(const char *fromcode, const char *tocode, - const char *from, char **to, char replace) -{ - int ret; - size_t fromlen; - char *s; - - fromlen = lstrlen(from); - ret = convert_buffer(fromcode, tocode, from, fromlen, to, 0); - if (ret == -2) - return -1; - if (ret != -1) - return ret; - - s = malloc(fromlen + 1); - if (!s) - return -1; - lstrcpy(s, from); - *to = s; - for (; *s; s++) - if (*s & ~0x7f) - *s = replace; - return 3; -} - -int utf8_encode(const char *from, char **to) -{ - char *charset; - - if (!current_charset) - convert_set_charset(0); - charset = current_charset ? current_charset : "US-ASCII"; - return convert_string(charset, "UTF-8", from, to, '#'); -} - -int utf8_decode(const char *from, char **to) -{ - char *charset; - - if(*from == 0) { - *to = malloc(1); - **to = 0; - return 1; - } - - if (!current_charset) - convert_set_charset(0); - charset = current_charset ? current_charset : "US-ASCII"; - return convert_string("UTF-8", charset, from, to, '?'); -} - -#endif diff --git a/protocols/SkypeClassic/utf8.h b/protocols/SkypeClassic/utf8.h deleted file mode 100644 index 70c533deca..0000000000 --- a/protocols/SkypeClassic/utf8.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Convert a string between UTF-8 and the locale's charset. - * Invalid bytes are replaced by '#', and characters that are - * not available in the target encoding are replaced by '?'. - * - * If the locale's charset is not set explicitly then it is - * obtained using nl_langinfo(CODESET), where available, the - * environment variable CHARSET, or assumed to be US-ASCII. - * - * Return value of conversion functions: - * - * -1 : memory allocation failed - * 0 : data was converted exactly - * 1 : valid data was converted approximately (using '?') - * 2 : input was invalid (but still converted, using '#') - * 3 : unknown encoding (but still converted, using '?') - */ - -#ifndef __UTF8_H -#define __UTF8_H - -#ifdef __cplusplus -extern "C" { -#endif - -void convert_set_charset(const char *charset); - -int utf8_encode(const char *from, char **to); -int utf8_decode(const char *from, char **to); -wchar_t *make_unicode_string(const unsigned char *utf8); -unsigned char *make_utf8_string(const wchar_t *unicode); -#ifdef _UNICODE -#define make_tchar_string make_unicode_string -// Helpers for strings that only can contain 7bit chars to not make unneccessary memory allocation -#define make_nonutf_tchar_string(x) make_tchar_string(x) -#define free_nonutf_tchar_string(x) if(x) free(x); -#else -char *make_tchar_string(const unsigned char *utf8); -#define make_nonutf_tchar_string(x) (char*)x -#define free_nonutf_tchar_string(x) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __UTF8_H */ diff --git a/protocols/SkypeClassic/util.cpp b/protocols/SkypeClassic/util.cpp deleted file mode 100644 index ce5ad9c756..0000000000 --- a/protocols/SkypeClassic/util.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include - -char * __cdecl strtok_r ( - char * string, - const char * control, - char **nextoken - ) -{ - unsigned char *str; - const unsigned char *ctrl = (const unsigned char*)control; - - unsigned char map[32]; - int count; - - /* Clear control map */ - for (count = 0; count < 32; count++) - map[count] = 0; - - /* Set bits in delimiter table */ - do { - map[*ctrl >> 3] |= (1 << (*ctrl & 7)); - } while (*ctrl++); - - /* Initialize str. If string is NULL, set str to the saved - * pointer (i.e., continue breaking tokens out of the string - * from the last strtok call) */ - if (string) - str = (unsigned char*)string; - else - str = (unsigned char*)(*nextoken); - - /* Find beginning of token (skip over leading delimiters). Note that - * there is no token iff this loop sets str to point to the terminal - * null (*str == '\0') */ - while ( (map[*str >> 3] & (1 << (*str & 7))) && *str ) - str++; - - string = (char*)str; - - /* Find the end of the token. If it is not the end of the string, - * put a null there. */ - for ( ; *str ; str++ ) - if ( map[*str >> 3] & (1 << (*str & 7)) ) { - *str++ = '\0'; - break; - } - - /* Update nextoken (or the corresponding field in the per-thread data - * structure */ - *nextoken = (char*)str; - - /* Determine if a token has been found. */ - if ( string == (char*)str ) - return NULL; - else - return string; -} diff --git a/protocols/SkypeClassic/util.h b/protocols/SkypeClassic/util.h deleted file mode 100644 index 181f5d1878..0000000000 --- a/protocols/SkypeClassic/util.h +++ /dev/null @@ -1,7 +0,0 @@ -char * __cdecl strtok_r ( - char * string, - const char * control, - char **nextoken - ); - -void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces); diff --git a/protocols/SkypeClassic/voiceservice.cpp b/protocols/SkypeClassic/voiceservice.cpp deleted file mode 100644 index 2a22bbe86c..0000000000 --- a/protocols/SkypeClassic/voiceservice.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "skype.h" -#include "skypeapi.h" -#include "skypesvc.h" -#include "voiceservice.h" -#include - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -#include -#pragma warning (pop) - -HANDLE hVoiceNotify = NULL; -BOOL has_voice_service = FALSE; - -extern char g_szProtoName[]; - - -BOOL HasVoiceService() -{ - return has_voice_service; -} - -void NofifyVoiceService(HANDLE hContact, char *callId, int state) -{ - VOICE_CALL vc = {0}; - vc.cbSize = sizeof(vc); - vc.szModule = SKYPE_PROTONAME; - vc.id = callId; - vc.flags = VOICE_CALL_CONTACT; - vc.state = state; - vc.hContact = hContact; - NotifyEventHooks(hVoiceNotify, (WPARAM) &vc, 0); -} - -static INT_PTR VoiceGetInfo(WPARAM wParam, LPARAM lParam) -{ - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - return VOICE_SUPPORTED | VOICE_CALL_CONTACT | VOICE_CAN_HOLD; -} - -static HANDLE FindContactByCallId(char *callId) -{ - HANDLE hContact; - int iCmpRes; - for (hContact = db_find_first(); - hContact != NULL; - hContact = db_find_next(hContact)) - { - char *szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - - DBVARIANT dbv; - if (szProto != NULL - && !strcmp(szProto, SKYPE_PROTONAME) - && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 - && !db_get_s(hContact, SKYPE_PROTONAME, "CallId", &dbv)) - { - iCmpRes = strcmp(callId, dbv.pszVal); - db_free(&dbv); - if (iCmpRes == 0) return hContact; - } - } - - return NULL; -} - -static INT_PTR VoiceCall(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (db_get_s((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) - return -1; - - SkypeSend("CALL %s", dbv.pszVal); - db_free (&dbv); - - return 0; -} - -static INT_PTR VoiceAnswer(WPARAM wParam, LPARAM lParam) -{ - char *callId = (char *) wParam; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (FindContactByCallId(callId) == NULL) - return -1; - - SkypeSend("SET %s STATUS INPROGRESS", callId); - testfor("ERROR", 200); - - return 0; -} - -static INT_PTR VoiceDrop(WPARAM wParam, LPARAM lParam) -{ - char *callId = (char *) wParam; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (FindContactByCallId(callId) == NULL) - return -1; - - SkypeSend("SET %s STATUS FINISHED", callId); - - return 0; -} - -static INT_PTR VoiceHold(WPARAM wParam, LPARAM lParam) -{ - char *callId = (char *) wParam; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (FindContactByCallId(callId) == NULL) - return -1; - - SkypeSend("SET %s STATUS ONHOLD", callId); - - return 0; -} - -void VoiceServiceInit() -{ - // leecher, 26.03.2011: Did this ever work in the old versions?? - char szEvent[MAXMODULELABELLENGTH]; - - _snprintf (szEvent, sizeof(szEvent), "%s%s", SKYPE_PROTONAME, PE_VOICE_CALL_STATE); - hVoiceNotify = CreateHookableEvent( szEvent ); - CreateProtoService( PS_VOICE_GETINFO, VoiceGetInfo ); - CreateProtoService( PS_VOICE_CALL, VoiceCall ); - CreateProtoService( PS_VOICE_ANSWERCALL, VoiceAnswer ); - CreateProtoService( PS_VOICE_DROPCALL, VoiceDrop ); - CreateProtoService( PS_VOICE_HOLDCALL, VoiceHold ); -} - -void VoiceServiceExit() -{ - DestroyHookableEvent(hVoiceNotify); -} - -void VoiceServiceModulesLoaded() -{ - has_voice_service = ServiceExists(MS_VOICESERVICE_REGISTER); -} \ No newline at end of file diff --git a/protocols/SkypeClassic/voiceservice.h b/protocols/SkypeClassic/voiceservice.h deleted file mode 100644 index 0ffbd6d9ca..0000000000 --- a/protocols/SkypeClassic/voiceservice.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _VOICESERVICE_H_ -#define _VOICESERVICE_H_ - -#pragma warning (push) -#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union -#include -#pragma warning (pop) - -BOOL HasVoiceService(); -void VoiceServiceInit(); -void VoiceServiceExit(); -void VoiceServiceModulesLoaded(); -void NofifyVoiceService(HANDLE hContact, char *callId, int state) ; - - - -#endif // _VOICESERVICE_H_ - -- cgit v1.2.3