void CIcqProto::icq_LogMessage(int level, const char *szMsg) { NetLog_Server("%s", szMsg); int displayLevel = getSettingByte(NULL, "ShowLogLevel", LOG_WARNING); if (level >= displayLevel) { if (!bErrorBoxVisible || !getSettingByte(NULL, "IgnoreMultiErrorBox", 0)) { // error not shown or allowed multi - show messagebox LogMessageInfo *lmi = (LogMessageInfo*)SAFE_MALLOC(sizeof(LogMessageInfo)); lmi->bLevel = (BYTE)level; lmi->szMsg = null_strdup(szMsg); lmi->szTitle = szLevelDescr[level]; ForkThread( &CIcqProto::icq_LogMessageThread, lmi); } } }
int CIcqProto::OnPreBuildContactMenu(WPARAM wParam, LPARAM) { HANDLE hContact = (HANDLE)wParam; if (hContact == NULL) return 0; if (icqOnline()) { BOOL bCtrlPressed = (GetKeyState(VK_CONTROL)&0x8000 ) != 0; DWORD dwUin = getContactUin(hContact); sttEnableMenuItem(g_hContactMenuItems[ICMI_AUTH_REQUEST], dwUin && (bCtrlPressed || (getSettingByte((HANDLE)wParam, "Auth", 0) && getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_ID, 0)))); sttEnableMenuItem(g_hContactMenuItems[ICMI_AUTH_GRANT], dwUin && (bCtrlPressed || getSettingByte((HANDLE)wParam, "Grant", 0))); sttEnableMenuItem(g_hContactMenuItems[ICMI_AUTH_REVOKE], dwUin && (bCtrlPressed || (getSettingByte(NULL, "PrivacyItems", 0) && !getSettingByte((HANDLE)wParam, "Grant", 0)))); sttEnableMenuItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST], m_bSsiEnabled && !getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_ID, 0) && !getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_IGNORE, 0) && !DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)); } sttEnableMenuItem(g_hContactMenuItems[ICMI_OPEN_PROFILE],getContactUin(hContact) != 0); BYTE bXStatus = getContactXStatus((HANDLE)wParam); sttEnableMenuItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], m_bHideXStatusUI ? 0 : bXStatus != 0); if (bXStatus && !m_bHideXStatusUI) { CLISTMENUITEM clmi = {0}; clmi.cbSize = sizeof(clmi); clmi.flags = CMIM_ICON; if (bXStatus > 0 && bXStatus <= XSTATUS_COUNT) clmi.hIcon = getXStatusIcon(bXStatus, LR_SHARED); else clmi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hContactMenuItems[ICMI_XSTATUS_DETAILS], (LPARAM)&clmi); } return 0; }
cookie_message_data* CIcqProto::CreateMessageCookieData(BYTE bMsgType, HANDLE hContact, DWORD dwUin, int bUseSrvRelay) { BYTE bAckType; WORD wStatus = getContactStatus(hContact); if (!getSettingByte(hContact, "SlowSend", getSettingByte(NULL, "SlowSend", DEFAULT_SLOWSEND)) || (!dwUin && wStatus == ID_STATUS_OFFLINE)) bAckType = ACKTYPE_NONE; else if (bUseSrvRelay) bAckType = ACKTYPE_CLIENT; else bAckType = ACKTYPE_SERVER; cookie_message_data* pCookieData = CreateMessageCookie(bMsgType, bAckType); // set flag for offline messages - to allow proper error handling if (wStatus == ID_STATUS_OFFLINE || wStatus == ID_STATUS_INVISIBLE) pCookieData->isOffline = TRUE; return pCookieData; }
void CIcqProto::makeContactTemporaryVisible(HANDLE hContact) { DWORD dwUin; uid_str szUid; if (getSettingByte(hContact, "TemporaryVisible", 0)) return; // already there if (getContactUid(hContact, &dwUin, &szUid)) return; // Invalid contact icq_sendGenericContact(dwUin, szUid, ICQ_BOS_FAMILY, ICQ_CLI_ADDTEMPVISIBLE); setSettingByte(hContact, "TemporaryVisible", 1); #ifdef _DEBUG NetLog_Server("Added contact %s to temporary visible list", strUID(dwUin, szUid)); #endif }
void __cdecl CIcqProto::icq_LogMessageThread(void* arg) { LogMessageInfo *err = (LogMessageInfo*)arg; if (!err) return; if (bPopUpService && getSettingByte(NULL, "PopupsLogEnabled", DEFAULT_LOG_POPUPS_ENABLED)) { ShowPopUpMsg(NULL, err->szTitle, err->szMsg, err->bLevel); SAFE_FREE((void**)&err->szMsg); SAFE_FREE((void**)&err); return; } bErrorBoxVisible = TRUE; if (err->szMsg && err->szTitle) MessageBoxUtf(NULL, err->szMsg, err->szTitle, MB_OK); SAFE_FREE((void**)&err->szMsg); SAFE_FREE((void**)&err); bErrorBoxVisible = FALSE; }
int CIcqProto::ShowPopUpMsg(HANDLE hContact, const char *szTitle, const char *szMsg, BYTE bType) { if (bPopUpService && getSettingByte(NULL, "PopupsEnabled", DEFAULT_POPUPS_ENABLED)) { POPUPDATAEX ppd = {0}; POPUPDATAW ppdw = {0}; LPCTSTR rsIcon; char szPrefix[32], szSetting[32]; strcpy(szPrefix, "Popups"); ppd.iSeconds = 0; switch(bType) { case LOG_NOTE: rsIcon = MAKEINTRESOURCE(IDI_INFORMATION); ppd.colorBack = DEFAULT_LOG0_BACK_COLORS; ppd.colorText = DEFAULT_LOG0_TEXT_COLORS; strcat(szPrefix, "0"); break; case LOG_WARNING: rsIcon = MAKEINTRESOURCE(IDI_WARNING); ppd.colorBack = DEFAULT_LOG1_BACK_COLORS; ppd.colorText = DEFAULT_LOG1_TEXT_COLORS; strcat(szPrefix, "1"); break; case LOG_ERROR: rsIcon = MAKEINTRESOURCE(IDI_ERROR); ppd.colorBack = DEFAULT_LOG2_BACK_COLORS; ppd.colorText = DEFAULT_LOG2_TEXT_COLORS; strcat(szPrefix, "2"); break; case LOG_FATAL: rsIcon = MAKEINTRESOURCE(IDI_ERROR); ppd.colorBack = DEFAULT_LOG3_BACK_COLORS; ppd.colorText = DEFAULT_LOG3_TEXT_COLORS; strcat(szPrefix, "3"); break; case POPTYPE_SPAM: rsIcon = MAKEINTRESOURCE(IDI_WARNING); ppd.colorBack = DEFAULT_SPAM_BACK_COLORS; ppd.colorText = DEFAULT_SPAM_TEXT_COLORS; strcat(szPrefix, "Spam"); break; default: return -1; } if (!getSettingByte(NULL, "PopupsSysIcons", DEFAULT_POPUPS_SYS_ICONS)) ppd.lchIcon = m_hIconProtocol->GetIcon(); else ppd.lchIcon = (HICON)LoadImage( NULL, rsIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); if (getSettingByte(NULL, "PopupsWinColors", DEFAULT_POPUPS_WIN_COLORS)) { ppd.colorText = GetSysColor(COLOR_WINDOWTEXT); ppd.colorBack = GetSysColor(COLOR_WINDOW); } else { strcpy(szSetting, szPrefix); strcat(szSetting, "TextColor"); ppd.colorText = getSettingDword(NULL, szSetting, ppd.colorText); strcpy(szSetting, szPrefix); strcat(szSetting, "BackColor"); ppd.colorBack = getSettingDword(NULL, szSetting, ppd.colorBack); } strcpy(szSetting, szPrefix); strcat(szSetting, "Timeout"); ppd.iSeconds = getSettingDword(NULL, szSetting, ppd.iSeconds); #if defined( _UNICODE ) // call unicode popup module - only on unicode OS otherwise it will not work properly :( // due to Popup Plug bug in ADDPOPUPW implementation if ( ServiceExists( MS_POPUP_ADDPOPUPW )) { char str[4096]; make_unicode_string_static(ICQTranslateUtfStatic(szTitle, str, sizeof(str)), ppdw.lpwzContactName, MAX_CONTACTNAME); make_unicode_string_static(ICQTranslateUtfStatic(szMsg, str, sizeof(str)), ppdw.lpwzText, MAX_SECONDLINE); ppdw.lchContact = hContact; ppdw.lchIcon = ppd.lchIcon; ppdw.colorBack = ppd.colorBack; ppdw.colorText = ppd.colorText; ppdw.PluginWindowProc = NULL; ppdw.PluginData = NULL; ppdw.iSeconds = ppd.iSeconds; return CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&ppdw, 0); } else #endif { char str[MAX_PATH]; utf8_decode_static(ICQTranslateUtfStatic(szTitle, str, MAX_PATH), ppd.lpzContactName, MAX_CONTACTNAME); utf8_decode_static(ICQTranslateUtfStatic(szMsg, str, MAX_PATH), ppd.lpzText, MAX_SECONDLINE); ppd.lchContact = hContact; ppd.PluginWindowProc = NULL; ppd.PluginData = NULL; return CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); } } return -1; // Failure }
void __cdecl CIcqProto::ServerThread(serverthread_start_info *infoParam) { serverthread_info info = {0}; info.isLoginServer = 1; info.wAuthKeyLen = infoParam->wPassLen; null_strcpy((char*)info.szAuthKey, infoParam->szPass, info.wAuthKeyLen); // store server port info.wServerPort = infoParam->nloc.wPort; srand(time(NULL)); ResetSettingsOnConnect(); // Connect to the login server NetLog_Server("Authenticating to server"); { NETLIBOPENCONNECTION nloc = infoParam->nloc; nloc.timeout = 6; if (m_bGatewayMode) nloc.flags |= NLOCF_HTTPGATEWAY; hServerConn = NetLib_OpenConnection(m_hServerNetlibUser, NULL, &nloc); SAFE_FREE((void**)&nloc.szHost); SAFE_FREE((void**)&infoParam); if (hServerConn && m_bSecureConnection) { if (!CallService(MS_NETLIB_STARTSSL, (WPARAM)hServerConn, 0)) { icq_LogMessage(LOG_ERROR, LPGEN("Unable to connect to ICQ login server, SSL could not be negotiated")); SetCurrentStatus(ID_STATUS_OFFLINE); NetLib_CloseConnection(&hServerConn, TRUE); return; } } } // Login error if (hServerConn == NULL) { DWORD dwError = GetLastError(); SetCurrentStatus(ID_STATUS_OFFLINE); icq_LogUsingErrorCode(LOG_ERROR, dwError, LPGEN("Unable to connect to ICQ login server")); return; } // Initialize direct connection ports { DWORD dwInternalIP; BYTE bConstInternalIP = getSettingByte(NULL, "ConstRealIP", 0); info.hDirectBoundPort = NetLib_BindPort(icq_newConnectionReceived, this, &wListenPort, &dwInternalIP); if (!info.hDirectBoundPort) { icq_LogUsingErrorCode(LOG_WARNING, GetLastError(), LPGEN("Miranda was unable to allocate a port to listen for direct peer-to-peer connections between clients. You will be able to use most of the ICQ network without problems but you may be unable to send or receive files.\n\nIf you have a firewall this may be blocking Miranda, in which case you should configure your firewall to leave some ports open and tell Miranda which ports to use in M->Options->ICQ->Network.")); wListenPort = 0; if (!bConstInternalIP) deleteSetting(NULL, "RealIP"); } else if (!bConstInternalIP) setSettingDword(NULL, "RealIP", dwInternalIP); } // Initialize rate limiting queues { icq_lock l(m_ratesMutex); m_ratesQueue_Request = new rates_queue(this, "request", RML_IDLE_30, RML_IDLE_50, 1); m_ratesQueue_Response = new rates_queue(this, "response", RML_IDLE_10, RML_IDLE_30, -1); } // This is the "infinite" loop that receives the packets from the ICQ server { int recvResult; NETLIBPACKETRECVER packetRecv = {0}; info.hPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)hServerConn, 0x2400); packetRecv.cbSize = sizeof(packetRecv); packetRecv.dwTimeout = INFINITE; while (serverThreadHandle) { if (info.bReinitRecver) { // we reconnected, reinit struct info.bReinitRecver = 0; ZeroMemory(&packetRecv, sizeof(packetRecv)); packetRecv.cbSize = sizeof(packetRecv); packetRecv.dwTimeout = INFINITE; } recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)info.hPacketRecver, (LPARAM)&packetRecv); if (recvResult == 0) { NetLog_Server("Clean closure of server socket"); break; } if (recvResult == SOCKET_ERROR) { NetLog_Server("Abortive closure of server socket, error: %d", GetLastError()); break; } if (m_iDesiredStatus == ID_STATUS_OFFLINE) { // Disconnect requested, send disconnect packet icq_sendCloseConnection(); // disconnected upon request m_bConnectionLost = FALSE; SetCurrentStatus(ID_STATUS_OFFLINE); NetLog_Server("Logged off."); break; } // Deal with the packet packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable, &info); } serverThreadHandle = NULL; // Time to shutdown NetLib_CloseConnection(&hServerConn, TRUE); // Close the packet receiver (connection may still be open) NetLib_SafeCloseHandle(&info.hPacketRecver); // Close DC port NetLib_SafeCloseHandle(&info.hDirectBoundPort); } // disable auto info-update thread icq_EnableUserLookup(FALSE); if (m_iStatus != ID_STATUS_OFFLINE && m_iDesiredStatus != ID_STATUS_OFFLINE) { if (!info.bLoggedIn) icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nLogin sequence failed for unknown reason.\nTry again later.")); // set flag indicating we were kicked out m_bConnectionLost = TRUE; SetCurrentStatus(ID_STATUS_OFFLINE); } // signal keep-alive thread to stop StopKeepAlive(&info); // Close all open DC connections CloseContactDirectConns(NULL); // Close avatar connection if any StopAvatarThread(); // Offline all contacts HANDLE hContact = FindFirstContact(); while (hContact) { DWORD dwUIN; uid_str szUID; if (!getContactUid(hContact, &dwUIN, &szUID)) { if (getContactStatus(hContact) != ID_STATUS_OFFLINE) { char tmp = 0; setSettingWord(hContact, "Status", ID_STATUS_OFFLINE); handleXStatusCaps(dwUIN, szUID, hContact, (BYTE*)&tmp, 0, &tmp, 0); } } hContact = FindNextContact(hContact); } setSettingDword(NULL, "LogonTS", 0); // clear logon time servlistPendingFlushOperations(); // clear pending operations list { // release rates queues icq_lock l(m_ratesMutex); SAFE_DELETE((void_struct**)&m_ratesQueue_Request); SAFE_DELETE((void_struct**)&m_ratesQueue_Response); SAFE_DELETE((void_struct**)&m_rates); } FlushServerIDs(); // clear server IDs list NetLog_Server("%s thread ended.", "Server"); }