/* Miranda NG: the free IM client for Microsoft* Windows* Copyright (c) 2012-16 Miranda NG project (http://miranda-ng.org) Copyright (c) 2000-09 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. */ // this module was created in v0.1.1.0 // none of these services should be used on their own (ie using CallService, // CreateServiceFunction(), etc), hence the PS_ prefix. Instead use the services // exposed in m_protocols.h #ifndef M_PROTOSVC_H__ #define M_PROTOSVC_H__ 1 #include "m_protocols.h" ///////////////////////////////////////////////////////////////////////////////////////// // WARNING: // all services from this file should be called via CallProtoService() ///////////////////////////////////////////////////////////////////////////////////////// // Get the capability flags of the module. // wParam = flagNum // lParam = 0 // Returns a bitfield corresponding to wParam. See the #defines below // Should return 0 for unknown values of flagNum // Non-network-access modules should return flags to represent the things they // actually actively use, not the values that it is known to pass through // correctly #define PFLAGNUM_1 1 #define PF1_IMSEND 0x00000001 // supports IM sending #define PF1_IMRECV 0x00000002 // supports IM receiving #define PF1_IM (PF1_IMSEND|PF1_IMRECV) #define PF1_URLSEND 0x00000004 // supports separate URL sending #define PF1_URLRECV 0x00000008 // supports separate URL receiving #define PF1_URL (PF1_URLSEND|PF1_URLRECV) #define PF1_FILESEND 0x00000010 // supports file sending #define PF1_FILERECV 0x00000020 // supports file receiving #define PF1_FILE (PF1_FILESEND|PF1_FILERECV) #define PF1_MODEMSGSEND 0x00000040 // supports broadcasting away messages #define PF1_MODEMSGRECV 0x00000080 // supports reading others' away messages #define PF1_MODEMSG (PF1_MODEMSGSEND|PF1_MODEMSGRECV) #define PF1_SERVERCLIST 0x00000100 // contact lists are stored on the server, not locally. See notes below #define PF1_AUTHREQ 0x00000200 // will get authorisation requests for some or all contacts #define PF1_ADDED 0x00000400 // will get 'you were added' notifications #define PF1_VISLIST 0x00000800 // has an invisible list #define PF1_INVISLIST 0x00001000 // has a visible list for when in invisible mode #define PF1_INDIVSTATUS 0x00002000 // supports setting different status modes to each contact #define PF1_EXTENSIBLE 0x00004000 // the protocol is extensible and supports plugin-defined messages #define PF1_PEER2PEER 0x00008000 // supports direct (not server mediated) communication between clients #define PF1_NEWUSER 0x00010000 // supports creation of new user IDs #define PF1_CHAT 0x00020000 // has a realtime chat capability #define PF1_INDIVMODEMSG 0x00040000 // supports replying to a mode message request with different text depending on the contact requesting #define PF1_BASICSEARCH 0x00080000 // supports a basic user searching facility #define PF1_EXTSEARCH 0x00100000 // supports one or more protocol-specific extended search schemes #define PF1_CANRENAMEFILE 0x00200000 // supports renaming of incoming files as they are transferred #define PF1_FILERESUME 0x00400000 // can resume broken file transfers, see PS_FILERESUME below #define PF1_ADDSEARCHRES 0x00800000 // can add search results to the contact list #define PF1_CONTACTSEND 0x01000000 // can send contacts to other users #define PF1_CONTACTRECV 0x02000000 // can receive contacts from other users #define PF1_CONTACT (PF1_CONTACTSEND|PF1_CONTACTRECV) #define PF1_CHANGEINFO 0x04000000 // can change our user information stored on server #define PF1_SEARCHBYEMAIL 0x08000000 // supports a search by e-mail feature #define PF1_USERIDISEMAIL 0x10000000 // set if the uniquely identifying field of the network is the e-mail address #define PF1_SEARCHBYNAME 0x20000000 // supports searching by nick/first/last names #define PF1_EXTSEARCHUI 0x40000000 // has a dialog box to allow searching all the possible fields #define PF1_NUMERICUSERID 0x80000000 // the unique user IDs for this protocol are numeric /////////////////////////////////////////////////////////////////////////////// // the status modes that the protocol supports #define PFLAGNUM_2 2 #define PF2_ONLINE 0x00000001 // an unadorned online mode #define PF2_INVISIBLE 0x00000002 #define PF2_SHORTAWAY 0x00000004 // Away on ICQ, BRB on MSN #define PF2_LONGAWAY 0x00000008 // NA on ICQ, Away on MSN #define PF2_LIGHTDND 0x00000010 // Occupied on ICQ, Busy on MSN #define PF2_HEAVYDND 0x00000020 // DND on ICQ #define PF2_FREECHAT 0x00000040 #define PF2_OUTTOLUNCH 0x00000080 #define PF2_ONTHEPHONE 0x00000100 #define PF2_IDLE 0x00000200 /////////////////////////////////////////////////////////////////////////////// // the status modes that the protocol supports // away-style messages for. Uses the PF2_ flags. // PFLAGNUM_3 is implemented by protocol services that support away messages // there may be no support and 0 will be returned, if there is // support it will consist of a set of PF2_* bits #define PFLAGNUM_3 3 // given a status will return what bit flags to test for static __inline unsigned long Proto_Status2Flag(int status) { switch (status) { case ID_STATUS_ONLINE: return PF2_ONLINE; case ID_STATUS_INVISIBLE: return PF2_INVISIBLE; case ID_STATUS_OUTTOLUNCH: return PF2_OUTTOLUNCH; case ID_STATUS_ONTHEPHONE: return PF2_ONTHEPHONE; case ID_STATUS_AWAY: return PF2_SHORTAWAY; case ID_STATUS_NA: return PF2_LONGAWAY; case ID_STATUS_OCCUPIED: return PF2_LIGHTDND; case ID_STATUS_DND: return PF2_HEAVYDND; case ID_STATUS_FREECHAT: return PF2_FREECHAT; case ID_STATUS_IDLE: return PF2_IDLE; } return 0; } /////////////////////////////////////////////////////////////////////////////// // another bunch of flags #define PFLAGNUM_4 4 #define PF4_FORCEAUTH 0x00000001 // forces auth requests to be sent when adding users #define PF4_FORCEADDED 0x00000002 // forces "you were added" requests to be sent #define PF4_NOCUSTOMAUTH 0x00000004 // protocol doesn't support custom auth text (doesn't show auth text box) #define PF4_SUPPORTTYPING 0x00000008 // protocol supports user is typing messages #define PF4_SUPPORTIDLE 0x00000010 // protocol understands idle #define PF4_AVATARS 0x00000020 // protocol has avatar support #define PF4_OFFLINEFILES 0x00000040 // protocols supports sending files to offline users #define PF4_IMSENDOFFLINE 0x00000100 // protocol supports sending offline messages #define PF4_INFOSETTINGSVC 0x00000200 // protocol supports user info translation services #define PF4_NOAUTHDENYREASON 0x00000400 // protocol doesn't support authorization deny reason #define PF4_GROUPCHATFILES 0x00000800 // protocol supports sending files to group chats #define PF4_SINGLEFILEONLY 0x00001000 // protocol supports sending files one by one only #define PF4_READNOTIFY 0x00002000 // protocol supports receiving notify of message reading #define PFLAG_UNIQUEIDTEXT 100 // returns a static buffer of text describing the unique field by which this protocol identifies users (already translated), or NULL #define PFLAG_MAXCONTACTSPERPACKET 200 // returns the maximum number of contacts which can be sent in a single PSS_CONTACTS, lParam = (LPARAM)hContact. #define PFLAG_UNIQUEIDSETTING 300 // returns the setting name of where the unique id is stored #define PFLAG_MAXLENOFMESSAGE 400 // 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. #define PFLAGNUM_5 5 /////////////////////////////////////////////////////////////////////////////// // 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. #define PS_GETCAPS "/GetCaps" /////////////////////////////////////////////////////////////////////////////// // Get a human-readable name for the protocol // wParam = cchName // lParam = (LPARAM)(char*)szName // Returns 0 on success, nonzero on failure // cchName is the number of characters in the buffer szName // This should be translated before being returned // Some example strings are: // "ICQ", "AIM", "RSA-1024 Encryption" #define PS_GETNAME "/GetName" /////////////////////////////////////////////////////////////////////////////// // Loads one of the protocol-specific icons // wParam = whichIcon // lParam = 0 // Returns the HICON, or NULL on failure // The returned HICON must be DestroyIcon()ed. // The UI should overlay the online icon with a further UI-specified icon to // represent the exact status mode. #define PLI_PROTOCOL 1 // An icon representing the protocol (eg the multicoloured flower for ICQ) #define PLI_ONLINE 2 // Online state icon for that protocol (eg green flower for ICQ) #define PLI_OFFLINE 3 // Offline state icon for that protocol (eg red flower for ICQ) #define PLIF_LARGE 0 // OR with one of the above to get the large (32x32 by default) icon #define PLIF_SMALL 0x10000 // OR with one of the above to get the small (16x16 by default) icon #define PLIF_ICOLIB 0x20000 // the returned HICON is managed by IcoLib, DO NOT DestroyIcon() it #define PLIF_ICOLIBHANDLE 0x40000 // the function will return IcoLib handle not HICON #define PS_LOADICON "/LoadIcon" /////////////////////////////////////////////////////////////////////////////// // Change the protocol's status mode // wParam = newMode, from ui/contactlist/statusmodes.h // lParam = 0 // returns 0 on success, nonzero on failure // Will send an ack with: // type = ACKTYPE_STATUS, result = ACKRESULT_SUCCESS, hProcess = (HANDLE)previousMode, lParam = newMode // when the change completes. This ack is sent for all changes, not just ones // caused by calling this function. // Note that 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. // Non-network-level protocol modules do not have the concept of a status and // should leave this service unimplemented // If a protocol doesn't support the specific status mode, it should pick the // closest one that it does support, and change to that. // If the new mode requires that the protocol switch from offline to online then // it will do so, but errors will be reported in the form of an additional ack: // type = ACKTYPE_LOGIN, result = ACKRESULT_FAILURE, hProcess = NULL, lParam = LOGINERR_ // (added during 0.3.4.3) the protocol will send LOGINERR_OTHERLOCATION if the login // was disconnected because of a login at another location #define LOGINERR_WRONGPASSWORD 1 #define LOGINERR_NONETWORK 2 #define LOGINERR_PROXYFAILURE 3 #define LOGINERR_BADUSERID 4 #define LOGINERR_NOSERVER 5 #define LOGINERR_TIMEOUT 6 #define LOGINERR_WRONGPROTOCOL 7 #define LOGINERR_OTHERLOCATION 8 // protocols may define more error codes starting at 1000 #define PS_SETSTATUS "/SetStatus" /////////////////////////////////////////////////////////////////////////////// // Sets the status-mode specific message for yourself // wParam = status mode // lParam = (LPARAM)(const wchar_t*)szMessage // Returns 0 on success, nonzero on failure // Note that this service will not be available unless PF1_MODEMSGSEND is set // and PF1_INDIVMODEMSG is *not* set. // Protocol modules must support szMessage = NULL. It may either mean to use an // empty message, or (preferably) to not reply at all to any requests #define PS_SETAWAYMSG "/SetAwayMsg" /////////////////////////////////////////////////////////////////////////////// // Get the status mode that a protocol is currently in // wParam = lParam = 0 // Returns the status mode // Non-network-level protocol modules do not have the concept of a status and // should leave this service unimplemented #define PS_GETSTATUS "/GetStatus" /////////////////////////////////////////////////////////////////////////////// // Allow somebody to add us to their contact list // wParam = (WPARAM)(HANDLE)hDbEvent // lParam = 0 // Returns 0 on success, nonzero on failure // Auth requests come in the form of an event added to the database for the NULL // user. The form is: // DWORD protocolSpecific // ASCIIZ nick, firstName, lastName, e-mail, requestReason // hDbEvent must be the handle of such an event // One or more fields may be empty if the protocol doesn't support them #define PS_AUTHALLOW "/Authorize" /////////////////////////////////////////////////////////////////////////////// // Deny an authorisation request // wParam = (WPARAM)(HANDLE)hDbEvent // lParam = (LPARAM)(const wchar_t*)szReason // Returns 0 on success, nonzero on failure // Protocol modules must be able to cope with szReason = NULL #define PS_AUTHDENY "/AuthDeny" /////////////////////////////////////////////////////////////////////////////// // Send a "You were added" event // wParam = lParam = 0 // Returns 0 on success, nonzero on failure #define 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. #define PS_CREATEACCMGRUI "/CreateAccMgrUI" /////////////////////////////////////////////////////////////////////////////// // Send a basic search request // wParam = 0 // lParam = (LPARAM)(const wchar_t*)szId // Returns a handle for the search, or zero on failure // All protocols identify users uniquely by a single field. This service will // search by that field. // Note that if users are identified by an integer (eg ICQ) szId should be a // string containing that integer, not the integer itself. // All search replies (even protocol-specific extended searches) are replied by // means of a series of acks: // result acks, one of more of: // type = ACKTYPE_SEARCH, result = ACKRESULT_DATA, lParam = (LPARAM)(PROTOSEARCHRESULT*)&psr // ending ack: // type = ACKTYPE_SEARCH, result = ACKRESULT_SUCCESS, lParam = 0 // Note that the pointers in the structure are not guaranteed to be valid after // the ack is complete. #define PSR_UNICODE 0x0001 // all strings go in UTF16-LE #define PSR_UTF8 0x0002 // all strings go in UTF8 typedef struct { int cbSize; MAllStrings nick; MAllStrings firstName; MAllStrings lastName; MAllStrings email; MAllStrings id; int flags; } PROTOSEARCHRESULT; #define PS_BASICSEARCH "/BasicSearch" /////////////////////////////////////////////////////////////////////////////// // Search for users by e-mail address // wParam = 0 // lParam = (LPARAM)(wchar_t*)szEmail // Returns a HANDLE to the search, or NULL on failure // Results are returned as for PS_BASICSEARCH. // This function is only available if the PF1_SEARCHBYEMAIL capability is set // If the PF1_USERIDISEMAIL capability is set then this function and // PS_BASICSEARCH should have the same result (and it's best if they are the // same function). #define PS_SEARCHBYEMAIL "/SearchByEmail" /////////////////////////////////////////////////////////////////////////////// // Search for users by name // wParam = 0 // lParam = (LPARAM)(PROTOSEARCHBYNAME*)&psbn // Returns a HANDLE to the search, or NULL on failure // Results are returned as for PS_BASICSEARCH. // This function is only available if the PF1_SEARCHBYNAME capability is set typedef struct { wchar_t *pszNick; wchar_t *pszFirstName; wchar_t *pszLastName; } PROTOSEARCHBYNAME; #define PS_SEARCHBYNAME "/SearchByName" /////////////////////////////////////////////////////////////////////////////// // Create the advanced search dialog box // wParam = 0 // lParam = (HWND)hwndOwner // Returns a HWND, or NULL on failure // This function is only available if the PF1_EXTSEARCHUI capability is set // Advanced search is very protocol-specific so it is left to the protocol // itself to supply a dialog containing the options. This dialog should not // have a title bar and contain only search fields. The rest of the UI is // supplied by Miranda. // The dialog should be created with CreateDialog() or its kin and still be // hidden when this function returns. // The dialog will be destroyed when the find/add dialog is closed. #define PS_CREATEADVSEARCHUI "/CreateAdvSearchUI" /////////////////////////////////////////////////////////////////////////////// // Search using the advanced search dialog // wParam = 0 // lParam = (LPARAM)(HWND)hwndAdvancedSearchDlg // Returns a HANDLE to the search, or NULL on failure // Results are returned as for PS_BASICSEARCH. // This function is only available if the PF1_EXTSEARCHUI capability is set #define PS_SEARCHBYADVANCED "/SearchByAdvanced" typedef struct { size_t nSize; int nFieldCount; wchar_t **pszFields; PROTOSEARCHRESULT psr; } CUSTOMSEARCHRESULTS; /////////////////////////////////////////////////////////////////////////////// // Adds a search result to the contact list // wParam = flags // lParam = (LPARAM)(PROTOSEARCHRESULT*)&psr // Returns a HANDLE to the new contact, or NULL on failure // psr must be a result returned by a search function, since the extended // information past the end of the official structure may contain important // data required by the protocol. // The protocol library should not allow duplicate contacts to be added, but if // such a request is received it should return the original hContact, and do the // appropriate thing with the temporary flag (ie newflag = (oldflag&thisflag)) #define PALF_TEMPORARY 1 // add the contact temporarily and invisibly, just to get user info or something #define PS_ADDTOLIST "/AddToList" /////////////////////////////////////////////////////////////////////////////// // Adds a contact to the contact list given an auth, added or contacts event // wParam = MAKEWPARAM(flags, iContact) // lParam = (LPARAM)(HANDLE)hDbEvent // Returns a HANDLE to the new contact, or NULL on failure // hDbEvent must be either EVENTTYPE_AUTHREQ or EVENTTYPE_ADDED // flags are the same as for PS_ADDTOLIST. // iContact is only used for contacts events. It is the 0-based index of the // contact in the event to add. There is no way to add two or more contacts at // once, you should just do lots of calls. #define PS_ADDTOLISTBYEVENT "/AddToListByEvent" /////////////////////////////////////////////////////////////////////////////// // Informs the protocol of the users chosen resume behaviour // wParam = (WPARAM)(HANDLE)hFileTransfer // lParam = (LPARAM)(PROTOFILERESUME*)&pfr // Returns 0 on success, nonzero on failure // If the protocol supports file resume (PF1_FILERESUME) then before each // individual file receive begins (note: not just each file that already exists) // it will broadcast an ack with type = ACKTYPE_FILE, result = ACKRESULT_RESUME, // hProcess = hFileTransfer, lParam = (LPARAM)(PROTOFILETRANSFERSTATUS*)&fts. If the // UI processes this ack it must return nonzero from its hook. If all the hooks // complete without returning nonzero then the protocol will assume that no // resume UI was available and will continue the file receive with a default // behaviour (overwrite for ICQ). If a hook does return nonzero then that UI // must call this function, PS_FILERESUME, at some point. When the protocol // module receives this call it will proceed with the file receive using the // given information. // Having said that PS_FILERESUME must be called, it is also acceptable to call // PSS_FILECANCEL to completely abort the transfer instead. #define FILERESUME_OVERWRITE 1 #define FILERESUME_RESUME 2 #define FILERESUME_RENAME 3 #define FILERESUME_SKIP 4 typedef struct { int action; // a FILERESUME_ flag const wchar_t *szFilename; // full path. Only valid if action == FILERESUME_RENAME } PROTOFILERESUME; #define PS_FILERESUME "/FileResume" /////////////////////////////////////////////////////////////////////////////// // Asks a protocol to join the chatroom from contact v0.8.0+ // wParam = (MCONTACT)hContact // lParam = 0 // Returns 0 on success, nonzero on failure #define PS_JOINCHAT "/JoinChat" /////////////////////////////////////////////////////////////////////////////// // Asks a protocol to leave the chatroom from contact v0.8.0+ // wParam = (MCONTACT)hContact // lParam = 0 // Returns 0 on success, nonzero on failure #define PS_LEAVECHAT "/LeaveChat" /////////////////////////////////////////////////////////////////////////////// // Asks a protocol to read contact information and translate them (for a lookup fields) // wParam = (MCONTACT)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 #define 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 #define SGMA_UNICODE 1 // return Unicode status #define 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 #define SMNN_UNICODE 1 // return Unicode status #define PS_SETMYNICKNAME "/SetNickname" /////////////////////////////////////////////////////////////////////////////// // Get the max allowed length for the user nickname // Optional, default value is 1024 // wParam = 0 // lParam = 0 // return = <= 0 for error, >0 the max length of the nick #define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength" // WAYD = What are you doing #define WAYD_UNICODE 1 // return Unicode texts /////////////////////////////////////////////////////////////////////////////// // Get the WAYD message for the user // wParam = (WPARAM)WAYD_xxx // lParam = 0 // Returns the text or NULL if there is none. Remember to mir_free the return value. #define PS_GETMYWAYD "/GetMyWAYD" /////////////////////////////////////////////////////////////////////////////// // Sets the WAYD message for the user // wParam = (WPARAM)WAYD_xxx // lParam = (LPARAM)(wchar_t * or char *)The message // Returns 0 on success, nonzero on failure #define PS_SETMYWAYD "/SetMyWAYD" /////////////////////////////////////////////////////////////////////////////// // Get the max allowed length that a WAYD message can have // Optional, default value is 1024 // wParam = 0 // lParam = 0 // Returns the max length #define PS_GETMYWAYDMAXLENGTH "/GetMyWAYDMaxLength" /////////////////////////////////////////////////////////////////////////////// // Get the unread email message count, optional // wParam = 0 // lParam = 0 // Returns the number of unread emails #define PS_GETUNREADEMAILCOUNT "/GetUnreadEmailCount" /////////////////////////////////////////////////////////////////////////////// // SENDING SERVICES // these should be called with CallContactService() // Updates a contact's details from the server // wParam = flags // lParam = 0 // returns 0 on success, nonzero on failure // Will update all the information in the database, and then send acks with // type = ACKTYPE_GETINFO, result = ACKRESULT_SUCCESS, hProcess = (HANDLE)(int)nReplies, lParam = thisReply // Since some protocols do not allow the library 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. #define SGIF_MINIMAL 1 // get only the most basic information. This should // contain at least a Nick and e-mail. #define SGIF_ONOPEN 2 // set when the User Info form is being opened #define PSS_GETINFO "/GetInfo" /////////////////////////////////////////////////////////////////////////////// // Send an instant message // wParam = flags // lParam = (LPARAM)(const char*)szMessage // returns a hProcess corresponding to the one in the ack event. // Will send an ack when the message actually gets sent // type = ACKTYPE_MESSAGE, result = success/failure, (char*)lParam = error message or NULL. // Protocols modules are free to define flags starting at 0x10000 // The event will *not* be added to the database automatically. #define PSS_MESSAGE "/SendMsg" /////////////////////////////////////////////////////////////////////////////// // Send an URL message // wParam = flags // lParam = (LPARAM)(const char*)szMessage // returns a hProcess corresponding to the one in the ack event. // szMessage should be encoded as the URL followed by the description, the // separator being a single nul (\0). If there is no description, do not forget // to end the URL with two nuls. // Will send an ack when the message actually gets sent // type = ACKTYPE_URL, result = success/failure, (char*)lParam = error message or NULL. // Protocols modules are free to define flags starting at 0x10000 // The event will *not* be added to the database automatically. #define PSS_URL "/SendUrl" /////////////////////////////////////////////////////////////////////////////// // Send a set of contacts // wParam = MAKEWPARAM(flags, nContacts) // lParam = (LPARAM)(HANDLE*)hContactsList // returns a hProcess corresponding to the one in the ack event, NULL on // failure. // hContactsList is an array of nContacts handles to contacts. If this array // includes one or more contacts that cannot be transferred using this protocol // the function will fail. // Will send an ack when the contacts actually get sent // type = ACKTYPE_CONTACTS, result = success/failure, (char*)lParam = error message or NULL. // No flags have yet been defined. // The event will *not* be added to the database automatically. #define PSS_CONTACTS "/SendContacts" /////////////////////////////////////////////////////////////////////////////// // Send a request to retrieve somebody's mode message. // wParam = lParam = 0 // returns an hProcess identifying the request, or 0 on failure // This function will fail if the contact's current status mode doesn't have an // associated message // The reply will be in the form of an ack: // type = ACKTYPE_AWAYMSG, result = success/failure, lParam = (const char*)szMessage #define PSS_GETAWAYMSG "/GetAwayMsg" /////////////////////////////////////////////////////////////////////////////// // Allows a file transfer to begin // wParam = (WPARAM)(HANDLE)hTransfer // lParam = (LPARAM)(const wchar_t*)szPath // Returns a new handle to the transfer, to be used from now on // If szPath does not point to a directory then: // if a single file is being transferred and the protocol supports file // renaming (PF1_CANRENAMEFILE) then the file is given this name // otherwise the filename is removed and the file(s) are placed in the // resulting directory // File transfers are marked by an EVENTTYPE_FILE added to the database. The // format is: // DWORD hTransfer // ASCIIZ filename(s), description #define PSS_FILEALLOW "/FileAllow" /////////////////////////////////////////////////////////////////////////////// // Refuses a file transfer request // wParam = (WPARAM)(HANDLE)hTransfer // lParam = (LPARAM)(const wchar_t*)szReason // Returns 0 on success, nonzero on failure #define PSS_FILEDENY "/FileDeny" /////////////////////////////////////////////////////////////////////////////// // Cancel an in-progress file transfer // wParam = (WPARAM)(HANDLE)hTransfer // lParam = 0 // Returns 0 on success, nonzero on failure #define PSS_FILECANCEL "/FileCancel" /////////////////////////////////////////////////////////////////////////////// // Initiate a file send // wParam = (WPARAM)(const wchar_t*)szDescription // lParam = (LPARAM)(wchar_t **)ppszFiles // Returns a transfer handle on success, NULL on failure // All notification is done through acks, with type = ACKTYPE_FILE // If result = ACKRESULT_FAILED then lParam = (LPARAM)(const char*)szReason #define PSS_FILE "/SendFile" /////////////////////////////////////////////////////////////////////////////// // Set the status mode you will appear in to a user // wParam = statusMode // lParam = 0 // Returns 0 on success, nonzero on failure // Set statusMode = 0 to revert to normal behaviour for the contact // ID_STATUS_ONLINE is possible iff PF1_VISLIST // ID_STATUS_OFFLINE is possible iff PF1_INVISLIST // Other modes are possible iff PF1_INDIVSTATUS #define PSS_SETAPPARENTMODE "/SetApparentMode" /////////////////////////////////////////////////////////////////////////////// // Send an auth request // wParam = 0 // lParam = (const wchar_t *)szMessage // Returns 0 on success, nonzero on failure #define PSS_AUTHREQUEST "/AuthRequest" /////////////////////////////////////////////////////////////////////////////// // Send "User is Typing" (user is typing a message to the user) v0.3.3+ // wParam = (MCONTACT)hContact // lParam = (LPARAM)(int)typing type - see PROTOTYPE_SELFTYPING_X defines in m_protocols.h #define PSS_USERISTYPING "/UserIsTyping" /////////////////////////////////////////////////////////////////////////////// // RECEIVING SERVICES // These services are not for calling by general modules. They serve a specific // role in communicating through protocol module chains before the whole app is // notified that an event has occurred. // When the respective event is received over the network, the network-level // protocol module initiates the chain by calling MS_PROTO_CHAINRECV with wParam // set to zero and lParam pointing to the CCSDATA structure. // Protocol modules should continue the message up the chain by calling // MS_PROTO_CHAINRECV with the same wParam they received and a modified (or not) // lParam (CCSDATA). If they do not do this and return nonzero then all further // processing for the event will cease and the event will be ignored. // Once all non-network protocol modules have been called (in reverse order), // the network protocol module will be called so that it can finish its // processing using the modified information. // This final processing should consist of the protocol module adding the // event to the database, and it is the ME_DB_EVENT_ADDED event that people who // just want to know the final result should hook. // In all cases, the database should store what the user read/wrote. // An instant message has been received // wParam = 0 // lParam = (LPARAM)(PROTORECVEVENT*)&pre // DB event: EVENTTYPE_MESSAGE, blob contains szMessage without 0 terminator // Return 0 - success, other failure typedef struct { DWORD flags; DWORD timestamp; // unix time char *szMessage; // message body in utf8 LPARAM lParam; // extra space for the network level protocol module void *pCustomData; DWORD cbCustomDataSize; } PROTORECVEVENT; #define PREF_CREATEREAD 1 // create the database event with the 'read' flag set #define PREF_RTL 4 // 0.5+ addition: support for right-to-left messages #define PREF_SENT 16 // message will be created with the DBEF_SENT flag /////////////////////////////////////////////////////////////////////////////// // Proto/RecvMessage // Copies a message from a PROTORECVEVENT event into the database // wParam = 0 (unused) // lParam = CCSDATA* // Returns the result of db_event_add() #define PSR_MESSAGE "/RecvMessage" #define MS_PROTO_RECVMSG "Proto/RecvMessage" __forceinline INT_PTR Proto_RecvMessage(MCONTACT hContact, PROTORECVEVENT *pcre) { CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM)pcre }; return CallService(MS_PROTO_RECVMSG, 0, (LPARAM)&ccs); } __forceinline INT_PTR ProtoChainRecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) { CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM)pre }; return Proto_ChainRecv(0, &ccs); } /////////////////////////////////////////////////////////////////////////////// // Proto/AuthRecv // Copies the EVENTTYPE_AUTHREQUEST event from PROTORECVEVENT into DBEVENTINFO and adds it // wParam = char* : protocol name // lParam = PROTORECVEVENT* // Returns the result of db_event_add() #define PSR_AUTH "/RecvAuth" #define MS_PROTO_AUTHRECV "Proto/AuthRecv" __forceinline INT_PTR Proto_AuthRecv(const char *szProtoName, PROTORECVEVENT *pcre) { return CallService(MS_PROTO_AUTHRECV, (WPARAM)szProtoName, (LPARAM)pcre); } /////////////////////////////////////////////////////////////////////////////// // File(s) have been received // wParam = 0 // lParam = (LPARAM)(PROTORECVFILET*)&prf #define PRFF_UNICODE 1 typedef struct { DWORD dwFlags; // PRFF_* DWORD timestamp; // unix time MAllStrings descr; // file description int fileCount; // number of files being transferred MAllStringArray files; // array of file names LPARAM lParam; // extra space for the network level protocol module } PROTORECVFILET; #define PSR_FILE "/RecvFile" #define MS_PROTO_RECVFILET "Proto/RecvFileT" __forceinline INT_PTR Proto_RecvFile(MCONTACT hContact, PROTORECVFILET *pcre) { CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)pcre }; return CallService(MS_PROTO_RECVFILET, 0, (LPARAM)&ccs); } __forceinline INT_PTR ProtoChainRecvFile(MCONTACT hContact, PROTORECVFILET *pre) { CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)pre }; return Proto_ChainRecv(0, &ccs); } /////////////////////////////////////////////////////////////////////////////// // An URL has been received // wParam = 0 // lParam = (LPARAM)(PROTORECVEVENT*)&pre // szMessage is encoded the same as for PSS_URL // DB event: EVENTTYPE_URL, blob contains szMessage without 0 terminator #define PSR_URL "/RecvUrl" /////////////////////////////////////////////////////////////////////////////// // Contacts have been received // wParam = 0 // lParam = (LPARAM)(PROTORECVEVENT*)&pre // pre.szMessage is actually a (PROTOSEARCHRESULT**) list. // pre.lParam is the number of contacts 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 the contacts to the contact list. #define PSR_CONTACTS "/RecvContacts" /////////////////////////////////////////////////////////////////////////////// // contacts database event format (EVENTTYPE_CONTACTS) // 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. // An away message reply has been received // wParam = statusMode // lParam = (LPARAM)(PROTORECVEVENT*)&pre #define PSR_AWAYMSG "/RecvAwayMsg" #endif // M_PROTOSVC_H__