Beispiel #1
0
char* CIcqProto::getSettingStringUtf(HANDLE hContact, const char *szModule, const char *szSetting, char *szDef)
{
	DBVARIANT dbv = {DBVT_DELETED};

	if (DBGetContactSettingUTF8String(hContact, szModule, szSetting, &dbv))
  {
    ICQFreeVariant(&dbv); // for a setting with invalid contents/type
		return null_strdup(szDef);
  }

	char *szRes = null_strdup(dbv.pszVal);
	ICQFreeVariant(&dbv);
	return szRes;
}
Beispiel #2
0
void ChangeInfoData::LoadSettingsFromDb(int keepChanged)
{
	for (int i=0; i < settingCount; i++) 
  {
		if (setting[i].displayType == LI_DIVIDER) continue;
		if (keepChanged && settingData[i].changed) continue;
		if (setting[i].dbType == DBVT_ASCIIZ || setting[i].dbType == DBVT_UTF8) 
			SAFE_FREE((void**)(char**)&settingData[i].value);
		else if (!keepChanged)
			settingData[i].value = 0;

		settingData[i].changed = 0;

		if (setting[i].displayType & LIF_PASSWORD) continue;

    DBVARIANT dbv = {DBVT_DELETED};
		if (!ppro->getSetting(NULL, setting[i].szDbSetting, &dbv))
    {
			switch(dbv.type) {
			case DBVT_ASCIIZ:
				settingData[i].value = (LPARAM)ppro->getSettingStringUtf(NULL, setting[i].szDbSetting, NULL);
        break;

			case DBVT_UTF8:
				settingData[i].value = (LPARAM)null_strdup(dbv.pszVal);
				break;

			case DBVT_WORD:
				if (setting[i].displayType & LIF_SIGNED) 
					settingData[i].value = dbv.sVal;
				else 
					settingData[i].value = dbv.wVal;
				break;

			case DBVT_BYTE:
				if (setting[i].displayType & LIF_SIGNED) 
					settingData[i].value = dbv.cVal;
				else 
					settingData[i].value = dbv.bVal;
				break;

#ifdef _DEBUG
			default:
				MessageBoxA(NULL, "That's not supposed to happen either", "Huh?", MB_OK);
				break;
#endif
			}
			db_free(&dbv);
		}

    char buf[MAX_PATH];
    TCHAR tbuf[MAX_PATH];

    if (utf8_to_tchar_static(GetItemSettingText(i, buf, SIZEOF(buf)), tbuf, SIZEOF(tbuf)))
      ListView_SetItemText(hwndList, i, 1, tbuf);
	}
}
Beispiel #3
0
TCHAR* CIcqProto::GetOwnAvatarFileName()
{
	DBVARIANT dbvFile = {DBVT_DELETED};
	if (getTString(NULL, "AvatarFile", &dbvFile))
		return NULL;

	TCHAR tmp[MAX_PATH * 2];
	PathToAbsoluteT(dbvFile.ptszVal, tmp);
	db_free(&dbvFile);

	return null_strdup(tmp);
}
Beispiel #4
0
rates_queue_item* rates_queue_item::copyItem(rates_queue_item *pDest)
{
	if (!pDest)
		pDest = new rates_queue_item(ppro, wGroup);

	pDest->hContact = hContact;
	pDest->dwUin = dwUin;
	pDest->szUid = dwUin ? null_strdup(szUid) : NULL;
	pDest->bCreated = TRUE;

	return pDest;
}
Beispiel #5
0
void ChangeInfoData::EndListEdit(int save)
{
	if (hwndListEdit == NULL || iEditItem == -1 || this != dataListEdit)
		return;

	if (save) {
		const SettingItem &si = setting[iEditItem];
		SettingItemData &sid = settingData[iEditItem];

		int iItem = SendMessage(hwndListEdit, LB_GETCURSEL, 0, 0);
		int i = SendMessage(hwndListEdit, LB_GETITEMDATA, iItem, 0);
		if (iItem != -1 && i != -1) {
			FieldNamesItem *list = (FieldNamesItem*)si.pList;
			if (list == timezonesField) {
				tmi.storeListResults(NULL, ppro->m_szModuleName, hwndListEdit, TZF_PLF_LB);
				list[i = 0].code = ppro->getDword("Timezone", 0);
			}

			FieldNamesItem &pItem = list[i];

			if (si.dbType == DBVT_ASCIIZ) {
				char *szNewValue = pItem.text;
				if (pItem.code || (si.displayType & LIF_ZEROISVALID)) {
					sid.changed = strcmpnull(szNewValue, (char*)sid.value);
					SAFE_FREE((void**)&sid.value);
					sid.value = (LPARAM)null_strdup(szNewValue);
				}
				else {
					sid.changed = (char*)sid.value != NULL;
					SAFE_FREE((void**)&sid.value);
				}
			}
			else {
				sid.changed = pItem.code != sid.value;
				sid.value = pItem.code;
			}

			if (sid.changed) {
				char buf[MAX_PATH];
				TCHAR tbuf[MAX_PATH];
				if (utf8_to_tchar_static(ICQTranslateUtfStatic(pItem.text, buf, SIZEOF(buf)), tbuf, SIZEOF(buf)))
					ListView_SetItemText(hwndList, iEditItem, 1, tbuf);

				EnableDlgItem(GetParent(hwndList), IDC_SAVE, TRUE);
			}
		}
	}
	ListView_RedrawItems(hwndList, iEditItem, iEditItem);
	iEditItem = -1;
	dataListEdit = NULL;
	DestroyWindow(hwndListEdit);
	hwndListEdit = NULL;
}
void CIcqProto::icq_sendFileResume(filetransfer *ft, int action, const char *szFilename)
{
	if (ft->hConnection == NULL)
		return;

	directconnect *dc = FindFileTransferDC(ft);
	if (!dc) return; // something is broken...

	int openFlags;

	switch (action)
	{
	case FILERESUME_RESUME:
		openFlags = _O_BINARY | _O_WRONLY;
		break;

	case FILERESUME_OVERWRITE:
		openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
		ft->dwFileBytesDone = 0;
		break;

	case FILERESUME_SKIP:
		openFlags = _O_BINARY | _O_WRONLY;
		ft->dwFileBytesDone = ft->dwThisFileSize;
		break;

	case FILERESUME_RENAME:
		openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
		SAFE_FREE(&ft->szThisFile);
		ft->szThisFile = null_strdup(szFilename);
		ft->dwFileBytesDone = 0;
		break;
	}

	ft->fileId = OpenFileUtf(ft->szThisFile, openFlags, _S_IREAD | _S_IWRITE);
	if (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."));
		NetLib_CloseConnection(&ft->hConnection, FALSE);
		return;
	}

	if (action == FILERESUME_RESUME)
		ft->dwFileBytesDone = _lseek(ft->fileId, 0, SEEK_END);
	else
		_lseek(ft->fileId, ft->dwFileBytesDone, SEEK_SET);

	ft->dwBytesDone += ft->dwFileBytesDone;

	file_sendResume(this, dc);

	BroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
}
Beispiel #7
0
void CIcqProto::setStatusMsgVar(HANDLE hContact, char* szStatusMsg, bool isAnsi)
{
	if (szStatusMsg && szStatusMsg[0])
	{
		if (isAnsi)
		{
			char* szStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, "");
			wchar_t* szStatusNoteW = make_unicode_string(szStatusNote);
			int len = (int)wcslen(szStatusNoteW) * 3 + 1;
			char* szStatusNoteAnsi = (char*)alloca(len);
			WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, szStatusNoteW, -1, szStatusNoteAnsi, len, NULL, NULL);
			bool notmatch = false;
			for (int i=0; ;++i)
			{
				if (szStatusNoteAnsi[i] != szStatusMsg[i] && szStatusNoteAnsi[i] != '?' && szStatusMsg[i] != '?')
				{
					notmatch = true;
					break;
				}
				if (!szStatusNoteAnsi[i] || !szStatusMsg[i])
					break;
			}
			szStatusMsg = notmatch ? ansi_to_utf8(szStatusMsg) : szStatusNote;
			SAFE_FREE(&szStatusNoteW);
			if (notmatch) SAFE_FREE(&szStatusNote);
		}

		char* oldStatusMsg = NULL;
		DBVARIANT dbv;
		if (!DBGetContactSetting(hContact, "CList", "StatusMsg", &dbv))
		{
			switch (dbv.type)
			{
			case DBVT_UTF8:
				oldStatusMsg = null_strdup(dbv.pszVal);
				break;

			case DBVT_WCHAR:
				oldStatusMsg = make_utf8_string(dbv.pwszVal);
				break;
			}
			ICQFreeVariant(&dbv);
		}
			
		if (!oldStatusMsg || strcmp(oldStatusMsg, szStatusMsg))
			setSettingStringUtf(hContact, "CList", "StatusMsg", szStatusMsg);
		SAFE_FREE(&oldStatusMsg);
		if (isAnsi) SAFE_FREE(&szStatusMsg);
	}
	else
		DBDeleteContactSetting(hContact, "CList", "StatusMsg");
}
Beispiel #8
0
								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);
								};
