From de6eb3e4bc30eff928dc932c03812ede3077926a Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 13 Oct 2012 08:54:34 +0000 Subject: MRA: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1900 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MRA/src/Mra_functions.cpp | 1834 +++++++++++++++++++++++++++++++++++ 1 file changed, 1834 insertions(+) create mode 100644 protocols/MRA/src/Mra_functions.cpp (limited to 'protocols/MRA/src/Mra_functions.cpp') diff --git a/protocols/MRA/src/Mra_functions.cpp b/protocols/MRA/src/Mra_functions.cpp new file mode 100644 index 0000000000..7083da1b8d --- /dev/null +++ b/protocols/MRA/src/Mra_functions.cpp @@ -0,0 +1,1834 @@ +#include "Mra.h" + +#define MRA_PASS_CRYPT_VER 2 + +struct SetXStatusData +{ + CMraProto *ppro; + DWORD dwXStatus; + DWORD dwCountdown; + HICON hDlgIcon; +}; + +struct SetBlogStatusData +{ + CMraProto *ppro; + HANDLE hContact; +}; + +#define RECURSION_DATA_STACK_ITEMS_MIN 128 +struct RECURSION_DATA_STACK_ITEM +{ + HANDLE hFind; + DWORD dwFileNameLen; + WIN32_FIND_DATA w32fdFindFileData; +}; + +LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +DWORD MraGetSelfVersionString(LPSTR lpszSelfVersion, size_t dwSelfVersionSize, size_t *pdwSelfVersionSizeRet) +{ + if (!lpszSelfVersion || !dwSelfVersionSize) + return ERROR_INVALID_HANDLE; + + WORD v[4]; + DWORD dwMirVer = CallService(MS_SYSTEM_GETFILEVERSION, 0, (LPARAM)v); + LPSTR lpszUnicode = (IsUnicodeEnv()? " Unicode":""), + lpszSecIM = ( ServiceExists("SecureIM/IsContactSecured")? " + SecureIM":""); + size_t dwSelfVersionSizeRet; + + dwSelfVersionSizeRet = mir_snprintf(lpszSelfVersion, dwSelfVersionSize, "Miranda NG %lu.%lu.%lu.%lu%s (MRA v%lu.%lu.%lu.%lu)%s, version: %lu.%lu", + v[0], v[1], v[2], v[3], lpszUnicode, + __FILEVERSION_STRING, lpszSecIM, PROTO_VERSION_MAJOR, PROTO_VERSION_MINOR); + + if (pdwSelfVersionSizeRet) + *pdwSelfVersionSizeRet = dwSelfVersionSizeRet; + return 0; +} + +DWORD GetParamValue(LPSTR lpszData, size_t dwDataSize, LPSTR lpszParamName, size_t dwParamNameSize, LPSTR lpszParamValue, size_t dwParamValueSize, size_t *pParamValueSizeRet) +{ + if (!lpszData || !dwDataSize || !lpszParamName || !dwParamNameSize || !lpszParamValue || !dwParamValueSize) + return ERROR_INVALID_HANDLE; + + char szData[USER_AGENT_MAX+4096]; + LPSTR lpszParamDataStart, lpszParamDataEnd; + + dwDataSize = ((dwDataSizedwAddrCount = 0; + pmalAddrList->pmaliAddress = (MRA_ADDR_LIST_ITEM*)mir_calloc(sizeof(MRA_ADDR_LIST_ITEM)*dwAllocatedCount); + lpszCurrentItem = lpszAddreses; + + while (TRUE) { + lpszEndItem = (LPSTR)MemoryFindByte((lpszCurrentItem-lpszAddreses), lpszAddreses, dwAddresesSize, ';'); + if (lpszEndItem == NULL) lpszEndItem = (lpszAddreses+dwAddresesSize); + if (!lpszEndItem) + break; + + lpszDelimiter = (LPSTR)MemoryFindByte((lpszCurrentItem-lpszAddreses), lpszAddreses, dwAddresesSize, ':'); + if (!lpszDelimiter) + break; + + if (pmalAddrList->dwAddrCount == dwAllocatedCount) { + dwAllocatedCount += ALLOCATED_COUNT; + pmalAddrList->pmaliAddress = (MRA_ADDR_LIST_ITEM*)mir_realloc(pmalAddrList->pmaliAddress, (sizeof(MRA_ADDR_LIST_ITEM)*dwAllocatedCount)); + } + + (*lpszDelimiter) = 0; + pmalAddrList->pmaliAddress[pmalAddrList->dwAddrCount].dwAddr = inet_addr(lpszCurrentItem); + pmalAddrList->pmaliAddress[pmalAddrList->dwAddrCount].dwPort = StrToUNum32((lpszDelimiter+1), (lpszEndItem-(lpszDelimiter+1))); + (*lpszDelimiter) = ':'; + pmalAddrList->dwAddrCount++; + lpszCurrentItem = (lpszEndItem+1); + + if (lpszEndItem == lpszAddreses + dwAddresesSize) + break; + } + pmalAddrList->pmaliAddress = (MRA_ADDR_LIST_ITEM*)mir_realloc(pmalAddrList->pmaliAddress, (sizeof(MRA_ADDR_LIST_ITEM)*pmalAddrList->dwAddrCount)); + return NO_ERROR; +} + +DWORD MraAddrListGetToBuff(MRA_ADDR_LIST *pmalAddrList, LPSTR lpszBuff, size_t dwBuffSize, size_t *pdwBuffSizeRet) +{ + if (!pmalAddrList || !lpszBuff || !dwBuffSize) + return ERROR_INVALID_HANDLE; + + LPSTR lpszCurPos = lpszBuff; + + for (size_t i = 0;idwAddrCount;i++) + lpszCurPos += mir_snprintf(lpszCurPos, (dwBuffSize-((size_t)lpszCurPos-(size_t)lpszBuff)), "%s:%lu;", + inet_ntoa((*((in_addr*)&pmalAddrList->pmaliAddress[i].dwAddr))), pmalAddrList->pmaliAddress[i].dwPort); + + if (pdwBuffSizeRet) + *pdwBuffSizeRet = lpszCurPos - lpszBuff; + return NO_ERROR; +} + +void CMraProto::MraAddrListStoreToContact(HANDLE hContact, MRA_ADDR_LIST *pmalAddrList) +{ + if (!hContact || !pmalAddrList) + return; + + if (!pmalAddrList->dwAddrCount) + return; + + mraSetDword(hContact, "OldIP", mraGetDword(hContact, "IP", 0)); + mraSetDword(hContact, "IP", HTONL(pmalAddrList->pmaliAddress[0].dwAddr)); + if (pmalAddrList->dwAddrCount > 1) { + mraSetDword(hContact, "OldRealIP", mraGetDword(hContact, "RealIP", 0)); + mraSetDword(hContact, "RealIP", HTONL(pmalAddrList->pmaliAddress[1].dwAddr)); + } +} + +void MraAddrListFree(MRA_ADDR_LIST *pmalAddrList) +{ + if (pmalAddrList) { + mir_free(pmalAddrList->pmaliAddress); + pmalAddrList->dwAddrCount = 0; + } +} + +void CMraProto::DB_MraCreateResidentSetting(LPSTR lpszValueName) +{ + char szSetting[2*MAX_PATH]; + mir_snprintf(szSetting, SIZEOF(szSetting), "%s/%s", m_szModuleName, lpszValueName); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (WPARAM)szSetting); +} + +BOOL DB_GetStaticStringA(HANDLE hContact, LPCSTR lpszModule, LPCSTR lpszValueName, LPSTR lpszRetBuff, size_t dwRetBuffSize, size_t *pdwRetBuffSize) +{ + BOOL bRet = FALSE; + size_t dwReadedStringLen, dwRetBuffSizeLocal; + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING sVal = {0}; + + dbv.type = DBVT_WCHAR; + sVal.pValue = &dbv; + sVal.szModule = lpszModule; + sVal.szSetting = lpszValueName; + if (CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&sVal) == 0) + { + dwReadedStringLen = lstrlenW(dbv.pwszVal); + if (lpszRetBuff && (dwRetBuffSize>dwReadedStringLen)) + { + dwRetBuffSizeLocal = WideCharToMultiByte(MRA_CODE_PAGE, 0, dbv.pwszVal, dwReadedStringLen, lpszRetBuff, dwRetBuffSize, NULL, NULL); + (*((CHAR*)(lpszRetBuff+dwRetBuffSizeLocal))) = 0; + bRet = TRUE; + }else { + dwRetBuffSizeLocal = dwReadedStringLen; + if (lpszRetBuff && dwRetBuffSize >= sizeof(WORD)) (*((WORD*)lpszRetBuff)) = 0; + } + if (pdwRetBuffSize) (*pdwRetBuffSize) = dwRetBuffSizeLocal; + + DBFreeVariant(&dbv); + }else { + if (lpszRetBuff && dwRetBuffSize >= sizeof(WORD)) (*((WORD*)lpszRetBuff)) = 0; + if (pdwRetBuffSize) (*pdwRetBuffSize) = 0; + } + return bRet; +} + + +BOOL DB_GetStaticStringW(HANDLE hContact, LPCSTR lpszModule, LPCSTR lpszValueName, LPWSTR lpwszRetBuff, size_t dwRetBuffSize, size_t *pdwRetBuffSize) +{// sizes in wchars + BOOL bRet = FALSE; + size_t dwReadedStringLen; + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING sVal = {0}; + + dbv.type = DBVT_WCHAR; + sVal.pValue = &dbv; + sVal.szModule = lpszModule; + sVal.szSetting = lpszValueName; + if (CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&sVal) == 0) + { + dwReadedStringLen = lstrlenW(dbv.pwszVal); + if (lpwszRetBuff && (dwRetBuffSize>dwReadedStringLen)) + { + memmove(lpwszRetBuff, dbv.pszVal, (dwReadedStringLen*sizeof(WCHAR)));//include null terminated + (*((WCHAR*)(lpwszRetBuff+dwReadedStringLen))) = 0; + bRet = TRUE; + }else { + if (lpwszRetBuff && dwRetBuffSize >= sizeof(WCHAR)) (*((WCHAR*)lpwszRetBuff)) = 0; + } + if (pdwRetBuffSize) (*pdwRetBuffSize) = dwReadedStringLen; + + DBFreeVariant(&dbv); + }else { + if (lpwszRetBuff && dwRetBuffSize >= sizeof(WCHAR)) (*((WCHAR*)lpwszRetBuff)) = 0; + if (pdwRetBuffSize) (*pdwRetBuffSize) = 0; + } + return bRet; +} + +BOOL DB_SetStringExA(HANDLE hContact, LPCSTR lpszModule, LPCSTR lpszValueName, LPCSTR lpszValue, size_t dwValueSize) +{ + BOOL bRet = FALSE; + + if (lpszValue && dwValueSize) { + LPWSTR lpwszValueLocal; + size_t dwValueSizeLocal; + + dwValueSizeLocal = (dwValueSize+MAX_PATH); + lpwszValueLocal = (LPWSTR)mir_calloc((dwValueSizeLocal*sizeof(WCHAR))); + + if (lpwszValueLocal) { + DBCONTACTWRITESETTING cws = {0}; + + cws.szModule = lpszModule; + cws.szSetting = lpszValueName; + cws.value.type = DBVT_WCHAR; + cws.value.pwszVal = (WCHAR*)lpwszValueLocal; + + dwValueSizeLocal = MultiByteToWideChar(MRA_CODE_PAGE, 0, lpszValue, dwValueSize, lpwszValueLocal, dwValueSizeLocal); + lpwszValueLocal[dwValueSizeLocal] = 0; + bRet = (CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws) == 0); + + mir_free(lpwszValueLocal); + } + } + else { + bRet = TRUE; + DBDeleteContactSetting(hContact, lpszModule, lpszValueName); + } + return bRet; +} + +BOOL DB_SetStringExW(HANDLE hContact, LPCSTR lpszModule, LPCSTR lpszValueName, LPCWSTR lpwszValue, size_t dwValueSize) +{ + BOOL bRet = FALSE; + + if (lpwszValue && dwValueSize) { + LPWSTR lpwszValueLocal = (LPWSTR)mir_calloc(((dwValueSize+MAX_PATH)*sizeof(WCHAR))); + + if (lpwszValueLocal) { + DBCONTACTWRITESETTING cws = {0}; + + cws.szModule = lpszModule; + cws.szSetting = lpszValueName; + cws.value.type = DBVT_WCHAR; + cws.value.pwszVal = (WCHAR*)lpwszValueLocal; + memmove(lpwszValueLocal, lpwszValue, (dwValueSize*sizeof(WCHAR))); + bRet = (CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws) == 0); + + mir_free(lpwszValueLocal); + } + } + else { + bRet = TRUE; + DBDeleteContactSetting(hContact, lpszModule, lpszValueName); + } + return bRet; +} + +int DB_WriteContactSettingBlob(HANDLE hContact, LPCSTR lpszModule, LPCSTR lpszValueName, LPVOID lpValue, size_t dwValueSize) +{ + DBCONTACTWRITESETTING cws = {0}; + + cws.szModule = lpszModule; + cws.szSetting = lpszValueName; + cws.value.type = DBVT_BLOB; + cws.value.pbVal = (LPBYTE)lpValue; + cws.value.cpbVal = (WORD)dwValueSize; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +BOOL DB_GetContactSettingBlob(HANDLE hContact, LPCSTR lpszModule, LPCSTR lpszValueName, LPVOID lpRet, size_t dwRetBuffSize, size_t *pdwRetBuffSize) +{ + BOOL bRet = FALSE; + DBVARIANT dbv; + DBCONTACTGETSETTING sVal = {0}; + + sVal.pValue = &dbv; + sVal.szModule = lpszModule; + sVal.szSetting = lpszValueName; + if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&sVal) == 0) + { + if (dbv.type == DBVT_BLOB) + { + if (dwRetBuffSize >= dbv.cpbVal) + { + memmove(lpRet, dbv.pbVal, dbv.cpbVal); + bRet = TRUE; + } + if (pdwRetBuffSize) (*pdwRetBuffSize) = dbv.cpbVal; + } + DBFreeVariant(&dbv); + } + else { + if (pdwRetBuffSize) (*pdwRetBuffSize) = 0; + bRet = FALSE; + } + return(bRet); +} + +DWORD CMraProto::GetContactFlags(HANDLE hContact) +{ + DWORD dwRet = 0; + + if (IsContactMra(hContact)) + { + CHAR szEMail[MAX_EMAIL_LEN]; + size_t dwEMailSize; + + dwRet = mraGetDword(hContact, "ContactFlags", 0); + dwRet &= ~(CONTACT_FLAG_REMOVED|CONTACT_FLAG_GROUP|CONTACT_FLAG_INVISIBLE|CONTACT_FLAG_VISIBLE|CONTACT_FLAG_IGNORE|CONTACT_FLAG_SHADOW|CONTACT_FLAG_MULTICHAT); + dwRet |= CONTACT_FLAG_UNICODE_NAME; + + if (mraGetStaticStringA(hContact, "e-mail", szEMail, SIZEOF(szEMail), &dwEMailSize)) + { + if (IsEMailChatAgent(szEMail, dwEMailSize)) + { + dwRet |= CONTACT_FLAG_MULTICHAT; + } + } + + if (db_get_b(hContact, "CList", "Hidden", 0)) dwRet |= CONTACT_FLAG_SHADOW; + + switch (mraGetWord(hContact, "ApparentMode", 0)) { + case ID_STATUS_OFFLINE: + dwRet |= CONTACT_FLAG_INVISIBLE; + break; + case ID_STATUS_ONLINE: + dwRet |= CONTACT_FLAG_VISIBLE; + break; + } + + if (CallService(MS_IGNORE_ISIGNORED, (WPARAM)hContact, IGNOREEVENT_MESSAGE)) dwRet |= CONTACT_FLAG_IGNORE; + } + return(dwRet); +} + +DWORD CMraProto::SetContactFlags(HANDLE hContact, DWORD dwContactFlag) +{ + if ( !IsContactMra(hContact)) + return ERROR_INVALID_HANDLE; + + mraSetDword(hContact, "ContactFlags", dwContactFlag); + + if (dwContactFlag&CONTACT_FLAG_SHADOW) + DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); + else + DBDeleteContactSetting(hContact, "CList", "Hidden"); + + switch (dwContactFlag&(CONTACT_FLAG_INVISIBLE|CONTACT_FLAG_VISIBLE)) { + case CONTACT_FLAG_INVISIBLE: + mraSetWord(hContact, "ApparentMode", ID_STATUS_OFFLINE); + break; + case CONTACT_FLAG_VISIBLE: + mraSetWord(hContact, "ApparentMode", ID_STATUS_ONLINE); + break; + default: + mraSetWord(hContact, "ApparentMode", 0); + break; + } + + if (dwContactFlag&CONTACT_FLAG_IGNORE) + CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, IGNOREEVENT_MESSAGE); + else + CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, IGNOREEVENT_MESSAGE); + + return 0; +} + +DWORD CMraProto::GetContactBasicInfoW(HANDLE hContact, DWORD *pdwID, DWORD *pdwGroupID, DWORD *pdwContactFlag, DWORD *pdwContactSeverFlags, DWORD *pdwStatus, LPSTR lpszEMail, size_t dwEMailSize, size_t *pdwEMailSize, LPWSTR lpwszNick, size_t dwNickSize, size_t *pdwNickSize, LPSTR lpszPhones, size_t dwPhonesSize, size_t *pdwPhonesSize) +{ + if ( !IsContactMra(hContact)) + return ERROR_INVALID_HANDLE; + + if (pdwID) + *pdwID = mraGetDword(hContact, "ContactID", -1); + if (pdwGroupID) + *pdwGroupID = mraGetDword(hContact, "GroupID", -1); + if (pdwContactSeverFlags) + *pdwContactSeverFlags = mraGetDword(hContact, "ContactSeverFlags", 0); + if (pdwStatus) + *pdwStatus = MraGetContactStatus(hContact); + if (pdwContactFlag) + *pdwContactFlag = GetContactFlags(hContact); + if (lpszEMail && pdwEMailSize) + mraGetStaticStringA(hContact, "e-mail", lpszEMail, dwEMailSize, pdwEMailSize); + if (lpwszNick && pdwNickSize) + DB_GetStaticStringW(hContact, "CList", "MyHandle", lpwszNick, dwNickSize, pdwNickSize); + + if (lpszPhones && pdwPhonesSize) { + char szPhone[MAX_PATH], szValue[MAX_PATH]; + size_t dwPhoneSize, dwCopied = 0; + + for (size_t i = 0; i < 3; i++) { + mir_snprintf(szValue, SIZEOF(szValue), "MyPhone%lu", i); + if ( DB_GetStaticStringA(hContact, "UserInfo", szValue, szPhone, SIZEOF(szPhone), &dwPhoneSize)) { + if (dwCopied) + *((LPBYTE)(lpszPhones+dwCopied++)) = ','; + dwCopied += CopyNumber((lpszPhones+dwCopied), szPhone, dwPhoneSize); + } + } + *pdwPhonesSize = dwCopied; + } + return 0; +} + +DWORD CMraProto::SetContactBasicInfoW(HANDLE hContact, DWORD dwSetInfoFlags, DWORD dwFlags, DWORD dwID, DWORD dwGroupID, DWORD dwContactFlag, DWORD dwContactSeverFlags, DWORD dwStatus, LPSTR lpszEMail, size_t dwEMailSize, LPWSTR lpwszNick, size_t dwNickSize, LPSTR lpszPhones, size_t dwPhonesSize) +{ + if ( !IsContactMra(hContact)) + return ERROR_INVALID_HANDLE; + + // LOCK + if (dwSetInfoFlags & SCBIFSI_LOCK_CHANGES_EVENTS) + mraSetDword(hContact, "HooksLocked", TRUE); + + // поля которые нужны, и изменения которых не отслеживаются + if (dwFlags & SCBIF_ID) + mraSetDword(hContact, "ContactID", dwID); + + if (dwFlags & SCBIF_EMAIL) + if (lpszEMail && dwEMailSize) + mraSetStringExA(hContact, "e-mail", lpszEMail, dwEMailSize); + + // поля изменения которых отслеживаются + if (dwFlags & SCBIF_GROUP_ID) + mraSetDword(hContact, "GroupID", dwGroupID); + + if (dwFlags & SCBIF_NICK) { + if ((dwFlags & SCBIF_FLAG) && ((dwContactFlag&CONTACT_FLAG_UNICODE_NAME) == 0)) + { + if (lpwszNick && dwNickSize) + DB_SetStringExA(hContact, "CList", "MyHandle", (LPSTR)lpwszNick, dwNickSize); + } + else { + if (lpwszNick && dwNickSize) + DB_SetStringExW(hContact, "CList", "MyHandle", lpwszNick, dwNickSize); + } + } + + if (dwFlags & SCBIF_PHONES) { + if (lpszPhones && dwPhonesSize) { + char szPhone[MAX_PATH], szValue[MAX_PATH]; + LPSTR lpszCurPhone, lpszPhoneNext; + size_t i, dwCurPhoneSize; + + i = 0; + lpszCurPhone = lpszPhones; + lpszPhoneNext = lpszPhones; + while (lpszPhoneNext) { + lpszPhoneNext = (LPSTR)MemoryFindByte((lpszCurPhone-lpszPhones), lpszPhones, dwPhonesSize, ','); + if (lpszPhoneNext) + dwCurPhoneSize = lpszPhoneNext - lpszCurPhone; + else + dwCurPhoneSize = (lpszPhones + dwPhonesSize) - lpszCurPhone; + + szPhone[0] = '+'; + memmove((szPhone+1), lpszCurPhone, min(dwCurPhoneSize, (SIZEOF(szPhone)-1))); + mir_snprintf(szValue, SIZEOF(szValue), "MyPhone%lu", i); + DB_SetStringExA(hContact, "UserInfo", szValue, szPhone, (1+dwCurPhoneSize)); + + i++; + lpszCurPhone = (lpszPhoneNext+1); + } + } + } + + if (dwFlags & SCBIF_FLAG) + SetContactFlags(hContact, dwContactFlag); + + if (dwFlags & SCBIF_SERVER_FLAG) + mraSetDword(hContact, "ContactSeverFlags", dwContactSeverFlags); + + if (dwFlags & SCBIF_STATUS) + MraSetContactStatus(hContact, dwStatus); + + SetExtraIcons(hContact); + // UNLOCK + if (dwSetInfoFlags & SCBIFSI_LOCK_CHANGES_EVENTS) + mraSetDword(hContact, "HooksLocked", FALSE); + + return 0; +} + +HANDLE CMraProto::MraHContactFromEmail(LPSTR lpszEMail, size_t dwEMailSize, BOOL bAddIfNeeded, BOOL bTemporary, BOOL *pbAdded) +{ + HANDLE hContact = NULL; + + if (lpszEMail && dwEMailSize) + { + BOOL bFound = FALSE; + CHAR szEMailLocal[MAX_EMAIL_LEN]; + size_t dwEMailLocalSize; + + if (dwEMailSize == -1) dwEMailSize = lstrlenA(lpszEMail); + //check not already on list + for (hContact = db_find_first();hContact != NULL;hContact = db_find_next(hContact)) + { + if (IsContactMra(hContact)) + if (mraGetStaticStringA(hContact, "e-mail", szEMailLocal, SIZEOF(szEMailLocal), &dwEMailLocalSize)) + if (CompareStringA( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, szEMailLocal, dwEMailLocalSize, lpszEMail, dwEMailSize) == CSTR_EQUAL) + { + if (bTemporary == FALSE) DBDeleteContactSetting(hContact, "CList", "NotOnList"); + bFound = TRUE; + break; + } + } + + if (bFound == FALSE && bAddIfNeeded) + {//not already there: add + if (IsEMailChatAgent(lpszEMail, dwEMailSize)) + { + GCSESSION gcw = {0}; + WCHAR wszEMail[MAX_EMAIL_LEN] = {0}; + + gcw.cbSize = sizeof(GCSESSION); + gcw.iType = GCW_CHATROOM; + gcw.pszModule = m_szModuleName; + gcw.ptszName = wszEMail; + gcw.ptszID = (LPWSTR)wszEMail; + gcw.dwFlags = GC_UNICODE; + MultiByteToWideChar(MRA_CODE_PAGE, 0, lpszEMail, dwEMailSize, wszEMail, SIZEOF(wszEMail)); + + if (CallServiceSync(MS_GC_NEWSESSION, NULL, (LPARAM)&gcw) == 0) + { + BOOL bChatAdded = FALSE; + for (hContact = db_find_first();hContact != NULL;hContact = db_find_next(hContact)) + { + if (IsContactMra(hContact)) + if (mraGetStaticStringA(hContact, "ChatRoomID", szEMailLocal, SIZEOF(szEMailLocal), &dwEMailLocalSize)) + if (CompareStringA( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, szEMailLocal, dwEMailLocalSize, lpszEMail, dwEMailSize) == CSTR_EQUAL) + { + bChatAdded = TRUE; + break; + } + } + if (bChatAdded == FALSE) hContact = NULL; + } + }else { + hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)m_szModuleName); + } + + if (hContact) { + if (IsEMailChatAgent(lpszEMail, dwEMailSize)) + SetContactBasicInfoW(hContact, SCBIFSI_LOCK_CHANGES_EVENTS, (SCBIF_ID|SCBIF_GROUP_ID|SCBIF_SERVER_FLAG|SCBIF_STATUS|SCBIF_EMAIL), -1, -1, 0, CONTACT_INTFLAG_NOT_AUTHORIZED, ID_STATUS_ONLINE, lpszEMail, dwEMailSize, NULL, 0, NULL, 0); + else { + if (bTemporary) + DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + mraSetStringExA(hContact, "MirVer", MIRVER_UNKNOWN, (sizeof(MIRVER_UNKNOWN)-1)); + SetContactBasicInfoW(hContact, SCBIFSI_LOCK_CHANGES_EVENTS, (SCBIF_ID|SCBIF_GROUP_ID|SCBIF_SERVER_FLAG|SCBIF_STATUS|SCBIF_EMAIL), -1, -1, 0, CONTACT_INTFLAG_NOT_AUTHORIZED, ID_STATUS_OFFLINE, lpszEMail, dwEMailSize, NULL, 0, NULL, 0); + } + } + } + + if (pbAdded) (*pbAdded) = (bFound == FALSE && bAddIfNeeded && hContact); + } + return hContact; +} + +BOOL CMraProto::MraUpdateContactInfo(HANDLE hContact) +{ + BOOL bRet = FALSE; + + if (m_bLoggedIn && hContact) + if (IsContactMra(hContact)) { + CHAR szEMail[MAX_EMAIL_LEN]; + size_t dwEMailSize; + + if (mraGetStaticStringA(hContact, "e-mail", szEMail, SIZEOF(szEMail), &dwEMailSize)) { + MraAvatarsQueueGetAvatarSimple(hAvatarsQueueHandle, GAIF_FORCE, hContact, 0); + + if (MraWPRequestByEMail(hContact, ACKTYPE_GETINFO, szEMail, dwEMailSize)) + bRet = TRUE; + } + } + return bRet; +} + +DWORD CMraProto::MraContactCapabilitiesGet(HANDLE hContact) +{ + return mraGetDword(hContact, DBSETTING_CAPABILITIES, 0); +} + +void CMraProto::MraContactCapabilitiesSet(HANDLE hContact, DWORD dwFutureFlags) +{ + mraSetDword(hContact, DBSETTING_CAPABILITIES, dwFutureFlags); +} + +DWORD CMraProto::MraGetContactStatus(HANDLE hContact) +{ + return mraGetWord(hContact, "Status", ID_STATUS_OFFLINE); +} + +DWORD CMraProto::MraSetContactStatus(HANDLE hContact, DWORD dwNewStatus) +{ + DWORD dwOldStatus = MraGetContactStatus(hContact); + + if (dwNewStatus != dwOldStatus) + { + BOOL bChatAgent; + + bChatAgent = IsContactChatAgent(hContact); + + if (dwNewStatus == ID_STATUS_OFFLINE) + { + if (hContact) + { + mraSetByte(hContact, DBSETTING_XSTATUSID, MRA_MIR_XSTATUS_NONE); + mraDelValue(hContact, DBSETTING_XSTATUSNAME); + mraDelValue(hContact, DBSETTING_XSTATUSMSG); + mraDelValue(hContact, DBSETTING_BLOGSTATUSTIME); + mraDelValue(hContact, DBSETTING_BLOGSTATUSID); + mraDelValue(hContact, DBSETTING_BLOGSTATUS); + mraDelValue(hContact, DBSETTING_BLOGSTATUSMUSIC); + MraContactCapabilitiesSet(hContact, 0); + if (bChatAgent) MraChatSessionDestroy(hContact); + } + mraSetDword(hContact, "LogonTS", 0); + mraDelValue(hContact, "IP"); + mraDelValue(hContact, "RealIP"); + }else { + if (dwOldStatus == ID_STATUS_OFFLINE) + { + DWORD dwTime = (DWORD)_time32(NULL); + + mraSetDword(hContact, "LogonTS", dwTime); + mraSetDword(hContact, "OldLogonTS", dwTime); + + if (bChatAgent) MraChatSessionNew(hContact); + } + MraAvatarsQueueGetAvatarSimple(hAvatarsQueueHandle, 0, hContact, 0); + } + + mraSetWord(hContact, "Status", (WORD)dwNewStatus); + } + return(dwOldStatus); +} + +void CMraProto::MraUpdateEmailStatus(LPSTR lpszFrom, size_t dwFromSize, LPSTR lpszSubject, size_t dwSubjectSize, DWORD dwDate, DWORD dwUIDL) +{ + BOOL bTrayIconNewMailNotify; + WCHAR szStatusText[MAX_SECONDLINE]; + + bTrayIconNewMailNotify = mraGetByte(NULL, "TrayIconNewMailNotify", MRA_DEFAULT_TRAYICON_NEW_MAIL_NOTIFY); + + if (dwEmailMessagesUnread) + { + LPSTR lpszEMail; + size_t dwEMailSize; + HANDLE hContact = NULL; + WCHAR szMailBoxStatus[MAX_SECONDLINE]; + + mir_sntprintf(szMailBoxStatus, SIZEOF(szMailBoxStatus), TranslateW(L"Unread mail is available: %lu/%lu messages"), dwEmailMessagesUnread, dwEmailMessagesTotal); + + if ((lpszFrom && dwFromSize) || (lpszSubject && dwSubjectSize)) + { + WCHAR szFrom[MAX_PATH] = {0}, szSubject[MAX_PATH] = {0}; + + if (GetEMailFromString(lpszFrom, dwFromSize, &lpszEMail, &dwEMailSize)) + { + hContact = MraHContactFromEmail(lpszEMail, dwEMailSize, FALSE, TRUE, NULL); + } + + dwFromSize = MultiByteToWideChar(MRA_CODE_PAGE, 0, lpszFrom, dwFromSize, szFrom, SIZEOF(szFrom)); + szFrom[dwFromSize] = 0; + + dwSubjectSize = MultiByteToWideChar(MRA_CODE_PAGE, 0, lpszSubject, dwSubjectSize, szSubject, SIZEOF(szSubject)); + szSubject[dwSubjectSize] = 0; + + mir_sntprintf(szStatusText, SIZEOF(szStatusText), TranslateW(L"From: %s\r\nSubject: %s\r\n%s"), szFrom, szSubject, szMailBoxStatus); + }else { + lstrcpynW(szStatusText, szMailBoxStatus, SIZEOF(szStatusText)); + } + + if (bTrayIconNewMailNotify) { + char szServiceFunction[MAX_PATH], *pszServiceFunctionName; + CLISTEVENT cle = {0}; + + cle.cbSize = sizeof(cle); + //cle.hContact; + //cle.hDbEvent; + cle.lpszProtocol = m_szModuleName; + cle.hIcon = IconLibGetIcon( gdiMenuItems[0].hIconHandle ); + cle.flags = (CLEF_UNICODE|CLEF_PROTOCOLGLOBAL); + cle.pszService = ""; + cle.ptszTooltip = szStatusText; + + if (mraGetByte(NULL, "TrayIconNewMailClkToInbox", MRA_DEFAULT_TRAYICON_NEW_MAIL_CLK_TO_INBOX)) + { + strncpy(szServiceFunction, m_szModuleName, MAX_PATH); + pszServiceFunctionName = szServiceFunction+strlen(m_szModuleName); + memmove(pszServiceFunctionName, MRA_GOTO_INBOX, sizeof(MRA_GOTO_INBOX)); + cle.pszService = szServiceFunction; + } + CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); + } + + SkinPlaySound(szNewMailSound); + if (hContact) + {// update user info + MraUpdateContactInfo(hContact); + MraPopupShowFromContactW(hContact, MRA_POPUP_TYPE_EMAIL_STATUS, (MRA_POPUP_ALLOW_ENTER), szStatusText); + }else { + MraPopupShowFromAgentW(MRA_POPUP_TYPE_EMAIL_STATUS, (MRA_POPUP_ALLOW_ENTER), szStatusText); + } + }else { + if (mraGetByte(NULL, "IncrementalNewMailNotify", MRA_DEFAULT_INC_NEW_MAIL_NOTIFY)) + { + if (bTrayIconNewMailNotify) CallService(MS_CLIST_REMOVEEVENT, 0, (LPARAM)m_szModuleName); + PUDeletePopUp(hWndEMailPopupStatus); + hWndEMailPopupStatus = NULL; + }else { + mir_sntprintf(szStatusText, SIZEOF(szStatusText), TranslateW(L"No unread mail is available\r\nTotal messages: %lu"), dwEmailMessagesTotal); + MraPopupShowFromAgentW(MRA_POPUP_TYPE_EMAIL_STATUS, (MRA_POPUP_ALLOW_ENTER), szStatusText); + } + } +} + + +BOOL IsUnicodeEnv() +{// Are we running under unicode Miranda core ? + return TRUE; +} + + +BOOL IsHTTPSProxyUsed(HANDLE hNetlibUser) +{ + BOOL bRet = FALSE; + NETLIBUSERSETTINGS nlus = {0}; + + nlus.cbSize = sizeof(nlus); + if (CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)hNetlibUser, (LPARAM)&nlus)) + { + if (nlus.useProxy && nlus.proxyType == PROXYTYPE_HTTPS) bRet = TRUE; + } + return(bRet); +} + +// определяет принадлежность контакта данной копии плагина +BOOL CMraProto::IsContactMra(HANDLE hContact) +{ + return(CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)m_szModuleName)); +} + +// определяется является ли контакт контактом MRA протокола, не зависимо от того какому плагину он принадлежит +BOOL IsContactMraProto(HANDLE hContact) +{ + BOOL bRet = FALSE; + LPSTR lpszProto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + + if (lpszProto) + { + WCHAR szBuff[MAX_PATH]; + + if (DB_GetStaticStringW(hContact, lpszProto, "AvatarLastCheckTime", szBuff, SIZEOF(szBuff), NULL)) + if (DB_GetStaticStringW(hContact, lpszProto, "AvatarLastModifiedTime", szBuff, SIZEOF(szBuff), NULL)) + { + bRet = TRUE; + } + } + return(bRet); +} + +BOOL CMraProto::IsEMailMy(LPSTR lpszEMail, size_t dwEMailSize) +{ + BOOL bRet = FALSE; + + if (lpszEMail) + { + CHAR szEMailMy[MAX_EMAIL_LEN]; + size_t dwEMailMySize; + + if (mraGetStaticStringA(NULL, "e-mail", szEMailMy, SIZEOF(szEMailMy), &dwEMailMySize)) + { + if (dwEMailSize == 0) dwEMailSize = lstrlenA(lpszEMail); + + if (dwEMailMySize == dwEMailSize) + if (CompareStringA( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, lpszEMail, dwEMailSize, szEMailMy, dwEMailMySize) == CSTR_EQUAL) + { + bRet = TRUE; + } + } + } +return(bRet); +} + + +BOOL CMraProto::IsEMailChatAgent(LPSTR lpszEMail, size_t dwEMailSize) +{ + BOOL bRet = FALSE; + + if (lpszEMail) + { + if (dwEMailSize == 0) dwEMailSize = lstrlenA(lpszEMail); + if ((sizeof(MAILRU_CHAT_CONF_DOMAIN)-1)'))) + { + if (plpszEMail) (*plpszEMail) = lpszEMailStart; + if (pdwEMailSize) (*pdwEMailSize) = (lpszEMailEnd-lpszEMailStart); + + bRet = TRUE; + } + } + } + + if (bRet == FALSE) + { + if (plpszEMail) (*plpszEMail) = NULL; + if (pdwEMailSize) (*pdwEMailSize) = 0; + } + +return(bRet); +} + + +DWORD GetContactEMailCountParam(HANDLE hContact, BOOL bMRAOnly, LPSTR lpszModule, LPSTR lpszValueName) +{ + DWORD dwRet = 0; + CHAR szBuff[MAX_PATH], szEMail[MAX_EMAIL_LEN]; + size_t i, dwEMailSize; + + if (DB_GetStaticStringA(hContact, lpszModule, lpszValueName, szEMail, SIZEOF(szEMail), &dwEMailSize)) + { + if (bMRAOnly == FALSE || IsEMailMR(szEMail, dwEMailSize)) dwRet++; + } + + for (i = 0;TRUE;i++) + { + mir_snprintf(szBuff, SIZEOF(szBuff), "%s%lu", lpszValueName, i); + if (DB_GetStaticStringA(hContact, lpszModule, szBuff, szEMail, SIZEOF(szEMail), &dwEMailSize)) + { + if (bMRAOnly == FALSE || IsEMailMR(szEMail, dwEMailSize)) dwRet++; + }else { + if (i>EMAILS_MIN_COUNT) break; + } + } +return(dwRet); +} + + +DWORD CMraProto::GetContactEMailCount(HANDLE hContact, BOOL bMRAOnly) +{ + DWORD dwRet = 0; + LPSTR lpszProto; + + if (hContact) + lpszProto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + else + lpszProto = m_szModuleName; + + dwRet += GetContactEMailCountParam(hContact, bMRAOnly, lpszProto, "e-mail"); + dwRet += GetContactEMailCountParam(hContact, bMRAOnly, "UserInfo", "e-mail"); + dwRet += GetContactEMailCountParam(hContact, bMRAOnly, "UserInfo", "Mye-mail"); + dwRet += GetContactEMailCountParam(hContact, bMRAOnly, "UserInfo", "Companye-mail"); + dwRet += GetContactEMailCountParam(hContact, bMRAOnly, "UserInfo", "MyCompanye-mail"); + +return(dwRet); +} + + + +BOOL GetContactFirstEMailParam(HANDLE hContact, BOOL bMRAOnly, LPSTR lpszModule, LPSTR lpszValueName, LPSTR lpszRetBuff, size_t dwRetBuffSize, size_t *pdwRetBuffSize) +{ + BOOL bRet = FALSE; + CHAR szBuff[MAX_PATH], szEMail[MAX_EMAIL_LEN]; + size_t i, dwEMailSize; + + if (DB_GetStaticStringA(hContact, lpszModule, lpszValueName, szEMail, SIZEOF(szEMail), &dwEMailSize)) + { + if (bMRAOnly == FALSE || IsEMailMR(szEMail, dwEMailSize)) + { + lstrcpynA(lpszRetBuff, szEMail, dwRetBuffSize); + if (pdwRetBuffSize) (*pdwRetBuffSize) = dwEMailSize; + bRet = TRUE; + } + } + + for (i = 0;bRet == FALSE;i++) + { + mir_snprintf(szBuff, SIZEOF(szBuff), "%s%lu", lpszValueName, i); + if (DB_GetStaticStringA(hContact, lpszModule, szBuff, szEMail, SIZEOF(szEMail), &dwEMailSize)) + { + if (bMRAOnly == FALSE || IsEMailMR(szEMail, dwEMailSize)) + { + lstrcpynA(lpszRetBuff, szEMail, dwRetBuffSize); + if (pdwRetBuffSize) (*pdwRetBuffSize) = dwEMailSize; + bRet = TRUE; + break; + } + }else { + if (i>EMAILS_MIN_COUNT) break; + } + } +return(bRet); +} + + +BOOL CMraProto::GetContactFirstEMail(HANDLE hContact, BOOL bMRAOnly, LPSTR lpszRetBuff, size_t dwRetBuffSize, size_t *pdwRetBuffSize) +{ + BOOL bRet = FALSE; + LPSTR lpszProto; + + if (hContact) + lpszProto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + else + lpszProto = m_szModuleName; + + bRet = GetContactFirstEMailParam(hContact, bMRAOnly, lpszProto, "e-mail", lpszRetBuff, dwRetBuffSize, pdwRetBuffSize); + if (bRet == FALSE) bRet = GetContactFirstEMailParam(hContact, bMRAOnly, "UserInfo", "e-mail", lpszRetBuff, dwRetBuffSize, pdwRetBuffSize); + if (bRet == FALSE) bRet = GetContactFirstEMailParam(hContact, bMRAOnly, "UserInfo", "Mye-mail", lpszRetBuff, dwRetBuffSize, pdwRetBuffSize); + if (bRet == FALSE) bRet = GetContactFirstEMailParam(hContact, bMRAOnly, "UserInfo", "Companye-mail", lpszRetBuff, dwRetBuffSize, pdwRetBuffSize); + if (bRet == FALSE) bRet = GetContactFirstEMailParam(hContact, bMRAOnly, "UserInfo", "MyCompanye-mail", lpszRetBuff, dwRetBuffSize, pdwRetBuffSize); + + return bRet; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMraProto::ShowFormattedErrorMessage(LPWSTR lpwszErrText, DWORD dwErrorCode) +{ + WCHAR szErrorText[2048], szErrDescription[1024]; + size_t dwErrDescriptionSize; + + if (dwErrorCode == NO_ERROR) + mir_sntprintf(szErrorText, SIZEOF(szErrorText), L"%s", TranslateW(lpwszErrText)); + else { + dwErrDescriptionSize = (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErrorCode, 0, szErrDescription, (SIZEOF(szErrDescription)-sizeof(WCHAR)), NULL)-2); + szErrDescription[dwErrDescriptionSize] = 0; + mir_sntprintf(szErrorText, SIZEOF(szErrorText), L"%s %lu: %s", TranslateW(lpwszErrText), dwErrorCode, szErrDescription); + } + MraPopupShowFromAgentW(MRA_POPUP_TYPE_ERROR, 0, szErrorText); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static void FakeThread(void* param) +{ + Sleep(100); + CallService(MS_PROTO_BROADCASTACK, 0, (LPARAM)param); + mir_free(param); +} + +DWORD CMraProto::ProtoBroadcastAckAsync(HANDLE hContact, int type, int hResult, HANDLE hProcess, LPARAM lParam, size_t paramSize) +{ + ACKDATA* ack = (ACKDATA*)mir_calloc(sizeof(ACKDATA) + paramSize); + ack->cbSize = sizeof(ACKDATA); + ack->szModule = m_szModuleName; ack->hContact = hContact; + ack->type = type; ack->result = hResult; + ack->hProcess = hProcess; ack->lParam = lParam; + if (paramSize) + memcpy(ack+1, (void*)lParam, paramSize); + mir_forkthread(FakeThread, ack); + return 0; +} + +DWORD CMraProto::CreateBlobFromContact(HANDLE hContact, LPWSTR lpwszRequestReason, size_t dwRequestReasonSize, LPBYTE lpbBuff, size_t dwBuffSize, size_t *pdwBuffSizeRet) +{ + DWORD dwRetErrorCode; + size_t dwBuffSizeRet = ((sizeof(DWORD)*2)+dwRequestReasonSize+5), dwSize; + + if (dwBuffSize >= dwBuffSizeRet) { + PBYTE pCurBlob = lpbBuff; + + *(DWORD*)pCurBlob = 0; pCurBlob += sizeof(DWORD); + *(DWORD*)pCurBlob = (DWORD)hContact; pCurBlob += sizeof(DWORD); + + mraGetStaticStringA(hContact, "Nick", (LPSTR)pCurBlob, (dwBuffSize-(pCurBlob-lpbBuff)), &dwSize); + *(pCurBlob+dwSize) = 0; + pCurBlob += (dwSize+1); + + mraGetStaticStringA(hContact, "FirstName", (LPSTR)pCurBlob, (dwBuffSize-(pCurBlob-lpbBuff)), &dwSize); + *(pCurBlob+dwSize) = 0; + pCurBlob += (dwSize+1); + + mraGetStaticStringA(hContact, "LastName", (LPSTR)pCurBlob, (dwBuffSize-(pCurBlob-lpbBuff)), &dwSize); + *(pCurBlob+dwSize) = 0; + pCurBlob += (dwSize+1); + + mraGetStaticStringA(hContact, "e-mail", (LPSTR)pCurBlob, (dwBuffSize-(pCurBlob-lpbBuff)), &dwSize); + *(pCurBlob+dwSize) = 0; + pCurBlob += (dwSize+1); + + dwSize = WideCharToMultiByte(MRA_CODE_PAGE, 0, lpwszRequestReason, dwRequestReasonSize, (LPSTR)pCurBlob, (dwBuffSize-(pCurBlob-lpbBuff)), NULL, NULL); + *(pCurBlob+dwSize) = 0; + pCurBlob += (dwSize+1); + + dwBuffSizeRet = (pCurBlob-lpbBuff); + dwRetErrorCode = NO_ERROR; + } + else dwRetErrorCode = ERROR_INSUFFICIENT_BUFFER; + + if (pdwBuffSizeRet) + *pdwBuffSizeRet = dwBuffSizeRet; + return dwRetErrorCode; +} + +void CMraProto::CListShowMenuItem(HANDLE hMenuItem, BOOL bShow) +{ + CLISTMENUITEM mi = {0}; + + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS; + if (bShow == FALSE) mi.flags |= CMIF_HIDDEN; + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&mi); +} + +int ExtraSetIcon(HANDLE hExtraIcon, HANDLE hContact, HANDLE hImage, int iColumnType) +{ + if (hImage == NULL) + hImage = INVALID_HANDLE_VALUE; + + if (hExtraIcon) + return ExtraIcon_SetIcon(hExtraIcon, hContact, hImage); + + IconExtraColumn iec; + iec.cbSize = sizeof(iec); + iec.ColumnType = iColumnType; + iec.hImage = hImage; + return CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)hContact, (LPARAM)&iec); +} + +size_t CopyNumber(LPCVOID lpcOutBuff, LPCVOID lpcBuff, size_t dwLen) +{ + BYTE btChar; + LPBYTE lpbOutBuff = (LPBYTE)lpcOutBuff, lpbInBuff = (LPBYTE)lpcBuff; + + for (size_t i = 0; i < dwLen; i++) { + btChar = (*lpbInBuff++); + if (btChar >= '0' && btChar <= '9') (*lpbOutBuff++) = btChar; + } + *lpbOutBuff = 0; + + return lpbOutBuff-(LPBYTE)lpcOutBuff; +} + +void EnableControlsArray(HWND hWndDlg, WORD *pwControlsList, size_t dwControlsListCount, BOOL bEnabled) +{ + for (size_t i = 0; i < dwControlsListCount; i++) + EnableWindow(GetDlgItem(hWndDlg, pwControlsList[i]), bEnabled); +} + +LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lrRet = 0; + WNDPROC OldMessageEditProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + if (msg == WM_CHAR) + if (GetKeyState(VK_CONTROL) & 0x8000) { + if (wParam == '\n') { + PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); + return 0; + } + if (wParam == 1) { // ctrl-a + SendMessage(hwnd, EM_SETSEL, 0, -1); + return 0; + } + if (wParam == 23) { // ctrl-w + SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0); + return 0; + } + } + + if (OldMessageEditProc) + lrRet = CallWindowProc(OldMessageEditProc, hwnd, msg, wParam, lParam); + + return lrRet; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR CALLBACK SetXStatusDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + INT_PTR iRet = FALSE; + SetXStatusData *dat = (SetXStatusData*)GetWindowLongPtr(hWndDlg, GWLP_USERDATA); + + switch (message) { + case WM_INITDIALOG:// set our xStatus + TranslateDialogDefault(hWndDlg); + + dat = (SetXStatusData*)lParam; + if (dat) { + char szValueName[MAX_PATH]; + HWND hWndEdit; + WCHAR szBuff[STATUS_TITLE_MAX+STATUS_DESC_MAX]; + WNDPROC OldMessageEditProc; + + dat->hDlgIcon = IconLibGetIcon(dat->ppro->hXStatusAdvancedStatusIcons[dat->dwXStatus]); + dat->dwCountdown = 5; + + hWndEdit = GetDlgItem(hWndDlg, IDC_XTITLE); + OldMessageEditProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)MessageEditSubclassProc); + SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldMessageEditProc); + + hWndEdit = GetDlgItem(hWndDlg, IDC_XMSG); + OldMessageEditProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)MessageEditSubclassProc); + SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldMessageEditProc); + + SetWindowLongPtr(hWndDlg, GWLP_USERDATA, (LONG_PTR)dat); + SEND_DLG_ITEM_MESSAGE(hWndDlg, IDC_XTITLE, EM_LIMITTEXT, STATUS_TITLE_MAX, 0); + SEND_DLG_ITEM_MESSAGE(hWndDlg, IDC_XMSG, EM_LIMITTEXT, STATUS_DESC_MAX, 0); + SendMessage(hWndDlg, WM_SETICON, ICON_BIG, (LPARAM)dat->hDlgIcon); + SendMessage(hWndDlg, WM_SETTEXT, 0, (LPARAM)TranslateW(lpcszXStatusNameDef[dat->dwXStatus])); + + mir_snprintf(szValueName, SIZEOF(szValueName), "XStatus%ldName", dat->dwXStatus); + if (dat->ppro->mraGetStaticStringW(NULL, szValueName, szBuff, (STATUS_TITLE_MAX+1), NULL)) + SET_DLG_ITEM_TEXT(hWndDlg, IDC_XTITLE, szBuff); // custom xstatus name + else // default xstatus name + SET_DLG_ITEM_TEXT(hWndDlg, IDC_XTITLE, TranslateW(lpcszXStatusNameDef[dat->dwXStatus])); + + mir_snprintf(szValueName, SIZEOF(szValueName), "XStatus%ldMsg", dat->dwXStatus); + if (dat->ppro->mraGetStaticStringW(NULL, szValueName, szBuff, (STATUS_DESC_MAX+1), NULL)) + SET_DLG_ITEM_TEXT(hWndDlg, IDC_XMSG, szBuff); // custom xstatus description + else // default xstatus description + SET_DLG_ITEM_TEXT(hWndDlg, IDC_XMSG, L""); + + SendMessage(hWndDlg, WM_TIMER, 0, 0); + SetTimer(hWndDlg, 1, 1000, 0); + iRet = TRUE; + } + break; + + case WM_TIMER: + if (dat->dwCountdown != -1) { + WCHAR szBuff[MAX_PATH]; + mir_sntprintf(szBuff, SIZEOF(szBuff), L"%s %ld", TranslateW(L"Closing in"), dat->dwCountdown); + SET_DLG_ITEM_TEXT(hWndDlg, IDOK, szBuff); + dat->dwCountdown--; + break; + } + + case WM_CLOSE: + DestroyWindow(hWndDlg); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + DestroyWindow(hWndDlg); + break; + case IDC_XTITLE: + case IDC_XMSG: + KillTimer(hWndDlg, 1); + SET_DLG_ITEM_TEXTW(hWndDlg, IDOK, TranslateW(L"OK")); + break; + } + break; + + case WM_DESTROY: + if (dat) { // set our xStatus + char szValueName[MAX_PATH]; + HWND hWndEdit; + WCHAR szBuff[STATUS_TITLE_MAX+STATUS_DESC_MAX]; + size_t dwBuffSize; + WNDPROC OldMessageEditProc; + CLISTMENUITEM mi = {0}; + + SetWindowLongPtr(hWndDlg, GWLP_USERDATA, (LONG_PTR)0); + + hWndEdit = GetDlgItem(hWndDlg, IDC_XTITLE); + OldMessageEditProc = (WNDPROC)GetWindowLongPtr(hWndEdit, GWLP_USERDATA); + SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)OldMessageEditProc); + SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)0); + + hWndEdit = GetDlgItem(hWndDlg, IDC_XMSG); + OldMessageEditProc = (WNDPROC)GetWindowLongPtr(hWndEdit, GWLP_USERDATA); + SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)OldMessageEditProc); + SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)0); + + dwBuffSize = GET_DLG_ITEM_TEXT(hWndDlg, IDC_XMSG, szBuff, (STATUS_DESC_MAX+1)); + mir_snprintf(szValueName, SIZEOF(szValueName), "XStatus%ldMsg", dat->dwXStatus); + dat->ppro->mraSetStringExW(NULL, szValueName, szBuff, dwBuffSize); + dat->ppro->mraSetStringExW(NULL, DBSETTING_XSTATUSMSG, szBuff, dwBuffSize); + + dwBuffSize = GET_DLG_ITEM_TEXT(hWndDlg, IDC_XTITLE, szBuff, (STATUS_TITLE_MAX+1)); + if (dwBuffSize == 0) { // user delete all text + lstrcpynW(szBuff, TranslateW(lpcszXStatusNameDef[dat->dwXStatus]), (STATUS_TITLE_MAX+1)); + dwBuffSize = lstrlenW(szBuff); + } + mir_snprintf(szValueName, SIZEOF(szValueName), "XStatus%dName", dat->dwXStatus); + dat->ppro->mraSetStringExW(NULL, szValueName, szBuff, dwBuffSize); + dat->ppro->mraSetStringExW(NULL, DBSETTING_XSTATUSNAME, szBuff, dwBuffSize); + + mi.cbSize = sizeof(mi); + mi.flags = (CMIM_NAME|CMIF_UNICODE); + mi.ptszName = szBuff; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)dat->ppro->hXStatusMenuItems[dat->dwXStatus], (LPARAM)&mi); + + dat->ppro->MraSetXStatusInternal(dat->dwXStatus); + + mir_free(dat); + } + EndDialog(hWndDlg, NO_ERROR); + break; + } + return iRet; +} + +BOOL CMraProto::MraRequestXStatusDetails(DWORD dwXStatus) +{ + if ( IsXStatusValid(dwXStatus)) { + SetXStatusData *dat = (SetXStatusData*)mir_calloc(sizeof(SetXStatusData)); + dat->dwXStatus = dwXStatus; + dat->ppro = this; + return DialogBoxParam(masMraSettings.hInstance, MAKEINTRESOURCE(IDD_SETXSTATUS), NULL, SetXStatusDlgProc, (LPARAM)dat) != -1; + } + + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR CALLBACK SendReplyBlogStatusDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + INT_PTR iRet = FALSE; + SetBlogStatusData *dat = (SetBlogStatusData*)GetWindowLongPtr(hWndDlg, GWLP_USERDATA); + + switch (message) { + case WM_INITDIALOG:// set our xStatus + TranslateDialogDefault(hWndDlg); + + dat = (SetBlogStatusData*)lParam; + if (dat) { + WCHAR szBuff[MICBLOG_STATUS_MAX]; + SYSTEMTIME stBlogStatusTime = {0}; + + SetWindowLongPtr(hWndDlg, GWLP_USERDATA, (LONG_PTR)dat); + + HWND hWndEdit = GetDlgItem(hWndDlg, IDC_MSG_TO_SEND); + WNDPROC OldMessageEditProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)MessageEditSubclassProc); + SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldMessageEditProc); + SendMessage(hWndEdit, EM_LIMITTEXT, MICBLOG_STATUS_MAX, 0); + + SendMessage(hWndDlg, WM_SETICON, ICON_BIG, (LPARAM)IconLibGetIcon(gdiMenuItems[5].hIconHandle)); + + // blog status message + if (dat->ppro->mraGetStaticStringW(dat->hContact, DBSETTING_BLOGSTATUS, szBuff, SIZEOF(szBuff), NULL)) + SET_DLG_ITEM_TEXT(hWndDlg, IDC_USER_BLOG_STATUS_MSG, szBuff); + + // reply to some user blog + if (dat->hContact) { + mir_sntprintf(szBuff, SIZEOF(szBuff), TranslateW(L"Reply to %s blog status"), GetContactNameW(dat->hContact)); + SendMessage(hWndDlg, WM_SETTEXT, 0, (LPARAM)szBuff); + } + else SendMessage(hWndDlg, WM_SETTEXT, 0, (LPARAM)TranslateW(L"Set my blog status")); + + DWORD dwTime = dat->ppro->mraGetDword(dat->hContact, DBSETTING_BLOGSTATUSTIME, 0); + if (dwTime && MakeLocalSystemTimeFromTime32(dwTime, &stBlogStatusTime)) + mir_sntprintf(szBuff, SIZEOF(szBuff), L"%s: %04ld.%02ld.%02ld %02ld:%02ld", TranslateW(L"Writed"), stBlogStatusTime.wYear, stBlogStatusTime.wMonth, stBlogStatusTime.wDay, stBlogStatusTime.wHour, stBlogStatusTime.wMinute); + else + szBuff[0] = 0; + + SET_DLG_ITEM_TEXT(hWndDlg, IDC_STATIC_WRITED_TIME, szBuff); + EnableWindow(GetDlgItem(hWndDlg, IDC_CHK_NOTIFY), (dat->hContact == NULL)); + iRet = TRUE; + } + break; + + case WM_CLOSE: + DestroyWindow(hWndDlg); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + { + DWORD dwFlags; + WCHAR szBuff[MICBLOG_STATUS_MAX]; + size_t dwBuffSize; + DWORDLONG dwBlogStatusID; + + dwBuffSize = GET_DLG_ITEM_TEXT(hWndDlg, IDC_MSG_TO_SEND, szBuff, SIZEOF(szBuff)); + if (dat->hContact) { + dwFlags = (MRIM_BLOG_STATUS_REPLY|MRIM_BLOG_STATUS_NOTIFY); + dat->ppro->mraGetContactSettingBlob(dat->hContact, DBSETTING_BLOGSTATUSID, &dwBlogStatusID, sizeof(DWORDLONG), NULL); + } + else { + dwFlags = MRIM_BLOG_STATUS_UPDATE; + if (IS_DLG_BUTTON_CHECKED(hWndDlg, IDC_CHK_NOTIFY)) dwFlags |= MRIM_BLOG_STATUS_NOTIFY; + dwBlogStatusID = 0; + } + dat->ppro->MraChangeUserBlogStatus(dwFlags, szBuff, dwBuffSize, dwBlogStatusID); + } + case IDCANCEL: + DestroyWindow(hWndDlg); + break; + + case IDC_MSG_TO_SEND: + if (HIWORD(wParam) == EN_CHANGE) { + WCHAR wszBuff[MAX_PATH]; + size_t dwMessageSize = GET_DLG_ITEM_TEXT_LENGTH(hWndDlg, IDC_MSG_TO_SEND); + + EnableWindow(GetDlgItem(hWndDlg, IDOK), dwMessageSize); + mir_sntprintf(wszBuff, SIZEOF(wszBuff), L"%d/%d", dwMessageSize, MICBLOG_STATUS_MAX); + SET_DLG_ITEM_TEXTW(hWndDlg, IDC_STATIC_CHARS_COUNTER, wszBuff); + } + break; + } + break; + + case WM_DESTROY: + if (dat) { + HWND hWndEdit; + WNDPROC OldMessageEditProc; + + SetWindowLongPtr(hWndDlg, GWLP_USERDATA, (LONG_PTR)0); + + hWndEdit = GetDlgItem(hWndDlg, IDC_MSG_TO_SEND); + OldMessageEditProc = (WNDPROC)GetWindowLongPtr(hWndEdit, GWLP_USERDATA); + SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)OldMessageEditProc); + SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)0); + mir_free(dat); + } + EndDialog(hWndDlg, NO_ERROR); + break; + } + return iRet; +} + +BOOL CMraProto::MraSendReplyBlogStatus(HANDLE hContact) +{ + SetBlogStatusData* dat = (SetBlogStatusData*)mir_calloc( sizeof(SetBlogStatusData)); + dat->ppro = this; + dat->hContact = hContact; + return CreateDialogParam(masMraSettings.hInstance, MAKEINTRESOURCE(IDD_MINIBLOG), NULL, SendReplyBlogStatusDlgProc, (LPARAM)dat) != NULL; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +DWORD GetYears(CONST PSYSTEMTIME pcstSystemTime) +{ + DWORD dwRet = 0; + + if (pcstSystemTime) { + SYSTEMTIME stTime; + GetLocalTime(&stTime); + dwRet = stTime.wYear - pcstSystemTime->wYear; + // день рожденья будет в след месяце + if (stTime.wMonthwMonth) + dwRet--; + // др ещё будет в этом месяце или уже был... + else { + // др в этом месяце + if (stTime.wMonth == pcstSystemTime->wMonth) + // ещё только будет, не сегодня + if (stTime.wDaywDay) + dwRet--; + } + } + return dwRet; +} + +DWORD FindFile(LPWSTR lpszFolder, DWORD dwFolderLen, LPWSTR lpszFileName, DWORD dwFileNameLen, LPWSTR lpszRetFilePathName, DWORD dwRetFilePathLen, DWORD *pdwRetFilePathLen) +{ + DWORD dwRetErrorCode; + + if (lpszFolder && dwFolderLen && lpszFileName && dwFileNameLen) { + WCHAR szPath[32768]; + DWORD dwPathLen, dwRecDeepAllocated, dwRecDeepCurPos, dwFilePathLen; + RECURSION_DATA_STACK_ITEM *prdsiItems; + + if (dwFolderLen == -1) dwFolderLen = lstrlenW(lpszFolder); + if (dwFileNameLen == -1) dwFileNameLen = lstrlenW(lpszFileName); + + dwRecDeepCurPos = 0; + dwRecDeepAllocated = RECURSION_DATA_STACK_ITEMS_MIN; + prdsiItems = (RECURSION_DATA_STACK_ITEM*)mir_calloc(dwRecDeepAllocated*sizeof(RECURSION_DATA_STACK_ITEM)); + if (prdsiItems) { + dwPathLen = dwFolderLen; + memmove(szPath, lpszFolder, (dwPathLen*sizeof(WCHAR))); + if (szPath[(dwPathLen-1)] != '\\') { + szPath[dwPathLen] = '\\'; + dwPathLen++; + } + szPath[dwPathLen] = 0; + lstrcatW(szPath, L"*.*"); + + prdsiItems[dwRecDeepCurPos].dwFileNameLen = 0; + prdsiItems[dwRecDeepCurPos].hFind = FindFirstFileEx(szPath, FindExInfoStandard, &prdsiItems[dwRecDeepCurPos].w32fdFindFileData, FindExSearchNameMatch, NULL, 0); + if (prdsiItems[dwRecDeepCurPos].hFind != INVALID_HANDLE_VALUE) { + dwRetErrorCode = ERROR_FILE_NOT_FOUND; + do { + dwPathLen-=prdsiItems[dwRecDeepCurPos].dwFileNameLen; + + while (dwRetErrorCode == ERROR_FILE_NOT_FOUND && FindNextFile(prdsiItems[dwRecDeepCurPos].hFind, &prdsiItems[dwRecDeepCurPos].w32fdFindFileData)) { + if (prdsiItems[dwRecDeepCurPos].w32fdFindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) {// folder + if (CompareString( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName, -1, L".", 1) != CSTR_EQUAL) + if (CompareString( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName, -1, L"..", 2) != CSTR_EQUAL) { + prdsiItems[dwRecDeepCurPos].dwFileNameLen = (lstrlenW(prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName)+1); + memmove((szPath+dwPathLen), prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName, (prdsiItems[dwRecDeepCurPos].dwFileNameLen*sizeof(WCHAR))); + lstrcatW(szPath, L"\\*.*"); + dwPathLen += prdsiItems[dwRecDeepCurPos].dwFileNameLen; + + dwRecDeepCurPos++; + if (dwRecDeepCurPos == dwRecDeepAllocated) { // need more space + dwRecDeepAllocated += RECURSION_DATA_STACK_ITEMS_MIN; + prdsiItems = (RECURSION_DATA_STACK_ITEM*)mir_realloc(prdsiItems, dwRecDeepAllocated*sizeof(RECURSION_DATA_STACK_ITEM)); + if (prdsiItems == NULL) { + dwRecDeepCurPos = 0; + dwRetErrorCode = GetLastError(); + break; + } + } + prdsiItems[dwRecDeepCurPos].hFind = FindFirstFileEx(szPath, FindExInfoStandard, &prdsiItems[dwRecDeepCurPos].w32fdFindFileData, FindExSearchNameMatch, NULL, 0); + } + } + else {// file + if (CompareString( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName, -1, lpszFileName, dwFileNameLen) == CSTR_EQUAL) { + prdsiItems[dwRecDeepCurPos].dwFileNameLen = lstrlenW(prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName); + memmove((szPath+dwPathLen), prdsiItems[dwRecDeepCurPos].w32fdFindFileData.cFileName, ((prdsiItems[dwRecDeepCurPos].dwFileNameLen+1)*sizeof(WCHAR))); + dwFilePathLen = (dwPathLen+prdsiItems[dwRecDeepCurPos].dwFileNameLen); + + if (pdwRetFilePathLen) (*pdwRetFilePathLen) = dwFilePathLen; + if (lpszRetFilePathName && dwRetFilePathLen) { + dwFilePathLen = min(dwFilePathLen, dwRetFilePathLen); + memmove(lpszRetFilePathName, szPath, ((dwFilePathLen+1)*sizeof(WCHAR))); + } + + dwRetErrorCode = NO_ERROR; + } + } + } + + if (prdsiItems) FindClose(prdsiItems[dwRecDeepCurPos].hFind); + dwRecDeepCurPos--; + } + while (dwRecDeepCurPos != -1); + } + mir_free(prdsiItems); + } + else dwRetErrorCode = GetLastError(); + } + else dwRetErrorCode = ERROR_INVALID_HANDLE; + + return dwRetErrorCode; +} + + +DWORD MemFillRandom(LPVOID lpBuff, size_t dwBuffSize) +{ + DWORD dwRetErrorCode; + + if (lpBuff && dwBuffSize) { + HCRYPTPROV hCryptProv = NULL; + + if (CryptAcquireContext(&hCryptProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, 0) == FALSE && GetLastError() == NTE_BAD_KEYSET) + CryptAcquireContext(&hCryptProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); + + if (hCryptProv) { + if (CryptGenRandom(hCryptProv, dwBuffSize, (BYTE*)lpBuff)) + dwRetErrorCode = NO_ERROR; + else + dwRetErrorCode = GetLastError(); + } + else dwRetErrorCode = GetLastError(); + + CryptReleaseContext(hCryptProv, 0); + } + else dwRetErrorCode = ERROR_INVALID_HANDLE; + + return dwRetErrorCode; +} + +BOOL CMraProto::SetPassDB(LPSTR lpszBuff, size_t dwBuffSize) +{ + BOOL bRet = FALSE; + BYTE btRandomData[256], btCryptedPass[256] = {0}, bthmacSHA1[SHA1HashSize] = {0}; + char szEMail[MAX_EMAIL_LEN] = {0}; + size_t dwEMailSize; + +#if /*defined (_DEBUG) ||*/ defined (REL_DEB) + + mraSetStringExA(NULL, "Pass", lpszBuff, dwBuffSize); + bRet = TRUE; +#else + if (dwBuffSize < 128) + if (mraGetStaticStringA(NULL, "e-mail", szEMail, SIZEOF(szEMail), &dwEMailSize)) { + MemFillRandom(btRandomData, sizeof(btRandomData)); + + SHA1GetDigest(lpszBuff, dwBuffSize, &btCryptedPass[1]); + + //BASE64EncodeUnSafe(lpszBuff, dwBuffSize, &btCryptedPass[(1+SHA1HashSize)], (sizeof(btCryptedPass)-1), &dwBuffSize); + memmove(&btCryptedPass[(1+SHA1HashSize)], lpszBuff, dwBuffSize); + btCryptedPass[0] = (BYTE)dwBuffSize; + //memmove(&btCryptedPass[1], lpszBuff, dwBuffSize); + + hmac_sha1(btRandomData, sizeof(btRandomData), (BYTE*)szEMail, dwEMailSize, bthmacSHA1); + + RC4(btCryptedPass, sizeof(btCryptedPass), bthmacSHA1, SHA1HashSize); + RC4(btCryptedPass, sizeof(btCryptedPass), btRandomData, sizeof(btRandomData)); + CopyMemoryReverseDWORD(btCryptedPass, btCryptedPass, sizeof(btCryptedPass)); + RC4(btCryptedPass, sizeof(btCryptedPass), bthmacSHA1, SHA1HashSize); + + + mraSetDword(NULL, "pCryptVer", MRA_PASS_CRYPT_VER); + mraWriteContactSettingBlob(NULL, "pCryptData", btRandomData, sizeof(btRandomData)); + mraWriteContactSettingBlob(NULL, "pCryptPass", btCryptedPass, sizeof(btCryptedPass)); + + bRet = TRUE; + } +#endif +return(bRet); +} + + +BOOL CMraProto::GetPassDB_v1(LPSTR lpszBuff, size_t dwBuffSize, size_t *pdwBuffSize) +{ + BYTE btRandomData[256] = {0}, btCryptedPass[256] = {0}, bthmacSHA1[SHA1HashSize] = {0}; + char szEMail[MAX_EMAIL_LEN] = {0}; + size_t dwRandomDataSize, dwCryptedPass, dwEMailSize, dwPassSize; + + if (mraGetDword(NULL, "pCryptVer", 0) == 1) + if (mraGetContactSettingBlob(NULL, "pCryptData", btRandomData, sizeof(btRandomData), &dwRandomDataSize)) + if (dwRandomDataSize == sizeof(btRandomData)) + if (mraGetContactSettingBlob(NULL, "pCryptPass", btCryptedPass, sizeof(btCryptedPass), &dwCryptedPass)) + if (dwCryptedPass == sizeof(btCryptedPass)) + if (mraGetStaticStringA(NULL, "e-mail", szEMail, SIZEOF(szEMail), &dwEMailSize)) { + hmac_sha1(btRandomData, sizeof(btRandomData), (BYTE*)szEMail, dwEMailSize, bthmacSHA1); + + RC4(btCryptedPass, sizeof(btCryptedPass), bthmacSHA1, SHA1HashSize); + CopyMemoryReverseDWORD(btCryptedPass, btCryptedPass, sizeof(btCryptedPass)); + RC4(btCryptedPass, sizeof(btCryptedPass), btRandomData, dwRandomDataSize); + RC4(btCryptedPass, sizeof(btCryptedPass), bthmacSHA1, SHA1HashSize); + + dwPassSize = (*btCryptedPass); + BASE64DecodeUnSafe(&btCryptedPass[(1+SHA1HashSize)], dwPassSize, &btCryptedPass[(1+SHA1HashSize)], (sizeof(btCryptedPass)-1), &dwPassSize); + SHA1GetDigest(&btCryptedPass[(1+SHA1HashSize)], dwPassSize, btRandomData); + if (MemoryCompare(&btCryptedPass[1], SHA1HashSize, btRandomData, SHA1HashSize) == CMEM_EQUAL) + if (dwBuffSize >= dwPassSize) { + memmove(lpszBuff, &btCryptedPass[(1+SHA1HashSize)], dwPassSize); + *(lpszBuff + dwPassSize) = 0; + + if (pdwBuffSize) + *pdwBuffSize = dwPassSize; + return TRUE; + } + } + + return FALSE; +} + + +BOOL CMraProto::GetPassDB_v2(LPSTR lpszBuff, size_t dwBuffSize, size_t *pdwBuffSize) +{ + BYTE btRandomData[256] = {0}, btCryptedPass[256] = {0}, bthmacSHA1[SHA1HashSize] = {0}; + char szEMail[MAX_EMAIL_LEN] = {0}; + size_t dwRandomDataSize, dwCryptedPass, dwEMailSize, dwPassSize; + + if (mraGetDword(NULL, "pCryptVer", 0) == 2) + if (mraGetContactSettingBlob(NULL, "pCryptData", btRandomData, sizeof(btRandomData), &dwRandomDataSize)) + if (dwRandomDataSize == sizeof(btRandomData)) + if (mraGetContactSettingBlob(NULL, "pCryptPass", btCryptedPass, sizeof(btCryptedPass), &dwCryptedPass)) + if (dwCryptedPass == sizeof(btCryptedPass)) + if (mraGetStaticStringA(NULL, "e-mail", szEMail, SIZEOF(szEMail), &dwEMailSize)) { + hmac_sha1(btRandomData, sizeof(btRandomData), (BYTE*)szEMail, dwEMailSize, bthmacSHA1); + + RC4(btCryptedPass, sizeof(btCryptedPass), bthmacSHA1, SHA1HashSize); + CopyMemoryReverseDWORD(btCryptedPass, btCryptedPass, sizeof(btCryptedPass)); + RC4(btCryptedPass, sizeof(btCryptedPass), btRandomData, dwRandomDataSize); + RC4(btCryptedPass, sizeof(btCryptedPass), bthmacSHA1, SHA1HashSize); + + dwPassSize = ((*btCryptedPass)&0xff); + SHA1GetDigest(&btCryptedPass[(1+SHA1HashSize)], dwPassSize, btRandomData); + if (MemoryCompare(&btCryptedPass[1], SHA1HashSize, btRandomData, SHA1HashSize) == CMEM_EQUAL) + if (dwBuffSize >= dwPassSize) + { + memmove(lpszBuff, &btCryptedPass[(1+SHA1HashSize)], dwPassSize); + (*(lpszBuff+dwPassSize)) = 0; + + if (pdwBuffSize) (*pdwBuffSize) = dwPassSize; + return TRUE; + } + } + + return FALSE; +} + +BOOL CMraProto::GetPassDB(LPSTR lpszBuff, size_t dwBuffSize, size_t *pdwBuffSize) +{ + #if /*defined (_DEBUG) ||*/ defined (REL_DEB) + mraGetStaticStringA(NULL, "Pass", lpszBuff, dwBuffSize, pdwBuffSize); + return TRUE; + #else + switch (mraGetDword(NULL, "pCryptVer", 0)) { + case 1: + return GetPassDB_v1(lpszBuff, dwBuffSize, pdwBuffSize); + case 2: + return GetPassDB_v2(lpszBuff, dwBuffSize, pdwBuffSize); + default: + return FALSE; + } + #endif +} + +DWORD ReplaceInBuff(LPVOID lpInBuff, size_t dwInBuffSize, size_t dwReplaceItemsCount, LPVOID *plpInReplaceItems, size_t *pdwInReplaceItemsCounts, LPVOID *plpOutReplaceItems, size_t *pdwOutReplaceItemsCounts, LPVOID lpOutBuff, size_t dwOutBuffSize, size_t *pdwOutBuffSize) +{ + DWORD dwRetErrorCode = NO_ERROR; + LPBYTE *plpbtFounded; + #ifdef _DEBUG //check tables + for (size_t i = 0;i(lpbtOutBuffCur+(dwMemPartToCopy+pdwInReplaceItemsCounts[dwFirstFoundIndex]))) + { + memmove(lpbtOutBuffCur, lpbtInBuffCurPrev, dwMemPartToCopy);lpbtOutBuffCur += dwMemPartToCopy; + memmove(lpbtOutBuffCur, plpOutReplaceItems[dwFirstFoundIndex], pdwOutReplaceItemsCounts[dwFirstFoundIndex]);lpbtOutBuffCur += pdwOutReplaceItemsCounts[dwFirstFoundIndex]; + lpbtInBuffCurPrev = (plpbtFounded[dwFirstFoundIndex]+pdwInReplaceItemsCounts[dwFirstFoundIndex]); + + for (i = 0;i")}; +static const size_t dwXMLSymbolsCount[] = {sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR)}; + +//Decode XML coded string. The function translate special xml code into standard characters. +DWORD DecodeXML(LPTSTR lptszMessage, size_t dwMessageSize, LPTSTR lptszMessageConverted, size_t dwMessageConvertedBuffSize, size_t *pdwMessageConvertedSize) +{ + DWORD dwRet = ReplaceInBuff(lptszMessage, (dwMessageSize*sizeof(TCHAR)), SIZEOF(lpszXMLTags), (LPVOID*)lpszXMLTags, (size_t*)dwXMLTagsCount, (LPVOID*)lpszXMLSymbols, (size_t*)dwXMLSymbolsCount, lptszMessageConverted, (dwMessageConvertedBuffSize*sizeof(TCHAR)), pdwMessageConvertedSize); + if (pdwMessageConvertedSize) + *pdwMessageConvertedSize /= sizeof(TCHAR); + return dwRet; +} + +//Encode XML coded string. The function translate special saved xml characters into special characters. +DWORD EncodeXML(LPTSTR lptszMessage, size_t dwMessageSize, LPTSTR lptszMessageConverted, size_t dwMessageConvertedBuffSize, size_t *pdwMessageConvertedSize) +{ + DWORD dwRet = ReplaceInBuff(lptszMessage, (dwMessageSize*sizeof(TCHAR)), SIZEOF(lpszXMLTags), (LPVOID*)lpszXMLSymbols, (size_t*)dwXMLSymbolsCount, (LPVOID*)lpszXMLTags, (size_t*)dwXMLTagsCount, lptszMessageConverted, (dwMessageConvertedBuffSize*sizeof(TCHAR)), pdwMessageConvertedSize); + if (pdwMessageConvertedSize) + *pdwMessageConvertedSize /= sizeof(TCHAR); + return dwRet; +} -- cgit v1.2.3