Beispiel #1
0
void __cdecl KeepAliveThread(LPVOID param)
{
	CSametimeProto* proto = (CSametimeProto*)param;
	int i = 120;
	proto->debugLog(_T("KeepAliveThread() start"));

	while (1) {

		if (i <= 0) {
			i = 120;
			// send keepalive every 120 * 250 = 30000[ms]
			if (mwSession_isStarted(proto->session) && proto->session) {
				mwSession_sendKeepalive(proto->session);
			}
		}

		i--;

		SleepEx(250, TRUE);

		EnterCriticalSection(&(proto->session_cs));
		if (Miranda_Terminated() || !proto->session) {
			LeaveCriticalSection(&(proto->session_cs));
			proto->debugLog(_T("KeepAliveThread() end"));
			break;
		}
		LeaveCriticalSection(&(proto->session_cs));
	}

	return;
}
Beispiel #2
0
void mwServiceConf_on_invited(mwConference* conf, mwLoginInfo* inviter, const char* invite)
{
	GList *members, *mem;
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_on_invited() start"));

	members = mem = mwConference_getMembers(conf);
	for (;mem;mem=mem->next) {
		if (proto->my_login_info && strcmp(proto->my_login_info->login_id, ((mwLoginInfo*)mem->data)->login_id) == 0) {
			proto->debugLog(_T("mwServiceConf_on_invited() already present"));
			char* utfs = mir_utf8encodeT(TranslateT("Invitation rejected - already present."));
			mwConference_reject(conf, 0, utfs);
			mir_free(utfs);
			return;
		}
	}
	g_list_free(members);

	wchar_t ws_username[128];
	MultiByteToWideChar(CP_UTF8, 0, (const char*)inviter->user_name, -1, ws_username, 128);

	wchar_t ws_invite[512];
	MultiByteToWideChar(CP_UTF8, 0, (const char*)invite, -1, ws_invite, 128);

	if (MessageBoxW(0, ws_invite, ws_username, MB_OKCANCEL) == IDOK) {
		proto->debugLog(_T("mwServiceConf_on_invited() mwConference_accept"));
		mwConference_accept(conf);
	}
	else {
		proto->debugLog(_T("mwServiceConf_on_invited() mwConference_reject"));
		char* temp = mir_utf8encodeT(TranslateT("Your invitation has been rejected."));
		mwConference_reject(conf, 0, temp);
		mir_free(temp);
	}
}
Beispiel #3
0
void __cdecl SessionStateChange(mwSession* session, mwSessionState state, gpointer info)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionStateChange()  state=[%d]"), state);

	switch (state) {
	case mwSession_STARTING:
		break;

	case mwSession_HANDSHAKE:
		break;

	case mwSession_HANDSHAKE_ACK:
		break;

	case mwSession_STARTED:
		proto->SessionStarted();
		break;

	case mwSession_STOPPING:
		if ((int)info) {// & ERR_FAILURE) {
			char *msg = mwError((int)info);
			TCHAR *msgT = mir_utf8decodeT(msg);
			proto->showPopup(TranslateTS(msgT), SAMETIME_POPUP_ERROR);
			mir_free(msgT);
			g_free(msg);
		}
		proto->SessionStopping();
		break;

	case mwSession_STOPPED:
		break;

	case mwSession_LOGIN_REDIR:
		proto->debugLog(_T("SessionStateChange()  mwSession_LOGIN_REDIR  info=[%s]"), _A2T((char*)info));
		//options.server_name = str((char*)info);
		strcpy(proto->options.server_name, (char*)info);
		proto->LogOut();
		proto->LogIn(proto->login_status, proto->m_hNetlibUser);
		break;

	case mwSession_LOGIN_CONT:
		break;

	case mwSession_LOGIN:
		break;

	case mwSession_LOGIN_ACK:
		break;

	case mwSession_UNKNOWN:
		break;
	}
}
Beispiel #4
0
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);
}
Beispiel #5
0
void __cdecl sttRecvAwayThread(void *param)
{
	TFakeAckParams* tParam = (TFakeAckParams*)param;
	CSametimeProto* proto = tParam->proto;
	proto->debugLog(_T("sttRecvAwayThread() start"));

	Sleep(100);
	proto->UserRecvAwayMessage(tParam->hContact);

	proto->debugLog(_T("sttRecvAwayThread() end"));
	free(tParam);
}
Beispiel #6
0
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);
}
Beispiel #7
0
void __cdecl SessionClose(mwSession* session)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionClose()  server_connection=[%d]"), proto->server_connection);
	Netlib_CloseHandle(proto->server_connection);
	proto->server_connection = 0;
}
Beispiel #8
0
/** triggered when someone says something */
void mwServiceConf_on_text(mwConference* conf, mwLoginInfo* user, const char* what)
{
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_on_text() start"));

	TCHAR* tszConfId = mir_utf8decodeT(mwConference_getName(conf));

	GCDEST gcd = { proto->m_szModuleName };
	gcd.ptszID = tszConfId;
	gcd.iType = GC_EVENT_MESSAGE;

	GCEVENT gce = { sizeof(gce), &gcd };
	gce.dwFlags = GCEF_ADDTOLOG;

	TCHAR* textT = mir_utf8decodeT(what);
	TCHAR* tszUserName = mir_utf8decodeT(user->user_name);
	TCHAR* tszUserId = mir_utf8decodeT(user->login_id);
	gce.ptszText = textT;
	gce.ptszNick = tszUserName;
	gce.ptszUID = tszUserId;
	gce.time = (DWORD)time(0);

	CallService(MS_GC_EVENT, 0, (LPARAM)(GCEVENT *) &gce);

	mir_free(textT);
	mir_free(tszUserName);
	mir_free(tszUserId);
	mir_free(tszConfId);
}
Beispiel #9
0
/** received an ack for a sent chunk on an outbound file transfer.
  this indicates that a previous call to mwFileTransfer_send has
  reached the target and that the target has responded. */
void mwFileTransfer_handle_ack(mwFileTransfer* ft)
{
	// see SendThread above - not all clients send us acks
	CSametimeProto* proto = getProtoFromMwFileTransfer(ft);
	//FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft);
	proto->debugLog(_T("mwFileTransfer_handle_ack()"));
}
Beispiel #10
0
void __cdecl SessionAdmin(struct mwSession* session, const char* text)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionAdmin()"));
	TCHAR* tt = mir_utf8decodeT(text);
	MessageBox(0, tt, TranslateT("Sametime administrator message"), MB_OK);
	mir_free(tt);
}
Beispiel #11
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;
}
Beispiel #12
0
int __cdecl SessionWrite(mwSession* session, const unsigned char* buf, gsize len)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionWrite()  server_connection=[%d], len=[%d]"), proto->server_connection, len);
	if (!proto->server_connection) return 1;
	if (Netlib_Send(proto->server_connection, (const char*)buf, len, 0) == SOCKET_ERROR)
		return 1;
	return 0;
}
Beispiel #13
0
/** 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"));
		}
	}
}
Beispiel #14
0
/** a file transfer has been fully initiated */
void mwFileTransfer_opened(mwFileTransfer* ft)
{
	CSametimeProto* proto = getProtoFromMwFileTransfer(ft);
	FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft);

	proto->debugLog(_T("Sametime mwFileTransfer_opened start"));

	if (ftcd->sending) {
		// create a thread to send chunks - since it seems not all clients send acks for each of our chunks!
		mir_forkthread(SendThread, ft);
	}
}
Beispiel #15
0
/** 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);
}
Beispiel #16
0
void __cdecl SessionAnnounce(struct mwSession* session, struct mwLoginInfo* from, gboolean may_reply, const char* text)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionAnnounce()"));
	TCHAR* stzFrom;
	TCHAR* stzText;
	TCHAR stzFromBuff[256];
	stzFrom = mir_utf8decodeT(from->user_name);
	stzText = mir_utf8decodeT(text);
	mir_sntprintf(stzFromBuff, SIZEOF(stzFromBuff), TranslateT("Session announcement - from '%s'"), stzFrom);
	MessageBox(0, TranslateTS(stzText), stzFromBuff, MB_OK);
	mir_free(stzText);
	mir_free(stzFrom);
}
Beispiel #17
0
/** triggered when a conference is closed. This is typically when
  we've left it */
