{ Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2009 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. 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. } {$IFNDEF M_PROTOSVC} {$DEFINE M_PROTOSVC} { ***** Unicode Services note ******** ****************************************** Only new style protocols (Miranda 0.9+) with m_iVersion set to 2 or higher support Unicode services documented below, all other support only ANSI. For all other that do not support Unicode services, Miranda core will convert Unicode to ANSI and call the appropriate service. } type // PFNAMECHAR = ^FNAMECHAR; //#if MIRANDA_VER >= 0x0900 FNAMECHAR = TCHAR; //#else // FNAMECHAR = AnsiChar; //#endif TFNAMECHAR = FNAMECHAR; {<</ none of these services should be used on there own (i.e. using CallService(), etc) hence the PS_ prefix, instead use the services exposed in m_protocols.inc these should be called with CallProtoService which prefixes the protocol module name before calling. - Deleting contacts from protocols that store the contact list on the server: If a contact is deleted while the protocol is online, it is expected that the protocol will have hooked me_db_contact_deleted and take the appropriate action by itself. If a contact is deleted while the protocol is offline, the contact list will display a message to the user about the problem, and set the byte setting "CList"/"Delete" to 1. Each time such a protocol changes status from offline or connecting to online the contact list will check for contacts with this flag set and delete them at that time. Your hook for me_db_contact_deleted will pick this up and everything will be good. />>} const PFLAGNUM_1 = $1; PF1_IMSEND = $00000001; // supports IM sending PF1_IMRECV = $00000002; // supports IM receiving PF1_IM = (PF1_IMSEND or PF1_IMRECV); PF1_URLSEND = $00000004; // supports separate URL sending PF1_URLRECV = $00000008; // supports separate URL receiving PF1_URL = (PF1_URLSEND or PF1_URLRECV); PF1_FILESEND = $00000010; // supports file sending PF1_FILERECV = $00000020; // supports file receiving PF1_FILE = (PF1_FILESEND or PF1_FILERECV); PF1_MODEMSGSEND = $00000040; // supports broadcasting away messages PF1_MODEMSGRECV = $00000080; // supports reading others' away messages PF1_MODEMSG = (PF1_MODEMSGSEND or PF1_MODEMSGRECV); PF1_SERVERCLIST = $00000100; // contact lists are stored on the server, not locally. See notes below PF1_AUTHREQ = $00000200; // will get authorisation requests for some or all contacts PF1_ADDED = $00000400; // will get 'you were added' notifications PF1_VISLIST = $00000800; // has an invisible list PF1_INVISLIST = $00001000; // has a visible list for when in invisible mode PF1_INDIVSTATUS = $00002000; // supports setting different status modes to each contact PF1_EXTENSIBLE = $00004000; // the protocol is extensible and supports plugin-defined messages PF1_PEER2PEER = $00008000; // supports direct (not server mediated) communication between clients PF1_NEWUSER = $00010000; // supports creation of new user IDs PF1_CHAT = $00020000; // has a realtime chat capability PF1_INDIVMODEMSG = $00040000; // supports replying to a mode message request with different text depending on the contact requesting PF1_BASICSEARCH = $00080000; // supports a basic user searching facility PF1_EXTSEARCH = $00100000; // supports one or more protocol-specific extended search schemes PF1_CANRENAMEFILE = $00200000; // supports renaming of incoming files as they are transferred PF1_FILERESUME = $00400000; // can resume broken file transfers, see PS_FILERESUME below PF1_ADDSEARCHRES = $00800000; // can add search results to the contact list PF1_CONTACTSEND = $01000000; // can send contacts to other users PF1_CONTACTRECV = $02000000; // can receive contacts from other users PF1_CONTACT = (PF1_CONTACTSEND or PF1_CONTACTRECV); PF1_CHANGEINFO = $04000000; // can change our user information stored on server PF1_SEARCHBYEMAIL = $08000000; // supports a search by e-mail feature PF1_USERIDISEMAIL = $10000000; // set if the uniquely identifying field of the network is the e-mail address PF1_SEARCHBYNAME = $20000000; // supports searching by nick/first/last names PF1_EXTSEARCHUI = $40000000; // has a dialog box to allow searching all the possible fields PF1_NUMERICUSERID = $80000000; // the unique user IDs for this protocol are numeric PFLAGNUM_2 = 2; // the status modes that the protocol supports PF2_ONLINE = $00000001; // an unadorned online mode PF2_INVISIBLE = $00000002; PF2_SHORTAWAY = $00000004; // Away on ICQ, BRB on MSN PF2_LONGAWAY = $00000008; // NA on ICQ, Away on MSN PF2_LIGHTDND = $00000010; // Occupied on ICQ, Busy on MSN PF2_HEAVYDND = $00000020; // DND on ICQ PF2_FREECHAT = $00000040; PF2_OUTTOLUNCH = $00000080; PF2_ONTHEPHONE = $00000100; PF2_IDLE = $00000200; //added during 0.3.4 (2004/09/13) PFLAGNUM_3 = 3; //the status modes that the protocol supports //away-style messages for. Uses the PF2_ flags. PFLAGNUM_4 = 4; // v0.3+: flag asking a protocol plugin how auths are handled PF4_FORCEAUTH = $00000001; // protocol has to send auth's for things to work PF4_FORCEADDED = $00000002; // protocol has to tell people that they were added (otherwise things don't work) PF4_NOCUSTOMAUTH = $00000004; // protocol can't send a custom message while asking others for auth PF4_SUPPORTTYPING = $00000008; // protocol supports user is typing messages v0.3.3+ PF4_SUPPORTIDLE = $00000010; // protocol understands idle, added during v0.3.4+ (2004/09/13) PF4_AVATARS = $00000020; // protocol has avatar support, added during v0.3.4 (2004/09/13) PF4_OFFLINEFILES = $00000040; // protocols supports sending files to offline users (v0.5.2) PF4_IMSENDUTF = $00000080; // protocol is able to process messages in utf-8 (v.0.7.0+) PF4_IMSENDOFFLINE = $00000100; // protocol supports sending offline messages (v0.8.0+) PF4_INFOSETTINGSVC = $00000200; // protocol supports user info translation services (v0.8.0+) PF4_NOAUTHDENYREASON = $00000400; // protocol doesn't support authorization deny reason (v0.9.0+) PFLAG_UNIQUEIDTEXT = 100; // returns a static buffer of text describing the unique field by which this protocol identifies users (already translated), or NULL PFLAG_MAXCONTACTSPERPACKET = 200; // v0.1.2.2+: returns the maximum number of contacts which can be sent in a single PSS_CONTACTS. lParam=(LPARAM)hContact. PFLAG_UNIQUEIDSETTING = 300; // v0.3+: returns the DB setting name (e.g. szProto=ICQ, szSetting=UIN) that has the ID which makes this user unique on that system (0.3a ONLY), the string is statically allocated so no need to free() PFLAG_MAXLENOFMESSAGE = 400; // v0.3.2+: return the maximum length of an instant message, lParam=(LPARAM)hContact { A protocol might not support this cap, it allows a protocol to say that PFLAGNUM_2 is for statuses contacts supports, and that PFLAGNUM_5 is for statuses a protocol can SET TO ITSELF, if this is not replied to, then PFLAGNUM_2 is alone in telling you which statuses a protocol can set to and what statuses a contact can set to as well. E.g. A protocol might report 'wireless' users but a login of the protocol from Miranda can not set itself to 'wireless' so PFLAGNUM_2 would return PF2_ONTHEPHONE and PFLAGNUM_5 would return PF2_ONTHEPHONE as well, this means "I will get contacts who are on the phone but you can not set on the phone" and so on. Do note that the reply here is a NEGATION of bitflags reported for PFLAGNUM_2, e.g. returning PF2_ONTHEPHONE for PFLAGNUM_2 and returning the same for PFLAGNUM_5 says that you DO NOT SUPPORT PF2_ONTHEPHONE for the user to PS_SETSTATUS to, but you will expect other contacts to have that status, e.g. you can get onthephone for users but can't go online with onthephone. The same PF2_ status flags are used in the reply. Added during 0.3.4 (2004/09/14) } PFLAGNUM_5 = 5; // for PS_SETSTATUS LOGINERR_WRONGPASSWORD = 1; LOGINERR_NONETWORK = 2; LOGINERR_PROXYFAILURE = 3; LOGINERR_BADUSERID = 4; LOGINERR_NOSERVER = 5; LOGINERR_TIMEOUT = 6; LOGINERR_WRONGPROTOCOL = 7; LOGINERR_OTHERLOCATION = 8; // flag for PS_ADDTOLIST PALF_TEMPORARY = 1; // add the contact temporarily and invisibly, just to get user info or something // flags for PS_GETINFO SGIF_MINIMAL = 1; // get only the most basic information. This should // contain at least a Nick and e-mail. SGIF_ONOPEN = 2; // set when the User Info form is being opened // for PSR_MESSAGE PREF_CREATEREAD = 1; // create the database event with the 'read' flag set PREF_UNICODE = 2; PREF_RTL = 4; // 0.5+ addition: support for right-to-left messages PREF_UTF = 8; // message is in utf-8 (0.7.0+) // for PS_FILERESUME FILERESUME_OVERWRITE = 1; FILERESUME_RESUME = 2; FILERESUME_RENAME = 3; FILERESUME_SKIP = 4; const PSR_UNICODE = 1; type PPROTOSEARCHRESULT = ^TPROTOSEARCHRESULT; TPROTOSEARCHRESULT = record cbSize : int; nick : TFNAMECHAR; firstName: TFNAMECHAR; lastName : TFNAMECHAR; email : TFNAMECHAR; id : TFNAMECHAR; flags : int; reserved : array [0..(8*SizeOf(THANDLE) div SizeOf(dword))-1] of Byte; // Protocols may extend this structure with extra members at will and supply // a larger cbSize to reflect the new information, but they must not change // any elements above this comment // The 'reserved' field is part of the basic structure, not space to // overwrite with protocol-specific information. // If modules do this, they should take steps to ensure that information // they put there will be retained by anyone trying to save this structure. end; PPROTOSEARCHBYNAME = ^TPROTOSEARCHBYNAME; TPROTOSEARCHBYNAME = record pszNick : TChar; pszFirstName: TChar; pszLastName : TChar; end; PPROTORECVEVENT = ^TPROTORECVEVENT; TPROTORECVEVENT = record flags : DWORD; timestamp: DWORD; szMessage: TChar; lParam : LPARAM; end; PPROTORECVFILE = ^TPROTORECVFILE; TPROTORECVFILE = record flags : DWORD; timestamp : DWORD; // unix time szDescription: PAnsiChar; pFiles : ^PAnsiChar; // pointer to an array of PAnsiChar's lParam : LPARAM; end; PPROTOFILERESUME = ^TPROTOFILERESUME; TPROTOFILERESUME = record action : int; // FILERESUME_* flag szFilename: TFNAMECHAR; // full path, only valid if action=FILERESUME_RENAME end; const { wParam : PFLAGNUM_* (see above) lParam : 0 Affects: Returns a bitfield for settings corresponding to flag number, see notes Returns: a bitfield of supported features -- or 0 if flag_num is not supported Notes : this checks what sort of things are actively supported by a protocol module } PS_GETCAPS = '/GetCaps'; { wParam : cchName lParam : Pointer to a buffer to fill with human-readable name Affect : Get a human-readable name for the protocol, see notes Result : 0 on success, [non zero] on failure Notes : Should be translated before being returned, cchName has the size of the buffer, example strings: "ICQ", "AIM" } PS_GETNAME = '/GetName'; { wParam : whichIcon lParam : 0 Affect : Loads one of the protocol-sspecific icons Returns: the HICON or NULL on failure, the returned icon must be DestroyIcon()ed, the UI should overlay the online icon with further UI-specified icon to repressent the exact status mode. } PLI_PROTOCOL = $1; // An icon representing the protocol (eg the multicoloured flower for ICQ) PLI_ONLINE = $2; // Online state icon for that protocol (eg green flower for ICQ) PLI_OFFLINE = $3; // Offline state icon for that protocol (eg red flower for ICQ) PLIF_LARGE = $0; // Or with one of the above to get the large (32x32 by default) icon PLIF_SMALL = $10000; // Or with one of the above to get the small (16x16 by default) icon PLIF_ICOLIB = $20000; // the returned HICON is managed by IcoLib, DO NOT DestroyIcon() it PLIF_ICOLIBHANDLE = $40000; // the function will return IcoLib handle not HICON PS_LOADICON = '/LoadIcon'; { wParam : status_mode lParam : Pointer to a null terminated string containing message Affect : Sets the status mode specific message for the user, see notes Returns: 0 on success, [non zero] on failure Notes : This service is not available unless PF1_MODEMSGSEND is set, and PF1_INDIVMODEMSG is *not* set. If PF1_INDIVMODEMSG is set, then see PSS_AWAYMSSG for details of operations of away messages. - Protocol modules smust support lParam=NULL, it may eithere mean to use an empty message or (preferably) not to reply at all to any requests. } PS_SETAWAYMSG = '/SetAwayMsg'; PS_SETAWAYMSGW = '/SetAwayMsgW'; { wParam : newMode from statusmodes.inc lParam : 0 Affect : Change the protocol's status mode, see notes Returns: 0 on success, [non zero] on failure Notes : Will send an ack with : type=ACKTYPE_SUCCESS, result=ACKRESULT_SUCCESS, hProcess=previousMode, lParam=newMode - when the change completes. This ack is sent for all changes, not just ones caused by calling this function. - NewMode can be ID_STATUS_CONNECTING<=newMode<ID_STATUS_CONNECTING+ MAX_CONNECT_RETRIES to signify that it's connecting and it's the nth retry. - Protocols are initially always in offline mode, if a protocol doesn't support a specific status mode, it should pick the closest ones that it does support, and change to that. If a protocol has to switch from offline mode to online (or a substate of online, like away) then it should report any errors in the form of an additional ack : type=ACKTYPE_LOGIN, result=ACKRESULT_FAILURE, hProcess=NULL, lParam=LOGINERR_* SetStatus() is called when a protocol module is first loaded with newMode=ID_STATUS_ONLINE. - Protocols can define their own LOGINERR_* starting at $1000, see LOGINERR_* above } PS_SETSTATUS = '/SetStatus'; { wParam : 0 lParam : 0 Affect : Get the status mode that a protocol is currently in, see notes Returns: The current status mode Notes : Only protocol modules need to implement this, non network level protocol modules do not need to (but if you register as a protocol you need to, Miranda will GPF otherwise) } PS_GETSTATUS = '/GetStatus'; { wParam : HDBEVENT lParam : 0 Affect : allow 'somebody' to add the user to their contact list, see notes Returns: 0 on success, [non zero] on failure Notes : Auth request come in the form of an event added to the database for the NULL(0) user, the form is: - protocolSpecific: DWORD; nick, firstname, lastName, e-mail, requestReason: ASCIIZ; - HDBEVENT musts be the handle of such an event, one or more fields may be empty if the protocol doesn't support them } PS_AUTHALLOW = '/Authorize'; { wParam : HDBEVENT lParam : TChar - Reason Affect : Deny an authorisation request Returns: 0 on success, [non zero] on failure Notes : Protocol modules must be able to cope with lParam=NULL(0) } PS_AUTHDENY = '/AuthDeny'; PS_AUTHDENYW = '/AuthDenyW'; { Send a "You were added" event wParam=lParam=0 Returns 0 on success, nonzero on failure } PSS_ADDED = '/YouWereAdded'; { Create account manager UI form wParam=0 lParam=(LPARAM)(HWND)hwndAccMgr Returns handle on newly created form. Size for best fit is 186x134 DLUs, please avoid groupboxes paddind and advanced options. This should provide minimal setup for initial connect. } PS_CREATEACCMGRUI = '/CreateAccMgrUI'; { wParam : 0 lParam : Pointer to a null terminated string containing an ID to search for Affect : Send a basic search request, see notes Returns: A handle to the search request or NULL(0) on failure Notes : All protocols identify users uniquely by a single field this service will search by that field. - All search replies (even protocol-spec extended searches) are replied by a series of ack's,- - Result acks are a series of: type=ACKTYPE_SEARCH, result=ACKRESULT_DATA, lParam=Pointer to a TPROTOSEARCHRESULT structure - ending ack: type=ACKTYPE_SEARCH, result=ACKRESULT_SUCCESS, lParam=0 - The pointers in the structure are not guaranteed to be valid after the ack is complete. - The structure to reply with search results can be extended per protocol basis (see below) } PS_BASICSEARCH = '/BasicSearch'; PS_BASICSEARCHW = '/BasicSearchW'; { wParam : 0 lParam : Pointer to a NULL terminated string containing the e-mail to search for Affect : Search for user(s) by e-mail address, see notes Returns: A HANDLE to the search, or NULL(0) on failure Notes : Results are returned as for PS_BASICSEARCH, this service is only available if the PF1_USERIDISEMAIL flag is set for caps -- - This service with the above service should be mapped to the same function if the aforementioned flag is set. Version: v0.1.2.1+ } PS_SEARCHBYEMAIL = '/SearchByEmail'; PS_SEARCHBYEMAILW = '/SearchByEmailW'; { wParam : 0 lParam : Pointer to a TPROTOSEARCHBYNAME structure Affect : Search for users by name, see notes Returns: Handle to the search, NULL(0) on failure Notes : this service is only available, if PF1_SEARCHBYNAME capability is set. Results are returned in the same manner as PS_BASICSEEARCH Version: v0.1.2.1+ } PS_SEARCHBYNAME = '/SearchByName'; PS_SEARCHBYNAMEW = '/SearchByNameW'; { wParam : 0 lParam : Handle to window owner Affect : Create the advanced search dialog box, see notes Returns: A window handle, or NULL(0) on failure Notes : this service is only available if PF1_EXTSEARCHUI capability is set, advanced search is very protocol-spec'd so it is left to the protocol itself to supply a dialog containing the options, this dialog should not have a titlebar and contain only search fields. the rest of the UI is supplied by Miranda. - The dialog should be created with CreateDialog() or it's kin and still be hidden when this function returns, - The dialog will be destroyed when the find/add dialog is closed Version: v0.1.2.1+ } PS_CREATEADVSEARCHUI = '/CreateAdvSearchUI'; { wParam : 0 lParam : Handle to advanced search window handle Affect : Search using the advanced search dialog, see notes Returns: A handle or NULL(0) on failure Notes : Results are returned in the same manner as PS_BASICSEARCH, this service is only available if PF1_EXTSEARCHUI capability is set Version: v0.1.2.1+ } PS_SEARCHBYADVANCED = '/SearchByAdvanced'; type CUSTOMSEARCHRESULTS = record nSize :size_t; nFieldCount:int; szFields :^TCHAR; psr :TPROTOSEARCHRESULT; end; { wParam : flags lParam : Pointer to a TPROTOSEARCHRESULT structure Affect : Adds a search result to the contact list, see notes Returns: A handle to the new contact (HCONTACT) or NULL(0) on failure Notes : The pointer MUST be a result returned by a search function since there maybe extra protocol-spec data required by the protocol. - the protocol module should not allow duplicate contains to be added, but if such a request *is* received it should return a HCONTACT to the original user, - If flags is PALF_TEMPORARY set, the contact should be added temorarily and invisiblely, just to get the user info (??) - } const PS_ADDTOLIST = '/AddToList'; { wParam : MAKEWPARAM(flags, iContact) lParam : HDBEVENT Affects: Add a contact to the contact list given an auth/added/contacts events, see notes Returns: A HCONTACT or NULL(0) on failure Notes : HDBEVENT must be either EVENTTYPE_AUTHREQ or EVENTTYPE_ADDED flags are the same as PS_ADDTOLIST, - iContacts is only used for contacts vents, it is 0-based index of the contacts in the event to add, there's no way to add two or more contacts at once, you should just call this as many times as needed. } PS_ADDTOLISTBYEVENT = '/AddToListByEvent'; { wParam : InfoType lParam : Pointer to InfoData Affect : Changes user details as stored on the server, see notes Returns: A Handle to the change request or NULL(0) on failure Notes : the details stored on the server are very protocol spec'd so this service just supplies an outline for protocols to use. See protocol-specific documentation for what infoTypes are available and what InfoData should be for each infoTypes. - Sends an ack type=ACKTYPE_SETINFO, result=ACKRESULT_SUCCESS/FAILURE, lParam=0 - This description just leaves me cold. Version: v0.1.2.0+ } PS_CHANGEINFO = '/ChangeInfo'; { wParam : HFILETRANSFER lParam : Pointer to a initalised TPROTOFILERESUME Affect : Informs the protocol of the user's chosen resume behaviour, see notes Returns: 0 on success, [non zero] on failure Notes : If the protocol supports file resume (caps: PF1_FILERESUME) then before each file receive begins it will broadcast an ack with : type=ACKTYPE_FILE, result=ACKRESULT_RESUME, hProcess=hFileTransfer, lParam = TPROTOFILETRANSFERSTATUS. If the UI processes this ack it must return a [non zero] valuee from it's hook, it all the hooks complete without returning [non zero] then the protocol will assume that no resume UI was available and will continue to receive the file with a default behaviour (default: overwrite) - If a hook does return [non zero] then that UI MUST call this service, PS_FILERESUME at some point. When the protocol module receives this call it will proceed wit the file recieve usingg the given information. - Having sasid that, PS_FILERESUME MUST be called, it is also acceptable to completely abort the transfer instead, i.e. the file exists locally and the user doesn't want to overwrite or resume or reget. Version: v0.1.2.2+ } PS_FILERESUME = '/FileResume'; PS_FILERESUMEW = '/FileResumeW'; { Asks a protocol to join the chatroom from contact v0.8.0+ wParam=(WPARAM)(HANDLE)hContact lParam=(LPARAM)0 Returns 0 on success, nonzero on failure } PS_JOINCHAT = '/JoinChat'; { Asks a protocol to leave the chatroom from contact v0.8.0+ wParam=(WPARAM)(HANDLE)hContact lParam=(LPARAM)0 Returns 0 on success, nonzero on failure } PS_LEAVECHAT = '/LeaveChat'; { Asks a protocol to read contact information and translate them (for a lookup fields) v0.8.0+ wParam=(WPARAM)(HANDLE)hContact lParam=(LPARAM)(DBCONTACTGETSETTING*)&dbcgs The flag PF4_INFOSETTINGSVC indicates that a protocol supports this. Basically it should do the same as MS_DB_CONTACT_GETSETTING_STR, except that for a lookup settings (e.g. Language) it returns string instead of an ID stored in the database. Caller is responsible for free()ing dbcgs.pValue->pszVal and pbVal if they are returned. You must **NOT** do this from your version of free() you have to use Miranda's free() you can get a function pointer to Miranda's free() via MS_SYSTEM_GET_MMI, see m_system.h Returns 0 on success or nonzero if the setting name was not found or hContact was invalid } PS_GETINFOSETTING = '/GetInfoSetting'; { Asks protocol for the status message for a status wParam=(WORD) 0 for current status or a status id lParam=SGMA_xxx Returns status msg or NULL if there is none. The protocol have to handle only the current status. Handling messages for other statuses is optional. Remember to mir_free the return value } SGMA_UNICODE = 1; // return Unicode status PS_GETMYAWAYMSG = '/GetMyAwayMsg'; { Set nickname for the user wParam=(WPARAM)SMNN_xxx lParam=(LPARAM)(char *) The new nickname for the user return=0 for success } SMNN_UNICODE = 1; // return Unicode status PS_SETMYNICKNAME = '/SetNickname'; { Get the max allowed length for the user nickname Optional, default value is 1024 wParam=(WPARAM)0 lParam=(LPARAM)0 return= <=0 for error, >0 the max length of the nick } PS_GETMYNICKNAMEMAXLENGTH = '/GetMyNicknameMaxLength'; // WAYD = What are you doing WAYD_UNICODE = 1; // return Unicode texts { Get the WAYD message for the user wParam=(WPARAM)WAYD_xxx lParam=(LPARAM)0 Returns the text or NULL if there is none. Remember to mir_free the return value. } PS_GETMYWAYD = '/GetMyWAYD'; { Sets the WAYD message for the user wParam=(WPARAM)WAYD_xxx lParam=(LPARAM)(WCHAR * or char *)The message Returns 0 on success, nonzero on failure } PS_SETMYWAYD = '/SetMyWAYD'; { Get the max allowed length that a WAYD message can have Optional, default value is 1024 wParam=(WPARAM)0 lParam=(LPARAM)0 Returns the max length } PS_GETMYWAYDMAXLENGTH = '/GetMyWAYDMaxLength'; // these should be called with CallContactService() {<</ !IMPORTANT! wParam, lParam data expected declarations should be treated with one level of indirection, where it says (CCSDATA: Yes) should be : What you *actually* get in the service: wParam = 0 lParam = pCCSDATA CCSDATA contains the ..wParam, ..lParam, hContact data declared with each service, so the wParam, lParam passed does not contain the data itself, but lParam contains a pointer to a structure which contains the data. />>} { CCSDATA: Yes wParam : flags Param : 0 Affect : Updates a contact's details from the server, see notes Returns: 0 on success, [non zero] on failure Notes : flags which may have SGIF_MINIMAL set to only get "basic" information, such as nickname, email address. PCCSDATA(lParam)^.hContact has the HCONTACT handle to get user information for. Will update all the information in the database and then send acks with : type=ACKTYPE_GETINFO, result=ACKRESULT_SUCCESS, hProcess=nReplies, lParam=thisReply - Since some protocol do not allow the module to tell when it has got all the information so it can send a final ack, one ack will be sent after each chunk of data has been received, - nReplies contains the number of distinct acks that will be sent to get all the information, 'thisReply' is the zero based index of this ack. When thisReply=0 the minimal information has just been received, all other numbering is arbitrary. } PSS_GETINFO = '/GetInfo'; { CCSDATA: Yes wParam : flags lParam : Pointer to a null terminated string Affect : Send an instant message Returns: an hProcess corresponding to an ACK which will be sent after the hProcess. Notes: type=ACKTYPE_MESSAGE, result=ACKRESULT_SUCCESS/FAILURE, lParam=ansi error message or NIL - here's the deal, you must return a 'seq' from this service which you have to ack when the message actually get's sent, or send a fake ack sometime soon if you can't find out if the message was successfully received with the protocol that you're using. - this event is NOT added to the database automatically. } PSS_MESSAGE = '/SendMsg'; // PSS_MESSAGEW = '/SendMsgW'; { CCSDATA: Yes wParam : flags lParam : null terminated string to the URL, see notes Affect : Send a URL message, see notes Returns: A hProcess which will be ack'd later Notes : lParam may contain TWO strings, the first for URL, the second for description, in the format : <url>#0<desc>#0 or <url>#0#0 Will send an ack for hProcess when the URL actually gets sent type=ACKTYPE_URL, result=ACKRESULT_SUCCESS/FAILURE, lParam=ansi error message or NIL - protocol modules are free to define flags starting at $10000 - The event will *not* be added to the database automatically } PSS_URL = '/SendUrl'; { CCSDATA: Yes wParam : MAKEWPARAM(flags) lParam : Pointer to hContactsList Affect : Send a set of contacts, see notes Returns: A hProcess which will be ack, NULL(0) on failure Notes : hContactsList is an array of nContacts handles to contacts, if this array includes one or more contains that can not be transferred using this protocol the function will fail. - Will send an ack when the contacts actually get sent: type=ACKTYPE_CONTACTS, result=ACKRESULT_SUCCESS/FAILURE, lParam=ansi error message or NIL - No flags have ben defined yet, - The event will *not* be added to the database automatically } PSS_CONTACTS = '/SendContacts'; { CCSDATA: Yes wParam : 0 lParam : 0 Affect : Send a request to retrieve HCONTACT's mode message, see notes Returns: a hProcess which will be ack'd later, NULL(0) on failure Notes : the reply will come in a form of an ack : type=ACKTYPE_AWAYMSG, result=ACKRESULT_SUCCESS/FAILURE, lParam=pointer to a null terminated string the containing message } PSS_GETAWAYMSG = '/GetAwayMsg'; { CCSDATA: Yes wParam : hProcess lParam : pointer to a buffer to fill with away message to reply with Affect : Sends an away message reply to a user, see notes Returns: 0 on success, [non zero] on failure Notes : This service must only be called is caps has PF1_MODEMSGSEND set as well as PF1_INDIVMODEMSG otherwise PS_SETAWAYMESSAGE should be used. - Reply will be sent in the form of an ack : type=ACKTYPE_AWAYMSG, result=ACKRESULT_SENTREQUEST, lParam=0 } PSS_AWAYMSG = '/SendAwayMsg'; { CCSDATA: Yes wParam : status_mode lParam : 0 Affect : Set the status mode the user will appear in to a user, see notes Returns: 0 on success, [non zero] on failure Notes : If status_mode = 0 then revert to normal state for the user, ID_STATUS_ONLINE is possible if PF1_VISLIST ID_STATUS_ONLINE is possible if PF1_INDIVSTATUS } PSS_SETAPPARENTMODE = '/SetApparentMode'; // only valid if caps support IM xfers { CCSDATA: Yes wParam : HTRANSFER lParam : null terminated string containing the path Affect : Allow a file transfer to begin, see notes Returns: A handle to the transfer to be used from now on. Notes : If the path does not point to a directory then: if a single file is being transfered and the protocol supports file renaming (PF1_CANRENAMEFILE) then the file is given this name, othewise the file is removed and file(s) are placed into the resulting directory. - File transfers are marked by a EVENTTYPE_FILE added to the database. The format is : hTransfer: DWORD filename(s), description: ASCIIZ } PSS_FILEALLOW = '/FileAllow'; PSS_FILEALLOWW = '/FileAllowW'; { CCSDATA: Yes wParam : HTRANSFER lparam : Pointer to a buffer to be filled with reason Affect : Refuses a file transfer request Returns: 0 on success, [non zero] on failure } PSS_FILEDENY = '/FileDeny'; PSS_FILEDENYW = '/FileDenyW'; { CCSDATA: Yes wParam : HTRANSFER lParam : 0 Affect : Cancel an in-progress file transfer Returns: 0 on success, [non zero] on failure } PSS_FILECANCEL = '/FileCancel'; { CCSDATA: Yes wParam : null terminated string containing description lParam : pointer to an array of PAnsiChar's containing file paths/directories Affect : Start a file(s) send, see notes Returns: A HTRANSFER handle on success, NULL(0) on failur Notes : All notifications are done thru acks : - type=ACKTYPE_FILE, if result=ACKRESULT_FAILED then lParam=null terminated string containing reason } PSS_FILE = '/SendFile'; PSS_FILEW = '/SendFileW'; { Send an auth request wParam=0 lParam=TChar szMessage Returns 0 on success, nonzero on failure } PSS_AUTHREQUEST = '/AuthRequest'; PSS_AUTHREQUESTW = '/AuthRequestW'; { Send "User is Typing" (user is typing a message to the user) v0.3.3+ wParam=(WPARAM)(HANDLE)hContact lParam=(LPARAM)(int)typing type - see PROTOTYPE_SELFTYPING_X defines in m_protocols.h } PSS_USERISTYPING = '/UserIsTyping'; // Receiving Services {>>/ Receiving Services: Before a message is sent to /RecvMessage it goes through a MS_PROTO_CHAINRECV which allows any other module to change data (for decryption, etc), this then reaches /RecvMessage. This does not have to be the same structure/memory contained within that structure that started the chain call. /RecvMessage adds the event to the database, any other modules who are interested in what message the user will see should hook at this point. />>} { CCSDATA: Yes wParam : 0 lParam : Pointer to a TPROTORECVEVENT Affect : An instant message has beeen received, see notes Returns: 0 - success, other failure // handle to the newly added event, or NULL on failure Notes : lParam^.lParam^.szMessage has the message, see structure above stored as DB event EVENTTYPE_MESSAGE, blob contains message string without null termination. } { Proto/RecvMessage Copies a message from a PROTORECVEVENT event into the database wParam = 0 (unused) lParam = CCSDATA* Returns the result of MS_DB_EVENT_ADD } PSR_MESSAGE = '/RecvMessage'; // PSR_MESSAGEW = '/RecvMessageW'; MS_PROTO_RECVMSG = 'Proto/RecvMessage'; { Proto/AuthRecv Copies the EVENTTYPE_AUTHREQUEST event from PROTORECVEVENT into DBEVENTINFO and adds it wParam = char* : protocol name lParam = PROTORECVEVENT* Returns the result of MS_DB_EVENT_ADD } PSR_AUTH = '/RecvAuth'; MS_PROTO_AUTHRECV = 'Proto/AuthRecv'; //File(s) have been received //wParam = 0 //lParam = (LPARAM)(PROTORECVFILET*)&prf type PROTORECVFILET = record flags:dword; timestamp:dword; // unix time szDescription:TChar; fileCount:int; ptszFiles:^TChar; lParam:LPARAM; // extra space for the network level protocol module end; const PSR_FILE = '/RecvFile'; MS_PROTO_RECVFILET = 'Proto/RecvFileT'; { CCSDATA: Yes wParam : 0 lParam : Pointer to a TPROTORECVEVENT, see notes Affect : A URL has been received Notes : szMessage is encoded the same as PSS_URL - Stored in the database : EVENTTYPE_URL, blob contains message without null termination } PSR_URL = '/RecvUrl'; { CCSDATA: Yes wParam : 0 lParam : Pointer to a TPROTORECVEVENT Affect : Contacts have been received, see notes Notes : pre.szMessage is actually a PROTOSEARCHRESULT list pre.lParam is the number of contains in that list. pre.flags can contain PREF_UTF defining the strings as utf-8 encoded (0.7.0+) - PS_ADDTOLIST can be used to add contacts to the list - repeat [ ASCIIZ userNick ASCIIZ userId ] userNick should be a human-readable description of the user. It need not be the nick, or even confined to displaying just one type of information. The dbe.flags can contain DBEF_UTF defining userNick as utf-8 encoded. userId should be a machine-readable representation of the unique protocol identifying field of the user. Because of the need to be zero-terminated, binary data should be converted to text. Use PS_ADDTOLISTBYEVENT to add the contacts from one of these to the list. } PSR_CONTACTS = '/RecvContacts'; { CCSDATA: Yes wParam : status_mode lParam : Pointer to a TPROTORECVEVENT structure Affect : An away message reply has been received } PSR_AWAYMSG = '/RecvAwayMsg'; {$ENDIF}