📄 slplink.c
字号:
else if (slpmsg->flags == 0x100) { msg->msnslp_header.ack_id = slpmsg->ack_id; msg->msnslp_header.ack_sub_id = slpmsg->ack_sub_id; msg->msnslp_header.ack_size = slpmsg->ack_size; } msg->msnslp_header.id = slpmsg->id; msg->msnslp_header.flags = slpmsg->flags; msg->msnslp_header.total_size = slpmsg->size; msn_message_set_attr(msg, "P2P-Dest", slplink->remote_user); msg->ack_cb = msg_ack; msg->nak_cb = msg_nak; msg->ack_data = slpmsg; msn_slplink_send_msgpart(slplink, slpmsg); msn_message_destroy(msg);}voidmsn_slplink_queue_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg){ slpmsg->id = slplink->slp_seq_id++; g_queue_push_head(slplink->slp_msg_queue, slpmsg);}voidmsn_slplink_send_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg){ slpmsg->id = slplink->slp_seq_id++; msn_slplink_release_slpmsg(slplink, slpmsg);}voidmsn_slplink_unleash(MsnSlpLink *slplink){ MsnSlpMessage *slpmsg; /* Send the queued msgs in the order they came. */ while ((slpmsg = g_queue_pop_tail(slplink->slp_msg_queue)) != NULL) { msn_slplink_release_slpmsg(slplink, slpmsg); }}voidmsn_slplink_send_ack(MsnSlpLink *slplink, MsnMessage *msg){ MsnSlpMessage *slpmsg; slpmsg = msn_slpmsg_new(slplink); slpmsg->session_id = msg->msnslp_header.session_id; slpmsg->size = msg->msnslp_header.total_size; slpmsg->flags = 0x02; slpmsg->ack_id = msg->msnslp_header.id; slpmsg->ack_sub_id = msg->msnslp_header.ack_id; slpmsg->ack_size = msg->msnslp_header.total_size;#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP ACK";#endif msn_slplink_send_slpmsg(slplink, slpmsg);}static voidsend_file_cb(MsnSlpSession *slpsession){ MsnSlpCall *slpcall; MsnSlpMessage *slpmsg; struct stat st; PurpleXfer *xfer; slpcall = slpsession->slpcall; slpmsg = msn_slpmsg_new(slpcall->slplink); slpmsg->slpcall = slpcall; slpmsg->flags = 0x1000030; slpmsg->slpsession = slpsession;#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP FILE";#endif xfer = (PurpleXfer *)slpcall->xfer; purple_xfer_start(slpcall->xfer, 0, NULL, 0); slpmsg->fp = xfer->dest_fp; if (g_stat(purple_xfer_get_local_filename(xfer), &st) == 0) slpmsg->size = st.st_size; xfer->dest_fp = NULL; /* Disable double fclose() */ msn_slplink_send_slpmsg(slpcall->slplink, slpmsg);}voidmsn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg){ MsnSlpMessage *slpmsg; const char *data; gsize offset; gsize len;#ifdef MSN_DEBUG_SLP msn_slpmsg_show(msg);#endif#ifdef MSN_DEBUG_SLP_FILES debug_msg_to_file(msg, FALSE);#endif if (msg->msnslp_header.total_size < msg->msnslp_header.length) { purple_debug_error("msn", "This can't be good\n"); g_return_if_reached(); } slpmsg = NULL; data = msn_message_get_bin_data(msg, &len); /* OVERHEAD! if (msg->msnslp_header.length < msg->msnslp_header.total_size) */ offset = msg->msnslp_header.offset; if (offset == 0) { slpmsg = msn_slpmsg_new(slplink); slpmsg->id = msg->msnslp_header.id; slpmsg->session_id = msg->msnslp_header.session_id; slpmsg->size = msg->msnslp_header.total_size; slpmsg->flags = msg->msnslp_header.flags; if (slpmsg->session_id) { if (slpmsg->slpcall == NULL) slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); if (slpmsg->slpcall != NULL) { if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) { PurpleXfer *xfer; xfer = slpmsg->slpcall->xfer; if (xfer != NULL) { purple_xfer_start(slpmsg->slpcall->xfer, 0, NULL, 0); slpmsg->fp = ((PurpleXfer *)slpmsg->slpcall->xfer)->dest_fp; xfer->dest_fp = NULL; /* Disable double fclose() */ } } } } if (!slpmsg->fp && slpmsg->size) { slpmsg->buffer = g_try_malloc(slpmsg->size); if (slpmsg->buffer == NULL) { purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n"); return; } } } else { slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); } if (slpmsg == NULL) { /* Probably the transfer was canceled */ purple_debug_error("msn", "Couldn't find slpmsg\n"); return; } if (slpmsg->fp) { /* fseek(slpmsg->fp, offset, SEEK_SET); */ len = fwrite(data, 1, len, slpmsg->fp); } else if (slpmsg->size) { if ((offset + len) > slpmsg->size) { purple_debug_error("msn", "Oversized slpmsg\n"); g_return_if_reached(); } else memcpy(slpmsg->buffer + offset, data, len); } if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; if (slpmsg->slpcall->progress_cb != NULL) { slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, len, offset); } }#if 0 if (slpmsg->buffer == NULL) return;#endif if (msg->msnslp_header.offset + msg->msnslp_header.length >= msg->msnslp_header.total_size) { /* All the pieces of the slpmsg have been received */ MsnSlpCall *slpcall; slpcall = msn_slp_process_msg(slplink, slpmsg); if (slpmsg->flags == 0x100) { MsnDirectConn *directconn; directconn = slplink->directconn; if (!directconn->acked) msn_directconn_send_handshake(directconn); } else if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) { /* Release all the messages and send the ACK */ msn_slplink_send_ack(slplink, msg); msn_slplink_unleash(slplink); } msn_slpmsg_destroy(slpmsg); if (slpcall != NULL && slpcall->wasted) msn_slp_call_destroy(slpcall); }}MsnSlpMessage *msn_slplink_message_find(MsnSlpLink *slplink, long session_id, long id){ GList *e; for (e = slplink->slp_msgs; e != NULL; e = e->next) { MsnSlpMessage *slpmsg = e->data; if ((slpmsg->session_id == session_id) && (slpmsg->id == id)) return slpmsg; } return NULL;}typedef struct{ guint32 length; guint32 unk1; guint32 file_size; guint32 unk2; guint32 unk3;} MsnContextHeader;#define MAX_FILE_NAME_LEN 0x226static gchar *gen_context(const char *file_name, const char *file_path){ struct stat st; gsize size = 0; MsnContextHeader header; gchar *u8 = NULL; guchar *base; guchar *n; gchar *ret; gunichar2 *uni = NULL; glong currentChar = 0; glong uni_len = 0; gsize len; if (g_stat(file_path, &st) == 0) size = st.st_size; if(!file_name) { u8 = purple_utf8_try_convert(g_basename(file_path)); file_name = u8; } uni = g_utf8_to_utf16(file_name, -1, NULL, &uni_len, NULL); if(u8) { g_free(u8); file_name = NULL; u8 = NULL; } len = sizeof(MsnContextHeader) + MAX_FILE_NAME_LEN + 4; header.length = GUINT32_TO_LE(len); header.unk1 = GUINT32_TO_LE(2); header.file_size = GUINT32_TO_LE(size); header.unk2 = GUINT32_TO_LE(0); header.unk3 = GUINT32_TO_LE(0); base = g_malloc(len + 1); n = base; memcpy(n, &header, sizeof(MsnContextHeader)); n += sizeof(MsnContextHeader); memset(n, 0x00, MAX_FILE_NAME_LEN); for(currentChar = 0; currentChar < uni_len; currentChar++) { *((gunichar2 *)n + currentChar) = GUINT16_TO_LE(uni[currentChar]); } n += MAX_FILE_NAME_LEN; memset(n, 0xFF, 4); n += 4; g_free(uni); ret = purple_base64_encode(base, len); g_free(base); return ret;}voidmsn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer){ MsnSlpCall *slpcall; char *context; const char *fn; const char *fp; fn = purple_xfer_get_filename(xfer); fp = purple_xfer_get_local_filename(xfer); g_return_if_fail(slplink != NULL); g_return_if_fail(fp != NULL); slpcall = msn_slp_call_new(slplink); msn_slp_call_init(slpcall, MSN_SLPCALL_DC); slpcall->session_init_cb = send_file_cb; slpcall->end_cb = msn_xfer_end_cb; slpcall->progress_cb = msn_xfer_progress_cb; slpcall->cb = msn_xfer_completed_cb; slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); slpcall->pending = TRUE; purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel); xfer->data = slpcall; context = gen_context(fn, fp); msn_slp_call_invite(slpcall, "5D3E02AB-6190-11D3-BBBB-00C04F795683", 2, context); g_free(context);}voidmsn_slplink_request_object(MsnSlpLink *slplink, const char *info, MsnSlpCb cb, MsnSlpEndCb end_cb, const MsnObject *obj){ MsnSlpCall *slpcall; char *msnobj_data; char *msnobj_base64; g_return_if_fail(slplink != NULL); g_return_if_fail(obj != NULL); msnobj_data = msn_object_to_string(obj); msnobj_base64 = purple_base64_encode((const guchar *)msnobj_data, strlen(msnobj_data)); g_free(msnobj_data); slpcall = msn_slp_call_new(slplink); msn_slp_call_init(slpcall, MSN_SLPCALL_ANY); slpcall->data_info = g_strdup(info); slpcall->cb = cb; slpcall->end_cb = end_cb; msn_slp_call_invite(slpcall, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6", 1, msnobj_base64); g_free(msnobj_base64);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -