// Functions really sending Xtraz stuff DWORD CIcqProto::SendXtrazNotifyRequest(MCONTACT hContact, char* szQuery, char* szNotify, int bForced) { char *szQueryBody; char *szNotifyBody; DWORD dwUin; int nBodyLen; char *szBody; DWORD dwCookie; if (getContactUid(hContact, &dwUin, NULL)) return 0; // Invalid contact if (!CheckContactCapabilities(hContact, CAPF_XTRAZ) && !bForced) return 0; // Contact does not support xtraz, do not send anything szQueryBody = MangleXml(szQuery, strlennull(szQuery)); szNotifyBody = MangleXml(szNotify, strlennull(szNotify)); nBodyLen = strlennull(szQueryBody) + strlennull(szNotifyBody) + 41; szBody = (char*)_alloca(nBodyLen); nBodyLen = mir_snprintf(szBody, nBodyLen, "<N><QUERY>%s</QUERY><NOTIFY>%s</NOTIFY></N>", szQueryBody, szNotifyBody); SAFE_FREE((void**)&szQueryBody); SAFE_FREE((void**)&szNotifyBody); // Set up the ack type cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_SCRIPT_NOTIFY, ACKTYPE_CLIENT); dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); // have we a open DC, send through that if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) icq_sendXtrazRequestDirect(hContact, dwCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY); else icq_sendXtrazRequestServ(dwUin, dwCookie, szBody, nBodyLen, pCookieData); return dwCookie; }
static void EscapesToBinary(char *str) { for(; *str; str++) { if(*str!='\\') continue; if(str[1]=='n') { *str++='\r'; *str='\n'; continue; } if(str[1]=='0') { char *codeend; *str=(char)strtol(str+1,&codeend,8); if(*str==0) { *str='\\'; continue; } memmove(str+1,codeend,strlennull(codeend)+1); continue; } for(int i=0; i<SIZEOF(escapes); i+=2) if(str[1]==escapes[i]) { *str=escapes[i+1]; memmove(str+1,str+2,strlennull(str)-1); break; } } }
int ChangeInfoData::UploadSettings(void) { if (!ppro->icqOnline()) { MessageBox(hwndDlg, TranslateT("You are not currently connected to the ICQ network. You must be online in order to update your information on the server."), TranslateT("Change ICQ Details"), MB_OK); return 0; } hUpload[0] = (HANDLE)ppro->ChangeInfoEx(CIXT_FULL, 0); //password char* tmp = ppro->GetUserPassword(TRUE); if (tmp) { if (strlennull(Password) > 0 && strcmpnull(Password, tmp)) { // update password in user info dialog (still open) strcpy(Password, tmp); // update password in protocol strcpy(ppro->m_szPassword, tmp); hUpload[1] = (HANDLE)ppro->icq_changeUserPasswordServ(tmp); char szPwd[PASSWORDMAXLEN] = {0}; // password is stored in DB, update if (ppro->GetUserStoredPassword(szPwd, sizeof(szPwd))) ppro->setString("Password", tmp); } } return 1; }
int ChangeInfoData::SaveSettingsToDb(HWND hwndDlg) { int ret = 1; for (int i = 0; i < settingCount; i++) { if (!settingData[i].changed) continue; if (!(setting[i].displayType & LIF_ZEROISVALID) && settingData[i].value==0) { ppro->delSetting(setting[i].szDbSetting); continue; } switch(setting[i].dbType) { case DBVT_ASCIIZ: if (setting[i].displayType & LIF_PASSWORD) { int nSettingLen = strlennull((char*)settingData[i].value); if (nSettingLen > 8 || nSettingLen < 1) { MessageBox(hwndDlg, TranslateT("The ICQ server does not support passwords longer than 8 characters. Please use a shorter password."), TranslateT("Change ICQ Details"), MB_OK); ret=0; break; } PwConfirmDlgParam param = { ppro, (char*)settingData[i].value }; if (IDOK != DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PWCONFIRM), hwndDlg, PwConfirmDlgProc, (LPARAM)¶m)) { ret = 0; break; } strcpy(ppro->m_szPassword, (char*)settingData[i].value); } else { if (*(char*)settingData[i].value) db_set_utf(NULL, ppro->m_szModuleName, setting[i].szDbSetting, (char*)settingData[i].value); else ppro->delSetting(setting[i].szDbSetting); } break; case DBVT_UTF8: if (*(char*)settingData[i].value) db_set_utf(NULL, ppro->m_szModuleName, setting[i].szDbSetting, (char*)settingData[i].value); else ppro->delSetting(setting[i].szDbSetting); break; case DBVT_WORD: ppro->setWord(setting[i].szDbSetting, (WORD)settingData[i].value); break; case DBVT_BYTE: ppro->setByte(setting[i].szDbSetting, (BYTE)settingData[i].value); break; } } return ret; }
static int DrawTextUtf(HDC hDC, char *text, LPRECT lpRect, UINT uFormat, LPSIZE lpSize) { int res; WCHAR *tmp = make_unicode_string(text); res = DrawTextW(hDC, tmp, -1, lpRect, uFormat); if (lpSize) GetTextExtentPoint32W(hDC, tmp, strlennull(tmp), lpSize); SAFE_FREE((void**)&tmp); return res; }
int icq_httpGatewayBegin(HANDLE hConn, NETLIBOPENCONNECTION* nloc) { // open our "virual data connection" icq_packet packet; size_t serverNameLen; serverNameLen = strlennull(nloc->szHost); packet.wLen = (WORD)(serverNameLen + 4); write_httphdr(&packet, HTTP_PACKETTYPE_LOGIN, GetGatewayIndex(hConn)); packWord(&packet, (WORD)serverNameLen); packBuffer(&packet, (LPBYTE)nloc->szHost, (WORD)serverNameLen); packWord(&packet, nloc->wPort); INT_PTR res = Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY|MSG_NOHTTPGATEWAYWRAP); SAFE_FREE((void**)&packet.pData); return res != SOCKET_ERROR; }
void NetLog_CapabilityChange(CIcqProto *ppro, const char *szChange, DWORD fdwCapabilities) { char szBuffer[MAX_PATH] = {0}; if (!fdwCapabilities) return; for (int nIndex = 0; nIndex < SIZEOF(CapabilityNames); nIndex++) { // Check if the current capability is present if ((fdwCapabilities & CapabilityNames[nIndex].capID) == CapabilityNames[nIndex].capID) { if (strlennull(szBuffer)) strcat(szBuffer, ", "); strcat(szBuffer, CapabilityNames[nIndex].capName); } } // Log the change ppro->debugLogA("Capabilities: %s %s", szChange, szBuffer); }
char *BinaryToEscapes(char *str) { int extra=10,len=strlennull(str)+11,i; char *out,*pout; out=pout=(char*)SAFE_MALLOC(len); for(; *str; str++) { if((unsigned char)*str>=' ') { *pout++=*str; continue; } if(str[0]=='\r' && str[1]=='\n') { *pout++='\\'; *pout++='n'; str++; continue; } if(extra<3) { extra+=8; len+=8; pout=out=(char*)SAFE_REALLOC(out,len); } *pout++='\\'; for(i = 0; i < SIZEOF(escapes); i += 2) if(*str==escapes[i+1]) { *pout++=escapes[i]; extra--; break; } if(i < SIZEOF(escapes)) continue; *pout++='0'; extra--; if(*str>=8) { *pout++=(*str>>3)+'0'; extra--; } *pout++=(*str&7)+'0'; extra--; }
void CIcqProto::GetAvatarFileName(int dwUin, const char *szUid, TCHAR *pszDest, int cbLen) { TCHAR szPath[MAX_PATH * 2]; mir_sntprintf(szPath, MAX_PATH * 2, _T("%s\\%S\\"), VARST(_T("%miranda_avatarcache%")), m_szModuleName); FOLDERSGETDATA fgd = {0}; fgd.cbSize = sizeof(FOLDERSGETDATA); fgd.nMaxPathSize = MAX_PATH * 2; fgd.szPathT = szPath; fgd.flags = FF_TCHAR; // fill the destination lstrcpyn(pszDest, szPath, cbLen - 1); int tPathLen = strlennull(pszDest); // make sure the avatar cache directory exists CreateDirectoryTreeT(szPath); if (dwUin != 0) { _ltot(dwUin, pszDest + tPathLen, 10); } else if (szUid) { TCHAR* p = mir_a2t(szUid); _tcscpy(pszDest + tPathLen, p); mir_free( p ); } else { TCHAR szBuf[MAX_PATH]; if (CallService(MS_DB_GETPROFILENAMET, MAX_PATH, (LPARAM)szBuf)) _tcscpy(pszDest + tPathLen, _T("avatar")); else { TCHAR *szLastDot = _tcsrchr(szBuf, '.'); if (szLastDot) szLastDot[0] = '\0'; _tcscpy(pszDest + tPathLen, szBuf); _tcscat(pszDest + tPathLen, _T("_avt")); } } }
void CIcqProto::SendXtrazNotifyResponse(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szResponse, int nResponseLen, BOOL bThruDC) { char *szResBody = MangleXml(szResponse, nResponseLen); int nBodyLen = strlennull(szResBody) + 21; char *szBody = (char*)_alloca(nBodyLen); MCONTACT hContact = HContactFromUIN(dwUin, NULL); if (hContact != INVALID_CONTACT_ID && !CheckContactCapabilities(hContact, CAPF_XTRAZ)) { SAFE_FREE(&szResBody); return; // Contact does not support xtraz, do not send anything } nBodyLen = mir_snprintf(szBody, nBodyLen, "<NR><RES>%s</RES></NR>", szResBody); SAFE_FREE(&szResBody); // Was request received thru DC and have we a open DC, send through that if (bThruDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) icq_sendXtrazResponseDirect(hContact, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY); else icq_sendXtrazResponseServ(dwUin, dwMID, dwMID2, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY); }
static void file_sendNick(CIcqProto* ppro, directconnect* dc) { icq_packet packet; char* szNick; WORD wNickLen; DBVARIANT dbv = {DBVT_DELETED}; if (ppro->getSettingString(NULL, "Nick", &dbv)) szNick = ""; else szNick = dbv.pszVal; wNickLen = strlennull(szNick); directPacketInit(&packet, (WORD)(8 + wNickLen)); packByte(&packet, PEER_FILE_INIT_ACK); /* Ident */ packLEDWord(&packet, dc->ft->dwTransferSpeed); packLEWord(&packet, (WORD)(wNickLen + 1)); packBuffer(&packet, (LPBYTE)szNick, (WORD)(wNickLen + 1)); ppro->sendDirectPacket(dc, &packet); ICQFreeVariant(&dbv); }
static void EscapesToMultiline(WCHAR *str,PDWORD selStart,PDWORD selEnd) { //converts "\\n" and "\\t" to "\r\n" and "\t" because a multi-line edit box can show them properly DWORD i; for(i=0; *str; str++, i++) { if (*str != '\\') continue; if (str[1] == 'n') { *str++ = '\r'; i++; *str = '\n'; } else if (str[1] == 't') { *str = '\t'; memmove(str+1, str+2, sizeof(WCHAR)*(strlennull(str)-1)); if (*selStart>i) --*selStart; if (*selEnd>i) --*selEnd; } } }
INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TRecvContactsData* wndData = (TRecvContactsData*)GetWindowLong(hwndDlg, DWLP_USER); switch (msg) { case WM_INITDIALOG: { CLISTEVENT* pcle = (CLISTEVENT*)lParam; /// got it TranslateDialogDefault(hwndDlg); WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact); SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); EnableDlgItem(hwndDlg, IDOK, FALSE); EnableDlgItem(hwndDlg, IDDETAILS, FALSE); wndData = new TRecvContactsData(pcle->hContact); SetWindowLong(hwndDlg, DWLP_USER, (LONG)wndData); wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1); wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU)); CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)wndData->mhPopup, 0); wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT); char *szProto = GetContactProto(wndData->mhContact); HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); // add columns RecvListView_AddColumn(hLV, 120, (char*)SRCCallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0), FALSE, 0); RecvListView_AddColumn(hLV, 100, "Nick", TRUE, 1); RecvListView_AddColumn(hLV, 100, "First Name", TRUE, 2); RecvListView_AddColumn(hLV, 100, "Last Name", TRUE, 3); // fill in groups SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); RebuildGroupCombo(hwndDlg); { // fill listview with received contacts DBEVENTINFO dbe = {0}; dbe.cbSize = sizeof(DBEVENTINFO); dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)wndData->mhDbEvent, 0); if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway... dbe.pBlob = (PBYTE)_malloca(dbe.cbBlob); CallService(MS_DB_EVENT_GET, (WPARAM)wndData->mhDbEvent, (LPARAM)&dbe); char* pcBlob = (char*)dbe.pBlob; char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob; HICON hiProto = LoadContactProtoIcon(wndData->mhContact); ImageList_AddIcon(wndData->mhListIcon, hiProto); DestroyIcon(hiProto); // imagelist copied the resource ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL); LVITEM lvi = {0}; lvi.iImage = 0; lvi.mask = LVIF_TEXT | LVIF_IMAGE; for (int nItem = 0; ; nItem++) { // Nick int strsize = (int)strlennull(pcBlob); TReceivedItem* pItem = wndData->AddReceivedItem(); if (dbe.flags & DBEF_UTF) pItem->mcaNick = utf8_to_tchar((unsigned char*)pcBlob); else pItem->mcaNick = ansi_to_tchar(pcBlob); pcBlob += strsize + 1; // UIN strsize = (int)strlennull(pcBlob); pItem->mcaUIN = null_strdup(pcBlob); pcBlob += strsize + 1; // add to listview lvi.iItem = nItem; lvi.pszText = pItem->mcaUIN; ListView_InsertItem(hLV, &lvi); // with image ListView_SetItemTextT(hLV, nItem, 1, pItem->mcaNick); // check for end of contacts if (pcBlob >= pcEnd) break; } } // new dlg init wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); // new dialog init done Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, ""); return TRUE; } case WM_NOTIFY: if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS) { switch (((LPNMHDR)lParam)->code) { case NM_DBLCLK: { HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED); if (wndData->iPopupItem == -1) break; // if no item selected no user details available return SendMessageT(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details } case LVN_ITEMCHANGED: { LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam; HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button if (ListView_GetCheckState(hLV, pNMLV->iItem)) { // the user has checked this item bExistsCheckedItem = true; // enable "Add" button } else { // loop thru items and check if at least one is checked for (int i = 0; i < ListView_GetItemCount(hLV); i++) if (ListView_GetCheckState(hLV, i)) { // we found checked item, enable add, exit loop bExistsCheckedItem = true; break; } } EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem); EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0); break; } } } break; case WM_COMMAND: { if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact)) break; switch(LOWORD(wParam)) { case IDOK: // "Add Selected" button click { // for each selected item, find its index in the hDbEvent // and after that add this item to the DB permanently char* caUIN; HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS); int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); TCHAR* caGroup = NULL; int nGroupId = -1; if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessageT(hGroupsCheck, BM_GETCHECK, 0, 0)) { //got groups, get the one selected in combo TCHAR* caGroup = (TCHAR*)_malloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup); nGroupId = SendMessageT(hGroupsCombo, CB_GETITEMDATA, curs, 0); } for (int i = 0; i < ListView_GetItemCount(hLV); i++) if (ListView_GetCheckState(hLV, i)) { // found checked contact item, add it caUIN = ListView_GetItemTextEx(hLV, i, 0); for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) { char* szProto = GetContactProto(wndData->mhContact); HANDLE hContact = (HANDLE)SRCCallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent); if (hContact && caGroup) { // use newest group API if available if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP)) CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, (LPARAM)nGroupId); else DBWriteContactSettingStringT(hContact, "CList", "Group", caGroup); } break; } SAFE_FREE((void**)&caUIN); } // move to next item break; } case IDDETAILS: { // for each selected item, find its index in the hDbEvent // and after that add this item to the DB // finally, request Details window for this hContact HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); for (int i = 0; i < ListView_GetItemCount(hLV); i++) if (ListView_GetItemState(hLV, i, LVIS_SELECTED)) { HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i); if (hContact) CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); } break; } case IDCANCEL: { SendMessageT(hwndDlg, WM_CLOSE, 0, 0); break; } case IDC_ENABLEGROUPS: { EnableGroupCombo(hwndDlg); break; } case IDC_GROUPS: { // rebuild group list on popup if (HIWORD(wParam) == CBN_DROPDOWN) RebuildGroupCombo(hwndDlg); break; } case ID_POPUP_ADDUSER: { HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); if (hContact) DialogAddContactExecute(hwndDlg, hContact); break; } case ID_POPUP_USERDETAILS: { HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); if (hContact) CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0 ); break; } case ID_POPUP_SENDMESSAGE: { HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); if (hContact) CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); break; } case IDC_USERMENU: { RECT rc; HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0); GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); break; } case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0); break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0); break; case IDC_ADD: DialogAddContactExecute(hwndDlg, wndData->mhContact); break; } break; } case WM_CONTEXTMENU: { HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); LVHITTESTINFO lvh; RECT rt; wndData->iPopupItem = -1; if ((HWND)wParam != hLV) break; // if not our ListView go away lvh.pt.x = LOWORD(lParam); lvh.pt.y = HIWORD(lParam); if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ?? ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates int ci = ListView_HitTest(hLV, &lvh); if (ci==-1) break; // mouse is not over any item wndData->iPopupItem = ci; TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL); break; } case HM_EVENTSENT: { ACKDATA *ack=(ACKDATA*)lParam; if (ack->type!=ACKTYPE_SEARCH) break; // not search ack, go away if (ack->hProcess!=wndData->rhSearch) break; //not our search, go away if (ack->result==ACKRESULT_DATA) { HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*)ack->lParam; LVFINDINFO fi; fi.flags = LVFI_STRING; fi.psz = wndData->haUin; int iLPos = ListView_FindItem(hLV, -1, &fi); if (iLPos==-1) iLPos=0; // ListView_SetItemText(hLV, iLPos, 0, psr->email); // not sent by ICQ, and currently unsupported either if (strcmpnull(psr->nick, "") && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick); ListView_SetItemText(hLV, iLPos, 2, psr->firstName); ListView_SetItemText(hLV, iLPos, 3, psr->lastName); break; } SAFE_FREE((void**)&wndData->haUin); break; } case WM_CLOSE: // user closed window, so destroy it { WindowList_Remove(ghRecvWindowList, hwndDlg); DestroyWindow(hwndDlg); break; } case WM_DESTROY: // last message received by this dialog, cleanup { CallService(MS_DB_EVENT_MARKREAD, (WPARAM)wndData->mhContact, (LPARAM)wndData->mhDbEvent); Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, ""); ImageList_Destroy(wndData->mhListIcon); UnhookEvent(wndData->hHook); DestroyMenu(wndData->mhPopup); for (int i=0; i < SIZEOF(wndData->hIcons); i++) DestroyIcon(wndData->hIcons[i]); delete wndData; // automatically calls destructor break; } case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); case WM_DRAWITEM: { DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact); return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); } case WM_SIZE: { // make the dlg resizeable UTILRESIZEDIALOG urd = {0}; if (IsIconic(hwndDlg)) break; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lParam = 0; // user-defined urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE); urd.pfnResizer = RecvDlg_Resize; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd); break; } case WM_GETMINMAXINFO: { MINMAXINFO* mmi=(MINMAXINFO*)lParam; mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME); mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME); break; } case DM_UPDATETITLE: { UpdateDialogTitle(hwndDlg, wndData?wndData->mhContact:NULL, "Contacts from"); if (wndData) UpdateDialogAddButton(hwndDlg, wndData->mhContact); break; } } return FALSE; }
// small utility function void NormalizeBackslash(char* path) { int len = strlennull(path); if (len && path[len-1] != '\\') strcat(path, "\\"); }
void CIcqProto::handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szMsg, int nMsgLen, BOOL bThruDC) { char *szNotify = strstrnull(szMsg, "<NOTIFY>"); char *szQuery = strstrnull(szMsg, "<QUERY>"); MCONTACT hContact = HContactFromUIN(dwUin, NULL); if (hContact) // user sent us xtraz, he supports it SetContactCapabilities(hContact, CAPF_XTRAZ); if (szNotify && szQuery) { // valid request char *szWork, *szEnd; int nNotifyLen, nQueryLen; szNotify += 8; szQuery += 7; szEnd = strstrnull(szMsg, "</NOTIFY>"); if (!szEnd) szEnd = szMsg + nMsgLen; nNotifyLen = (szEnd - szNotify); szEnd = strstrnull(szMsg, "</QUERY>"); if (!szEnd) szEnd = szNotify; szNotify = DemangleXml(szNotify, nNotifyLen); nQueryLen = (szEnd - szQuery); szQuery = DemangleXml(szQuery, nQueryLen); szWork = strstrnull(szQuery, "<PluginID>"); szEnd = strstrnull(szQuery, "</PluginID>"); #ifdef _DEBUG debugLogA("Query: %s", szQuery); debugLogA("Notify: %s", szNotify); #endif if (szWork && szEnd) { // this is our plugin szWork += 10; *szEnd = '\0'; if (!stricmpnull(szWork, "srvMng") && strstrnull(szNotify, "AwayStat")) { char *szSender = strstrnull(szNotify, "<senderId>"); char *szEndSend = strstrnull(szNotify, "</senderId>"); if (szSender && szEndSend) { szSender += 10; *szEndSend = '\0'; if ((DWORD)atoi(szSender) == dwUin) { BYTE dwXId = m_bXStatusEnabled ? getContactXStatus(NULL) : 0; if (dwXId && validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) { // apply privacy rules NotifyEventHooks(m_modeMsgsEvent, (WPARAM)MTYPE_SCRIPT_NOTIFY, (LPARAM)dwUin); char *tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_NAME, ""); char *szXName = MangleXml(tmp, strlennull(tmp)); SAFE_FREE(&tmp); tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, ""); char *szXMsg = MangleXml(tmp, strlennull(tmp)); SAFE_FREE(&tmp); int nResponseLen = 212 + strlennull(szXName) + strlennull(szXMsg) + UINMAXLEN + 2; char *szResponse = (char*)_alloca(nResponseLen + 1); // send response mir_snprintf(szResponse, nResponseLen, "<ret event=\"OnRemoteNotification\">" "<srv><id>cAwaySrv</id>" "<val srv_id=\"cAwaySrv\"><Root>" "<CASXtraSetAwayMessage></CASXtraSetAwayMessage>" "<uin>%d</uin>" "<index>%d</index>" "<title>%s</title>" "<desc>%s</desc></Root></val></srv></ret>", m_dwLocalUIN, dwXId, szXName, szXMsg); SAFE_FREE(&szXName); SAFE_FREE(&szXMsg); struct rates_xstatus_response : public rates_queue_item { protected: virtual rates_queue_item* copyItem(rates_queue_item *aDest = NULL) { rates_xstatus_response *pDest = (rates_xstatus_response*)aDest; if (!pDest) pDest = new rates_xstatus_response(ppro, wGroup); pDest->bThruDC = bThruDC; pDest->dwMsgID1 = dwMsgID1; pDest->dwMsgID2 = dwMsgID2; pDest->wCookie = wCookie; pDest->szResponse = null_strdup(szResponse); return rates_queue_item::copyItem(pDest); }; public: rates_xstatus_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup), szResponse(NULL) {}; virtual ~rates_xstatus_response() { if (bCreated) SAFE_FREE(&szResponse); }; virtual void execute() { ppro->SendXtrazNotifyResponse(dwUin, dwMsgID1, dwMsgID2, wCookie, szResponse, strlennull(szResponse), bThruDC); }; BOOL bThruDC; DWORD dwMsgID1; DWORD dwMsgID2; WORD wCookie; char *szResponse; }; m_ratesMutex->Enter(); WORD wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); m_ratesMutex->Leave(); rates_xstatus_response rr(this, wGroup); rr.hContact = hContact; rr.dwUin = dwUin; rr.bThruDC = bThruDC; rr.dwMsgID1 = dwMID; rr.dwMsgID2 = dwMID2; rr.wCookie = wCookie; rr.szResponse = szResponse; handleRateItem(&rr, RQT_RESPONSE, 0, !bThruDC); } else if (dwXId) debugLogA("Privacy: Ignoring XStatus request"); else debugLogA("Error: We are not in XStatus, skipping"); } else debugLogA("Error: Invalid sender information"); } else debugLogA("Error: Missing sender information"); } else debugLogA("Error: Unknown plugin \"%s\" in Xtraz message", szWork); } else debugLogA("Error: Missing PluginID in Xtraz message"); SAFE_FREE(&szNotify); SAFE_FREE(&szQuery); } else debugLogA("Error: Invalid Xtraz Notify message"); }
void CIcqProto::handleXtrazNotifyResponse(DWORD dwUin, MCONTACT hContact, WORD wCookie, char* szMsg, int nMsgLen) { char *szMem, *szRes, *szEnd; int nResLen; #ifdef _DEBUG debugLogA("Received Xtraz Notify Response"); #endif szRes = strstrnull(szMsg, "<RES>"); szEnd = strstrnull(szMsg, "</RES>"); if (szRes && szEnd) { // valid response char *szNode, *szWork; szRes += 5; nResLen = szEnd - szRes; szMem = szRes = DemangleXml(szRes, nResLen); #ifdef _DEBUG debugLogA("Response: %s", szRes); #endif ProtoBroadcastAck(hContact, ICQACKTYPE_XTRAZNOTIFY_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, (LPARAM)szRes); NextVal: szNode = strstrnull(szRes, "<val srv_id="); if (szNode) szEnd = strstrnull(szNode, ">"); else szEnd = NULL; if (szNode && szEnd) { *(szEnd - 1) = '\0'; szNode += 13; //one more than the length of the string to skip ' or " too szWork = szEnd + 1; if (!stricmpnull(szNode, "cAwaySrv")) { int bChanged = FALSE; *szEnd = ' '; szNode = strstrnull(szWork, "<index>"); szEnd = strstrnull(szWork, "</index>"); if (szNode && szEnd) { szNode += 7; *szEnd = '\0'; if (atoi(szNode) != getContactXStatus(hContact)) { // this is strange - but go on debugLogA("Warning: XStatusIds do not match!"); } *szEnd = ' '; } szNode = strstrnull(szWork, "<title>"); szEnd = strstrnull(szWork, "</title>"); if (szNode && szEnd) { // we got XStatus title, save it char *szXName, *szOldXName; szNode += 7; *szEnd = '\0'; szXName = DemangleXml(szNode, strlennull(szNode)); // check if the name changed szOldXName = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, NULL); if (strcmpnull(szOldXName, szXName)) bChanged = TRUE; SAFE_FREE(&szOldXName); db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, szXName); SAFE_FREE(&szXName); *szEnd = ' '; } szNode = strstrnull(szWork, "<desc>"); szEnd = strstrnull(szWork, "</desc>"); if (szNode && szEnd) { // we got XStatus mode msg, save it char *szXMsg, *szOldXMsg; szNode += 6; *szEnd = '\0'; szXMsg = DemangleXml(szNode, strlennull(szNode)); // check if the decription changed szOldXMsg = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, NULL); if (strcmpnull(szOldXMsg, szXMsg)) bChanged = TRUE; SAFE_FREE(&szOldXMsg); db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_MSG, szXMsg); SAFE_FREE(&szXMsg); } ProtoBroadcastAck(hContact, ICQACKTYPE_XSTATUS_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); } else { char *szSrvEnd = strstrnull(szEnd, "</srv>"); if (szSrvEnd && strstrnull(szSrvEnd, "<val srv_id=")) { // check all values ! szRes = szSrvEnd + 6; // after first value goto NextVal; } // no next val, we were unable to handle packet, write error debugLogA("Error: Unknown serverId \"%s\" in Xtraz response", szNode); } } else debugLogA("Error: Missing serverId in Xtraz response"); SAFE_FREE(&szMem); } else debugLogA("Error: Invalid Xtraz Notify response"); }
virtual void execute() { ppro->SendXtrazNotifyResponse(dwUin, dwMsgID1, dwMsgID2, wCookie, szResponse, strlennull(szResponse), bThruDC); };
void CIcqProto::handleFileTransferPacket(directconnect* dc, PBYTE buf, WORD wLen) { if (wLen < 1) return; NetLog_Direct("Handling file packet"); switch (buf[0]) { case PEER_FILE_INIT: /* first packet of a file transfer */ if (dc->initialised) return; if (wLen < 19) return; buf += 5; /* id, and unknown 0 */ dc->type = DIRECTCONN_FILE; { DWORD dwFileCount; DWORD dwTotalSize; DWORD dwTransferSpeed; WORD wNickLength; int bAdded; unpackLEDWord(&buf, &dwFileCount); unpackLEDWord(&buf, &dwTotalSize); unpackLEDWord(&buf, &dwTransferSpeed); unpackLEWord(&buf, &wNickLength); dc->ft = FindExpectedFileRecv(dc->dwRemoteUin, dwTotalSize); if (dc->ft == NULL) { NetLog_Direct("Unexpected file receive"); CloseDirectConnection(dc); return; } dc->ft->dwFileCount = dwFileCount; dc->ft->dwTransferSpeed = dwTransferSpeed; dc->ft->hContact = HContactFromUIN(dc->ft->dwUin, &bAdded); dc->ft->dwBytesDone = 0; dc->ft->iCurrentFile = -1; dc->ft->fileId = -1; dc->ft->hConnection = dc->hConnection; dc->ft->dwLastNotify = GetTickCount(); dc->initialised = 1; file_sendTransferSpeed(this, dc); file_sendNick(this, dc); } BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, dc->ft, 0); break; case PEER_FILE_INIT_ACK: if (wLen < 8) return; buf++; unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); /* followed by nick */ file_sendNextFile(this, dc); break; case PEER_FILE_NEXTFILE: if (wLen < 20) return; buf++; /* id */ { char *szAnsi; WORD wThisFilenameLen, wSubdirLen; BYTE isDirectory; unpackByte(&buf, &isDirectory); unpackLEWord(&buf, &wThisFilenameLen); if (wLen < 19 + wThisFilenameLen) return; SAFE_FREE(&dc->ft->szThisFile); szAnsi = (char *)_malloca(wThisFilenameLen + 1); memcpy(szAnsi, buf, wThisFilenameLen); szAnsi[wThisFilenameLen] = '\0'; dc->ft->szThisFile = ansi_to_utf8(szAnsi); buf += wThisFilenameLen; unpackLEWord(&buf, &wSubdirLen); if (wLen < 18 + wThisFilenameLen + wSubdirLen) return; SAFE_FREE(&dc->ft->szThisSubdir); szAnsi = (char *)_malloca(wSubdirLen + 1); memcpy(szAnsi, buf, wSubdirLen); szAnsi[wSubdirLen] = '\0'; dc->ft->szThisSubdir = ansi_to_utf8(szAnsi); buf += wSubdirLen; unpackLEDWord(&buf, &dc->ft->dwThisFileSize); unpackLEDWord(&buf, &dc->ft->dwThisFileDate); unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); /* no cheating with paths */ if (!IsValidRelativePath(dc->ft->szThisFile) || !IsValidRelativePath(dc->ft->szThisSubdir)) { NetLog_Direct("Invalid path information"); break; } char *szFullPath = (char*)SAFE_MALLOC(strlennull(dc->ft->szSavePath)+strlennull(dc->ft->szThisSubdir)+strlennull(dc->ft->szThisFile)+3); strcpy(szFullPath, dc->ft->szSavePath); NormalizeBackslash(szFullPath); strcat(szFullPath, dc->ft->szThisSubdir); NormalizeBackslash(szFullPath); // _chdir(szFullPath); // set current dir - not very useful strcat(szFullPath, dc->ft->szThisFile); // we joined the full path to dest file SAFE_FREE(&dc->ft->szThisFile); dc->ft->szThisFile = szFullPath; dc->ft->dwFileBytesDone = 0; dc->ft->iCurrentFile++; if (isDirectory) { MakeDirUtf(dc->ft->szThisFile); dc->ft->fileId = -1; } else { /* file resume */ PROTOFILETRANSFERSTATUS pfts = {0}; file_buildProtoFileTransferStatus(dc->ft, &pfts); if (BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, dc->ft, (LPARAM)&pfts)) break; /* UI supports resume: it will call PS_FILERESUME */ dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE); if (dc->ft->fileId == -1) { icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder.")); CloseDirectConnection(dc); dc->ft->hConnection = NULL; break; } } } file_sendResume(this, dc); BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0); break; case PEER_FILE_RESUME: if (dc->ft->fileId == -1 && !dc->ft->currentIsDir) return; if (wLen < 13) return; if (wLen < 17) NetLog_Direct("Warning: Received short PEER_FILE_RESUME"); buf++; { DWORD dwRestartFrom; unpackLEDWord(&buf, &dwRestartFrom); if (dwRestartFrom > dc->ft->dwThisFileSize) return; buf += 4; /* unknown. 0 */ unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); buf += 4; /* unknown. 1 */ if (!dc->ft->currentIsDir) _lseek(dc->ft->fileId, dwRestartFrom, 0); dc->wantIdleTime = 1; dc->ft->dwBytesDone += dwRestartFrom; dc->ft->dwFileBytesDone += dwRestartFrom; } break; case PEER_FILE_SPEED: if (wLen < 5) return; buf++; unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); dc->ft->dwLastNotify = GetTickCount(); break; case PEER_FILE_DATA: if (!dc->ft->currentIsDir) { if (dc->ft->fileId == -1) break; buf++; wLen--; _write(dc->ft->fileId, buf, wLen); } else wLen = 0; dc->ft->dwBytesDone += wLen; dc->ft->dwFileBytesDone += wLen; if (GetTickCount() > dc->ft->dwLastNotify + 500 || wLen < 2048) { PROTOFILETRANSFERSTATUS pfts; file_buildProtoFileTransferStatus(dc->ft, &pfts); BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts); dc->ft->dwLastNotify = GetTickCount(); } if (wLen < 2048) { /* EOF */ if (!dc->ft->currentIsDir) _close(dc->ft->fileId); dc->ft->fileId = -1; if ((DWORD)dc->ft->iCurrentFile == dc->ft->dwFileCount - 1) { dc->type = DIRECTCONN_CLOSING; /* this guarantees that we won't accept any more data but that the sender is still free to closesocket() neatly */ BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0); } } break; default: NetLog_Direct("Unknown file transfer packet ignored."); break; } }
// pszDescription points to a string with the reason // buf points to the first data after the string void CIcqProto::handleFileRequest(PBYTE buf, WORD wLen, DWORD dwUin, DWORD dwCookie, DWORD dwID1, DWORD dwID2, char* pszDescription, int nVersion, BOOL bDC) { BOOL bEmptyDesc = FALSE; if (strlennull(pszDescription) == 0) { pszDescription = Translate("No description given"); bEmptyDesc = TRUE; } // Empty port+pad buf += 4; wLen -= 4; // Filename WORD wFilenameLength; unpackLEWord(&buf, &wFilenameLength); if (!wFilenameLength) { NetLog_Direct("Ignoring malformed file send request"); return; } char *pszFileName = (char*)_alloca(wFilenameLength + 1); unpackString(&buf, pszFileName, wFilenameLength); pszFileName[wFilenameLength] = '\0'; wLen = wLen - 2 - wFilenameLength; // Total filesize DWORD dwFileSize; unpackLEDWord(&buf, &dwFileSize); wLen -= 4; int bAdded; HANDLE hContact = HContactFromUIN(dwUin, &bAdded); // Initialize a filetransfer struct filetransfer *ft = CreateFileTransfer(hContact, dwUin, nVersion); ft->dwCookie = dwCookie; ft->szFilename = mir_strdup(pszFileName); ft->szDescription = 0; ft->fileId = -1; ft->dwTotalSize = dwFileSize; ft->pMessage.dwMsgID1 = dwID1; ft->pMessage.dwMsgID2 = dwID2; ft->bDC = bDC; ft->bEmptyDesc = bEmptyDesc; // Send chain event TCHAR* ptszFileName = mir_utf8decodeT(pszFileName); PROTORECVFILET pre = {0}; pre.flags = PREF_TCHAR; pre.fileCount = 1; pre.timestamp = time(NULL); pre.tszDescription = mir_utf8decodeT(pszDescription); pre.ptszFiles = &ptszFileName; pre.lParam = (LPARAM)ft; ProtoChainRecvFile(hContact, &pre); mir_free(pre.tszDescription); mir_free(ptszFileName); }
void CIcqProto::parseDirectorySearchData(oscar_tlv_chain *cDetails, DWORD dwCookie, cookie_directory_data *pCookieData, WORD wReplySubType) { ICQSEARCHRESULT isr = {0}; char *szUid = cDetails->getString(0x32, 1); // User ID #ifdef _DEBUG debugLogA("Directory Search: Found user %s", szUid); #endif isr.hdr.cbSize = sizeof(ICQSEARCHRESULT); isr.hdr.flags = PSR_TCHAR; isr.hdr.id = ansi_to_tchar(szUid); if (IsStringUIN(szUid)) isr.uin = atoi(szUid); else isr.uin = 0; SAFE_FREE(&szUid); oscar_tlv *pTLV = cDetails->getTLV(0x50, 1); char *szData = NULL; if (pTLV && pTLV->wLen > 0) szData = cDetails->getString(0x50, 1); // Verified e-mail else szData = cDetails->getString(0x55, 1); // Pending e-mail if (strlennull(szData)) isr.hdr.email = ansi_to_tchar(szData); SAFE_FREE(&szData); szData = cDetails->getString(0x64, 1); // First Name if (strlennull(szData)) isr.hdr.firstName = utf8_to_tchar(szData); SAFE_FREE(&szData); szData = cDetails->getString(0x6E, 1); // Last Name if (strlennull(szData)) isr.hdr.lastName = utf8_to_tchar(szData); SAFE_FREE(&szData); szData = cDetails->getString(0x78, 1); // Nick if (strlennull(szData)) isr.hdr.nick = utf8_to_tchar(szData); SAFE_FREE(&szData); switch (cDetails->getNumber(0x82, 1)) // Gender { case 1: isr.gender = 'F'; break; case 2: isr.gender = 'M'; break; } pTLV = cDetails->getTLV(0x96, 1); if (pTLV && pTLV->wLen >= 4) { BYTE *buf = pTLV->pData; oscar_tlv_chain *chain = readIntoTLVChain(&buf, pTLV->wLen, 0); if (chain) isr.country = chain->getDWord(0x8C, 1); // Home Country disposeChain(&chain); } isr.auth = !cDetails->getByte(0x19A, 1); // Require Authorization isr.maritalStatus = cDetails->getNumber(0x12C, 1); // Marital Status // calculate Age if Birthdate is available isr.age = calcAgeFromBirthDate(cDetails->getDouble(0x1A4, 1)); // Finally, broadcast the result ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)dwCookie, (LPARAM)&isr); // Release memory SAFE_FREE(&isr.hdr.id); SAFE_FREE(&isr.hdr.nick); SAFE_FREE(&isr.hdr.firstName); SAFE_FREE(&isr.hdr.lastName); SAFE_FREE(&isr.hdr.email); // Search is over, broadcast final ack if (wReplySubType == META_DIRECTORY_RESPONSE) ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); }
static void file_sendNextFile(CIcqProto* ppro, directconnect* dc) { icq_packet packet; struct _stati64 statbuf; char szThisSubDir[MAX_PATH]; if (dc->ft->iCurrentFile >= (int)dc->ft->dwFileCount) { ppro->BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0); ppro->CloseDirectConnection(dc); dc->ft->hConnection = NULL; return; } dc->ft->szThisFile = dc->ft->pszFiles[dc->ft->iCurrentFile]; if (FileStatUtf(dc->ft->szThisFile, &statbuf)) { ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.")); ppro->CloseDirectConnection(dc); dc->ft->hConnection = NULL; return; } char *pszThisFileName = FindFilePathContainer((LPCSTR*)dc->ft->pszFiles, dc->ft->iCurrentFile, szThisSubDir); if (statbuf.st_mode&_S_IFDIR) { dc->ft->currentIsDir = 1; } else { dc->ft->currentIsDir = 0; dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_RDONLY, _S_IREAD); if (dc->ft->fileId == -1) { ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.")); ppro->CloseDirectConnection(dc); dc->ft->hConnection = NULL; return; } } dc->ft->dwThisFileSize = statbuf.st_size; dc->ft->dwThisFileDate = statbuf.st_mtime; dc->ft->dwFileBytesDone = 0; char *szThisFileNameAnsi = NULL, *szThisSubDirAnsi = NULL; if (!utf8_decode(pszThisFileName, &szThisFileNameAnsi)) szThisFileNameAnsi = NULL; if (!utf8_decode(szThisSubDir, &szThisSubDirAnsi)) szThisSubDirAnsi = NULL; WORD wThisFileNameLen = strlennull(szThisFileNameAnsi); WORD wThisSubDirLen = strlennull(szThisSubDirAnsi); directPacketInit(&packet, (WORD)(20 + wThisFileNameLen + wThisSubDirLen)); packByte(&packet, PEER_FILE_NEXTFILE); /* Ident */ packByte(&packet, (BYTE)((statbuf.st_mode & _S_IFDIR) != 0)); // Is subdir packLEWord(&packet, (WORD)(wThisFileNameLen + 1)); packBuffer(&packet, (LPBYTE)szThisFileNameAnsi, (WORD)(wThisFileNameLen + 1)); packLEWord(&packet, (WORD)(wThisSubDirLen + 1)); packBuffer(&packet, (LPBYTE)szThisSubDirAnsi, (WORD)(wThisSubDirLen + 1)); packLEDWord(&packet, dc->ft->dwThisFileSize); packLEDWord(&packet, statbuf.st_mtime); packLEDWord(&packet, dc->ft->dwTransferSpeed); SAFE_FREE(&szThisFileNameAnsi); SAFE_FREE(&szThisSubDirAnsi); ppro->sendDirectPacket(dc, &packet); ppro->BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0); }
static INT_PTR CALLBACK DlgProcIcqOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); ppro = (CIcqProto*)lParam; SetWindowLongPtr( hwndDlg, GWLP_USERDATA, lParam ); { DWORD dwUin = ppro->getContactUin(NULL); if (dwUin) SetDlgItemInt(hwndDlg, IDC_ICQNUM, dwUin, FALSE); else // keep it empty when no UIN entered SetDlgItemTextA(hwndDlg, IDC_ICQNUM, ""); SendDlgItemMessage(hwndDlg, IDC_PASSWORD, EM_LIMITTEXT, PASSWORDMAXLEN - 1, 0); // bit of a security hole here, since it's easy to extract a password from an edit box char pszPwd[PASSWORDMAXLEN]; if (ppro->GetUserStoredPassword(pszPwd, sizeof(pszPwd))) SetDlgItemTextA(hwndDlg, IDC_PASSWORD, pszPwd); LoadDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection", DEFAULT_SECURE_CONNECTION); LoadDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin", DEFAULT_SECURE_LOGIN); LoadDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix", DEFAULT_LEGACY_FIX); char szServer[MAX_PATH]; if (!ppro->getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH)) SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, szServer); else SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST); SetDlgItemInt(hwndDlg, IDC_ICQPORT, ppro->getWord("OscarPort", IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT), FALSE); LoadDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive", DEFAULT_KEEPALIVE_ENABLED); SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETRANGE, FALSE, MAKELONG(0, 4)); SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETPOS, TRUE, 4-ppro->getByte("ShowLogLevel", LOG_WARNING)); SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateTS(szLogLevelDescr[4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)])); ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_HIDE); LoadDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox", 0); } return TRUE; case WM_HSCROLL: SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateTS(szLogLevelDescr[4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL,TBM_GETPOS, 0, 0)])); OptDlgChanged(hwndDlg); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_LOOKUPLINK: CallService(MS_UTILS_OPENURL, 1, (LPARAM)URL_FORGOT_PASSWORD); return TRUE; case IDC_NEWUINLINK: CallService(MS_UTILS_OPENURL, 1, (LPARAM)URL_REGISTER); return TRUE; case IDC_RESETSERVER: SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE); case IDC_SSL: SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST); SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE); OptDlgChanged(hwndDlg); return TRUE; } if (ppro->icqOnline() && LOWORD(wParam) != IDC_NOERRMULTI) { char szClass[80]; GetClassNameA((HWND)lParam, szClass, sizeof(szClass)); if (stricmpnull(szClass, "EDIT") || HIWORD(wParam) == EN_CHANGE) ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_SHOW); } if ((LOWORD(wParam)==IDC_ICQNUM || LOWORD(wParam)==IDC_PASSWORD || LOWORD(wParam)==IDC_ICQSERVER || LOWORD(wParam)==IDC_ICQPORT) && (HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus())) { return 0; } OptDlgChanged(hwndDlg); break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: char str[128]; ppro->setDword(UNIQUEIDSETTING, GetDlgItemInt(hwndDlg, IDC_ICQNUM, NULL, FALSE)); GetDlgItemTextA(hwndDlg, IDC_PASSWORD, str, sizeof(ppro->m_szPassword)); if (strlennull(str)) { strcpy(ppro->m_szPassword, str); ppro->m_bRememberPwd = TRUE; } else ppro->m_bRememberPwd = ppro->getByte("RememberPass", 0); ppro->setString("Password", str); GetDlgItemTextA(hwndDlg,IDC_ICQSERVER, str, sizeof(str)); ppro->setString("OscarServer", str); ppro->setWord("OscarPort", (WORD)GetDlgItemInt(hwndDlg, IDC_ICQPORT, NULL, FALSE)); StoreDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive"); StoreDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection"); StoreDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin"); StoreDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix"); StoreDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox"); ppro->setByte("ShowLogLevel", (BYTE)(4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0))); return TRUE; } break; } return FALSE; }
INT_PTR CALLBACK SendDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); SetAllContactChecks(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)lParam); WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); wndData = new TSendContactsData((HANDLE)lParam); SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); // new dlg init wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), LPGEN("Add Contact Permanently to List")); wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), LPGEN("View User's Details")); wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), LPGEN("View User's History")); wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), LPGEN("User Menu")); SendMessage(hwndDlg, DM_UPDATETITLE, 0, 0); // new dialog init done return TRUE; case WM_SETFOCUS: SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); break; case WM_NOTIFY: if (((LPNMHDR)lParam)->idFrom == IDC_LIST) { switch (((LPNMHDR)lParam)->code) { case CLN_NEWCONTACT: case CLN_LISTREBUILT: // rebuild list if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg, IDC_LIST), wndData->hContact); case CLN_OPTIONSCHANGED: ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); break; } } break; case WM_TIMER: if (wParam == TIMERID_MSGSEND) { KillTimer(hwndDlg, wParam); wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); } break; case DM_ERRORDECIDED: EnableWindow(hwndDlg, TRUE); wndData->hError = NULL; switch (wParam) { case MSGERROR_CANCEL: wndData->UnhookProtoAck(); if (wndData->uacklist.Count) { for (int i = 0; i < wndData->uacklist.Count; i++) delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure mir_free(wndData->uacklist.Items); wndData->uacklist.Items = NULL; wndData->uacklist.Count = 0; } EnableDlgItem(hwndDlg, IDOK, TRUE); EnableDlgItem(hwndDlg, IDC_LIST, TRUE); ShowWindow(hwndDlg, SW_SHOWNORMAL); SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); break; case MSGERROR_DONE: // contacts were delivered succesfully after timeout SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); wndData->UnhookProtoAck(); break; case MSGERROR_RETRY:// resend timeouted packets for (int i = 0; i < wndData->uacklist.Count; i++) { TAckData *lla = gaAckData.Remove(wndData->uacklist.Items[i]); HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); if (!hProcc) { // if fatal do not include wndData->uacklist.Remove(wndData->uacklist.Items[i]); delete lla; // release the structure continue; } else { // update process code wndData->uacklist.Items[i] = hProcc; gaAckData.Add(hProcc, lla); } }// collect TAckData for our window, resend break; } break; case WM_COMMAND: if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) break; switch (LOWORD(wParam)) { case IDOK: if (IsWindowEnabled(GetDlgItem(hwndDlg, IDOK))) { HANDLE hContact, hItem; wndData->ClearContacts(); // do not include contacts twice HWND hList = GetDlgItem(hwndDlg, IDC_LIST); hContact = FindFirstClistContact(hList, &hItem); while (hContact) { // build list of contacts to send if (SendMessage(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) wndData->AddContact(hContact); hContact = FindNextClistContact(hList, hContact, &hItem); } /* send contacts */ if (!wndData->SendContacts(hwndDlg)) break; SetTimer(hwndDlg, TIMERID_MSGSEND, db_get_dw(NULL, "SRMsg", "MessageTimeout", TIMEOUT_MSGSEND), NULL); } break; case IDCANCEL: DestroyWindow(hwndDlg); break; case ID_SELECTALL: { // select all contacts HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); HANDLE hItem, hContact = FindFirstClistContact(hwndList, &hItem); while (hContact) { SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)hItem, 1); hContact = FindNextClistContact(hwndList, hContact, &hItem); } } break; case IDC_USERMENU: { RECT rc; HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->hContact, 0); GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)wndData->hContact, 0); break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)wndData->hContact, 0); break; case IDC_ADD: DialogAddContactExecute(hwndDlg, wndData->hContact); break; } break; case HM_EVENTSENT: { ACKDATA *ack = (ACKDATA*)lParam; if (ack->type != ACKTYPE_CONTACTS) break; TAckData *ackData = gaAckData.Get(ack->hProcess); if (ackData == NULL) break; // on unknown hprocc go away if (ackData->hContact != ack->hContact) break; // this is not ours, strange if (ack->result == ACKRESULT_FAILED) { // some process failed, show error dialog KillTimer(hwndDlg, TIMERID_MSGSEND); wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); // ackData get used in error handling, released there break; } DBEVENTINFO dbei = { sizeof(dbei) }; dbei.szModule = GetContactProto(ackData->hContact); dbei.eventType = EVENTTYPE_CONTACTS; dbei.flags = DBEF_SENT | DBEF_UTF; dbei.timestamp = time(NULL); //make blob TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); dbei.cbBlob = 0; char* pBlob; int i; for (i = 0; i < ackData->nContacts; i++) { // prepare data & count size maSend[i].mcaNick = mir_utf8encodeT(pcli->pfnGetContactDisplayName(ackData->aContacts[i], 0)); maSend[i].mcaUIN = mir_utf8encodeT(ptrT(GetContactUID(ackData->aContacts[i]))); dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; } dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); for (i = 0, pBlob = (char*)dbei.pBlob; i < ackData->nContacts; i++) { strcpynull(pBlob, (char*)maSend[i].mcaNick); pBlob += strlennull(pBlob) + 1; strcpynull(pBlob, maSend[i].mcaUIN); pBlob += strlennull(pBlob) + 1; } db_event_add(ackData->hContact, &dbei); gaAckData.Remove(ack->hProcess); // do not release here, still needed wndData->uacklist.Remove(ack->hProcess); // packet confirmed for (i = 0; i < ackData->nContacts; i++) { mir_free(maSend[i].mcaUIN); mir_free(maSend[i].mcaNick); } delete ackData; // all done, release structure if (!wndData->uacklist.Count) { SkinPlaySound("SentContacts"); KillTimer(hwndDlg, TIMERID_MSGSEND); if (wndData->hError) SendMessage(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); SendMessage(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog } } break; case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); case WM_DRAWITEM: DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); case DM_UPDATETITLE: UpdateDialogTitle(hwndDlg, wndData ? wndData->hContact : NULL, TranslateT("Send Contacts to")); if (wndData) UpdateDialogAddButton(hwndDlg, wndData->hContact); break; case WM_CLOSE: wndData->UnhookProtoAck(); DestroyWindow(hwndDlg); break; case WM_DESTROY: for (int i = 0; i < SIZEOF(wndData->hIcons); i++) DestroyIcon(wndData->hIcons[i]); WindowList_Remove(ghSendWindowList, hwndDlg); delete wndData; break; } return FALSE; }
void CIcqProto::handleLoginChannel(BYTE *buf, WORD datalen, serverthread_info *info) { icq_packet packet; #ifdef _DEBUG NetLog_Server("Received SRV_HELLO from %s", info->isLoginServer ? "login server" : "communication server"); #endif // isLoginServer is "1" if we just received SRV_HELLO if (info->isLoginServer) { if (m_bSecureLogin) { char szUin[UINMAXLEN]; WORD wUinLen; #ifdef _DEBUG NetLog_Server("Sending %s to %s", "CLI_HELLO", "login server"); #endif packet.wLen = 12; write_flap(&packet, ICQ_LOGIN_CHAN); packDWord(&packet, 0x00000001); packTLVDWord(&packet, 0x8003, 0x00100000); // unknown sendServPacket(&packet); // greet login server wUinLen = strlennull(strUID(m_dwLocalUIN, szUin)); #ifdef _DEBUG NetLog_Server("Sending %s to %s", "ICQ_SIGNON_AUTH_REQUEST", "login server"); #endif serverPacketInit(&packet, (WORD)(14 + wUinLen)); packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_AUTH_REQUEST, 0, 0); packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin); sendServPacket(&packet); // request login digest } else { sendClientAuth((char*)info->szAuthKey, info->wAuthKeyLen, FALSE); #ifdef _DEBUG NetLog_Server("Sent CLI_IDENT to %s", "login server"); #endif } info->isLoginServer = 0; if (info->cookieDataLen) { SAFE_FREE((void**)&info->cookieData); info->cookieDataLen = 0; } } else { if (info->cookieDataLen) { wLocalSequence = generate_flap_sequence(); serverCookieInit(&packet, info->cookieData, (WORD)info->cookieDataLen); sendServPacket(&packet); #ifdef _DEBUG NetLog_Server("Sent CLI_IDENT to %s", "communication server"); #endif SAFE_FREE((void**)&info->cookieData); info->cookieDataLen = 0; } else { // We need a cookie to identify us to the communication server NetLog_Server("Error: Connected to %s without a cookie!", "communication server"); } } }