Beispiel #9
0
void CIcqProto::icq_LogMessage(int level, const char *szMsg)
{
	debugLogA("%s", szMsg);

	int displayLevel = getByte("ShowLogLevel", LOG_WARNING);
	if (level >= displayLevel) {
		if (!bErrorBoxVisible || !getByte("IgnoreMultiErrorBox", 0)) {
			// error not shown or allowed multi - show messagebox
			LogMessageInfo *lmi = (LogMessageInfo*)SAFE_MALLOC(sizeof(LogMessageInfo));
			lmi->bLevel = (BYTE)level;
			lmi->szMsg = null_strdup(szMsg);
			lmi->szTitle = szLevelDescr[level];
			ForkThread(&CIcqProto::icq_LogMessageThread, lmi);
		}
	}
}
Beispiel #10
0
void ChangeInfoData::EndListEdit(int save)
{
  if (hwndListEdit == NULL || iEditItem == -1 || this != dataListEdit) return;
  if (save) 
  {
    int iItem = SendMessage(hwndListEdit, LB_GETCURSEL, 0, 0);
    int i = SendMessage(hwndListEdit, LB_GETITEMDATA, iItem, 0);

    if (setting[iEditItem].dbType == DBVT_ASCIIZ) 
    {
      char *szNewValue = (((FieldNamesItem*)setting[iEditItem].pList)[i].text);
      if (((FieldNamesItem*)setting[iEditItem].pList)[i].code || setting[iEditItem].displayType & LIF_ZEROISVALID)
      { 
        settingData[iEditItem].changed = strcmpnull(szNewValue, (char*)settingData[iEditItem].value);
        SAFE_FREE((void**)&settingData[iEditItem].value);
        settingData[iEditItem].value = (LPARAM)null_strdup(szNewValue);
      }
      else 
      {
        settingData[iEditItem].changed = (char*)settingData[iEditItem].value!=NULL;
        SAFE_FREE((void**)&settingData[iEditItem].value);
      }
    }
    else 
    {
      settingData[iEditItem].changed = ((FieldNamesItem*)setting[iEditItem].pList)[i].code != settingData[iEditItem].value;
      settingData[iEditItem].value = ((FieldNamesItem*)setting[iEditItem].pList)[i].code;
    }
    if (settingData[iEditItem].changed)
    {
      char buf[MAX_PATH];
      TCHAR tbuf[MAX_PATH];

      if (utf8_to_tchar_static(ICQTranslateUtfStatic(((FieldNamesItem*)setting[iEditItem].pList)[i].text, buf, SIZEOF(buf)), tbuf, SIZEOF(buf)))
        ListView_SetItemText(hwndList, iEditItem, 1, tbuf);

      EnableDlgItem(GetParent(hwndList), IDC_SAVE, TRUE);

    }
  }
  ListView_RedrawItems(hwndList, iEditItem, iEditItem);
  iEditItem = -1;
  dataListEdit = NULL;
  DestroyWindow(hwndListEdit);
  hwndListEdit = NULL;
}
Beispiel #11
0
IcqIconHandle IconLibDefine(const char *desc, const char *section, const char *module, const char *ident, const TCHAR *def_file, int def_idx)
{
	SKINICONDESC sid = {0};

	sid.cbSize = SKINICONDESC_SIZE;
	sid.pwszSection = make_unicode_string(section);
	sid.pwszDescription = make_unicode_string(desc);
	sid.flags = SIDF_UNICODE | SIDF_PATH_TCHAR;

	char szName[MAX_PATH + 128];
	null_snprintf(szName, sizeof(szName), "%s_%s", module ? module : ICQ_PROTOCOL_NAME, ident);
	sid.pszName = szName;
	sid.ptszDefaultFile = (TCHAR*)def_file;
	sid.iDefaultIndex = def_idx;

	IcqIconHandle hIcon = (IcqIconHandle)SAFE_MALLOC(sizeof(IcqIconHandle_s));
	hIcon->szName = null_strdup(sid.pszName);
	hIcon->hIcoLib = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);

	SAFE_FREE(&sid.pwszSection);
	SAFE_FREE(&sid.pwszDescription);

	return hIcon;
}
Beispiel #12
0
DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD dwUin, char *szUid, const BYTE *hash, size_t hashlen, const TCHAR *file)
{
	int i;
	DWORD dwNow = GetTickCount();

	mir_cslockfull alck(ppro->m_avatarsMutex);

	for (i = 0; i < runCount;) { // look for timeouted requests
		if (runTime[i] < dwNow) { // found outdated, remove
			runContact[i] = runContact[runCount - 1];
			runTime[i] = runTime[runCount - 1];
			runCount--;
		}
		else i++;
	}

	for (i = 0; i < runCount; i++) {
		if (runContact[i] == hContact) {
			ppro->debugLogA("Ignoring duplicate get %s image request.", strUID(dwUin, szUid));
			return -1; // Success: request ignored
		}
	}

	if (runCount < 4) { // 4 concurent requests at most
		int bSendNow = TRUE;
		{
			// rate management
			mir_cslock l(m_ratesMutex);
			WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST);

			if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_ALERT)) { // we will be over quota if we send the request now, add to queue instead
				bSendNow = FALSE;
				ppro->debugLogA("Rates: Delay avatar request.");
			}
		}

		if (bSendNow) {
			runContact[runCount] = hContact;
			runTime[runCount] = GetTickCount() + 30000; // 30sec to complete request
			runCount++;

			alck.unlock();

			int nUinLen = getUIDLen(dwUin, szUid);

			cookie_avatar *ack = (cookie_avatar*)SAFE_MALLOC(sizeof(cookie_avatar));
			if (!ack)
				return 0; // Failure: out of memory

			ack->dwUin = 1; //dwUin; // I should be damned for this - only to identify get request
			ack->hContact = hContact;
			ack->hash = (BYTE*)SAFE_MALLOC(hashlen);
			memcpy(ack->hash, hash, hashlen); // copy the data
			ack->hashlen = hashlen;
			ack->szFile = null_strdup(file); // duplicate the string

			DWORD dwCookie = ppro->AllocateCookie(CKT_AVATAR, ICQ_AVATAR_GET_REQUEST, hContact, ack);
			icq_packet packet;

			serverPacketInit(&packet, 12 + nUinLen + hashlen);
			packFNACHeader(&packet, ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST, 0, dwCookie);
			packUID(&packet, dwUin, szUid);
			packByte(&packet, 1); // unknown, probably type of request: 1 = get icon :)
			packBuffer(&packet, hash, hashlen);

			if (sendServerPacket(&packet)) {
				ppro->debugLogA("Request to get %s image sent.", strUID(dwUin, szUid));
				return dwCookie;
			}
			ppro->FreeCookie(dwCookie); // sending failed, free resources
			SAFE_FREE(&ack->szFile);
			SAFE_FREE((void**)&ack->hash);
			SAFE_FREE((void**)&ack);
		}
	}

	return 0; // Failure
}
Beispiel #13
0
// request avatar data from server
int CIcqProto::GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, const BYTE *hash, size_t hashlen, const TCHAR *file)
{
	uid_str szUidData;
	char *pszUid = NULL;
	if (!dwUin && szUid) { // create a copy in local writable buffer
		mir_strcpy(szUidData, szUid);
		pszUid = szUidData;
	}

	mir_cslockfull alck(m_avatarsMutex);

	if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready
		// check if requests for this user are not blocked
		for (int i = 0; i < m_arAvatars.getCount();) {
			avatars_request *ar = m_arAvatars[i];
			if (ar->hContact == hContact && ar->type == ART_BLOCK) { // found a block item
				if (GetTickCount() > ar->timeOut) { // remove timeouted block
					m_arAvatars.remove(i);
					delete ar;
					continue;
				}
				debugLogA("Avatars: Requests for %s avatar are blocked.", strUID(dwUin, pszUid));
				return 0;
			}
			i++;
		}

		mir_cslock l(m_avatarsConnection->getLock());
		alck.unlock();

		DWORD dwCookie = m_avatarsConnection->sendGetAvatarRequest(hContact, dwUin, pszUid, hash, hashlen, file);
		if (dwCookie) // return now if the request was sent successfully
			return dwCookie;

		alck.lock();
	}
	// we failed to send request, or avatar thread not ready

	// check if any request for this user is not already in the queue
	for (int i = 0; i < m_arAvatars.getCount();) {
		avatars_request *ar = m_arAvatars[i];
		if (ar->hContact == hContact) { // we found it, return error
			if (ar->type == ART_BLOCK && GetTickCount() > ar->timeOut) { // remove timeouted block
				m_arAvatars.remove(i);
				delete ar;
				continue;
			}
			alck.unlock();
			debugLogA("Avatars: Ignoring duplicate get %s avatar request.", strUID(dwUin, pszUid));

			// make sure avatar connection is in progress
			requestAvatarConnection();
			return 0;
		}
		i++;
	}

	// add request to queue, processed after successful login
	avatars_request *ar = new avatars_request(ART_GET); // get avatar
	ar->hContact = hContact;
	ar->dwUin = dwUin;
	if (!dwUin)
		mir_strcpy(ar->szUid, szUid);
	ar->hash = (BYTE*)SAFE_MALLOC(hashlen);
	if (!ar->hash) { // alloc failed
		delete ar;
		return 0;
	}
	memcpy(ar->hash, hash, hashlen); // copy the data
	ar->hashlen = hashlen;
	ar->szFile = null_strdup(file); // duplicate the string
	m_arAvatars.insert(ar);
	alck.unlock();

	debugLogA("Avatars: Request to get %s image added to queue.", strUID(dwUin, pszUid));

	// make sure avatar connection is in progress
	requestAvatarConnection();
	return -1; // we added to queue
}
Beispiel #14
0
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;
}
Beispiel #15
0
// request avatar data from server
int CIcqProto::GetAvatarData(HANDLE hContact, DWORD dwUin, const char *szUid, const BYTE *hash, unsigned int hashlen, const TCHAR *file)
{
	uid_str szUidData;
	char *pszUid = NULL;
	if (!dwUin && szUid)
	{ // create a copy in local writable buffer
		strcpy(szUidData, szUid);
		pszUid = szUidData;
	}

	m_avatarsMutex->Enter();

	if (m_avatarsConnection && m_avatarsConnection->isReady()) // check if we are ready
	{	// check if requests for this user are not blocked
		DWORD dwNow = GetTickCount();
		avatars_request *ar = m_avatarsQueue;

		while (ar)
		{
			if (ar->hContact == hContact && ar->type == ART_BLOCK)
			{ // found a block item
				if (GetTickCount() > ar->timeOut)
				{ // remove timeouted block
					ar = ReleaseAvatarRequestInQueue(ar);
					continue;
				}
				m_avatarsMutex->Leave();
				debugLogA("Avatars: Requests for %s avatar are blocked.", strUID(dwUin, pszUid));
				return 0;
			}
			ar = ar->pNext;
		}

		avatars_server_connection *pConnection = m_avatarsConnection;

		pConnection->_Lock();
		m_avatarsMutex->Leave();

		DWORD dwCookie = pConnection->sendGetAvatarRequest(hContact, dwUin, pszUid, hash, hashlen, file);

		m_avatarsMutex->Enter();
		pConnection->_Release();

		if (dwCookie)
		{ // return now if the request was sent successfully
			m_avatarsMutex->Leave();
			return dwCookie;
		}
	}
	// we failed to send request, or avatar thread not ready

	// check if any request for this user is not already in the queue
	avatars_request *ar = m_avatarsQueue;

	while (ar)
	{
		if (ar->hContact == hContact)
		{ // we found it, return error
			if (ar->type == ART_BLOCK && GetTickCount() > ar->timeOut)
			{ // remove timeouted block
				ar = ReleaseAvatarRequestInQueue(ar);
				continue;
			}
			m_avatarsMutex->Leave();
			debugLogA("Avatars: Ignoring duplicate get %s avatar request.", strUID(dwUin, pszUid));

			// make sure avatar connection is in progress
			requestAvatarConnection();
			return 0;
		}
		ar = ar->pNext;
	}
	// add request to queue, processed after successful login
	ar = new avatars_request(ART_GET); // get avatar
	if (!ar)
	{ // out of memory, go away
		m_avatarsMutex->Leave();
		return 0;
	}
	ar->hContact = hContact;
	ar->dwUin = dwUin;
	if (!dwUin)
		strcpy(ar->szUid, szUid);
	ar->hash = (BYTE*)SAFE_MALLOC(hashlen);
	if (!ar->hash)
	{ // alloc failed
		m_avatarsMutex->Leave();
		delete ar;
		return 0;
	}
	memcpy(ar->hash, hash, hashlen); // copy the data
	ar->hashlen = hashlen;
	ar->szFile = null_strdup(file); // duplicate the string
	ar->pNext = m_avatarsQueue;
	m_avatarsQueue = ar;
	m_avatarsMutex->Leave();

	debugLogA("Avatars: Request to get %s image added to queue.", strUID(dwUin, pszUid));

	// make sure avatar connection is in progress
	requestAvatarConnection();

	return -1; // we added to queue
}