void mwResolve_handler_callback(mwServiceResolve* srvc, guint32 id, guint32 code, GList* results, gpointer data) { CSametimeProto* proto = getProtoFromMwServiceResolve(srvc); BOOL advanced = (INT_PTR)data; MYCUSTOMSEARCHRESULTS mcsr; memset(&mcsr, 0, sizeof(mcsr)); mcsr.nSize = sizeof(MYCUSTOMSEARCHRESULTS); mcsr.psr.nick.a = mcsr.name; mcsr.nFieldCount = 4; TCHAR fields[4][512]; TCHAR *fields_addr[4]; mcsr.pszFields = fields_addr; mcsr.pszFields[0] = fields[0]; mcsr.pszFields[1] = fields[1]; mcsr.pszFields[2] = fields[2]; mcsr.pszFields[3] = fields[3]; if (advanced == TRUE) { // send column names mcsr.psr.cbSize = 0; _tcsncpy(mcsr.pszFields[0], TranslateT("ID"), 512); _tcsncpy(mcsr.pszFields[1], TranslateT("Name"), 512); _tcsncpy(mcsr.pszFields[2], TranslateT("Description"), 512); _tcsncpy(mcsr.pszFields[3], TranslateT("Group?"), 512); proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, (HANDLE)id, (LPARAM)&mcsr); } mcsr.psr.cbSize = sizeof(MYPROTOSEARCHRESULT); if (code == mwResolveCode_SUCCESS) { for (GList *ri = results; ri; ri = ri->next) { for (GList *mri = ((mwResolveResult *)ri->data)->matches; mri; mri = mri->next) { strncpy_s(mcsr.stid, ((mwResolveMatch *)mri->data)->id, _TRUNCATE); MultiByteToWideChar(CP_UTF8, 0, mcsr.stid, -1, mcsr.pszFields[0], 512); strncpy_s(mcsr.name, ((mwResolveMatch *)mri->data)->name, _TRUNCATE); MultiByteToWideChar(CP_UTF8, 0, mcsr.name, -1, mcsr.pszFields[1], 512); if (((mwResolveMatch *)mri->data)->desc) MultiByteToWideChar(CP_UTF8, 0, ((mwResolveMatch *)mri->data)->desc, -1, mcsr.pszFields[2], 512); else mcsr.pszFields[2][0] = 0; mcsr.group = (((mwResolveMatch *)mri->data)->type == mwResolveMatch_GROUP); _tcsncpy_s(mcsr.pszFields[3], 512, mcsr.group ? TranslateT("True") : TranslateT("False"), _TRUNCATE); if (advanced == TRUE) proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, (HANDLE)id, (LPARAM)&mcsr); else proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)id, (LPARAM)&mcsr.psr); } } proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); } }
void __cdecl SendThread(LPVOID param) { mwFileTransfer* ft = (mwFileTransfer*)param; if (!ft) return; CSametimeProto* proto = getProtoFromMwFileTransfer(ft); FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("SendThread() start")); PROTOFILETRANSFERSTATUS pfts = {0}; pfts.cbSize = sizeof(pfts); pfts.flags = PFTS_UTF; pfts.hContact = ftcd->hContact; if (ftcd->sending == 1) pfts.flags |= PFTS_SENDING; pfts.pszFiles = NULL; pfts.totalFiles = ftcd->first->ft_count; pfts.totalBytes = ftcd->first->totalSize; while(SendFileChunk(proto, ft, ftcd) && !Miranda_Terminated()) { pfts.currentFileNumber = ftcd->ft_number; pfts.totalProgress = ftcd->sizeToHere + mwFileTransfer_getSent(ft); pfts.szWorkingDir = ftcd->save_path; pfts.szCurrentFile = (char*)mwFileTransfer_getFileName(ft); pfts.currentFileSize = mwFileTransfer_getFileSize(ft); pfts.currentFileProgress = mwFileTransfer_getSent(ft); pfts.currentFileTime = 0; //? proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftcd->hFt, (LPARAM)&pfts); SleepEx(500,TRUE); } proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftcd->hFt, 0); mwFileTransfer_removeClientData(ft); if (ftcd->save_path) free(ftcd->save_path); if (ftcd->buffer) delete[] ftcd->buffer; delete ftcd; proto->debugLog(_T("SendThread() end")); return; }
/** receive a chunk of a file from an inbound file transfer. */ void mwFileTransfer_recv(mwFileTransfer* ft, struct mwOpaque* data) { CSametimeProto* proto = getProtoFromMwFileTransfer(ft); FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("mwFileTransfer_recv() start")); DWORD bytes_written; if (!WriteFile(ftcd->hFile, data->data, data->len, &bytes_written, 0)) { proto->debugLog(_T("mwFileTransfer_recv() !WriteFile")); mwFileTransfer_cancel(ft); proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftcd->hFt, 0); proto->debugLog(_T("mwFileTransfer_recv() ACKRESULT_FAILED")); } else { mwFileTransfer_ack(ft); // acknowledge chunk PROTOFILETRANSFERSTATUS pfts = { 0 }; pfts.cbSize = sizeof(pfts); pfts.flags = PFTS_UTF; pfts.hContact = ftcd->hContact; if (ftcd->sending == 1) { pfts.flags |= PFTS_SENDING; } pfts.pszFiles = NULL; pfts.totalFiles = 1; pfts.currentFileNumber = 0; pfts.totalBytes = mwFileTransfer_getFileSize(ft); pfts.totalProgress = mwFileTransfer_getSent(ft); pfts.szWorkingDir = ftcd->save_path; pfts.szCurrentFile = (char*)mwFileTransfer_getFileName(ft); pfts.currentFileSize = mwFileTransfer_getFileSize(ft); pfts.currentFileProgress = mwFileTransfer_getSent(ft); pfts.currentFileTime = 0; //? proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftcd->hFt, (LPARAM)&pfts); proto->debugLog(_T("mwFileTransfer_recv() ACKRESULT_DATA")); if (mwFileTransfer_isDone(ft)) { proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftcd->hFt, 0); proto->debugLog(_T("mwFileTransfer_recv() ACKRESULT_SUCCESS")); } } }
void __cdecl sttFakeAckMessageFailedThread(void *param) { TFakeAckParams* tParam = (TFakeAckParams*)param; CSametimeProto* proto = tParam->proto; proto->debugLog(_T("sttFakeAckMessageFailedThread() start")); Sleep(100); proto->ProtoBroadcastAck(tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, NULL, tParam->lParam); ///TODO tParam->lParam: add error message proto->debugLog(_T("sttFakeAckMessageFailedThread() end")); mir_free(tParam); }
void __cdecl sttFakeAckMessageSuccessThread(void *param) { TFakeAckParams* tParam = (TFakeAckParams*)param; CSametimeProto* proto = tParam->proto; proto->debugLog(_T("sttFakeAckMessageSuccessThread() start")); Sleep(100); proto->ProtoBroadcastAck(tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)tParam->lParam, 0); proto->debugLog(_T("sttFakeAckMessageSuccessThread() end")); mir_free(tParam); }
/** an incoming file transfer has been offered */ void mwFileTransfer_offered(mwFileTransfer* ft) { CSametimeProto* proto = getProtoFromMwFileTransfer(ft); proto->debugLog(_T("mwFileTransfer_offered() start")); const mwIdBlock* idb = mwFileTransfer_getUser(ft); MCONTACT hContact = proto->FindContactByUserId(idb->user); proto->debugLog(_T("Sametime mwFileTransfer_offered hContact=[%x]"), hContact); if (!hContact) { mwSametimeList* user_list = mwSametimeList_new(); mwSametimeGroup* stgroup = mwSametimeGroup_new(user_list, mwSametimeGroup_NORMAL, Translate("None")); mwSametimeUser* stuser = mwSametimeUser_new(stgroup, mwSametimeUser_NORMAL, (mwIdBlock*)idb); hContact = proto->AddContact(stuser, (proto->options.add_contacts ? false : true)); } proto->ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, (HANDLE)ft, 0); TCHAR* filenameT = mir_utf8decodeT(mwFileTransfer_getFileName(ft)); const char* message = mwFileTransfer_getMessage(ft); TCHAR descriptionT[512]; if (message) { TCHAR* messageT = mir_utf8decodeT(message); mir_sntprintf(descriptionT, _T("%s - %s"), filenameT, messageT); mir_free(messageT); } else _tcsncpy_s(descriptionT, filenameT, _TRUNCATE); PROTORECVFILET pre = {0}; pre.dwFlags = PRFF_TCHAR; pre.fileCount = 1; pre.timestamp = time(NULL); pre.descr.t = descriptionT; pre.files.t = &filenameT; pre.lParam = (LPARAM)ft; ProtoChainRecvFile(hContact, &pre); mir_free(filenameT); }
/** a file transfer has been closed. Check the status of the file transfer to determine if the transfer was complete or if it had been interrupted */ void mwFileTransfer_closed(mwFileTransfer* ft, guint32 code) { CSametimeProto* proto = getProtoFromMwFileTransfer(ft); FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("mwFileTransfer_closed() start")); if (ftcd) { if (ftcd->hFile != INVALID_HANDLE_VALUE) CloseHandle(ftcd->hFile); if (code != mwFileTransfer_SUCCESS || !mwFileTransfer_isDone(ft)) { if (!ftcd->sending) { char fn[MAX_PATH]; if (ftcd->save_path) mir_strcpy(fn, ftcd->save_path); else fn[0] = 0; mir_strcat(fn, mwFileTransfer_getFileName(ft)); DeleteFileA(fn); } if (code == mwFileTransfer_REJECTED) proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ftcd->hFt, 0); else proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftcd->hFt, 0); if (ftcd->sending) { FileTransferClientData* ftcd_next = ftcd->next; while(ftcd_next) { mwFileTransfer_free((mwFileTransfer*)ftcd_next->ft); FileTransferClientData *ftcd_temp = ftcd_next->next; if (ftcd_next->hFile != INVALID_HANDLE_VALUE) CloseHandle(ftcd_next->hFile); if (ftcd_next->save_path) free(ftcd_next->save_path); if (ftcd_next->buffer) delete[] ftcd_next->buffer; delete ftcd_next; ftcd_next = ftcd_temp; } } else { mwFileTransfer_removeClientData(ft); if (ftcd->save_path) free(ftcd->save_path); if (ftcd->buffer) delete[] ftcd->buffer; delete ftcd; mwFileTransfer_free(ft); } } else { if (ftcd->sending) { // check if we have more files to send... if (ftcd->next) { proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftcd->hFt, 0); mwFileTransfer_offer(ftcd->next->ft); } } else { proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftcd->hFt, 0); mwFileTransfer_removeClientData(ft); if (ftcd->save_path) free(ftcd->save_path); if (ftcd->buffer) delete[] ftcd->buffer; delete ftcd; mwFileTransfer_free(ft); } } } }