From ce3ab93c2c61a22ac4cd38c05ea9e71e4f9695ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sat, 9 Feb 2013 09:49:40 +0000 Subject: ICQ: Added patch from ryo-oh-ki: 1. Compatibility fix for third-party local ICQ servers - ICQ Groupware and IserverD. Added new option in Network -> ICQ -> Account -> "[X] Legacy fix", it's off by default (wont connect to old ICQ servers). 2. Compatibility fix for old non-unicode ICQ clients (crashes on file transfer). 3. Fixed double-freed memory in oscar_filetransfer.cpp (crashes after file transfer). git-svn-id: http://svn.miranda-ng.org/main/trunk@3499 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/IcqOscarJ/res/resources.rc | 18 ++-- protocols/IcqOscarJ/src/directpackets.cpp | 15 ++- protocols/IcqOscarJ/src/fam_02location.cpp | 3 +- protocols/IcqOscarJ/src/fam_15icqserver.cpp | 12 +++ protocols/IcqOscarJ/src/fam_17signon.cpp | 5 +- protocols/IcqOscarJ/src/icq_constants.h | 1 + protocols/IcqOscarJ/src/icq_filetransfer.cpp | 4 +- protocols/IcqOscarJ/src/icq_opts.cpp | 2 + protocols/IcqOscarJ/src/icq_proto.h | 1 + protocols/IcqOscarJ/src/icq_rates.cpp | 2 +- protocols/IcqOscarJ/src/init.cpp | 1 + protocols/IcqOscarJ/src/oscar_filetransfer.cpp | 7 +- protocols/IcqOscarJ/src/resource.h | 1 + protocols/IcqOscarJ/src/stdpackets.cpp | 124 +++++++++++++++++++++---- 14 files changed, 156 insertions(+), 40 deletions(-) diff --git a/protocols/IcqOscarJ/res/resources.rc b/protocols/IcqOscarJ/res/resources.rc index d1dc830ab1..7b930b049f 100644 --- a/protocols/IcqOscarJ/res/resources.rc +++ b/protocols/IcqOscarJ/res/resources.rc @@ -93,15 +93,17 @@ BEGIN LTEXT "Port:",IDC_STATIC,182,108,25,8 EDITTEXT IDC_ICQPORT,208,106,29,12,ES_AUTOHSCROLL PUSHBUTTON "Default",IDC_RESETSERVER,244,106,50,12 - LTEXT "Hint: Use port 0 to connect on a random port. Try port 80 or port 443 if you are having problems connecting through a http proxy server.",IDC_STATIC,12,123,286,19 - CONTROL "Secure Connection (SSL)",IDC_SSL,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,143,286,10 - CONTROL "Secure (MD5) login",IDC_MD5LOGIN,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,154,286,10 + LTEXT "Hint: Use port 0 to connect on a random port. Try port 80 or port 443 if you are having problems connecting through a http proxy server.",IDC_STATIC,12,120,286,18 + CONTROL "Secure Connection (SSL)",IDC_SSL,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,138,290,10 + CONTROL "Secure (MD5) login",IDC_MD5LOGIN,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,150,290,10 + CONTROL "Legacy fix (for ICQ Groupware or IServerD only)",IDC_LEGACY, + "Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,162,290,10 CONTROL "Send 'Keep-alives' (enable this if you use a proxy server and frequently get disconnected)",IDC_KEEPALIVE, - "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,12,166,286,18 - CONTROL "Ignore concurrent error messages",IDC_NOERRMULTI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,190,286,10 - LTEXT "Show connection error messages:",IDC_STATIC,12,204,238,8 - CONTROL "Slider1",IDC_LOGLEVEL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,18,214,52,10 - LTEXT "",IDC_LEVELDESCR,72,214,226,8,SS_NOPREFIX + "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,12,174,290,18 + CONTROL "Ignore concurrent error messages",IDC_NOERRMULTI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,192,290,10 + LTEXT "Show connection error messages:",IDC_STATIC,12,204,290,8 + CONTROL "Slider1",IDC_LOGLEVEL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,12,216,58,10 + LTEXT "",IDC_LEVELDESCR,72,216,230,10,SS_NOPREFIX END IDD_OPT_ICQCONTACTS DIALOGEX 0, 0, 310, 234 diff --git a/protocols/IcqOscarJ/src/directpackets.cpp b/protocols/IcqOscarJ/src/directpackets.cpp index 594f005675..fa21a949d5 100644 --- a/protocols/IcqOscarJ/src/directpackets.cpp +++ b/protocols/IcqOscarJ/src/directpackets.cpp @@ -151,9 +151,8 @@ void CIcqProto::icq_sendFileDenyDirect(HANDLE hContact, filetransfer *ft, const char *szReasonAnsi = NULL; int cbReasonAnsi = 0; - if (!utf8_decode(szReason, &szReasonAnsi)) - szReasonAnsi = NULL; - else + if (!utf8_decode(szReason, &szReasonAnsi)) + szReasonAnsi = _strdup(szReason); // Legacy fix cbReasonAnsi = strlennull(szReasonAnsi); packDirectMsgHeader(&packet, (WORD)(18 + cbReasonAnsi), DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 1, 0); @@ -181,9 +180,8 @@ int CIcqProto::icq_sendFileSendDirectv7(filetransfer *ft, const char *pszFiles) char *szFilesAnsi = NULL; WORD wDescrLen = strlennull(ft->szDescription), wFilesLen = 0; - if (!utf8_decode(pszFiles, &szFilesAnsi)) - szFilesAnsi = NULL; - else + if (!utf8_decode(pszFiles, &szFilesAnsi)) + szFilesAnsi = _strdup(pszFiles); // Legacy fix wFilesLen = strlennull(szFilesAnsi); packDirectMsgHeader(&packet, (WORD)(18 + wDescrLen + wFilesLen), DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0); @@ -209,9 +207,8 @@ int CIcqProto::icq_sendFileSendDirectv8(filetransfer *ft, const char *pszFiles) char *szFilesAnsi = NULL; WORD wDescrLen = strlennull(ft->szDescription), wFilesLen = 0; - if (!utf8_decode(pszFiles, &szFilesAnsi)) - szFilesAnsi = NULL; - else + if (!utf8_decode(pszFiles, &szFilesAnsi)) + szFilesAnsi = _strdup(pszFiles); // Legacy fix wFilesLen = strlennull(szFilesAnsi); packDirectMsgHeader(&packet, (WORD)(0x2E + 22 + wDescrLen + wFilesLen + 1), DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_PLUGIN, 0, 0, 0); diff --git a/protocols/IcqOscarJ/src/fam_02location.cpp b/protocols/IcqOscarJ/src/fam_02location.cpp index a4b8601e78..9e1fdd2ad6 100644 --- a/protocols/IcqOscarJ/src/fam_02location.cpp +++ b/protocols/IcqOscarJ/src/fam_02location.cpp @@ -89,7 +89,8 @@ static char* AimApplyEncoding(char* pszStr, const char* pszEncoding) char *szRes = NULL; SAFE_FREE((void**)&pszStr); - utf8_decode(szStr, &szRes); + if (!utf8_decode(szStr, &szRes)) + szRes = _strdup(szStr); // Legacy fix SAFE_FREE((void**)&szStr); return szRes; diff --git a/protocols/IcqOscarJ/src/fam_15icqserver.cpp b/protocols/IcqOscarJ/src/fam_15icqserver.cpp index 3f332e4f27..60163c0e64 100644 --- a/protocols/IcqOscarJ/src/fam_15icqserver.cpp +++ b/protocols/IcqOscarJ/src/fam_15icqserver.cpp @@ -289,6 +289,18 @@ void CIcqProto::handleExtensionMetaResponse(BYTE *databuf, WORD wPacketLen, WORD NetLog_Server("Error: Directory request failed, code %u", bResultCode); break; + case META_BASIC_USERINFO: + case META_WORK_USERINFO: + case META_MORE_USERINFO: + case META_NOTES_USERINFO: + case META_EMAIL_USERINFO: + case META_INTERESTS_USERINFO: + case META_AFFILATIONS_USERINFO: + case META_SHORT_USERINFO: + case META_HPAGECAT_USERINFO: + NetLog_Server("Warning: Ignored 15/03 (legacy user info) replysubtype x%x", wReplySubtype); + break; + default: NetLog_Server("Warning: Ignored 15/03 replysubtype x%x", wReplySubtype); // _ASSERTE(0); diff --git a/protocols/IcqOscarJ/src/fam_17signon.cpp b/protocols/IcqOscarJ/src/fam_17signon.cpp index b35a432a48..dae5c38a0e 100644 --- a/protocols/IcqOscarJ/src/fam_17signon.cpp +++ b/protocols/IcqOscarJ/src/fam_17signon.cpp @@ -82,7 +82,7 @@ void CIcqProto::sendClientAuth(const char *szKey, WORD wKeyLen, BOOL bSecure) wUinLen = strlennull(strUID(m_dwLocalUIN, szUin)); - packet.wLen = 70 + sizeof(CLIENT_ID_STRING) + wUinLen + wKeyLen + (m_bSecureConnection ? 4 : 0); + packet.wLen = (m_bLegacyFix ? 65 : 70) + sizeof(CLIENT_ID_STRING) + wUinLen + wKeyLen + (m_bSecureConnection ? 4 : 0); if (bSecure) { @@ -119,7 +119,8 @@ void CIcqProto::sendClientAuth(const char *szKey, WORD wKeyLen, BOOL bSecure) packTLVDWord(&packet, 0x0014, CLIENT_DISTRIBUTION); packTLV(&packet, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE); packTLV(&packet, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY); - packTLV(&packet, 0x0094, 0x0001, &m_bConnectionLost); // CLIENT_RECONNECT flag + if (!m_bLegacyFix) + packTLV(&packet, 0x0094, 0x0001, &m_bConnectionLost); // CLIENT_RECONNECT flag if (m_bSecureConnection) packDWord(&packet, 0x008C0000); // empty TLV(0x8C): use SSL diff --git a/protocols/IcqOscarJ/src/icq_constants.h b/protocols/IcqOscarJ/src/icq_constants.h index 41460e029b..5321c170bb 100644 --- a/protocols/IcqOscarJ/src/icq_constants.h +++ b/protocols/IcqOscarJ/src/icq_constants.h @@ -63,6 +63,7 @@ #define DEFAULT_SECURE_LOGIN 1 #define DEFAULT_SECURE_CONNECTION 1 +#define DEFAULT_LEGACY_FIX 0 #define DEFAULT_KEEPALIVE_ENABLED 1 #define DEFAULT_AIM_ENABLED 1 #define DEFAULT_UTF_ENABLED 2 // everything unicode is default diff --git a/protocols/IcqOscarJ/src/icq_filetransfer.cpp b/protocols/IcqOscarJ/src/icq_filetransfer.cpp index 0c08e15f22..48a567b1d9 100644 --- a/protocols/IcqOscarJ/src/icq_filetransfer.cpp +++ b/protocols/IcqOscarJ/src/icq_filetransfer.cpp @@ -135,9 +135,9 @@ static void file_sendNextFile(CIcqProto* ppro, directconnect* dc) char *szThisFileNameAnsi = NULL, *szThisSubDirAnsi = NULL; if (!utf8_decode(pszThisFileName, &szThisFileNameAnsi)) - szThisFileNameAnsi = NULL; + szThisFileNameAnsi = _strdup(pszThisFileName); // Legacy fix if (!utf8_decode(szThisSubDir, &szThisSubDirAnsi)) - szThisSubDirAnsi = NULL; + szThisSubDirAnsi = _strdup(szThisSubDir); // Legacy fix WORD wThisFileNameLen = strlennull(szThisFileNameAnsi); WORD wThisSubDirLen = strlennull(szThisSubDirAnsi); diff --git a/protocols/IcqOscarJ/src/icq_opts.cpp b/protocols/IcqOscarJ/src/icq_opts.cpp index a4c7778507..e43d1dc719 100644 --- a/protocols/IcqOscarJ/src/icq_opts.cpp +++ b/protocols/IcqOscarJ/src/icq_opts.cpp @@ -89,6 +89,7 @@ static INT_PTR CALLBACK DlgProcIcqOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP 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)) @@ -185,6 +186,7 @@ static INT_PTR CALLBACK DlgProcIcqOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP 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->setSettingByte(NULL, "ShowLogLevel", (BYTE)(4-SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0))); diff --git a/protocols/IcqOscarJ/src/icq_proto.h b/protocols/IcqOscarJ/src/icq_proto.h index 28a005dfe6..4d25bdb95b 100644 --- a/protocols/IcqOscarJ/src/icq_proto.h +++ b/protocols/IcqOscarJ/src/icq_proto.h @@ -159,6 +159,7 @@ struct CIcqProto : public PROTO_INTERFACE, public MZeroedObject BYTE m_bGatewayMode; BYTE m_bSecureLogin; BYTE m_bSecureConnection; + BYTE m_bLegacyFix; BYTE m_bAimEnabled; BYTE m_bUtfEnabled; WORD m_wAnsiCodepage; diff --git a/protocols/IcqOscarJ/src/icq_rates.cpp b/protocols/IcqOscarJ/src/icq_rates.cpp index e7513ec148..cfe8a9508f 100644 --- a/protocols/IcqOscarJ/src/icq_rates.cpp +++ b/protocols/IcqOscarJ/src/icq_rates.cpp @@ -129,7 +129,7 @@ WORD rates::getGroupFromSNAC(WORD wFamily, WORD wCommand) } } } - _ASSERTE(0); + // Legacy ICQ server } return 0; // Failure diff --git a/protocols/IcqOscarJ/src/init.cpp b/protocols/IcqOscarJ/src/init.cpp index 5271be4849..2489646844 100644 --- a/protocols/IcqOscarJ/src/init.cpp +++ b/protocols/IcqOscarJ/src/init.cpp @@ -188,6 +188,7 @@ void CIcqProto::UpdateGlobalSettings() } m_bSecureLogin = getSettingByte(NULL, "SecureLogin", DEFAULT_SECURE_LOGIN); + m_bLegacyFix = getSettingByte(NULL, "LegacyFix", DEFAULT_LEGACY_FIX); m_bAimEnabled = getSettingByte(NULL, "AimEnabled", DEFAULT_AIM_ENABLED); m_bUtfEnabled = getSettingByte(NULL, "UtfEnabled", DEFAULT_UTF_ENABLED); m_wAnsiCodepage = getSettingWord(NULL, "AnsiCodePage", DEFAULT_ANSI_CODEPAGE); diff --git a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp b/protocols/IcqOscarJ/src/oscar_filetransfer.cpp index d6723ded10..1352f6918f 100644 --- a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp +++ b/protocols/IcqOscarJ/src/oscar_filetransfer.cpp @@ -210,14 +210,19 @@ void CIcqProto::SafeReleaseFileTransfer(void **ft) SAFE_FREE(&ift->szFilename); SAFE_FREE(&ift->szDescription); SAFE_FREE(&ift->szSavePath); - SAFE_FREE(&ift->szThisFile); SAFE_FREE(&ift->szThisSubdir); if (ift->pszFiles) { for (int i = 0; i < (int)ift->dwFileCount; i++) + { + // szThisFile can be a duplicate of pszFiles[i] + if (ift->szThisFile == ift->pszFiles[i]) + ift->szThisFile = NULL; SAFE_FREE(&ift->pszFiles[i]); + } SAFE_FREE((void**)&ift->pszFiles); } + SAFE_FREE(&ift->szThisFile); // Invalidate transfer ReleaseFileTransfer(ift); #ifdef _DEBUG diff --git a/protocols/IcqOscarJ/src/resource.h b/protocols/IcqOscarJ/src/resource.h index 1dbd905dde..9e373e27c9 100644 --- a/protocols/IcqOscarJ/src/resource.h +++ b/protocols/IcqOscarJ/src/resource.h @@ -53,6 +53,7 @@ #define IDC_MD5LOGIN 1009 #define IDC_UTFENABLE 1010 #define IDC_XTITLE 1010 +#define IDC_LEGACY 1010 #define IDC_KEEPALIVE 1011 #define IDC_XMSG 1011 #define IDC_UTFALL 1012 diff --git a/protocols/IcqOscarJ/src/stdpackets.cpp b/protocols/IcqOscarJ/src/stdpackets.cpp index b08c152cb5..1eb1e696a3 100644 --- a/protocols/IcqOscarJ/src/stdpackets.cpp +++ b/protocols/IcqOscarJ/src/stdpackets.cpp @@ -570,6 +570,22 @@ DWORD CIcqProto::icq_sendGetInfoServ(HANDLE hContact, DWORD dwUin, int bManual) } cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data)); + + if (m_bLegacyFix) + { + pCookieData->bRequestType = REQUESTTYPE_USERDETAILED; + + dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, 0, hContact, (void*)pCookieData); + + packServIcqExtensionHeader(&packet, this, 6, CLI_META_INFO_REQ, (WORD)dwCookie); + packLEWord(&packet, META_REQUEST_FULL_INFO); + packLEDWord(&packet, dwUin); + + sendServPacket(&packet); + + return dwCookie; + } + pCookieData->bRequestType = DIRECTORYREQUEST_INFOUSER; dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, hContact, (void*)pCookieData); @@ -745,14 +761,13 @@ void CIcqProto::icq_sendFileSendServv7(filetransfer* ft, const char *szFiles) char *szFilesAnsi = NULL, *szDescrAnsi = NULL; if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = NULL; - else - wFilesLen = strlennull(szFilesAnsi); + szFilesAnsi = _strdup(szFiles); // Legacy fix if (!utf8_decode(ft->szDescription, &szDescrAnsi)) - szDescrAnsi = NULL; - else - wDescrLen = strlennull(szDescrAnsi); + szDescrAnsi = _strdup(ft->szDescription); // Legacy fix + + wFilesLen = strlennull(szFilesAnsi); + wDescrLen = strlennull(szDescrAnsi); packServChannel2Header(&packet, this, ft->dwUin, (WORD)(18 + wDescrLen + wFilesLen), ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ICQ_VERSION, MTYPE_FILEREQ, 0, 1, 0, 1, 1); @@ -778,14 +793,13 @@ void CIcqProto::icq_sendFileSendServv8(filetransfer* ft, const char *szFiles, in char *szFilesAnsi = NULL, *szDescrAnsi = NULL; if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = NULL; - else - wFilesLen = strlennull(szFilesAnsi); + szFilesAnsi = _strdup(szFiles); // Legacy fix if (!utf8_decode(ft->szDescription, &szDescrAnsi)) - szDescrAnsi = NULL; - else - wDescrLen = strlennull(szDescrAnsi); + szDescrAnsi = _strdup(ft->szDescription); // Legacy fix + + wFilesLen = strlennull(szFilesAnsi); + wDescrLen = strlennull(szDescrAnsi); // 202 + UIN len + file description (no null) + file name (null included) // Packet size = Flap length + 4 @@ -839,10 +853,10 @@ void CIcqProto::icq_sendFileAcceptServv8(DWORD dwUin, DWORD TS1, DWORD TS2, DWOR if (!accepted) szFiles = ""; if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = NULL; + szFilesAnsi = _strdup(szFiles); // Legacy fix if (!utf8_decode(szDescr, &szDescrAnsi)) - szDescrAnsi = NULL; + szDescrAnsi = _strdup(szDescr); // Legacy fix wDescrLen = strlennull(szDescrAnsi); wFilesLen = strlennull(szFilesAnsi); @@ -900,10 +914,10 @@ void CIcqProto::icq_sendFileAcceptServv7(DWORD dwUin, DWORD TS1, DWORD TS2, DWOR if (!accepted) szFiles = ""; if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = NULL; + szFilesAnsi = _strdup(szFiles); // Legacy fix if (!utf8_decode(szDescr, &szDescrAnsi)) - szDescrAnsi = NULL; + szDescrAnsi = _strdup(szDescr); // Legacy fix wDescrLen = strlennull(szDescrAnsi); wFilesLen = strlennull(szFilesAnsi); @@ -1120,6 +1134,24 @@ DWORD CIcqProto::SearchByUin(DWORD dwUin) WORD wInfoLen; icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer // I should be ashamed! ;) + if (m_bLegacyFix) + { + // Calculate data size + wInfoLen = 8; + + // Initialize our handy data buffer + pBuffer.wPlace = 0; + pBuffer.pData = (BYTE *)_alloca(wInfoLen); + pBuffer.wLen = wInfoLen; + + // Initialize our handy data buffer + packLEWord(&pBuffer, TLV_UIN); + packLEWord(&pBuffer, 0x0004); + packLEDWord(&pBuffer, dwUin); + + // Send it off for further packing + return sendTLVSearchPacket(SEARCHTYPE_UID, (char*)pBuffer.pData, META_SEARCH_UIN, wInfoLen, FALSE); + } // Calculate data size wInfoLen = 4 + getUINLen(dwUin); @@ -1143,6 +1175,66 @@ DWORD CIcqProto::SearchByNames(const char *pszNick, const char *pszFirstName, co WORD wNickLen,wFirstLen,wLastLen; icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer // I should be ashamed! ;) + if (m_bLegacyFix) + { + // Legacy protocol uses ANSI-string searches + + char* pszNickAnsi = NULL; + if (!utf8_decode(pszNick, &pszNickAnsi)) + pszNickAnsi = _strdup(pszNick); + + char* pszFirstNameAnsi = NULL; + if (!utf8_decode(pszFirstName, &pszFirstNameAnsi)) + pszFirstNameAnsi = _strdup(pszFirstName); + + char* pszLastNameAnsi = NULL; + if (!utf8_decode(pszLastName, &pszLastNameAnsi)) + pszLastNameAnsi = _strdup(pszLastName); + + wNickLen = strlennull(pszNickAnsi); + wFirstLen = strlennull(pszFirstNameAnsi); + wLastLen = strlennull(pszLastNameAnsi); + + _ASSERTE(wFirstLen || wLastLen || wNickLen); + + // Calculate data size + if (wFirstLen > 0) + wInfoLen = wFirstLen + 7; + if (wLastLen > 0) + wInfoLen += wLastLen + 7; + if (wNickLen > 0) + wInfoLen += wNickLen + 7; + + // Initialize our handy data buffer + pBuffer.wPlace = 0; + pBuffer.pData = (BYTE *)_alloca(wInfoLen); + pBuffer.wLen = wInfoLen; + + int pBufferPos = 0; + + // Pack the search details + if (wFirstLen > 0) + { + packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszFirstNameAnsi, TLV_FIRSTNAME); + } + + if (wLastLen > 0) + { + packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszLastNameAnsi, TLV_LASTNAME); + } + + if (wNickLen > 0) + { + packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszNickAnsi, TLV_NICKNAME); + } + + SAFE_FREE(&pszFirstNameAnsi); + SAFE_FREE(&pszLastNameAnsi); + SAFE_FREE(&pszNickAnsi); + + // Send it off for further packing + return sendTLVSearchPacket(SEARCHTYPE_NAMES, (char*)pBuffer.pData, META_SEARCH_GENERIC, wInfoLen, FALSE); + } wNickLen = strlennull(pszNick); wFirstLen = strlennull(pszFirstName); -- cgit v1.2.3