summaryrefslogtreecommitdiff
path: root/icqj_s7_sss_mod/capabilities.c
diff options
context:
space:
mode:
Diffstat (limited to 'icqj_s7_sss_mod/capabilities.c')
-rw-r--r--icqj_s7_sss_mod/capabilities.c527
1 files changed, 527 insertions, 0 deletions
diff --git a/icqj_s7_sss_mod/capabilities.c b/icqj_s7_sss_mod/capabilities.c
new file mode 100644
index 0000000..ac7b2b6
--- /dev/null
+++ b/icqj_s7_sss_mod/capabilities.c
@@ -0,0 +1,527 @@
+// ---------------------------------------------------------------------------80
+// ICQ plugin for Miranda Instant Messenger
+// ________________________________________
+//
+// Copyright 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
+// Copyright 2001,2002 Jon Keating, Richard Hughes
+// Copyright 2002,2003,2004 Martin berg, Sam Kothari, Robert Rainwater
+// Copyright 2004,2005,2006,2007 Joe Kucera
+// Copyright 2006,2007 [sss], chaos.persei, [sin], Faith Healer, Theif, nullbie
+//
+// 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.
+//
+// -----------------------------------------------------------------------------
+//
+// File name : $Source$
+// Revision : $Revision: 36 $
+// Last change on : $Date: 2007-08-05 03:45:10 +0300 (Вс, 05 авг 2007) $
+// Last change by : $Author: sss123next $
+//
+// DESCRIPTION:
+//
+// Contains helper functions to handle oscar user capabilities. Scanning and
+// adding capabilities are assumed to be more timecritical than looking up
+// capabilites. During the login sequence there could possibly be many hundred
+// scans but only a few lookups. So when you add or change something in this
+// code you must have this in mind, dont do anything that will slow down the
+// adding process too much.
+//
+// -----------------------------------------------------------------------------
+
+#include "icqoscar.h"
+
+
+// -----------------------------------------------------------------------------
+const capstr capSrvRelay = {CAP_SRV_RELAY};
+const capstr capNewCap = {CAP_NEWCAP};
+const capstr capUTF = {CAP_UTF};
+const capstr capTyping = {CAP_TYPING};
+const capstr capXtraz = {CAP_XTRAZ};
+const capstr capAimFile = {CAP_AIM_FILE};
+const capstr capPush2Talk = {CAP_PUSH2TALK};
+// this is defined among all clients caps
+//const capstr capIcqLite = {CAP_ICQ_LITE};
+const capstr capRTF = {CAP_RTF};
+const capstr capXtrazChat = {CAP_XTRAZ_CHAT};
+const capstr capVoiceChat = {CAP_VOICE_CHAT};
+const capstr capIcqDevil = {CAP_ICQ_DEVIL};
+const capstr capDirect = {CAP_DIRECT};
+// -----------------------------------------------------------------------------
+const capstr capMirandaIm = {'M', 'i', 'r', 'a', 'n', 'd', 'a', 'M', 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capMirandaMobile = {'M', 'i', 'r', 'a', 'n', 'd', 'a', 'M', 'o', 'b', 'i', 'l', 'e', 0, 0, 0}; //port by Nullbie
+const capstr capMimPack = {'M', 'I', 'M', '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capIcqJs7 = {'i', 'c', 'q', 'j', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capIcqJp = {'i', 'c', 'q', 'p', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capIcqJs7s = {'i', 'c', 'q', 'j', 0, 'S', 'e', 'c', 'u', 'r', 'e', 0, 'I', 'M', 0, 0};
+const capstr capIcqJs7old = {0x69, 0x63, 0x71, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capIcqJSin = {'s', 'i', 'n', 'j', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Miranda ICQJ S!N
+const capstr capIcqJen = {'e', 'n', 'q', 'j', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // eternity mod (mod of mod of mod of mod of mod)
+const capstr capAimOscar = {'M', 'i', 'r', 'a', 'n', 'd', 'a', 'A', 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capTrillian = {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09};
+const capstr capTrilCrypt = {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb, 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00};
+const capstr capSim = {'S', 'I', 'M', ' ', 'c', 'l', 'i', 'e', 'n', 't', ' ', ' ', 0, 0, 0, 0};
+const capstr capSimOld = {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x00};
+const capstr capLicq = {'L', 'i', 'c', 'q', ' ', 'c', 'l', 'i', 'e', 'n', 't', ' ', 0, 0, 0, 0};
+const capstr capKopete = {'K', 'o', 'p', 'e', 't', 'e', ' ', 'I', 'C', 'Q', ' ', ' ', 0, 0, 0, 0};
+const capstr capmIcq = {'m', 'I', 'C', 'Q', ' ', 0xA9, ' ', 'R', '.', 'K', '.', ' ', 0, 0, 0, 0};
+const capstr capClimm = {'c', 'l', 'i', 'm', 'm', 0xA9, ' ', 'R', '.', 'K', '.', ' ', 0, 0, 0, 0};
+const capstr capAndRQ = {'&', 'R', 'Q', 'i', 'n', 's', 'i', 'd', 'e', 0, 0, 0, 0, 0, 0, 0};
+const capstr capRAndQ = {'R', '&', 'Q', 'i', 'n', 's', 'i', 'd', 'e', 0, 0, 0, 0, 0, 0, 0};
+const capstr capmChat = {'m', 'C', 'h', 'a', 't', ' ', 'i', 'c', 'q', ' ', 0, 0, 0, 0, 0, 0};
+const capstr capJimm = {'J', 'i', 'm', 'm', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capCorePager = {'C', 'O', 'R', 'E', ' ', 'P', 'a', 'g', 'e', 'r', 0, 0, 0, 0, 0, 0};
+const capstr capDiChat = {'D', '[', 'i', ']', 'C', 'h', 'a', 't', ' ', 0, 0, 0, 0, 0, 0, 0};
+const capstr capNaim = {0xFF, 0xFF, 0xFF, 0xFF, 'n', 'a', 'i', 'm', 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capAnastasia = {0x44, 0xE5, 0xBF, 0xCE, 0xB0, 0x96, 0xE5, 0x47, 0xBD, 0x65, 0xEF, 0xD6, 0xA3, 0x7E, 0x36, 0x02};
+const capstr capQip = {0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', '2', '0', '0', '5', 'a'};
+const capstr capQipPDA = {0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', ' ', ' ', ' ', ' ', '!'};
+const capstr capQipMobile = {0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', ' ', ' ', ' ', ' ', '"'};
+const capstr capQipInfium = {0x7C, 0x73, 0x75, 0x02, 0xC3, 0xBE, 0x4F, 0x3E, 0xA6, 0x9F, 0x01, 0x53, 0x13, 0x43, 0x1E, 0x1A};
+const capstr capQipPlugins ={0x7c, 0x53, 0x3f, 0xfa, 0x68, 0x00, 0x4f, 0x21, 0xbc, 0xfb, 0xc7, 0xd2, 0x43, 0x9a, 0xad, 0x31}; //QIP Plugins
+const capstr capQip_1 = {0xd3, 0xd4, 0x53, 0x19, 0x8b, 0x32, 0x40, 0x3b, 0xac, 0xc7, 0xd1, 0xa9, 0xe2, 0xb5, 0x81, 0x3e}; // QIP-ProtectMsg (now use for fake id only)
+const capstr capQipSymbian = {0x51, 0xad, 0xd1, 0x90, 0x72, 0x04, 0x47, 0x3d, 0xa1, 0xa1, 0x49, 0xf4, 0xa3, 0x97, 0xa4, 0x1f};
+const capstr capVmICQ = {0x56, 0x6d, 0x49, 0x43, 0x51, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capSmapeR = {'S', 'm', 'a', 'p', 'e', 'r', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capIMPlus = {0x8e, 0xcd, 0x90, 0xe7, 0x4f, 0x18, 0x28, 0xf8, 0x02, 0xec, 0xd6, 0x18, 0xa4, 0xe9, 0xde, 0x68};
+const capstr capYapp = {0x59, 0x61, 0x70, 0x70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Yapp
+const capstr capIm2 = {0x74, 0xED, 0xC3, 0x36, 0x44, 0xDF, 0x48, 0x5B, 0x8B, 0x1C, 0x67, 0x1A, 0x1F, 0x86, 0x09, 0x9F}; // IM2 Ext Msg
+const capstr capMacIcq = {0xdd, 0x16, 0xf2, 0x02, 0x84, 0xe6, 0x11, 0xd4, 0x90, 0xdb, 0x00, 0x10, 0x4b, 0x9b, 0x4b, 0x7d};
+const capstr capIs2001 = {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8, 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf};
+const capstr capIs2002 = {0x10, 0xcf, 0x40, 0xd1, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capComm20012 = {0xa0, 0xe9, 0x3f, 0x37, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capStrIcq = {0xa0, 0xe9, 0x3f, 0x37, 0x4f, 0xe9, 0xd3, 0x11, 0xbc, 0xd2, 0x00, 0x04, 0xac, 0x96, 0xdd, 0x96};
+const capstr capAimIcon = {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}; // CAP_AIM_BUDDYICON
+const capstr capAimDirect = {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}; // CAP_AIM_DIRECTIM
+const capstr capAimFileShare = {0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}; // CAP_AIM_FILE_SHARE
+const capstr capIcqLite = {0x17, 0x8C, 0x2D, 0x9B, 0xDA, 0xA5, 0x45, 0xBB, 0x8D, 0xDB, 0xF3, 0xBD, 0xBD, 0x53, 0xA1, 0x0A};
+const capstr capAimChat = {0x74, 0x8F, 0x24, 0x20, 0x62, 0x87, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capUim = {0xA7, 0xE4, 0x0A, 0x96, 0xB3, 0xA0, 0x47, 0x9A, 0xB8, 0x45, 0xC9, 0xE4, 0x67, 0xC5, 0x6B, 0x1F};
+const capstr capRambler = {0x7E, 0x11, 0xB7, 0x78, 0xA3, 0x53, 0x49, 0x26, 0xA8, 0x02, 0x44, 0x73, 0x52, 0x08, 0xC4, 0x2A};
+const capstr capAbv = {0x00, 0xE7, 0xE0, 0xDF, 0xA9, 0xD0, 0x4F, 0xe1, 0x91, 0x62, 0xC8, 0x90, 0x9A, 0x13, 0x2A, 0x1B};
+const capstr capNetvigator= {0x4C, 0x6B, 0x90, 0xA3, 0x3D, 0x2D, 0x48, 0x0E, 0x89, 0xD6, 0x2E, 0x4B, 0x2C, 0x10, 0xD9, 0x9F};
+const capstr captZers = {0xb2, 0xec, 0x8f, 0x16, 0x7c, 0x6f, 0x45, 0x1b, 0xbd, 0x79, 0xdc, 0x58, 0x49, 0x78, 0x88, 0xb9}; // CAP_TZERS
+const capstr capHtmlMsgs = {0x01, 0x38, 0xca, 0x7b, 0x76, 0x9a, 0x49, 0x15, 0x88, 0xf2, 0x13, 0xfc, 0x00, 0x97, 0x9e, 0xa8}; // icq6 html msgs
+const capstr capLiveVideo = {0x09, 0x46, 0x01, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}; // icq6 live video
+const capstr capSimpLite = {0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50};
+const capstr capSimpPro = {0x53, 0x49, 0x4D, 0x50, 0x5F, 0x50, 0x52, 0x4F, 0x53, 0x49, 0x4D, 0x50, 0x5F, 0x50, 0x52, 0x4F};
+const capstr capIMsecure = {'I', 'M', 's', 'e', 'c', 'u', 'r', 'e', 'C', 'p', 'h', 'r', 0x00, 0x00, 0x06, 0x01}; // ZoneLabs
+const capstr capMsgType2 = {0x09, 0x49, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capAimIcq = {0x09, 0x46, 0x13, 0x4D, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capAimVoice = {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capAimAudio = {0x09, 0x46, 0x01, 0x04, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}; //added to ICQ 6 & AIM 6
+const capstr capPalmJicq = {'J', 'I', 'C', 'Q', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capInluxMsgr = {0xA7, 0xE4, 0x0A, 0x96, 0xB3, 0xA0, 0x47, 0x9A, 0xB8, 0x45, 0xC9, 0xE4, 0x67, 0xC5, 0x6B, 0x1F};
+const capstr capMipClient = {0x4D, 0x49, 0x50, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const capstr capIMadering = {'I', 'M', 'a', 'd', 'e', 'r', 'i', 'n', 'g', ' ', 'C', 'l', 'i', 'e', 'n', 't'};
+//AIM Client version 5.9 capabilities
+const capstr capAimAddins = {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capAimContactSnd= {0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capAimUnk2 = {0x09, 0x46, 0x01, 0x02, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00};
+const capstr capAimSendbuddylist = {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x13, 0x4B};
+//
+const capstr capIMSecKey1 = {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ZoneLabs
+const capstr capIMSecKey2 = {2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ZoneLabs
+const capstr capUnknown1 = {0x17, 0x8c, 0x2d,0x9b, 0xda, 0xa5, 0x45, 0xbb, 0x8d, 0xdb, 0xf3, 0xbd, 0xbd, 0x53, 0xa1,0x0a};
+
+// -----------------------------------------------------------------------------
+
+typedef struct icq_capability_s
+{
+ DWORD fdwMirandaID; // A bitmask, we use it in order to save database space
+ const BYTE *CapCLSID; // A binary representation of a oscar capability
+} icq_capability;
+
+static icq_capability CapabilityRecord[] =
+{
+ {CAPF_SRV_RELAY, capSrvRelay},
+ {CAPF_UTF, capUTF},
+ {CAPF_TYPING, capTyping},
+ {CAPF_XTRAZ, capXtraz},
+ {CAPF_AIM_FILE, capAimFile},
+ {CAPF_PUSH2TALK, capPush2Talk},
+ {CAPF_ICQ_LITE, capIcqLite},
+ {CAPF_RTF, capRTF},
+ {CAPF_XTRAZ_CHAT, capXtrazChat},
+ {CAPF_VOICE_CHAT, capVoiceChat},
+ {CAPF_ICQ_DEVIL, capIcqDevil},
+ {CAPF_DIRECT, capDirect},
+};
+
+// Deletes all oscar capabilities for a given contact
+void ClearAllContactCapabilities(HANDLE hContact)
+{
+ ICQWriteContactSettingDword(hContact, DBSETTING_CAPABILITIES, 0);
+}
+
+
+
+// Deletes one or many oscar capabilities for a given contact
+void ClearContactCapabilities(HANDLE hContact, DWORD fdwCapabilities)
+{
+ DWORD fdwContactCaps;
+
+
+ // Get current capability flags
+ fdwContactCaps = ICQGetContactSettingDword(hContact, DBSETTING_CAPABILITIES, 0);
+
+ // Clear unwanted capabilities
+ fdwContactCaps &= ~fdwCapabilities;
+
+ // And write it back to disk
+ ICQWriteContactSettingDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
+}
+
+
+
+// Sets one or many oscar capabilities for a given contact
+void SetContactCapabilities(HANDLE hContact, DWORD fdwCapabilities)
+{
+ DWORD fdwContactCaps;
+
+
+ // Get current capability flags
+ fdwContactCaps = ICQGetContactSettingDword(hContact, DBSETTING_CAPABILITIES, 0);
+
+ // Update them
+ fdwContactCaps |= fdwCapabilities;
+
+ // And write it back to disk
+ ICQWriteContactSettingDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
+}
+
+
+
+// Returns true if the given contact supports the requested capabilites
+BOOL CheckContactCapabilities(HANDLE hContact, DWORD fdwCapabilities)
+{
+ DWORD fdwContactCaps;
+
+
+ // Get current capability flags
+ fdwContactCaps = ICQGetContactSettingDword(hContact, DBSETTING_CAPABILITIES, 0);
+
+ // Check if all requested capabilities are supported
+ if ((fdwContactCaps & fdwCapabilities) == fdwCapabilities)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+
+// Scans a binary buffer for oscar capabilities and adds them to the contact.
+// You probably want to call ClearAllContactCapabilities() first.
+void AddCapabilitiesFromBuffer(HANDLE hContact, BYTE* pbyBuffer, int nLength)
+{
+ DWORD fdwContactCaps;
+ int iCapability;
+ int nIndex;
+ int nRecordSize;
+
+
+ // Calculate the number of records
+ nRecordSize = sizeof(CapabilityRecord)/sizeof(icq_capability);
+
+ // Get current capability flags
+ fdwContactCaps = ICQGetContactSettingDword(hContact, DBSETTING_CAPABILITIES, 0);
+
+ // Loop over all capabilities in the buffer and
+ // compare them to our own record of capabilities
+ for (iCapability = 0; (iCapability + BINARY_CAP_SIZE) <= nLength; iCapability += BINARY_CAP_SIZE)
+ {
+ BOOL knownCAP = FALSE;
+ for (nIndex = 0; nIndex < nRecordSize; nIndex++)
+ {
+ if (!memcmp(pbyBuffer + iCapability, CapabilityRecord[nIndex].CapCLSID, BINARY_CAP_SIZE))
+ {
+ // Match
+ fdwContactCaps |= CapabilityRecord[nIndex].fdwMirandaID;
+ knownCAP = TRUE;
+ break;
+ }
+ }
+ if(!knownCAP) {
+ char szCap[64];
+ int i;
+ for (i = 0; i < 16; i++)
+ wsprintf(szCap+i*3, " %02X", (BYTE)((BYTE*)(pbyBuffer + iCapability)[i]));
+ Netlib_Logf(ghServerNetlibUser, "Found unknown CAP%s", szCap);
+ }
+ }
+
+ // And write it back to disk
+ ICQWriteContactSettingDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
+}
+
+// Pack binary caps to output buffer
+void AddCapabilitiesToBuffer(BYTE* packet, DWORD fdwContactCaps)
+{
+ int iCapability = 0;
+ int nIndex;
+ int nRecordSize;
+
+ nRecordSize = sizeof(CapabilityRecord)/sizeof(icq_capability);
+
+ for (nIndex = 0; nIndex < nRecordSize; nIndex++)
+ {
+ if(CapabilityRecord[nIndex].fdwMirandaID & fdwContactCaps)
+ {
+ packBuffer(( icq_packet*)packet, CapabilityRecord[nIndex].CapCLSID, BINARY_CAP_SIZE);
+ }
+ }
+}
+
+
+typedef struct tagSTDCAPINFO
+{
+ const char *name;
+ int type;
+ const BYTE *caps;
+ int capSize;
+} STDCAPINFO;
+
+STDCAPINFO stdCapInfo[] = {
+ {"ServerRelay", 0, capSrvRelay, 16},
+ {"NewCaps support", 0, capNewCap, 16},
+ {"Aim support", 0, capAimIcq, 16},
+ {"UTF8 Messages", 0, capUTF, 16},
+ {"Typing Notifications", 0, capTyping, 16},
+ {"ICQ Xtraz", 0, capXtraz, 16},
+ {"File Transfer (AIMFile)", 0, capAimFile, 16},
+ {"Push2Talk", 0, capPush2Talk, 16},
+ {"ICQ Lite", 0, capIcqLite, 16},
+ {"RTF Messages", 0, capRTF, 16},
+ {"Xtraz Chat", 0, capXtrazChat, 16},
+ {"Voice Chat", 0, capVoiceChat, 16},
+ {"Avatars (ICQDevil)", 0, capIcqDevil, 16},
+ {"Direct Connections", 0, capDirect, 16},
+ {"Miranda IM", 0, capMirandaIm, 8},
+ {"Miranda IM Mobile", 0, capMirandaMobile, 13},
+ {"Miranda IM Custom Pack", 0, capMimPack, 4},
+ {"Miranda ICQJ eternity/PlusPlus++", 0, capIcqJen, 4},
+ {"Miranda ICQJ S7&SSS OLD", 0, capIcqJs7old, 16},
+ {"Miranda ICQJ S7&SSS + SecureIM", 0, capIcqJs7s, 16},
+ {"Miranda ICQJ S7&SSS", 0, capIcqJs7, 4},
+ {"Miranda ICQJ Plus", 0, capIcqJp, 4},
+ {"Miranda ICQJ S!N", 0, capIcqJSin, 4},
+ {"AIM Oscar", 0, capAimOscar, 8},
+ {"IMadering Client", 0, capIMadering, 0x10},
+ {"Trillian", 0, capTrillian, 16},
+ {"Trillian Crypt", 0, capTrilCrypt, 16},
+ {"SIM", 0, capSim, 0xC},
+ {"SIM (old)", 0, capSimOld, 0xF},
+ {"Licq", 0, capLicq, 0xC},
+ {"Kopete", 0, capKopete, 0xC},
+ {"mIcq", 0, capmIcq, 0xC},
+ {"&RQ", 0, capAndRQ, 9},
+ {"R&Q", 0, capRAndQ, 9},
+ {"mChat", 0, capmChat, 0xA},
+ {"Jimm", 0, capJimm, 5},
+ {"Yapp", 0, capYapp, 4},
+ {"Naim", 0, capNaim, 8},
+ {"Anastacia", 0, capAnastasia, 16},
+ {"JICQ", 0, capPalmJicq, 16},
+ {"Inlux Messenger", 0, capInluxMsgr, 16},
+ {"MIP Client", 0, capMipClient, 0xC},
+ {"QIP 2005", 0, capQip, 16},
+ {"QIP Infium", 0, capQipInfium, 16},
+ {"QIP Infium Plugins", 0, capQipPlugins, 16},
+ {"QIP PDA", 0, capQipPDA, 16},
+ {"QIP Mobile (Java)", 0, capQipMobile, 16},
+ {"QIP Mobile (Symbian)", 0, capQipSymbian, 16},
+ {"VmICQ (Symbian)", 0, capVmICQ, 6},
+ {"QIP-ProtectMsg", 0, capQip_1, 16},
+ {"IM2", 0, capIm2, 16},
+ {"ICQ for Mac", 0, capMacIcq, 16},
+ {"ICQ 2001", 0, capIs2001, 16},
+ {"ICQ 2002", 0, capIs2002, 16},
+ {"Comm20012", 0, capComm20012, 16},
+ {"StrICQ", 0, capStrIcq, 16},
+ {"AIM Buddy Icon", 0, capAimIcon, 16}, // CAP_AIM_BUDDYICON
+ {"AIM Direct IM", 0, capAimDirect, 16}, // CAP_AIM_DIRECTIM
+ {"AIM Send Buddy List", 0, capAimSendbuddylist, 16},
+ {"AIM Send Contact", 0, capAimContactSnd,16},
+ {"ICQ Lite", 0, capIcqLite, 16},
+ {"AIM Chat", 0, capAimChat, 16},
+ {"UIM", 0, capUim, 16},
+ {"Rambler ICQ", 0, capRambler, 16},
+ {"ABV ICQ", 0, capAbv, 16},
+ {"Netvigator ICQ", 0, capNetvigator, 16},
+ {"tZers", 0, captZers, 16}, // CAP_TZERS
+ {"ICQ 6 (HTML msgs)", 0, capHtmlMsgs, 16}, // icq6
+ {"Live Video", 0, capLiveVideo, 16},
+ {"Simp Lite", 0, capSimpLite, 16},
+ {"Simp Pro", 0, capSimpPro, 16},
+ {"IMsecure (ZoneLabs)", 0, capIMsecure, 16}, // ZoneLabs
+ {"Messages Type 2 support", 0, capMsgType2, 16},
+ {"Aim Voice Chat", 0, capAimVoice, 16},
+ {"Live Audio(new VoiceChat)", 0, capAimAudio, 16},
+ {"climm client", 0, capClimm, 0xC},
+ {"IM+ Client", 0, capIMPlus, 16},
+ {"mChct Client", 0, capmChat, 0xA},
+ {"SmapeR Client", 0, capSmapeR, 0x07},
+ {"CORE Pager Client", 0, capCorePager, 0xA},
+ {"Zone Alarm IMsecure key 1", 0, capIMSecKey1, 5},
+ {"Zone Alarm IMsecure key 2", 0, capIMSecKey2, 5}
+};
+
+char *GetCapabilityName(BYTE *cap, ICQ_CAPINFO *info)
+{
+ static char capabilityName[256];
+ int i;
+ BOOL found;
+ char *ptr;
+
+ if (info)
+ {
+ ptr = info->caps;
+ *ptr++ = '{';
+ for (i = 0; i < 0x10; ++i)
+ {
+ wsprintf(ptr, "0x%.2x%s", cap[i], ((i==0x0F)?"":", "));
+ ptr += 4;
+ ptr += ((i==0x0F)?0:2);
+ }
+ *ptr++ = '}';
+ *ptr = 0;
+ }
+
+ ptr = capabilityName;
+ found = FALSE;
+ for (i = 0; i < sizeof(stdCapInfo)/(sizeof(*stdCapInfo)); ++i)
+ if (!memcmp(stdCapInfo[i].caps, cap, stdCapInfo[i].capSize))
+ {
+ lstrcpyA(ptr, "01. "); ptr += 4;
+ lstrcpyA(ptr, stdCapInfo[i].name);
+ ptr += lstrlen(stdCapInfo[i].name);
+ if (info)
+ {
+ info->type = 1;
+ info->hIcon = NULL;
+ lstrcpyA(info->name, stdCapInfo[i].name);
+ }
+ found = TRUE;
+ break;
+ }
+ for (i = 0; i < sizeof(capXStatus)/(sizeof(*capXStatus)); ++i)
+ if (!memcmp(capXStatus[i], cap, 0x10))
+ {
+ lstrcpyA(ptr, "01. "); ptr += 4;
+ lstrcpyA(ptr, "XStatus: ");
+ ptr += lstrlen("XStatus: ");
+ lstrcpyA(ptr, nameXStatus[i]);
+ ptr += lstrlen(nameXStatus[i]);
+ if (info)
+ {
+ info->type = 1;
+ info->hIcon = NULL;
+ lstrcpyA(info->name, capabilityName+4);
+ }
+ found = TRUE;
+ break;
+ }
+ if (!found)
+ {
+ for (i = 0; i < lstCustomCaps->realCount; ++i)
+ if (!memcmp(((ICQ_CUSTOMCAP *)(lstCustomCaps->items[i]))->caps, cap, BINARY_CAP_SIZE))
+ {
+ lstrcpyA(ptr, "02. "); ptr += 4;
+ lstrcpyA(ptr, ((ICQ_CUSTOMCAP *)(lstCustomCaps->items[i]))->name);
+ ptr += lstrlen(((ICQ_CUSTOMCAP *)(lstCustomCaps->items[i]))->name);
+ if (info)
+ {
+ info->type = 2;
+ info->hIcon = NULL;
+ lstrcpyA(info->name, ((ICQ_CUSTOMCAP *)(lstCustomCaps->items[i]))->name);
+ }
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ int nAlpha = 0;
+ for (i = 0; i < 0x10; ++i)
+ if ((cap[i] >= 0x20) && (cap[i] <= 0x7e) || (cap[i] == 0x99))
+ {
+ if ((cap[i] >= '0') && (cap[i] <= '9') || (cap[i] >= 'a') && (cap[i] <= 'z') || (cap[i] >= 'A') && (cap[i] <= 'Z'))
+ ++nAlpha;
+ if (!found)
+ {
+ lstrcpyA(ptr, "00. ");
+ ptr += 4;
+ }
+ *ptr++ = cap[i];
+ found = TRUE;
+ }
+ *ptr = 0;
+ if (found)
+ {
+ if (!strncmp(capabilityName+4, "Miranda/", 8))
+ {
+ capabilityName[1] = '3';
+ if (info)
+ {
+ info->type = 3;
+ info->hIcon = NULL;
+ }
+ lstrcpyA(info->name, capabilityName+4);
+ } else
+ if (nAlpha > 4)
+ {
+ capabilityName[1] = '4';
+ if (info)
+ {
+ info->type = 4;
+ info->hIcon = NULL;
+ }
+ lstrcpyA(info->name, capabilityName+4);
+ } else
+ {
+ found = FALSE;
+ ptr = capabilityName;
+ }
+ }
+ }
+ if (!found)
+ {
+ lstrcpyA(ptr, "05. "); ptr += 4;
+ if (info)
+ {
+ info->type = 5;
+ lstrcpyA(ptr, info->caps);
+ ptr += lstrlenA(info->caps);
+ lstrcpyA(info->name, info->caps);
+ } else
+ {
+ info->type = 5;
+ *ptr++ = '{';
+ for (i = 0; i < 0x10; ++i)
+ {
+ wsprintf(ptr, "0x%.2x%s", cap[i], ((i==0x0F)?"":", "));
+ ptr += 4;
+ ptr += ((i==0x0F)?0:2);
+ }
+ *ptr++ = '}';
+ *ptr = 0;
+ }
+ }
+ *ptr = 0;
+ return capabilityName;
+}