int CMsnProto::OnPrebuildContactMenu(WPARAM wParam, LPARAM) { const HANDLE hContact = (HANDLE)wParam; char szEmail[MSN_MAX_EMAIL_LEN]; CLISTMENUITEM mi = {0}; mi.cbSize = sizeof(mi); if (!MSN_IsMyContact(hContact)) return 0; bool isMe = MSN_IsMeByContact(hContact, szEmail); if (szEmail[0]) { int listId = Lists_GetMask(szEmail); bool noChat = !(listId & LIST_FL) || isMe || getByte(hContact, "ChatRoom", 0); mi.flags = CMIM_NAME | CMIM_FLAGS | CMIF_ICONFROMICOLIB; if (noChat) mi.flags |= CMIF_HIDDEN; mi.pszName = (char*)((listId & LIST_BL) ? "&Unblock" : "&Block"); MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hBlockMenuItem, (LPARAM)&mi); mi.flags = CMIM_NAME | CMIM_FLAGS | CMIF_ICONFROMICOLIB; if (!emailEnabled) mi.flags |= CMIF_HIDDEN; mi.pszName = isMe ? LPGEN("Open &Hotmail Inbox") : LPGEN("Send &Hotmail E-mail"); MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hOpenInboxMenuItem, (LPARAM)&mi); mi.flags = CMIM_FLAGS | CMIF_ICONFROMICOLIB | CMIF_NOTOFFLINE; if (noChat) mi.flags |= CMIF_HIDDEN; MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hNetmeetingMenuItem, (LPARAM)&mi); MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hChatInviteMenuItem, (LPARAM)&mi); } return 0; }
void __stdcall MSN_CloseConnections() { int i; EnterCriticalSection( &sttLock ); for ( i=0; i < MAX_THREAD_COUNT; i++ ) { ThreadData* T = sttThreads[ i ]; if ( T == NULL ) continue; switch (T->mType) { case SERVER_DISPATCH : case SERVER_NOTIFICATION : case SERVER_SWITCHBOARD : if (T->s != NULL) T->sendPacket( "OUT", NULL ); break; case SERVER_P2P_DIRECT : { SOCKET s = MSN_CallService( MS_NETLIB_GETSOCKET, LPARAM( T->s ), 0 ); if ( s != INVALID_SOCKET ) shutdown( s, 2 ); } break; } } LeaveCriticalSection( &sttLock ); }
void MSN_RemoveContactMenus(void) { UnhookEvent(hPrebuildMenuHook); MSN_CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hBlockMenuItem, 0); MSN_CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hLiveSpaceMenuItem, 0); MSN_CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hNetmeetingMenuItem, 0); MSN_CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hChatInviteMenuItem, 0); MSN_CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hOpenInboxMenuItem, 0); DestroyServiceFunction(hNetMeeting); DestroyServiceFunction(hBlockCom); DestroyServiceFunction(hSendHotMail); DestroyServiceFunction(hInviteChat); DestroyServiceFunction(hViewProfile); }
int __cdecl CMsnProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam) { switch(eventType) { case EV_PROTO_ONLOAD: return OnModulesLoaded(0, 0); case EV_PROTO_ONEXIT: return OnPreShutdown(0, 0); case EV_PROTO_ONOPTIONS: return OnOptionsInit(wParam, lParam); case EV_PROTO_ONMENU: MsnInitMainMenu(); break; case EV_PROTO_ONERASE: { char szDbsettings[64]; mir_snprintf(szDbsettings, sizeof(szDbsettings), "%s_HTTPS", m_szModuleName); MSN_CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)szDbsettings); break; } case EV_PROTO_ONRENAME: if (mainMenuRoot) { CLISTMENUITEM clmi = {0}; clmi.cbSize = sizeof(CLISTMENUITEM); clmi.flags = CMIM_NAME | CMIF_TCHAR; clmi.ptszName = m_tszUserName; MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)mainMenuRoot, (LPARAM)&clmi); } break; case EV_PROTO_ONCONTACTDELETED: return OnContactDeleted(wParam, lParam); case EV_PROTO_DBSETTINGSCHANGED: return OnDbSettingChanged(wParam, lParam); } return 1; }
void MSN_InitContactMenu(void) { char servicefunction[100]; strcpy(servicefunction, "MSN"); char* tDest = servicefunction + strlen(servicefunction); CLISTMENUITEM mi = {0}; mi.cbSize = sizeof(mi); mi.flags = CMIF_ICONFROMICOLIB; mi.pszService = servicefunction; strcpy(tDest, MSN_BLOCK); hBlockCom = CreateServiceFunction(servicefunction, MsnMenuBlockCommand); mi.position = -500050000; mi.icolibItem = GetIconHandle(IDI_MSNBLOCK); mi.pszName = LPGEN("&Block"); hBlockMenuItem = (HGENMENU)MSN_CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, MSN_VIEW_PROFILE); hViewProfile = CreateServiceFunction(servicefunction, MsnMenuViewProfile); mi.position = -500050003; mi.icolibItem = GetIconHandle(IDI_PROFILE); mi.pszName = LPGEN("View &Profile"); hLiveSpaceMenuItem = (HGENMENU)MSN_CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, MSN_NETMEETING); hNetMeeting = CreateServiceFunction(servicefunction, MsnMenuSendNetMeeting); mi.flags = CMIF_ICONFROMICOLIB | CMIF_NOTOFFLINE; mi.position = -500050002; mi.icolibItem = GetIconHandle(IDI_NETMEETING); mi.pszName = LPGEN("&Start Netmeeting"); hNetmeetingMenuItem = (HGENMENU)MSN_CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, "/SendHotmail"); hSendHotMail = CreateServiceFunction(servicefunction, MsnMenuSendHotmail); mi.position = -2000010005; mi.flags = CMIF_ICONFROMICOLIB | CMIF_HIDDEN; mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_SENDEMAIL); mi.pszName = LPGEN("Open &Hotmail Inbox"); hOpenInboxMenuItem = (HGENMENU)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); hPrebuildMenuHook = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, MSN_OnPrebuildContactMenu); }
HANDLE __cdecl CMsnProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent) { DBEVENTINFO dbei = {0}; dbei.cbSize = sizeof(dbei); if ((dbei.cbBlob = MSN_CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == (DWORD)(-1)) return NULL; dbei.pBlob=(PBYTE) _malloca(dbei.cbBlob); if (MSN_CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei)) return NULL; if (strcmp(dbei.szModule, m_szModuleName)) return NULL; if (dbei.eventType != EVENTTYPE_AUTHREQUEST) return NULL; char* nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); char* firstName = nick + strlen(nick) + 1; char* lastName = firstName + strlen(firstName) + 1; char* email = lastName + strlen(lastName) + 1; return AddToListByEmail(email, nick, flags); }
int CMsnProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason) { if (!msnLoggedIn) return 1; DBEVENTINFO dbei = { 0 }; dbei.cbSize = sizeof(dbei); if ((int)(dbei.cbBlob = MSN_CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == -1) return 1; dbei.pBlob = (PBYTE)_malloca(dbei.cbBlob); if (MSN_CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei)) return 1; if (dbei.eventType != EVENTTYPE_AUTHREQUEST) return 1; if (strcmp(dbei.szModule, m_szModuleName)) return 1; char* nick = (char*)(dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); char* firstName = nick + strlen(nick) + 1; char* lastName = firstName + strlen(firstName) + 1; char* email = lastName + strlen(lastName) + 1; MsnContact* msc = Lists_Get(email); if (msc == NULL) return 0; MSN_AddUser(NULL, email, msc->netId, LIST_PL + LIST_REMOVE); MSN_AddUser(NULL, email, msc->netId, LIST_BL); MSN_AddUser(NULL, email, msc->netId, LIST_RL); if (!(msc->list & (LIST_FL | LIST_LL))) { if (msc->hContact) MSN_CallService(MS_DB_CONTACT_DELETE, (WPARAM)msc->hContact, 0); msc->hContact = NULL; HANDLE hContact = MSN_HContactFromEmail(email); if (hContact) MSN_CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); } return 0; }
int msn_httpGatewayInit(HANDLE hConn, NETLIBOPENCONNECTION* nloc, NETLIBHTTPREQUEST* nlhr) { NETLIBHTTPPROXYINFO nlhpi = {0}; nlhpi.cbSize = sizeof(nlhpi); nlhpi.szHttpGetUrl = NULL; nlhpi.szHttpPostUrl = "messenger.hotmail.com"; nlhpi.flags = NLHPIF_HTTP11; nlhpi.combinePackets = MSN_PACKETS_COMBINE; return MSN_CallService(MS_NETLIB_SETHTTPPROXYINFO, (WPARAM)hConn, (LPARAM)&nlhpi); }
int CMsnProto::SendBroadcast(HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam) { ACKDATA ack = {0}; ack.cbSize = sizeof(ACKDATA); ack.szModule = m_szModuleName; ack.hContact = hContact; ack.type = type; ack.result = result; ack.hProcess = hProcess; ack.lParam = lParam; return MSN_CallService(MS_PROTO_BROADCASTACK, 0, (LPARAM)&ack); }
int __cdecl CMsnProto::RecvMsg(HANDLE hContact, PROTORECVEVENT* pre) { char tEmail[MSN_MAX_EMAIL_LEN]; getStaticString(hContact, "e-mail", tEmail, sizeof(tEmail)); if (Lists_IsInList(LIST_FL, tEmail)) DBDeleteContactSetting(hContact, "CList", "Hidden"); CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM)pre }; MSN_CallService(MS_PROTO_RECVMSG, 0, (LPARAM)&ccs); return 0; }
void CMsnProto::MSN_EnableMenuItems(bool bEnable) { CLISTMENUITEM mi = {0}; mi.cbSize = sizeof(mi); mi.flags = CMIM_FLAGS; if (!bEnable) mi.flags |= CMIF_GRAYED; for (unsigned i=0; i < SIZEOF(menuItemsMain); i++) { if (menuItemsMain[i] != NULL) MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)menuItemsMain[i], (LPARAM)&mi); } if (bEnable) { mi.flags = CMIM_FLAGS; if (!emailEnabled) mi.flags |= CMIF_HIDDEN; MSN_CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)menuItemsMain[1], (LPARAM)&mi); } }
int CMsnProto::Authorize(HANDLE hDbEvent) { if (!msnLoggedIn) return 1; DBEVENTINFO dbei = { 0 }; dbei.cbSize = sizeof(dbei); if ((int)(dbei.cbBlob = MSN_CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == -1) return 1; dbei.pBlob = (PBYTE)_malloca(dbei.cbBlob); if (MSN_CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei)) return 1; if (dbei.eventType != EVENTTYPE_AUTHREQUEST) return 1; if (strcmp(dbei.szModule, m_szModuleName)) return 1; char* nick = (char*)(dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); char* firstName = nick + strlen(nick) + 1; char* lastName = firstName + strlen(firstName) + 1; char* email = lastName + strlen(lastName) + 1; HANDLE hContact = MSN_HContactFromEmail(email, nick, true, 0); int netId = Lists_GetNetId(email); MSN_AddUser(hContact, email, netId, LIST_AL); MSN_AddUser(hContact, email, netId, LIST_BL + LIST_REMOVE); MSN_AddUser(hContact, email, netId, LIST_PL + LIST_REMOVE); MSN_SetContactDb(hContact, email); return 0; }
void ThreadData::applyGatewayData( HANDLE hConn, bool isPoll ) { char szHttpPostUrl[300]; getGatewayUrl( szHttpPostUrl, sizeof( szHttpPostUrl ), isPoll ); MSN_DebugLog( "applying '%s' to %08X [%d]", szHttpPostUrl, this, GetCurrentThreadId() ); NETLIBHTTPPROXYINFO nlhpi = {0}; nlhpi.cbSize = sizeof(nlhpi); nlhpi.flags = NLHPIF_HTTP11; nlhpi.szHttpGetUrl = NULL; nlhpi.szHttpPostUrl = szHttpPostUrl; nlhpi.firstPostSequence = 1; MSN_CallService( MS_NETLIB_SETHTTPPROXYINFO, (WPARAM)hConn, (LPARAM)&nlhpi); }
void __stdcall MSN_CloseThreads() { EnterCriticalSection( &sttLock ); for ( int i=0; i < MAX_THREAD_COUNT; i++ ) { ThreadData* T = sttThreads[ i ]; if ( T == NULL || T->s == NULL ) continue; SOCKET s = MSN_CallService( MS_NETLIB_GETSOCKET, LPARAM( T->s ), 0 ); if ( s != INVALID_SOCKET ) shutdown( s, 2 ); } LeaveCriticalSection( &sttLock ); }
TCHAR* CMsnProto::GetContactNameT(HANDLE hContact) { if (hContact) return (TCHAR*)MSN_CallService(MS_CLIST_GETCONTACTDISPLAYNAME, WPARAM(hContact), GCDNF_TCHAR); else { CONTACTINFO ci = {0}; ci.cbSize = sizeof(ci); ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; ci.szProto = m_szModuleName; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) return (TCHAR*)ci.pszVal; else return _T("Me"); } }
int CMsnProto::getStaticString(HANDLE hContact, const char* valueName, char* dest, unsigned dest_len) { DBVARIANT dbv; dbv.pszVal = dest; dbv.cchVal = (WORD)dest_len; dbv.type = DBVT_ASCIIZ; DBCONTACTGETSETTING sVal; sVal.pValue = &dbv; sVal.szModule = m_szModuleName; sVal.szSetting = valueName; if (MSN_CallService(MS_DB_CONTACT_GETSETTINGSTATIC, (WPARAM)hContact, (LPARAM)&sVal) != 0) return 1; return (dbv.type != DBVT_ASCIIZ); }
int CMsnProto::AuthRecv(HANDLE hContact, PROTORECVEVENT* pre) { DBEVENTINFO dbei = { 0 }; dbei.cbSize = sizeof(dbei); dbei.szModule = m_szModuleName; dbei.timestamp = pre->timestamp; dbei.flags = (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0; dbei.flags |= (pre->flags & PREF_UTF) ? DBEF_UTF : 0; dbei.eventType = EVENTTYPE_AUTHREQUEST; /* Just copy the Blob from PSR_AUTH event. */ dbei.cbBlob = pre->lParam; dbei.pBlob = (PBYTE)pre->szMessage; MSN_CallService(MS_DB_EVENT_ADD, 0,(LPARAM)&dbei); return 0; }
void CMsnProto::MsnRemoveMainMenus(void) { if (mainMenuRoot) MSN_CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)mainMenuRoot, 0); }
int __cdecl CMsnProto::RecvFile(HANDLE hContact, PROTOFILEEVENT* evt) { CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)evt }; return MSN_CallService(MS_PROTO_RECVFILET, 0, (LPARAM)&ccs); }
CMsnProto::CMsnProto(const char* aProtoName, const TCHAR* aUserName) : contList(10, CompareLists), grpList(10, CompareId), sttThreads(10, PtrKeySortT), sessionList(10, PtrKeySortT), dcList(10, PtrKeySortT), msgQueueList(1), msgCache(5, CompareId) { char path[MAX_PATH]; m_iVersion = 2; m_tszUserName = mir_tstrdup(aUserName); m_szModuleName = mir_strdup(aProtoName); m_szProtoName = mir_strdup(aProtoName); _strlwr(m_szProtoName); m_szProtoName[0] = (char)toupper(m_szProtoName[0]); mir_snprintf(path, sizeof(path), "%s/Status", m_szModuleName); MSN_CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)path); mir_snprintf(path, sizeof(path), "%s/IdleTS", m_szModuleName); MSN_CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)path); mir_snprintf(path, sizeof(path), "%s/p2pMsgId", m_szModuleName); MSN_CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)path); mir_snprintf(path, sizeof(path), "%s/MobileEnabled", m_szModuleName); MSN_CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)path); mir_snprintf(path, sizeof(path), "%s/MobileAllowed", m_szModuleName); MSN_CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)path); // Protocol services and events... hMSNNudge = CreateProtoEvent("/Nudge"); CreateProtoService(PS_CREATEACCMGRUI, &CMsnProto::SvcCreateAccMgrUI); CreateProtoService(PS_GETAVATARINFOT, &CMsnProto::GetAvatarInfo); CreateProtoService(PS_GETMYAWAYMSG, &CMsnProto::GetMyAwayMsg); CreateProtoService(PS_LEAVECHAT, &CMsnProto::OnLeaveChat); CreateProtoService(PS_GETMYAVATART, &CMsnProto::GetAvatar); CreateProtoService(PS_SETMYAVATART, &CMsnProto::SetAvatar); CreateProtoService(PS_GETAVATARCAPS, &CMsnProto::GetAvatarCaps); CreateProtoService(PS_GET_LISTENINGTO, &CMsnProto::GetCurrentMedia); CreateProtoService(PS_SET_LISTENINGTO, &CMsnProto::SetCurrentMedia); CreateProtoService(PS_SETMYNICKNAME, &CMsnProto::SetNickName); CreateProtoService(MSN_SEND_NUDGE, &CMsnProto::SendNudge); CreateProtoService(MSN_GETUNREAD_EMAILCOUNT, &CMsnProto::GetUnreadEmailCount); // service to get from protocol chat buddy info // CreateProtoService(MS_GC_PROTO_GETTOOLTIPTEXT, &CMsnProto::GCGetToolTipText); HookProtoEvent(ME_MSG_WINDOWPOPUP, &CMsnProto::OnWindowPopup); // HookProtoEvent(ME_MSG_WINDOWEVENT, &CMsnProto::OnWindowEvent); HookProtoEvent(ME_CLIST_GROUPCHANGE, &CMsnProto::OnGroupChange); HookProtoEvent(ME_OPT_INITIALISE, &CMsnProto::OnOptionsInit); HookProtoEvent(ME_CLIST_DOUBLECLICKED, &CMsnProto::OnContactDoubleClicked); LoadOptions(); HANDLE hContact = (HANDLE)MSN_CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); while (hContact != NULL) { if (MSN_IsMyContact(hContact)) { deleteSetting(hContact, "Status"); deleteSetting(hContact, "IdleTS"); deleteSetting(hContact, "p2pMsgId"); deleteSetting(hContact, "AccList"); // DBDeleteContactSetting(hContact, "CList", "StatusMsg"); } hContact = (HANDLE)MSN_CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact, 0); } deleteSetting(NULL, "MobileEnabled"); deleteSetting(NULL, "MobileAllowed"); if (getStaticString(NULL, "LoginServer", path, sizeof(path)) == 0 && (strcmp(path, MSN_DEFAULT_LOGIN_SERVER) == 0 || strcmp(path, MSN_DEFAULT_GATEWAY) == 0)) deleteSetting(NULL, "LoginServer"); if (MyOptions.SlowSend) { if (DBGetContactSettingDword(NULL, "SRMsg", "MessageTimeout", 10000) < 60000) DBWriteContactSettingDword(NULL, "SRMsg", "MessageTimeout", 60000); if (DBGetContactSettingDword(NULL, "SRMM", "MessageTimeout", 10000) < 60000) DBWriteContactSettingDword(NULL, "SRMM", "MessageTimeout", 60000); } mailsoundname = (char*)mir_alloc(64); mir_snprintf(mailsoundname, 64, "%s:Hotmail", m_szModuleName); SkinAddNewSoundExT(mailsoundname, m_tszUserName, LPGENT("Live Mail")); alertsoundname = (char*)mir_alloc(64); mir_snprintf(alertsoundname, 64, "%s:Alerts", m_szModuleName); SkinAddNewSoundExT(alertsoundname, m_tszUserName, LPGENT("Live Alert")); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; MSN_InitThreads(); Lists_Init(); MsgQueue_Init(); P2pSessions_Init(); InitCustomFolders(); TCHAR szBuffer[MAX_PATH]; char szDbsettings[64]; NETLIBUSER nlu1 = {0}; nlu1.cbSize = sizeof(nlu1); nlu1.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu1.szSettingsModule = szDbsettings; nlu1.ptszDescriptiveName = szBuffer; mir_snprintf(szDbsettings, sizeof(szDbsettings), "%s_HTTPS", m_szModuleName); mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s plugin HTTPS connections"), m_tszUserName); hNetlibUserHttps = (HANDLE)MSN_CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu1); NETLIBUSER nlu = {0}; nlu.cbSize = sizeof(nlu); nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; nlu.ptszDescriptiveName = szBuffer; nlu.szHttpGatewayUserAgent = (char*)MSN_USER_AGENT; nlu.pfnHttpGatewayInit = msn_httpGatewayInit; nlu.pfnHttpGatewayWrapSend = msn_httpGatewayWrapSend; nlu.pfnHttpGatewayUnwrapRecv = msn_httpGatewayUnwrapRecv; mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s plugin connections"), m_tszUserName); hNetlibUser = (HANDLE)MSN_CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); }
void __cdecl MSNServerThread( ThreadData* info ) { if ( !sttRedirectorWasChecked ) { sttRedirectorWasChecked = true; MSN_StartThread(( pThreadFunc )msn_RedirectorThread, NULL ); } NETLIBOPENCONNECTION tConn = { 0 }; tConn.cbSize = sizeof( tConn ); tConn.flags = NLOCF_V2; char* tPortDelim = strrchr( info->mServer, ':' ); if ( tPortDelim != NULL ) *tPortDelim = '\0'; if ( MyOptions.UseGateway && !MyOptions.UseProxy ) { tConn.szHost = MSN_DEFAULT_GATEWAY; tConn.wPort = 80; } else { tConn.szHost = info->mServer; tConn.wPort = MSN_DEFAULT_PORT; if ( tPortDelim != NULL ) { int tPortNumber; if ( sscanf( tPortDelim+1, "%d", &tPortNumber ) == 1 ) tConn.wPort = ( WORD )tPortNumber; } } MSN_DebugLog( "Thread started: server='%s', type=%d", tConn.szHost, info->mType ); info->s = ( HANDLE )MSN_CallService( MS_NETLIB_OPENCONNECTION, ( WPARAM )hNetlibUser, ( LPARAM )&tConn ); if ( info->s == NULL ) { MSN_DebugLog( "Connection Failed (%d)", WSAGetLastError() ); switch ( info->mType ) { case SERVER_NOTIFICATION: case SERVER_DISPATCH: MSN_SendBroadcast( NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NOSERVER ); MSN_GoOffline(); break; } return; } if ( MyOptions.UseGateway ) MSN_CallService( MS_NETLIB_SETPOLLINGTIMEOUT, WPARAM( info->s ), 2 ); MSN_DebugLog( "Connected with handle=%08X", info->s ); if ( info->mType == SERVER_DISPATCH || info->mType == SERVER_NOTIFICATION ) { if ( MyOptions.UseMSNP11 ) info->sendPacket( "VER", "MSNP11 MSNP10 CVR0" ); else info->sendPacket( "VER", "MSNP10 MSNP9 CVR0" ); } else if ( info->mType == SERVER_SWITCHBOARD ) { char tEmail[ MSN_MAX_EMAIL_LEN ]; MSN_GetStaticString( "e-mail", NULL, tEmail, sizeof( tEmail )); info->sendPacket( info->mCaller ? "USR" : "ANS", "%s %s", tEmail, info->mCookie ); } else if ( info->mType == SERVER_FILETRANS && info->mCaller == 0 ) { info->send( "VER MSNFTP\r\n", 12 ); } if ( info->mIsMainThread ) { MSN_EnableMenuItems( TRUE ); msnPingTimeout = msnPingTimeoutCurrent; msnNsThread = info; if (hKeepAliveThreadEvt == NULL) { hKeepAliveThreadEvt = ::CreateEvent( NULL, TRUE, FALSE, NULL ); MSN_StartThread(( pThreadFunc )msn_keepAliveThread, NULL ); } } MSN_DebugLog( "Entering main recv loop" ); info->mBytesInData = 0; while ( TRUE ) { int handlerResult; int recvResult = info->recv( info->mData + info->mBytesInData, sizeof( info->mData ) - info->mBytesInData ); if ( recvResult == SOCKET_ERROR ) { MSN_DebugLog( "Connection %08p [%d] was abortively closed", info->s, GetCurrentThreadId()); break; } if ( !recvResult ) { MSN_DebugLog( "Connection %08p [%d] was gracefully closed", info->s, GetCurrentThreadId()); break; } info->mBytesInData += recvResult; if ( info->mCaller == 1 && info->mType == SERVER_FILETRANS ) { handlerResult = MSN_HandleMSNFTP( info, info->mData ); if ( handlerResult ) break; } else { while( TRUE ) { char* peol = strchr(info->mData,'\r'); if ( peol == NULL ) break; if ( info->mBytesInData < peol-info->mData+2 ) break; //wait for full line end char msg[ sizeof(info->mData) ]; memcpy( msg, info->mData, peol-info->mData ); msg[ peol-info->mData ] = 0; if ( *++peol != '\n' ) MSN_DebugLog( "Dodgy line ending to command: ignoring" ); else peol++; info->mBytesInData -= peol - info->mData; memmove( info->mData, peol, info->mBytesInData ); MSN_DebugLog( "RECV:%s", msg ); if ( !isalnum( msg[0] ) || !isalnum(msg[1]) || !isalnum(msg[2]) || (msg[3] && msg[3]!=' ')) { MSN_DebugLog( "Invalid command name" ); continue; } if ( info->mType != SERVER_FILETRANS ) { if ( isdigit(msg[0]) && isdigit(msg[1]) && isdigit(msg[2])) //all error messages handlerResult = MSN_HandleErrors( info, msg ); else handlerResult = MSN_HandleCommands( info, msg ); } else handlerResult = MSN_HandleMSNFTP( info, msg ); if ( handlerResult ) goto LBL_Exit; } } if ( info->mBytesInData == sizeof( info->mData )) { MSN_DebugLog( "sizeof(data) is too small: the longest line won't fit" ); break; } } LBL_Exit: if ( info->mIsMainThread ) { MSN_GoOffline(); msnNsThread = NULL; if ( hKeepAliveThreadEvt ) SetEvent( hKeepAliveThreadEvt ); } MSN_DebugLog( "Thread [%d] ending now", GetCurrentThreadId() ); }
int CMsnProto::MSN_GCEventHook(WPARAM, LPARAM lParam) { GCHOOK *gch = (GCHOOK*) lParam; if (!gch) return 1; if (_stricmp(gch->pDest->pszModule, m_szModuleName)) return 0; switch (gch->pDest->iType) { case GC_SESSION_TERMINATE: { ThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID); if (thread != NULL) thread->sendTerminate(); break; } case GC_USER_MESSAGE: if (gch->ptszText && gch->ptszText[0]) { ThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID); if (thread) { rtrim(gch->ptszText); // remove the ending linebreak TCHAR* pszMsg = UnEscapeChatTags(NEWTSTR_ALLOCA(gch->ptszText)); thread->sendMessage('N', NULL, NETID_MSN, UTF8(pszMsg), 0); DBVARIANT dbv; int bError = getTString("Nick", &dbv); GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_MESSAGE }; gcd.ptszID = gch->pDest->ptszID; GCEVENT gce = {0}; gce.cbSize = sizeof(GCEVENT); gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; gce.pDest = &gcd; gce.ptszNick = bError ? _T("") : dbv.ptszVal; gce.ptszUID = mir_a2t(MyOptions.szEmail); gce.time = time(NULL); gce.ptszText = gch->ptszText; gce.bIsMe = TRUE; CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); mir_free((void*)gce.ptszUID); if (!bError) MSN_FreeVariant(&dbv); } } break; case GC_USER_CHANMGR: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat, LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this))); break; case GC_USER_PRIVMESS: { char *email = mir_t2a(gch->ptszUID); HANDLE hContact = MSN_HContactFromEmail(email); MSN_CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); mir_free(email); break; } case GC_USER_LOGMENU: switch(gch->dwData) { case 10: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat, LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this))); break; case 20: MSN_KillChatSession(gch->pDest->ptszID); break; } break; case GC_USER_NICKLISTMENU: { char *email = mir_t2a(gch->ptszUID); HANDLE hContact = MSN_HContactFromEmail(email); mir_free(email); switch(gch->dwData) { case 10: MSN_CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); break; case 20: MSN_CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0); break; case 110: MSN_KillChatSession(gch->pDest->ptszID); break; } break; } /* haven't implemented in chat.dll case GC_USER_TYPNOTIFY: { int chatID = atoi(p); ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID); for (int j=0; j < thread->mJoinedCount; j++) { if ((long)thread->mJoinedContacts[j] > 0) CallService(MS_PROTO_SELFISTYPING, (WPARAM) thread->mJoinedContacts[j], (LPARAM) PROTOTYPE_SELFTYPING_ON); } break; } */ } return 0; }
unsigned MSN_GenRandom(void) { unsigned rndnum; MSN_CallService(MS_UTILS_GETRANDOM, sizeof(rndnum), (LPARAM)&rndnum); return rndnum & 0x7FFFFFFF; }
void CMsnProto::MsnInitMainMenu(void) { char servicefunction[100]; strcpy(servicefunction, m_szModuleName); char* tDest = servicefunction + strlen(servicefunction); CLISTMENUITEM mi = {0}; mi.cbSize = sizeof(mi); HGENMENU hRoot = MO_GetProtoRootMenu(m_szModuleName); if (hRoot == NULL) { mi.popupPosition = 500085000; mi.hParentMenu = HGENMENU_ROOT; mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; mi.icolibItem = GetIconHandle(IDI_MSN); mi.ptszName = m_tszUserName; hRoot = mainMenuRoot = (HGENMENU)MSN_CallService(MS_CLIST_ADDPROTOMENUITEM, (WPARAM)0, (LPARAM)&mi); } else { MsnRemoveMainMenus(); mainMenuRoot = NULL; } mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP; mi.hParentMenu = hRoot; mi.pszService = servicefunction; strcpy(tDest, MS_SET_NICKNAME_UI); CreateProtoService(MS_SET_NICKNAME_UI, &CMsnProto::SetNicknameUI); mi.position = 201001; mi.icolibItem = GetIconHandle(IDI_MSN); mi.pszName = LPGEN("Set &Nickname"); menuItemsMain[0] = (HGENMENU)MSN_CallService(MS_CLIST_ADDPROTOMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, MSN_INVITE); CreateProtoService(MSN_INVITE, &CMsnProto::MsnInviteCommand); mi.position = 201002; mi.icolibItem = GetIconHandle(IDI_INVITE); mi.pszName = LPGEN("Create &Chat"); menuItemsMain[0] = (HGENMENU)MSN_CallService(MS_CLIST_ADDPROTOMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, MS_GOTO_INBOX); CreateProtoService(MS_GOTO_INBOX, &CMsnProto::MsnGotoInbox); mi.position = 201003; mi.icolibItem = GetIconHandle(IDI_INBOX); mi.pszName = LPGEN("Display &Hotmail Inbox"); menuItemsMain[1] = (HGENMENU)MSN_CallService(MS_CLIST_ADDPROTOMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, MS_EDIT_PROFILE); CreateProtoService(MS_EDIT_PROFILE, &CMsnProto::MsnEditProfile); mi.position = 201004; mi.icolibItem = GetIconHandle(IDI_PROFILE); mi.pszName = LPGEN("View &Profile"); menuItemsMain[2] = (HGENMENU)MSN_CallService(MS_CLIST_ADDPROTOMENUITEM, 0, (LPARAM)&mi); strcpy(tDest, MS_EDIT_ALERTS); CreateProtoService(MS_EDIT_ALERTS, &CMsnProto::MsnSetupAlerts); mi.position = 201004; mi.icolibItem = GetIconHandle(IDI_PROFILE); mi.pszName = LPGEN("Setup Live &Alerts"); menuItemsMain[3] = (HGENMENU)MSN_CallService(MS_CLIST_ADDPROTOMENUITEM, 0, (LPARAM)&mi); MSN_EnableMenuItems(m_iStatus >= ID_STATUS_ONLINE); }
void CMsnProto::MSNatDetect(void) { unsigned i; PHOSTENT host = gethostbyname("echo.edge.messenger.live.com"); if (host == NULL) { MSN_DebugLog("P2PNAT could not find echo server \"echo.edge.messenger.live.com\""); return; } SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_port = _htons(7001); addr.sin_addr = *( PIN_ADDR )host->h_addr_list[0]; MSN_DebugLog("P2PNAT Detected echo server IP %d.%d.%d.%d", addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2, addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4); SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); connect(s, (SOCKADDR*)&addr, sizeof(addr)); UDPProbePkt pkt = { 0 }; UDPProbePkt pkt2; // Detect My IP pkt.version = 2; pkt.serviceCode = 4; send(s, (char*)&pkt, sizeof(pkt), 0); SOCKADDR_IN myaddr; int szname = sizeof(myaddr); getsockname(s, (SOCKADDR*)&myaddr, &szname); MyConnection.intIP = myaddr.sin_addr.S_un.S_addr; MSN_DebugLog("P2PNAT Detected IP facing internet %d.%d.%d.%d", myaddr.sin_addr.S_un.S_un_b.s_b1, myaddr.sin_addr.S_un.S_un_b.s_b2, myaddr.sin_addr.S_un.S_un_b.s_b3, myaddr.sin_addr.S_un.S_un_b.s_b4); SOCKET s1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); pkt.version = 2; pkt.serviceCode = 1; pkt.clientPort = 0x3141; pkt.clientIP = 0x31413141; UDPProbePkt rpkt = {0}; // NAT detection for (i=0; i<4; ++i) { if (Miranda_Terminated()) break; // Send echo request to server 1 MSN_DebugLog("P2PNAT Request 1 attempt %d sent", i); sendto(s1, (char*)&pkt, sizeof(pkt), 0, (SOCKADDR*)&addr, sizeof(addr)); fd_set fd; FD_ZERO(&fd); FD_SET(s1, &fd); TIMEVAL tv = {0, 200000 * (1 << i) }; if (select(1, &fd, NULL, NULL, &tv) == 1) { MSN_DebugLog("P2PNAT Request 1 attempt %d response", i); recv(s1, (char*)&rpkt, sizeof(rpkt), 0); pkt2 = rpkt; DecryptEchoPacket(rpkt); break; } else MSN_DebugLog("P2PNAT Request 1 attempt %d timeout", i); } closesocket(s); // Server did not respond if (i >= 4) { MyConnection.udpConType = conFirewall; closesocket(s1); return; } MyConnection.extIP = rpkt.clientIP; // Check if NAT not found if (MyConnection.extIP == MyConnection.intIP) { if (msnExternalIP != NULL && inet_addr(msnExternalIP) != MyConnection.extIP) MyConnection.udpConType = conISALike; else MyConnection.udpConType = conDirect; closesocket(s1); return; } // Detect UPnP NAT NETLIBBIND nlb = {0}; nlb.cbSize = sizeof(nlb); nlb.pfnNewConnectionV2 = MSN_ConnectionProc; nlb.pExtra = this; HANDLE sb = (HANDLE) MSN_CallService(MS_NETLIB_BINDPORT, (WPARAM)hNetlibUser, (LPARAM)&nlb); if ( sb != NULL ) { MyConnection.upnpNAT = htonl(nlb.dwExternalIP) == MyConnection.extIP; Sleep(100); Netlib_CloseHandle(sb); } DiscardExtraPackets(s1); // Start IP Restricted NAT detection UDPProbePkt rpkt2 = {0}; pkt2.serviceCode = 3; SOCKADDR_IN addr2 = addr; addr2.sin_addr.S_un.S_addr = rpkt.testIP; addr2.sin_port = rpkt.discardPort; for (i=0; i<4; ++i) { if (Miranda_Terminated()) break; MSN_DebugLog("P2PNAT Request 2 attempt %d sent", i); // Remove IP restriction for server 2 sendto(s1, NULL, 0, 0, (SOCKADDR*)&addr2, sizeof(addr2)); // Send echo request to server 1 for server 2 sendto(s1, (char*)&pkt2, sizeof(pkt2), 0, (SOCKADDR*)&addr, sizeof(addr)); fd_set fd; FD_ZERO(&fd); FD_SET(s1, &fd); TIMEVAL tv = {0, 200000 * (1 << i) }; if (select(1, &fd, NULL, NULL, &tv) == 1) { MSN_DebugLog("P2PNAT Request 2 attempt %d response", i); recv(s1, (char*)&rpkt2, sizeof(rpkt2), 0); DecryptEchoPacket(rpkt2); break; } else MSN_DebugLog("P2PNAT Request 2 attempt %d timeout", i); } // Response recieved so it's an IP Restricted NAT (Restricted Cone NAT) // (MSN does not detect Full Cone NAT and consider it as IP Restricted NAT) if (i < 4) { MyConnection.udpConType = conIPRestrictNAT; closesocket(s1); return; } DiscardExtraPackets(s1); // Symmetric NAT detection addr2.sin_port = rpkt.testPort; for (i=0; i<4; ++i) { if (Miranda_Terminated()) break; MSN_DebugLog("P2PNAT Request 3 attempt %d sent", i); // Send echo request to server 1 sendto(s1, (char*)&pkt, sizeof(pkt), 0, (SOCKADDR*)&addr2, sizeof(addr2)); fd_set fd; FD_ZERO(&fd); FD_SET(s1, &fd); TIMEVAL tv = {1 << i, 0 }; if ( select(1, &fd, NULL, NULL, &tv) == 1 ) { MSN_DebugLog("P2PNAT Request 3 attempt %d response", i); recv(s1, (char*)&rpkt2, sizeof(rpkt2), 0); DecryptEchoPacket(rpkt2); break; } else MSN_DebugLog("P2PNAT Request 3 attempt %d timeout", i); } if (i < 4) { // If ports different it's symmetric NAT MyConnection.udpConType = rpkt.clientPort == rpkt2.clientPort ? conPortRestrictNAT : conSymmetricNAT; } closesocket(s1); }