void mwServiceConf_conf_closed(mwConference* conf, guint32 reason)
{
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_conf_closed() start"));

	TCHAR* tszConfId = mir_utf8decodeT(mwConference_getName(conf));

	GCDEST gcd = { proto->m_szModuleName };
	gcd.ptszID = tszConfId;
	gcd.iType = GC_EVENT_CONTROL;

	GCEVENT gce = { sizeof(gce), &gcd };
	gce.dwFlags = GCEF_ADDTOLOG;

	CallService(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce);
	CallService(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gce);
	mir_free(tszConfId);
}
Beispiel #18
0
/** triggered when someone joins the conference */
void mwServiceConf_on_peer_joined(mwConference* conf, mwLoginInfo *user)
{
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_on_peer_joined() start"));

	MCONTACT hContact = proto->FindContactByUserId(user->user_id);
	if (!hContact) {
		mwIdBlock idb;
		idb.user = ((mwLoginInfo *)user)->user_id;
		idb.community = 0;

		mwSametimeList* user_list = mwSametimeList_new();
		char* utfs = mir_utf8encodeT(TranslateT("None"));
		mwSametimeGroup* stgroup = mwSametimeGroup_new(user_list, mwSametimeGroup_NORMAL, utfs);
		mwSametimeUser* stuser = mwSametimeUser_new(stgroup, mwSametimeUser_NORMAL, &idb);

		hContact = proto->AddContact(stuser, (proto->options.add_contacts ? false : true));

		mwSametimeList_free(user_list);
		mir_free(utfs);
	}

	ptrT tszConfId(mir_utf8decodeT(mwConference_getName(conf)));
	ptrT tszUserName(mir_utf8decodeT(user->user_name));
	ptrT tszUserId(mir_utf8decodeT(user->login_id));

	// add user
	GCDEST gcd = { proto->m_szModuleName };
	gcd.ptszID = tszConfId;
	gcd.iType = GC_EVENT_JOIN;

	GCEVENT gce = { sizeof(gce), &gcd };
	gce.dwFlags = GCEF_ADDTOLOG;
	gce.ptszNick = tszUserName;
	gce.ptszUID = tszUserId;
	gce.ptszStatus = _T("Normal");
	gce.time = (DWORD)time(0);

	CallServiceSync(MS_GC_EVENT, 0, (LPARAM) &gce);

	mir_free(tszUserName);
	mir_free(tszUserId);
	mir_free(tszConfId);
}
Beispiel #19
0
/** triggered when someone leaves the conference */
void mwServiceConf_on_peer_parted(mwConference* conf, mwLoginInfo* user)
{
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_on_peer_parted() start"));

	ptrT tszConfId(mir_utf8decodeT(mwConference_getName(conf)));
	ptrT tszUserName(mir_utf8decodeT(user->user_name));
	ptrT tszUserId(mir_utf8decodeT(user->login_id));

	// remove user
	GCDEST gcd = { proto->m_szModuleName };
	gcd.ptszID = tszConfId;
	gcd.iType = GC_EVENT_PART;

	GCEVENT gce = { sizeof(gce), &gcd };
	gce.dwFlags = GCEF_ADDTOLOG;
	gce.ptszNick = tszUserName;
	gce.ptszUID = tszUserId;
	gce.ptszStatus = _T("Normal");
	gce.time = (DWORD)time(0);
	CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
}
Beispiel #20
0
void __cdecl SessionSetUserStatus(struct mwSession* session)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");

	int new_status;
	struct mwUserStatus us;
	mwUserStatus_clone(&us, mwSession_getUserStatus(session));

	proto->debugLog(_T("SessionSetUserStatus()  us.status=[%d]"), us.status);

	switch (us.status) {
	case mwStatus_ACTIVE:
		new_status = ID_STATUS_ONLINE;
		break;

	case mwStatus_AWAY:
		new_status = ID_STATUS_AWAY;
		if (proto->idle_status) {
			// ignore setting to away by idle module, after we've set ourselves idle
			// most standard clients represent idle and away the same way anyway,
			// but this allows miranda users to make use of the idle timestamp
			// but show our status in clist as away
			proto->BroadcastNewStatus(new_status);
			mwUserStatus_clear(&us);
			return;
		}
		break;

	case mwStatus_BUSY:
		new_status = ID_STATUS_DND;
		break;

	case mwStatus_IDLE:
		new_status = ID_STATUS_AWAY;
		if (!proto->first_online && !proto->options.idle_as_away) { // show our status in clist as away if idle when going online or treating idle as away
			mwUserStatus_clear(&us);
			return;
		}
		break;

	case mwStatus_IN_MEETING: // new 'in meeting' status
		new_status = ID_STATUS_OCCUPIED;
		break;

	default:
		TCHAR buff[512];
		mir_sntprintf(buff, SIZEOF(buff), TranslateT("Unknown user status: %d"), us.status);
		proto->showPopup(buff, SAMETIME_POPUP_ERROR);
		proto->debugLog(buff);

		mwUserStatus_clear(&us);
		// just go online...to prevent us getting stuck 'connecting'
		new_status = ID_STATUS_ONLINE;
		break;
	}

	proto->m_iDesiredStatus = new_status;

	if (proto->first_online) {
		proto->first_online = false;
		//proto->showPopup(TranslateT("Setting login status"), SAMETIME_POPUP_INFO);
		proto->debugLog(_T("Setting login status"));
		proto->SetSessionStatus(proto->login_status);
	}
	else proto->BroadcastNewStatus(new_status);

	mwUserStatus_clear(&us);
}
Beispiel #21
0
void __cdecl SessionSetPrivacyInfo(struct mwSession* session)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionSetPrivacyInfo()"));
}
Beispiel #22
0
void __cdecl SessionClear(mwSession* session)
{
	CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR");
	proto->debugLog(_T("SessionClear()"));
}
Beispiel #23
0
/** typing notification */
void mwServiceConf_on_typing(mwConference* conf, mwLoginInfo* who, gboolean typing)
{
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_on_typing() start"));
	///TODO unimplemented
}
Beispiel #24
0
void LogFromGLib(const gchar* log_domain, GLogLevelFlags log_level, const gchar* message, gpointer user_data)
{
	CSametimeProto* proto = (CSametimeProto*)user_data;
	proto->debugLog(_A2T(message));
}
Beispiel #25
0
/** triggered when we enter the conference. Provides the initial
  conference membership list as a GList of mwLoginInfo structures

  @param conf     the conference just joined
  @param members  mwLoginInfo list of existing conference members
*/
void mwServiceConf_conf_opened(mwConference* conf, GList* members) 
{	
	CSametimeProto* proto = getProtoFromMwConference(conf);
	proto->debugLog(_T("mwServiceConf_conf_opened() start"));

	TCHAR* tszConfId = mir_utf8decodeT(mwConference_getName(conf));
	TCHAR* tszConfTitle = mir_utf8decodeT(mwConference_getTitle(conf));

	// create new chat session
	GCSESSION gcs = { sizeof(gcs) };
	gcs.dwFlags = 0;
	gcs.iType = GCW_CHATROOM;
	gcs.pszModule = proto->m_szModuleName;
	gcs.ptszID = tszConfId;
	gcs.ptszName = tszConfTitle;
	gcs.dwItemData = 0;

	CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcs);
	mir_free(tszConfTitle);

	//add a group
	GCDEST gcd = { proto->m_szModuleName, 0 };
	gcd.iType = GC_EVENT_ADDGROUP;
	gcd.ptszID = tszConfId;

	GCEVENT gce = { sizeof(gce), &gcd };
	gce.dwFlags = GCEF_ADDTOLOG;
	gce.ptszStatus = TranslateT("Normal");

	CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);

	// add users
	gcd.iType = GC_EVENT_JOIN;

	GList *user = members;
	for (;user; user=user->next) {
		proto->debugLog(_T("mwServiceConf_conf_opened() add user"));

		TCHAR* tszUserName = mir_utf8decodeT(((mwLoginInfo*)user->data)->user_name);
		TCHAR* tszUserId = mir_utf8decodeT(((mwLoginInfo*)user->data)->login_id);
		gce.ptszNick = tszUserName;
		gce.ptszUID = tszUserId;
		gce.bIsMe = (strcmp(((mwLoginInfo*)user->data)->login_id, proto->my_login_info->login_id) == 0);

		CallServiceSync(MS_GC_EVENT, 0, (LPARAM) &gce);

		mir_free(tszUserName);
		mir_free(tszUserId);
	}

	// finalize setup (show window)
	gcd.iType = GC_EVENT_CONTROL;
	CallServiceSync(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce);

	gcd.iType = GC_EVENT_CONTROL;
	CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce);

	if (conf == proto->my_conference)
		proto->ClearInviteQueue();

	mir_free(tszConfId);
}
INT_PTR CALLBACK SessionAnnounceDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	SessionAnnounceDialogProc_arg* arg = (SessionAnnounceDialogProc_arg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
	CSametimeProto *proto;

	switch (uMsg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		{

			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
			arg = (SessionAnnounceDialogProc_arg*)lParam;
			proto = arg->proto;
			proto->debugLog(_T("SessionAnnounceDialogProc WM_INITDIALOG"));

			SendDlgItemMessage(hwndDlg, IDC_LST_ANTO, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES);
			{
				LVCOLUMN lvc;
				// Initialize the LVCOLUMN structure.
				// The mask specifies that the format, width, text, and
				// subitem members of the structure are valid. 
				lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
				lvc.fmt = LVCFMT_LEFT;

				lvc.iSubItem = 0;
				lvc.pszText = TranslateT("Recipients");
				lvc.cx = 300;     // width of column in pixels
				ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_LST_ANTO), 0, &lvc);
			}
			//enumerate plugins, fill in list
			{
				ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_LST_ANTO));
				LVITEM lvI;
				// Some code to create the list-view control.
				// Initialize LVITEM members that are common to all items. 
				lvI.mask = LVIF_TEXT | LVIF_PARAM;// | LVIF_NORECOMPUTE;// | LVIF_IMAGE; 
				lvI.iItem = 0;
				lvI.iSubItem = 0;

				for (MCONTACT hContact = db_find_first(proto->m_szModuleName); hContact; hContact = db_find_next(hContact, proto->m_szModuleName)) {
					if (db_get_b(hContact, proto->m_szModuleName, "ChatRoom", 0) == 0
						&& db_get_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) {
						lvI.lParam = (LPARAM)hContact;
						lvI.pszText = pcli->pfnGetContactDisplayName(hContact, 0);
						ListView_InsertItem(GetDlgItem(hwndDlg, IDC_LST_ANTO), &lvI);
						lvI.iItem++;
					}
				}
			}
		}
		return 0;

	case WM_CLOSE:
		proto = arg->proto;
		proto->debugLog(_T("SessionAnnounceDialogProc WM_CLOSE"));
		mir_free(arg);
		DestroyWindow(hwndDlg);
		break;

	case WM_COMMAND:
		proto = arg->proto;
		if (HIWORD(wParam) == BN_CLICKED) {
			int size;
			switch (LOWORD(wParam)) {
			case IDC_BUT_SELALL:
				size = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_LST_ANTO));
				for (int i = 0; i < size; i++)
					ListView_SetCheckState(GetDlgItem(hwndDlg, IDC_LST_ANTO), i, true);
				return 0;

			case IDC_BUT_SELINV:
				size = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_LST_ANTO));
				for (int i = 0; i < size; i++)
					ListView_SetCheckState(GetDlgItem(hwndDlg, IDC_LST_ANTO), i,
					!ListView_GetCheckState(GetDlgItem(hwndDlg, IDC_LST_ANTO), i));
				return 0;

			case IDOK:
				proto->debugLog(_T("SessionAnnounceDialogProc IDOK BN_CLICKED"));
				{
					// build SendAnnouncementFunc_arg
					SendAnnouncementFunc_arg* safArg = (SendAnnouncementFunc_arg*)mir_calloc(sizeof(SendAnnouncementFunc_arg));
					DBVARIANT dbv;
					LVITEM lvI = { 0 };

					char id[1024];
					mir_strcpy(id, "@U");		// documentation says prepend '@U' to usernames and '@G' to notes group names - but
					char *p = id + 2;		// it's wrong - it works for a list of user id's with no prefix - so we'll do both

					// build recipient list
					safArg->recipients = 0;

					int size = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_LST_ANTO));
					int send_count = 0;
					for (int i = 0; i < size; i++) {
						if (ListView_GetCheckState(GetDlgItem(hwndDlg, IDC_LST_ANTO), i)) {
							lvI.iItem = i;
							lvI.iSubItem = 0;
							lvI.mask = LVIF_PARAM;
							ListView_GetItem(GetDlgItem(hwndDlg, IDC_LST_ANTO), &lvI);

							if (!db_get_utf((MCONTACT)lvI.lParam, proto->m_szModuleName, "stid", &dbv)) {
								safArg->recipients = g_list_prepend(safArg->recipients, _strdup(dbv.pszVal));
								mir_strcpy(p, dbv.pszVal);
								safArg->recipients = g_list_prepend(safArg->recipients, _strdup(id));
								send_count++;
								db_free(&dbv);
							}
						}
					}

					if (send_count > 0) {
						GetDlgItemText(hwndDlg, IDC_ED_ANMSG, safArg->msg, MAX_MESSAGE_SIZE);
						safArg->proto = proto;
						SendAnnouncementFunc sendAnnouncementFunc = arg->sendAnnouncementFunc;
						sendAnnouncementFunc(safArg);
					}

					// clean up recipient list
					if (safArg->recipients) {
						for (GList *rit = safArg->recipients; rit; rit = rit->next) {
							free(rit->data);
						}
						g_list_free(safArg->recipients);
					}
					mir_free(safArg);

					DestroyWindow(hwndDlg);
				}
				return 0;

			case IDCANCEL:
				DestroyWindow(hwndDlg);
				return 0;
			}
		}
		break;
	}

	return 0;
}
Beispiel #27
0
void __cdecl SessionThread(LPVOID param)
{
	CSametimeProto* proto = (CSametimeProto*)param;
	HANDLE hNetlibUser = proto->m_hNetlibUser;
	proto->debugLog(_T("SessionThread() start"));

	continue_connect = true;

	//setup
	NETLIBOPENCONNECTION conn_data = { 0 };
	conn_data.cbSize = sizeof(NETLIBOPENCONNECTION);
	conn_data.flags = NLOCF_V2;
	conn_data.szHost = proto->options.server_name;
	conn_data.wPort = proto->options.port;
	conn_data.timeout = 20;
	conn_data.waitcallback = waitcallback;

	proto->BroadcastNewStatus(ID_STATUS_CONNECTING);

	proto->server_connection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn_data);

	if (!proto->server_connection) {

		proto->BroadcastNewStatus(ID_STATUS_OFFLINE);

		if (continue_connect) {
			// real timeout - not user cancelled
			proto->showPopup(TranslateT("No server connection!"), SAMETIME_POPUP_ERROR);
		}

		proto->debugLog(_T("SessionThread() end, no server_connection, continue_connect=[%d]"), continue_connect);
		return;
	}

	mwSessionHandler handler = { 0 };
	handler.clear = SessionClear;
	handler.io_write = SessionWrite;
	handler.io_close = SessionClose;
	handler.on_stateChange = SessionStateChange;
	handler.on_admin = SessionAdmin;
	handler.on_announce = SessionAnnounce;
	handler.on_setPrivacyInfo = SessionSetPrivacyInfo;
	handler.on_setUserStatus = SessionSetUserStatus;

	EnterCriticalSection(&proto->session_cs);
	proto->session = mwSession_new(&handler);

	proto->InitMeanwhileServices();

	mwSession_start(proto->session);
	LeaveCriticalSection(&proto->session_cs);

	mir_forkthread(KeepAliveThread, (void*)proto);

	unsigned char* recv_buffer = (unsigned char*)mir_alloc(1024 * 32);
	int bytes;
	//while(session && server_connection && mwSession_getState(session) != mwSession_STOPPED) {
	while (proto->server_connection) {// && session) {// && !mwSession_isStopped(session)) { // break on error
		bytes = Netlib_Recv(proto->server_connection, (char *)recv_buffer, 1024 * 32, 0);
		proto->debugLog(_T("SessionThread() Netlib_Recv'ed bytes=[%d]"), bytes);

		if (bytes == 0) {
			break;
		}
		else if (bytes == SOCKET_ERROR) {
			// this is normal - e.g. socket closed due to log off, during blocking read above
			break;
		}
		else {
			EnterCriticalSection(&proto->session_cs);
			mwSession_recv(proto->session, recv_buffer, bytes);
			LeaveCriticalSection(&proto->session_cs);
		}
	}
	mir_free(recv_buffer);

	EnterCriticalSection(&proto->session_cs);
	proto->DeinitMeanwhileServices();
	mwSession* old_session = proto->session;
	proto->session = 0; // kills keepalive thread, if awake
	mwSession_free(old_session);
	LeaveCriticalSection(&proto->session_cs);

	proto->BroadcastNewStatus(ID_STATUS_OFFLINE);
	proto->SetAllOffline();
	proto->first_online = true;

	proto->debugLog(_T("SessionThread() end"));
	return;
}
Beispiel #28
0
/** 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);
			}
		}
	}
}