From 24c0dd3e35ae97183a994cc6f25fc78d08da1311 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sun, 2 Nov 2014 12:12:42 +0000 Subject: reverted MSN removal (too early) git-svn-id: http://svn.miranda-ng.org/main/trunk@10901 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/!Deprecated/MSN/src/msn_misc.cpp | 1293 ------------------------------ 1 file changed, 1293 deletions(-) delete mode 100644 plugins/!Deprecated/MSN/src/msn_misc.cpp (limited to 'plugins/!Deprecated/MSN/src/msn_misc.cpp') diff --git a/plugins/!Deprecated/MSN/src/msn_misc.cpp b/plugins/!Deprecated/MSN/src/msn_misc.cpp deleted file mode 100644 index d370429c57..0000000000 --- a/plugins/!Deprecated/MSN/src/msn_misc.cpp +++ /dev/null @@ -1,1293 +0,0 @@ -/* -Plugin of Miranda IM for communicating with users of the MSN Messenger protocol. - -Copyright (c) 2012-2014 Miranda NG Team -Copyright (c) 2006-2012 Boris Krasnovskiy. -Copyright (c) 2003-2005 George Hazan. -Copyright (c) 2002-2003 Richard Hughes (original version). - -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, see . -*/ - -#include "msn_global.h" -#include "msn_proto.h" -#include "version.h" - - -///////////////////////////////////////////////////////////////////////////////////////// -// MirandaStatusToMSN - status helper functions - -const char* CMsnProto::MirandaStatusToMSN(int status) -{ - switch(status) - { - case ID_STATUS_OFFLINE: return "FLN"; - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - case ID_STATUS_NA: - case ID_STATUS_AWAY: return "AWY"; - case ID_STATUS_DND: - case ID_STATUS_OCCUPIED: return "BSY"; - case ID_STATUS_INVISIBLE: return "HDN"; - case ID_STATUS_IDLE: return "IDL"; - default: return "NLN"; -} } - -WORD CMsnProto::MSNStatusToMiranda(const char *status) -{ - switch((*(PDWORD)status&0x00FFFFFF) | 0x20000000) - { - case ' LDI': return ID_STATUS_IDLE; - case ' NLN': return ID_STATUS_ONLINE; - case ' NHP': - case ' NUL': - case ' BRB': - case ' YWA': return ID_STATUS_AWAY; - case ' YSB': return ID_STATUS_OCCUPIED; - case ' NDH': return ID_STATUS_INVISIBLE; - default: return ID_STATUS_OFFLINE; - } -} - -char** CMsnProto::GetStatusMsgLoc(int status) -{ - static const int modes[MSN_NUM_MODES] = - { - ID_STATUS_ONLINE, - ID_STATUS_AWAY, - ID_STATUS_DND, - ID_STATUS_NA, - ID_STATUS_OCCUPIED, - ID_STATUS_FREECHAT, - ID_STATUS_INVISIBLE, - ID_STATUS_ONTHEPHONE, - ID_STATUS_OUTTOLUNCH, - }; - - for (int i=0; i < MSN_NUM_MODES; i++) - if (modes[i] == status) return &msnModeMsgs[i]; - - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_AddAuthRequest - adds the authorization event to the database - -void CMsnProto::MSN_AddAuthRequest(const char *email, const char *nick, const char *reason) -{ - //blob is: UIN=0(DWORD), hContact(DWORD), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ) - - MCONTACT hContact = MSN_HContactFromEmail(email, nick, true, true); - - int emaillen = (int)strlen(email); - - if (nick == NULL) nick = ""; - int nicklen = (int)strlen(nick); - - if (reason == NULL) reason = ""; - int reasonlen = (int)strlen(reason); - - PROTORECVEVENT pre = { 0 }; - pre.flags = PREF_UTF; - pre.timestamp = (DWORD)time(NULL); - pre.lParam = sizeof(DWORD) + sizeof(HANDLE) + nicklen + emaillen + 5 + reasonlen; - - char* pCurBlob = (char*)alloca(pre.lParam); - pre.szMessage = pCurBlob; - - *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID - *(PDWORD)pCurBlob = (DWORD)hContact; pCurBlob += sizeof(DWORD); // Contact Handle - strcpy(pCurBlob, nick); pCurBlob += nicklen + 1; // Nickname - *pCurBlob = '\0'; pCurBlob++; // First Name - *pCurBlob = '\0'; pCurBlob++; // Last Name - strcpy(pCurBlob, email); pCurBlob += emaillen + 1; // E-mail - strcpy(pCurBlob, reason); // Reason - - ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsnProto::InitCustomFolders(void) -{ - if (InitCstFldRan) return; - - TCHAR folder[MAX_PATH]; - mir_sntprintf(folder, SIZEOF(folder), _T("%%miranda_avatarcache%%\\%S"), m_szModuleName); - hCustomSmileyFolder = FoldersRegisterCustomPathT(LPGEN("Custom Smileys"), m_szModuleName, folder, m_tszUserName); - - InitCstFldRan = true; -} - - -char* MSN_GetAvatarHash(char* szContext, char** pszUrl) -{ - if (pszUrl) - *pszUrl = NULL; - - if (szContext == NULL) - return NULL; - - char *res = NULL; - - ezxml_t xmli = ezxml_parse_str(NEWSTR_ALLOCA(szContext), strlen(szContext)); - const char *szAvatarHash = ezxml_attr(xmli, "SHA1D"); - if (szAvatarHash != NULL) { - unsigned hashLen; - mir_ptr hash((BYTE*)mir_base64_decode(szAvatarHash, &hashLen)); - if (hash) - res = arrayToHex(hash, hashLen); - - if (pszUrl) { - const char *pszUrlAttr; - for (int i=0; ; i++) { - char szSetting[20]; - if (i == 0) - strcpy(szSetting, "Url"); - else - mir_snprintf(szSetting, sizeof(szSetting), "Url%d", i); - pszUrlAttr = ezxml_attr(xmli, szSetting); - if (pszUrlAttr == NULL) - break; - - if (pszUrlAttr[0] != 0) { - *pszUrl = mir_strdup(pszUrlAttr); - break; - } - } - } - } - ezxml_free(xmli); - - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_GetAvatarFileName - gets a file name for an contact's avatar - -void CMsnProto::MSN_GetAvatarFileName(MCONTACT hContact, TCHAR* pszDest, size_t cbLen, const TCHAR *ext) -{ - size_t tPathLen = mir_sntprintf(pszDest, cbLen, _T("%s\\%S"), VARST(_T("%miranda_avatarcache%")), m_szModuleName); - - if (_taccess(pszDest, 0)) - CreateDirectoryTreeT(pszDest); - - size_t tPathLen2 = tPathLen; - if (hContact != NULL) { - DBVARIANT dbv; - if (getString(hContact, "PictContext", &dbv) == 0) { - char* szAvatarHash = MSN_GetAvatarHash(dbv.pszVal); - if (szAvatarHash != NULL) { - TCHAR *sztAvatarHash = mir_a2t(szAvatarHash); - tPathLen += mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s."), sztAvatarHash); - mir_free(sztAvatarHash); - mir_free(szAvatarHash); - } - else { - delSetting(hContact, "PictContext"); - if (cbLen) pszDest[0] = 0; - } - db_free(&dbv); - } - else if (cbLen) - pszDest[0] = 0; - } - else { - TCHAR *sztModuleName = mir_a2t(m_szModuleName); - tPathLen += mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s avatar."), sztModuleName); - mir_free(sztModuleName); - } - - if (ext == NULL) { - mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("*")); - - bool found = false; - _tfinddata_t c_file; - long hFile = _tfindfirst(pszDest, &c_file); - if (hFile > -1L) { - do { - if (_tcsrchr(c_file.name, '.')) { - mir_sntprintf(pszDest + tPathLen2, cbLen - tPathLen2, _T("\\%s"), c_file.name); - found = true; - } - } - while(_tfindnext(hFile, &c_file) == 0); - _findclose( hFile ); - } - - if (!found) pszDest[0] = 0; - } - else { - tPathLen--; - mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, ext); - } -} - -int CMsnProto::MSN_SetMyAvatar(const TCHAR* sztFname, void* pData, size_t cbLen) -{ - mir_sha1_ctx sha1ctx; - BYTE sha1c[MIR_SHA1_HASH_SIZE], sha1d[MIR_SHA1_HASH_SIZE]; - - char *szFname = mir_utf8encodeT(sztFname); - - mir_sha1_init(&sha1ctx); - mir_sha1_append(&sha1ctx, (BYTE*)pData, (int)cbLen); - mir_sha1_finish(&sha1ctx, sha1d); - - ptrA szSha1d( mir_base64_encode((PBYTE)sha1d, sizeof(sha1d))); - - mir_sha1_init(&sha1ctx); - ezxml_t xmlp = ezxml_new("msnobj"); - - mir_sha1_append(&sha1ctx, (PBYTE)"Creator", 7); - mir_sha1_append(&sha1ctx, (PBYTE)MyOptions.szEmail, (int)strlen(MyOptions.szEmail)); - ezxml_set_attr(xmlp, "Creator", MyOptions.szEmail); - - char szFileSize[20]; - _ultoa((unsigned)cbLen, szFileSize, 10); - mir_sha1_append(&sha1ctx, (PBYTE)"Size", 4); - mir_sha1_append(&sha1ctx, (PBYTE)szFileSize, (int)strlen(szFileSize)); - ezxml_set_attr(xmlp, "Size", szFileSize); - - mir_sha1_append(&sha1ctx, (PBYTE)"Type", 4); - mir_sha1_append(&sha1ctx, (PBYTE)"3", 1); // MSN_TYPEID_DISPLAYPICT - ezxml_set_attr(xmlp, "Type", "3"); - - mir_sha1_append(&sha1ctx, (PBYTE)"Location", 8); - mir_sha1_append(&sha1ctx, (PBYTE)szFname, (int)strlen(szFname)); - ezxml_set_attr(xmlp, "Location", szFname); - - mir_sha1_append(&sha1ctx, (PBYTE)"Friendly", 8); - mir_sha1_append(&sha1ctx, (PBYTE)"AAA=", 4); - ezxml_set_attr(xmlp, "Friendly", "AAA="); - - mir_sha1_append(&sha1ctx, (PBYTE)"SHA1D", 5); - mir_sha1_append(&sha1ctx, (PBYTE)(char*)szSha1d, (int)strlen(szSha1d)); - ezxml_set_attr(xmlp, "SHA1D", szSha1d); - - mir_sha1_finish(&sha1ctx, sha1c); - - ptrA szSha1c( mir_base64_encode((PBYTE)sha1c, sizeof(sha1c))); - - // ezxml_set_attr(xmlp, "SHA1C", szSha1c); - - char* szBuffer = ezxml_toxml(xmlp, false); - ezxml_free(xmlp); - mir_free(szFname); - ptrA szEncodedBuffer(mir_urlEncode(szBuffer)); - free(szBuffer); - - const TCHAR *szExt; - int fmt = ProtoGetBufferFormat(pData, &szExt); - if (fmt == PA_FORMAT_UNKNOWN) - return fmt; - - TCHAR szFileName[MAX_PATH]; - MSN_GetAvatarFileName(NULL, szFileName, SIZEOF(szFileName), NULL); - _tremove(szFileName); - - MSN_GetAvatarFileName(NULL, szFileName, SIZEOF(szFileName), szExt); - - int fileId = _topen(szFileName, _O_CREAT | _O_TRUNC | _O_WRONLY | O_BINARY, _S_IREAD | _S_IWRITE); - if (fileId >= 0) { - _write(fileId, pData, (unsigned)cbLen); - _close(fileId); - - char szAvatarHashdOld[41] = ""; - db_get_static(NULL, m_szModuleName, "AvatarHash", szAvatarHashdOld, sizeof(szAvatarHashdOld)); - char *szAvatarHash = arrayToHex(sha1d, sizeof(sha1d)); - if (strcmp(szAvatarHashdOld, szAvatarHash)) { - setString("PictObject", szEncodedBuffer); - setString("AvatarHash", szAvatarHash); - } - mir_free(szAvatarHash); - } - else MSN_ShowError("Cannot set avatar. File '%s' could not be created/overwritten", szFileName); - - return fmt; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_GetCustomSmileyFileName - gets a file name for an contact's custom smiley - -void CMsnProto::MSN_GetCustomSmileyFileName(MCONTACT hContact, TCHAR* pszDest, size_t cbLen, const char* SmileyName, int type) -{ - size_t tPathLen; - - InitCustomFolders(); - - TCHAR* path = (TCHAR*)alloca(cbLen * sizeof(TCHAR)); - if (hCustomSmileyFolder == NULL || FoldersGetCustomPathT(hCustomSmileyFolder, path, (int)cbLen, _T(""))) { - TCHAR *tmpPath = Utils_ReplaceVarsT(_T("%miranda_userdata%")); - TCHAR *tszModuleName = mir_a2t(m_szModuleName); - tPathLen = mir_sntprintf(pszDest, cbLen, _T("%s\\%s\\CustomSmiley"), tmpPath, tszModuleName); - mir_free(tszModuleName); - mir_free(tmpPath); - } - else { - _tcscpy(pszDest, path); - tPathLen = _tcslen(pszDest); - } - - if (hContact != NULL) - { - DBVARIANT dbv = {0}; - if (getTString(hContact, "e-mail", &dbv)) - { - dbv.type = DBVT_ASCIIZ; - dbv.ptszVal = (TCHAR*)mir_alloc(11); - _ui64tot((UINT_PTR)hContact, dbv.ptszVal, 10); - } - - tPathLen += mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s"), dbv.ptszVal); - db_free(&dbv); - } - else { - TCHAR *tszModuleName = mir_a2t(m_szModuleName); - tPathLen += mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s"), tszModuleName); - mir_free(tszModuleName); - } - - bool exist = _taccess(pszDest, 0) == 0; - - if (type == 0) { - if (!exist) pszDest[0] = 0; - return; - } - - if (!exist) - CreateDirectoryTreeT(pszDest); - - TCHAR *sztSmileyName = mir_a2t(SmileyName); - mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s.%s"), sztSmileyName, - type == MSN_APPID_CUSTOMSMILEY ? _T("png") : _T("gif")); - mir_free(sztSmileyName); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_GoOffline - performs several actions when a server goes offline - -void CMsnProto::MSN_GoOffline(void) -{ - if (m_iStatus == ID_STATUS_OFFLINE) return; - - msnLoggedIn = false; - - if (mStatusMsgTS) - ForkThread(&CMsnProto::msn_storeProfileThread, NULL); - - mir_free(msnPreviousUUX); - msnPreviousUUX = NULL; - msnSearchId = NULL; - - if (!Miranda_Terminated()) - MSN_EnableMenuItems(false); - - MSN_FreeGroups(); - MsgQueue_Clear(); - clearCachedMsg(); - - if (!Miranda_Terminated()) { - int msnOldStatus = m_iStatus; m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)msnOldStatus, ID_STATUS_OFFLINE); - isIdle = false; - - int count = -1; - for (;;) { - MsnContact *msc = Lists_GetNext(count); - if (msc == NULL) break; - - if (ID_STATUS_OFFLINE != getWord(msc->hContact, "Status", ID_STATUS_OFFLINE)) { - setWord(msc->hContact, "Status", ID_STATUS_OFFLINE); - setDword(msc->hContact, "IdleTS", 0); - } - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_SendMessage - formats and sends a MSG packet through the server - -int ThreadData::sendMessage(int msgType, const char* email, int netId, const char* parMsg, int parFlags) -{ - char buf[2048]; - int off; - - off = mir_snprintf(buf, sizeof(buf), "MIME-Version: 1.0\r\n"); - - if ((parFlags & MSG_DISABLE_HDR) == 0) { - char tFontName[100], tFontStyle[3]; - DWORD tFontColor; - - strcpy(tFontName, "Arial"); - - if (proto->getByte("SendFontInfo", 1)) { - char* p; - - DBVARIANT dbv; - if (!db_get_s(NULL, "SRMsg", "Font0", &dbv)) { - for (p = dbv.pszVal; *p; p++) - if (BYTE(*p) >= 128 || *p < 32) - break; - - if (*p == 0) { - strncpy_s(tFontName, sizeof(tFontName), ptrA(mir_urlEncode(dbv.pszVal)), _TRUNCATE); - db_free(&dbv); - } - } - - int tStyle = db_get_b(NULL, "SRMsg", "Font0Sty", 0); - p = tFontStyle; - if (tStyle & 1) *p++ = 'B'; - if (tStyle & 2) *p++ = 'I'; - *p = 0; - - tFontColor = db_get_dw(NULL, "SRMsg", "Font0Col", 0); - } - else { - tFontColor = 0; - tFontStyle[0] = 0; - } - - if (parFlags & MSG_OFFLINE) - off += mir_snprintf(buf + off, sizeof(buf) - off, "Dest-Agent: client\r\n"); - - off += mir_snprintf(buf + off, sizeof(buf) - off, "Content-Type: text/plain; charset=UTF-8\r\n"); - off += mir_snprintf(buf + off, sizeof(buf) - off, "X-MMS-IM-Format: FN=%s; EF=%s; CO=%x; CS=0; PF=31%s\r\n\r\n", - tFontName, tFontStyle, tFontColor, (parFlags & MSG_RTL) ? ";RL=1" : ""); - } - - int seq; - if (netId == NETID_YAHOO || netId == NETID_MOB || (parFlags & MSG_OFFLINE)) - seq = sendPacket("UUM", "%s %d %c %d\r\n%s%s", email, netId, msgType, - strlen(parMsg)+off, buf, parMsg); - else - seq = sendPacket("MSG", "%c %d\r\n%s%s", msgType, - strlen(parMsg)+off, buf, parMsg); - - return seq; -} - -void ThreadData::sendCaps(void) -{ - char mversion[100], capMsg[1000]; - CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof(mversion), (LPARAM)mversion); - - mir_snprintf(capMsg, sizeof(capMsg), - "Content-Type: text/x-clientcaps\r\n\r\n" - "Client-Name: Miranda NG %s (MSN v.%s)\r\n", - mversion, __VERSION_STRING_DOTS); - - sendMessage('U', NULL, 1, capMsg, MSG_DISABLE_HDR); -} - -void ThreadData::sendTerminate(void) -{ - if (!termPending) { - sendPacket("OUT", NULL); - termPending = true; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_SendRawPacket - sends a packet accordingly to the MSN protocol - -int ThreadData::sendRawMessage(int msgType, const char* data, int datLen) -{ - if (data == NULL) - data = ""; - - if (datLen == -1) - datLen = (int)strlen(data); - - char* buf = (char*)alloca(datLen + 100); - - int thisTrid = InterlockedIncrement(&mTrid); - int nBytes = mir_snprintf(buf, 100, "MSG %d %c %d\r\nMIME-Version: 1.0\r\n", - thisTrid, msgType, datLen + 19); - memcpy(buf + nBytes, data, datLen); - - send(buf, nBytes + datLen); - - return thisTrid; -} - -// Typing notifications support - -void CMsnProto::MSN_SendTyping(ThreadData* info, const char* email, int netId ) -{ - char tCommand[1024]; - mir_snprintf(tCommand, sizeof(tCommand), - "Content-Type: text/x-msmsgscontrol\r\n" - "TypingUser: %s\r\n\r\n\r\n", MyOptions.szEmail); - - info->sendMessage(netId == NETID_MSN ? 'U' : '2', email, netId, tCommand, MSG_DISABLE_HDR); -} - - -static ThreadData* FindThreadTimer(UINT timerId) -{ - ThreadData* res = NULL; - for (int i = 0; i < g_Instances.getCount() && res == NULL; ++i) - res = g_Instances[i].MSN_GetThreadByTimer(timerId); - - return res; -} - -static VOID CALLBACK TypingTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) -{ - ThreadData* T = FindThreadTimer(idEvent); - if (T != NULL) - T->proto->MSN_SendTyping(T, NULL, 1); - else - KillTimer(NULL, idEvent); -} - - -void CMsnProto::MSN_StartStopTyping(ThreadData* info, bool start) -{ - if (start && info->mTimerId == 0) { - info->mTimerId = SetTimer(NULL, 0, 5000, TypingTimerProc); - MSN_SendTyping(info, NULL, 1); - } - else if (!start && info->mTimerId != 0) { - KillTimer(NULL, info->mTimerId); - info->mTimerId = 0; - } -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_SendStatusMessage - notify a server about the status message change - -// Helper to process texts -static char * HtmlEncodeUTF8T(const TCHAR *src) -{ - if (src == NULL) - return mir_strdup(""); - - return HtmlEncode(UTF8(src)); -} - -void CMsnProto::MSN_SendStatusMessage(const char* msg) -{ - if (!msnLoggedIn) - return; - - char* msgEnc = HtmlEncode(msg ? msg : ""); - - size_t sz; - char szMsg[2048]; - if (msnCurrentMedia.cbSize == 0) { - sz = mir_snprintf(szMsg, sizeof(szMsg), "%s%s" - "", - msgEnc, MyOptions.szMachineGuid); - } - else { - char *szFormatEnc; - if (ServiceExists(MS_LISTENINGTO_GETPARSEDTEXT)) { - LISTENINGTOINFO lti = {0}; - lti.cbSize = sizeof(lti); - if (msnCurrentMedia.ptszTitle != NULL) lti.ptszTitle = _T("{0}"); - if (msnCurrentMedia.ptszArtist != NULL) lti.ptszArtist = _T("{1}"); - if (msnCurrentMedia.ptszAlbum != NULL) lti.ptszAlbum = _T("{2}"); - if (msnCurrentMedia.ptszTrack != NULL) lti.ptszTrack = _T("{3}"); - if (msnCurrentMedia.ptszYear != NULL) lti.ptszYear = _T("{4}"); - if (msnCurrentMedia.ptszGenre != NULL) lti.ptszGenre = _T("{5}"); - if (msnCurrentMedia.ptszLength != NULL) lti.ptszLength = _T("{6}"); - if (msnCurrentMedia.ptszPlayer != NULL) lti.ptszPlayer = _T("{7}"); - if (msnCurrentMedia.ptszType != NULL) lti.ptszType = _T("{8}"); - - TCHAR *tmp = (TCHAR *)CallService(MS_LISTENINGTO_GETPARSEDTEXT, (WPARAM) _T("%title% - %artist%"), (LPARAM) <i); - szFormatEnc = HtmlEncodeUTF8T(tmp); - mir_free(tmp); - } - else szFormatEnc = HtmlEncodeUTF8T(_T("{0} - {1}")); - - char *szArtist = HtmlEncodeUTF8T(msnCurrentMedia.ptszArtist); - char *szAlbum = HtmlEncodeUTF8T(msnCurrentMedia.ptszAlbum); - char *szTitle = HtmlEncodeUTF8T(msnCurrentMedia.ptszTitle); - char *szTrack = HtmlEncodeUTF8T(msnCurrentMedia.ptszTrack); - char *szYear = HtmlEncodeUTF8T(msnCurrentMedia.ptszYear); - char *szGenre = HtmlEncodeUTF8T(msnCurrentMedia.ptszGenre); - char *szLength = HtmlEncodeUTF8T(msnCurrentMedia.ptszLength); - char *szPlayer = HtmlEncodeUTF8T(msnCurrentMedia.ptszPlayer); - char *szType = HtmlEncodeUTF8T(msnCurrentMedia.ptszType); - - sz = mir_snprintf(szMsg, sizeof szMsg, - "" - "%s" - "%s\\0%s\\01\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0\\0" - "%s" - "" - "", - msgEnc, szPlayer, szType, szFormatEnc, szTitle, szArtist, szAlbum, szTrack, szYear, szGenre, - szLength, szPlayer, szType, MyOptions.szMachineGuid); - - mir_free(szArtist); - mir_free(szAlbum); - mir_free(szTitle); - mir_free(szTrack); - mir_free(szYear); - mir_free(szGenre); - mir_free(szLength); - mir_free(szPlayer); - mir_free(szType); - } - mir_free(msgEnc); - - if (msnPreviousUUX == NULL || strcmp(msnPreviousUUX, szMsg)) { - replaceStr(msnPreviousUUX, szMsg); - msnNsThread->sendPacket("UUX", "%d\r\n%s", sz, szMsg); - mStatusMsgTS = clock(); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_SendPacket - sends a packet accordingly to the MSN protocol - -int ThreadData::sendPacket(const char* cmd, const char* fmt,...) -{ - if (this == NULL) return 0; - - size_t strsize = 512; - char* str = (char*)mir_alloc(strsize); - - int thisTrid = 0; - - if (fmt == NULL) - mir_snprintf(str, strsize, "%s", cmd); - else { - thisTrid = InterlockedIncrement(&mTrid); - if (fmt[0] == '\0') - mir_snprintf(str, strsize, "%s %d", cmd, thisTrid); - else { - va_list vararg; - va_start(vararg, fmt); - - int paramStart = mir_snprintf(str, strsize, "%s %d ", cmd, thisTrid); - while (mir_vsnprintf(str+paramStart, strsize-paramStart-3, fmt, vararg) == -1) - str = (char*)mir_realloc(str, strsize += 512); - - str[strsize-3] = 0; - va_end(vararg); - } - } - - if (strchr(str, '\r') == NULL) - strcat(str,"\r\n"); - - int result = send(str, strlen(str)); - mir_free(str); - return (result > 0) ? thisTrid : -1; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_SetServerStatus - changes plugins status at the server - -void CMsnProto::MSN_SetServerStatus(int newStatus) -{ - debugLogA("Setting MSN server status %d, logged in = %d", newStatus, msnLoggedIn); - - if (!msnLoggedIn) - return; - - if (isIdle) - newStatus = ID_STATUS_IDLE; - - const char* szStatusName = MirandaStatusToMSN(newStatus); - - if (newStatus != ID_STATUS_OFFLINE) { - DBVARIANT msnObject = {0}; - if (ServiceExists(MS_AV_SETMYAVATAR)) - getString("PictObject", &msnObject); - - // Capabilties: WLM 2009, Chunking, UUN Bootstrap - myFlags = 0xA0000000 | cap_SupportsChunking | cap_SupportsP2PBootstrap | cap_SupportsSipInvite; - if (getByte("MobileEnabled", 0) && getByte("MobileAllowed", 0)) - myFlags |= cap_MobileEnabled; - - unsigned myFlagsEx = capex_SupportsPeerToPeerV2; - - char szMsg[256]; - if (m_iStatus < ID_STATUS_ONLINE) { - int sz = mir_snprintf(szMsg, sizeof(szMsg), - "%u:%u", myFlags, myFlagsEx); - msnNsThread->sendPacket( "UUX", "%d\r\n%s", sz, szMsg ); - - msnNsThread->sendPacket("BLP", msnOtherContactsBlocked ? "BL" : "AL"); - - DBVARIANT dbv; - if (!getStringUtf("Nick", &dbv)) { - if (dbv.pszVal[0]) - MSN_SetNicknameUtf(dbv.pszVal); - db_free(&dbv); - } - } - - char *szPlace; - DBVARIANT dbv; - if (!getStringUtf("Place", &dbv)) - szPlace = dbv.pszVal; - else { - TCHAR buf[128] = _T("Miranda"); - DWORD buflen = SIZEOF(buf); - GetComputerName(buf, &buflen); - szPlace = mir_utf8encodeT(buf); - } - - int sz = mir_snprintf(szMsg, sizeof(szMsg), - "" - "%s" - "%s" - "1" - "%s" - "", - szPlace, newStatus == ID_STATUS_IDLE ? "true" : "false", szStatusName); - msnNsThread->sendPacket("UUX", "%d\r\n%s", sz, szMsg); - mir_free(szPlace); - - if (newStatus != ID_STATUS_IDLE) { - char** msgptr = GetStatusMsgLoc(newStatus); - if (msgptr != NULL) - MSN_SendStatusMessage(*msgptr); - } - - msnNsThread->sendPacket("CHG", "%s %u:%u %s", szStatusName, myFlags, myFlagsEx, msnObject.pszVal ? msnObject.pszVal : "0"); - db_free(&msnObject); - } - else msnNsThread->sendPacket("CHG", szStatusName); -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// Display Hotmail Inbox thread - -static const char postdataM[] = "ct=%u&bver=7&wa=wsignin1.0&ru=%s&pl=MBI"; -static const char postdataS[] = "ct=%u&bver=7&id=73625&ru=%s&js=yes&pl=%%3Fid%%3D73625"; - -void CMsnProto::MsnInvokeMyURL(bool ismail, const char* url) -{ - char* hippy = NULL; - if (!url) - url = ismail ? "http://mail.live.com?rru=inbox" : "http://profile.live.com"; - - const char *postdata = ismail ? postdataM : postdataS; - - char passport[256]; - if (db_get_static(NULL, m_szModuleName, "MsnPassportHost", passport, 256)) - strcpy(passport, "https://login.live.com/"); - - char *p = strchr(passport, '/'); - if (p && p[1] == '/') p = strchr(p + 2, '/'); - if (p) - *p = 0; - - CMStringA post = HotmailLogin(CMStringA().Format(postdata, (unsigned)time(NULL), ptrA(mir_urlEncode(url)))); - if (!post.IsEmpty()) { - CMStringA hippy(passport); - hippy.AppendFormat("/ppsecure/sha1auth.srf?lc=%d&token=%s", itoa(langpref, passport, 10), ptrA(mir_urlEncode(post))); - - debugLogA("Starting URL: '%s'", hippy); - CallService(MS_UTILS_OPENURL, 1, (LPARAM)hippy.GetString()); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_ShowError - shows an error - -void CMsnProto::MSN_ShowError(const char* msgtext, ...) -{ - TCHAR tBuffer[4096]; - va_list tArgs; - - TCHAR *buf = Langpack_PcharToTchar(msgtext); - - va_start(tArgs, msgtext); - mir_vsntprintf(tBuffer, SIZEOF(tBuffer), buf, tArgs); - va_end(tArgs); - - mir_free(buf); - - MSN_ShowPopup(m_tszUserName, tBuffer, MSN_ALLOW_MSGBOX | MSN_SHOW_ERROR, NULL); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Popup plugin window proc - -LRESULT CALLBACK NullWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - PopupData *tData = (PopupData*)PUGetPluginData(hWnd); - - switch (msg) { - case WM_COMMAND: - if (tData != NULL) { - if (tData->flags & MSN_HOTMAIL_POPUP) { - MCONTACT hContact = tData->proto->MSN_HContactFromEmail(tData->proto->MyOptions.szEmail, NULL); - if (hContact) CallService(MS_CLIST_REMOVEEVENT, hContact, (LPARAM) 1); - if (tData->flags & MSN_ALLOW_ENTER) - tData->proto->MsnInvokeMyURL(true, tData->url); - } - else if (tData->url != NULL) - CallService(MS_UTILS_OPENURL, 1, (LPARAM)tData->url); - } - PUDeletePopup(hWnd); - break; - - case WM_CONTEXTMENU: - if (tData != NULL && tData->flags & MSN_HOTMAIL_POPUP) { - MCONTACT hContact = tData->proto->MSN_HContactFromEmail(tData->proto->MyOptions.szEmail, NULL); - if (hContact) - CallService(MS_CLIST_REMOVEEVENT, hContact, (LPARAM) 1); - } - PUDeletePopup(hWnd); - break; - - case UM_FREEPLUGINDATA: - if (tData != NULL && tData != (PopupData*)CALLSERVICE_NOTFOUND) { - mir_free(tData->title); - mir_free(tData->text); - mir_free(tData->url); - mir_free(tData); - } - break; - } - - return DefWindowProc(hWnd, msg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// InitPopups - popup plugin support - -void CMsnProto::InitPopups(void) -{ - TCHAR desc[256]; - char name[256]; - - POPUPCLASS ppc = { sizeof(ppc) }; - ppc.flags = PCF_TCHAR; - ppc.PluginWindowProc = NullWindowProc; - ppc.hIcon = LoadIconEx("main"); - ppc.ptszDescription = desc; - ppc.pszName = name; - - ppc.colorBack = RGB(173, 206, 247); - ppc.colorText = GetSysColor(COLOR_WINDOWTEXT); - ppc.iSeconds = 3; - mir_sntprintf(desc, SIZEOF(desc), _T("%s/%s"), m_tszUserName, TranslateT("Hotmail")); - mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Hotmail"); - hPopupHotmail = Popup_RegisterClass(&ppc); - - ppc.colorBack = RGB(173, 206, 247); - ppc.colorText = GetSysColor(COLOR_WINDOWTEXT); - ppc.iSeconds = 3; - mir_sntprintf(desc, SIZEOF(desc), _T("%s/%s"), m_tszUserName, TranslateT("Notify")); - mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Notify"); - hPopupNotify = Popup_RegisterClass(&ppc); - - ppc.hIcon = (HICON)LoadImage(NULL, IDI_WARNING, IMAGE_ICON, 0, 0, LR_SHARED); - ppc.colorBack = RGB(191, 0, 0); //Red - ppc.colorText = RGB(255, 245, 225); //Yellow - ppc.iSeconds = 60; - - mir_sntprintf(desc, SIZEOF(desc), _T("%s/%s"), m_tszUserName, TranslateT("Error")); - mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Error"); - hPopupError = Popup_RegisterClass(&ppc); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_ShowPopup - popup plugin support - -void CALLBACK sttMainThreadCallback(PVOID dwParam) -{ - PopupData* pud = (PopupData*)dwParam; - - bool iserr = (pud->flags & MSN_SHOW_ERROR) != 0; - if ((iserr && !pud->proto->MyOptions.ShowErrorsAsPopups) || !ServiceExists(MS_POPUP_ADDPOPUPCLASS)) { - if (pud->flags & MSN_ALLOW_MSGBOX) { - TCHAR szMsg[MAX_SECONDLINE + MAX_CONTACTNAME]; - mir_sntprintf(szMsg, SIZEOF(szMsg), _T("%s:\n%s"), pud->title, pud->text); - MessageBox(NULL, szMsg, TranslateT("MSN Protocol"), - MB_OK | (iserr ? MB_ICONERROR : MB_ICONINFORMATION)); - } - mir_free(pud->title); - mir_free(pud->text); - mir_free(pud->url); - mir_free(pud); - return; - } - - char name[256]; - - POPUPDATACLASS ppd = { sizeof(ppd) }; - ppd.ptszTitle = pud->title; - ppd.ptszText = pud->text; - ppd.PluginData = pud; - ppd.pszClassName = name; - - if (pud->flags & MSN_SHOW_ERROR) - mir_snprintf(name, SIZEOF(name), "%s_%s", pud->proto->m_szModuleName, "Error"); - else if (pud->flags & (MSN_HOTMAIL_POPUP | MSN_ALERT_POPUP)) - mir_snprintf(name, SIZEOF(name), "%s_%s", pud->proto->m_szModuleName, "Hotmail"); - else - mir_snprintf(name, SIZEOF(name), "%s_%s", pud->proto->m_szModuleName, "Notify"); - - CallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&ppd); -} - -void CMsnProto::MSN_ShowPopup(const TCHAR* nickname, const TCHAR* msg, int flags, const char* url, MCONTACT hContact) -{ - if (Miranda_Terminated()) return; - - PopupData *pud = (PopupData*)mir_calloc(sizeof(PopupData)); - pud->flags = flags; - pud->url = mir_strdup(url); - pud->title = mir_tstrdup(nickname); - pud->text = mir_tstrdup(msg); - pud->proto = this; - - CallFunctionAsync(sttMainThreadCallback, pud); -} - - -void CMsnProto::MSN_ShowPopup(const MCONTACT hContact, const TCHAR* msg, int flags) -{ - const TCHAR* nickname = hContact ? GetContactNameT(hContact) : _T("Me"); - MSN_ShowPopup(nickname, msg, flags, NULL, hContact); -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// filetransfer class members - -filetransfer::filetransfer(CMsnProto* prt) -{ - memset(this, 0, sizeof(filetransfer)); - fileId = -1; - std.cbSize = sizeof(std); - std.flags = PFTS_TCHAR; - proto = prt; - - hLockHandle = CreateMutex(NULL, FALSE, NULL); -} - -filetransfer::~filetransfer(void) -{ - if (p2p_sessionid) - proto->debugLogA("Destroying file transfer session %08X", p2p_sessionid); - - WaitForSingleObject(hLockHandle, 2000); - CloseHandle(hLockHandle); - - if (fileId != -1) - { - _close(fileId); - if (p2p_appID != MSN_APPID_FILE && !(std.flags & PFTS_SENDING)) - proto->p2p_pictureTransferFailed(this); - } - - if (!bCompleted && p2p_appID == MSN_APPID_FILE) - { - std.ptszFiles = NULL; - std.totalFiles = 0; - proto->ProtoBroadcastAck(std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, this, 0); - } - - mir_free(p2p_branch); - mir_free(p2p_callID); - mir_free(p2p_dest); - mir_free(p2p_object); - - mir_free(std.tszCurrentFile); - mir_free(std.tszWorkingDir); - if (std.ptszFiles != NULL) - { - for (int i=0; std.ptszFiles[i]; i++) - mir_free(std.ptszFiles[i]); - mir_free(std.ptszFiles); - } - - mir_free(szInvcookie); -} - -void filetransfer::close(void) -{ - if (fileId != -1) _close(fileId); - fileId = -1; -} - -void filetransfer::complete(void) -{ - close(); - - bCompleted = true; - proto->ProtoBroadcastAck(std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, this, 0); -} - -int filetransfer::create(void) -{ - fileId = _topen(std.tszCurrentFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE); - - if (fileId == -1) - proto->MSN_ShowError("Cannot create file '%s' during a file transfer", std.tszCurrentFile); - // else if (std.currentFileSize != 0) - // _chsize(fileId, std.currentFileSize); - - return fileId; -} - -int filetransfer::openNext(void) -{ - if (fileId != -1) - { - close(); - ++std.currentFileNumber; - ++cf; - } - - while (std.ptszFiles && std.ptszFiles[cf]) - { - struct _stati64 statbuf; - if (_tstati64(std.ptszFiles[cf], &statbuf) == 0 && (statbuf.st_mode & _S_IFDIR) == 0) - break; - - ++cf; - } - - if (std.ptszFiles && std.ptszFiles[cf]) - { - bCompleted = false; - replaceStrT(std.tszCurrentFile, std.ptszFiles[cf]); - fileId = _topen(std.tszCurrentFile, _O_BINARY | _O_RDONLY, _S_IREAD); - if (fileId != -1) - { - std.currentFileSize = _filelengthi64(fileId); - std.currentFileProgress = 0; - - p2p_sendmsgid = 0; - p2p_byemsgid = 0; - tType = SERVER_NOTIFICATION; - bAccepted = false; - - mir_free(p2p_branch); p2p_branch = NULL; - mir_free(p2p_callID); p2p_callID = NULL; - } - else - proto->MSN_ShowError("Unable to open file '%s' for the file transfer, error %d", std.tszCurrentFile, errno); - } - - return fileId; -} - -directconnection::directconnection(const char* CallID, const char* Wlid) -{ - memset(this, 0, sizeof(directconnection)); - - wlid = mir_strdup(Wlid); - callId = mir_strdup(CallID); - mNonce = (UUID*)mir_alloc(sizeof(UUID)); - UuidCreate(mNonce); - ts = time(NULL); -} - -directconnection::~directconnection() -{ - mir_free(wlid); - mir_free(callId); - mir_free(mNonce); - mir_free(xNonce); -} - - -char* directconnection::calcHashedNonce(UUID* nonce) -{ - mir_sha1_ctx sha1ctx; - BYTE sha[MIR_SHA1_HASH_SIZE]; - - mir_sha1_init(&sha1ctx); - mir_sha1_append(&sha1ctx, (BYTE*)nonce, sizeof(UUID)); - mir_sha1_finish(&sha1ctx, sha); - - char* p; - UuidToStringA((UUID*)&sha, (BYTE**)&p); - size_t len = strlen(p) + 3; - char* result = (char*)mir_alloc(len); - mir_snprintf(result, len, "{%s}", p); - _strupr(result); - RpcStringFreeA((BYTE**)&p); - - return result; -} - -char* directconnection::mNonceToText(void) -{ - char* p; - UuidToStringA(mNonce, (BYTE**)&p); - size_t len = strlen(p) + 3; - char* result = (char*)mir_alloc(len); - mir_snprintf(result, len, "{%s}", p); - _strupr(result); - RpcStringFreeA((BYTE**)&p); - - return result; -} - - -void directconnection::xNonceToBin(UUID* nonce) -{ - size_t len = strlen(xNonce); - char *p = (char*)alloca(len); - strcpy(p, xNonce + 1); - p[len-2] = 0; - UuidFromStringA((BYTE*)p, nonce); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// TWinErrorCode class - -TWinErrorCode::TWinErrorCode() : mErrorText(NULL) -{ - mErrorCode = ::GetLastError(); -} - -TWinErrorCode::~TWinErrorCode() -{ - mir_free(mErrorText); -} - -char* TWinErrorCode::getText() -{ - if (mErrorText == NULL) - return NULL; - - int tBytes = 0; - mErrorText = (char*)mir_alloc(256); - - if (tBytes == 0) - tBytes = FormatMessageA( - FORMAT_MESSAGE_FROM_SYSTEM, NULL, - mErrorCode, LANG_NEUTRAL, mErrorText, 256, NULL); - - if (tBytes == 0) - tBytes = mir_snprintf(mErrorText, 256, "unknown Windows error code %d", mErrorCode); - - *mErrorText = (char)tolower(*mErrorText); - - if (mErrorText[tBytes-1] == '\n') - mErrorText[--tBytes] = 0; - if (mErrorText[tBytes-1] == '\r') - mErrorText[--tBytes] = 0; - if (mErrorText[tBytes-1] == '.') - mErrorText[tBytes-1] = 0; - - return mErrorText; -} - -bool CMsnProto::MSN_IsMyContact(MCONTACT hContact) -{ - const char* szProto = GetContactProto(hContact); - return szProto != NULL && strcmp(m_szModuleName, szProto) == 0; -} - -bool CMsnProto::MSN_IsMeByContact(MCONTACT hContact, char* szEmail) -{ - char tEmail[MSN_MAX_EMAIL_LEN]; - char *emailPtr = szEmail ? szEmail : tEmail; - - *emailPtr = 0; - if (db_get_static(hContact, m_szModuleName, "e-mail", emailPtr, sizeof(tEmail))) - return false; - - return _stricmp(emailPtr, MyOptions.szEmail) == 0; -} - -bool MSN_MsgWndExist(MCONTACT hContact) -{ - MessageWindowInputData msgWinInData = - { sizeof(MessageWindowInputData), hContact, MSG_WINDOW_UFLAG_MSG_BOTH }; - MessageWindowData msgWinData = {0}; - msgWinData.cbSize = sizeof(MessageWindowData); - - bool res = CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&msgWinInData, (LPARAM)&msgWinData) != 0; - res = res || msgWinData.hwndWindow; - if (res) { - msgWinInData.hContact = db_mc_getMeta(hContact); - if (msgWinInData.hContact != NULL) { - res = CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&msgWinInData, (LPARAM)&msgWinData) != 0; - res |= (msgWinData.hwndWindow == NULL); - } - } - return res; -} - -void MSN_MakeDigest(const char* chl, char* dgst) -{ - //Digest it - DWORD md5hash[4], md5hashOr[4]; - mir_md5_state_t context; - mir_md5_init(&context); - mir_md5_append(&context, (BYTE*)chl, (int)strlen(chl)); - mir_md5_append(&context, (BYTE*)msnProtChallenge, (int)strlen(msnProtChallenge)); - mir_md5_finish(&context, (BYTE*)md5hash); - - memcpy(md5hashOr, md5hash, sizeof(md5hash)); - - size_t i; - for (i=0; i < 4; i++) - md5hash[i] &= 0x7FFFFFFF; - - char chlString[128]; - mir_snprintf(chlString, sizeof(chlString), "%s%s00000000", chl, msnProductID); - chlString[(strlen(chl)+strlen(msnProductID)+7) & 0xF8] = 0; - - LONGLONG high=0, low=0; - int* chlStringArray = (int*)chlString; - for (i=0; i < strlen(chlString) / 4; i += 2) { - LONGLONG temp = chlStringArray[i]; - - temp = (0x0E79A9C1 * temp) % 0x7FFFFFFF; - temp += high; - temp = md5hash[0] * temp + md5hash[1]; - temp = temp % 0x7FFFFFFF; - - high = chlStringArray[i + 1]; - high = (high + temp) % 0x7FFFFFFF; - high = md5hash[2] * high + md5hash[3]; - high = high % 0x7FFFFFFF; - - low = low + high + temp; - } - high = (high + md5hash[1]) % 0x7FFFFFFF; - low = (low + md5hash[3]) % 0x7FFFFFFF; - - md5hashOr[0] ^= high; - md5hashOr[1] ^= low; - md5hashOr[2] ^= high; - md5hashOr[3] ^= low; - - char* str = arrayToHex((PBYTE)md5hashOr, sizeof(md5hashOr)); - strcpy(dgst, str); - mir_free(str); -} - -char* GetGlobalIp(void) -{ - NETLIBIPLIST* ihaddr = (NETLIBIPLIST*)CallService(MS_NETLIB_GETMYIP, 1, 0); - for (unsigned i = 0; i < ihaddr->cbNum; ++i) - if (strchr(ihaddr->szIp[i], ':')) - return mir_strdup(ihaddr->szIp[i]); - - mir_free(ihaddr); - return NULL; -} -- cgit v1.2.3