diff options
| author | George Hazan <george.hazan@gmail.com> | 2025-05-28 16:09:12 +0300 |
|---|---|---|
| committer | George Hazan <george.hazan@gmail.com> | 2025-05-28 16:09:12 +0300 |
| commit | 3ddd3cd6ae9875ace960d3d959c4ed2a22f71bff (patch) | |
| tree | 73c88cebac3f297ad60a5efe7be5759e3055b498 | |
| parent | e03a74ebbe45017423275277ceac380fdfc44919 (diff) | |
Teams: fix for receiving cookies for /mt/api
| -rw-r--r-- | protocols/Teams/src/requests/chatrooms.h | 26 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_avatars.cpp | 40 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_chatrooms.cpp | 31 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_endpoint.cpp | 6 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_http.cpp | 7 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_proto.h | 155 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_server.cpp | 13 | ||||
| -rw-r--r-- | protocols/Teams/src/teams_utils.cpp | 9 |
8 files changed, 137 insertions, 150 deletions
diff --git a/protocols/Teams/src/requests/chatrooms.h b/protocols/Teams/src/requests/chatrooms.h index d94f66a13a..e691b533f1 100644 --- a/protocols/Teams/src/requests/chatrooms.h +++ b/protocols/Teams/src/requests/chatrooms.h @@ -37,32 +37,6 @@ struct CreateChatroomRequest : public AsyncHttpRequest } }; -struct GetChatMembersRequest : public AsyncHttpRequest -{ - GetChatMembersRequest(const LIST<char> &ids, SESSION_INFO *si) : - AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, "/profiles", &CTeamsProto::OnGetChatMembers) - { - JSONNode node, mris(JSON_ARRAY); mris.set_name("mris"); - for (auto &it : ids) - mris.push_back(JSONNode("", it)); - node << mris << CHAR_PARAM("locale", "en-US"); - m_szParam = node.write().c_str(); - - pUserInfo = si; - } -}; - -struct GetChatInfoRequest : public AsyncHttpRequest -{ - GetChatInfoRequest(const wchar_t *chatId) : - AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, 0, &CTeamsProto::OnGetChatInfo) - { - m_szUrl.AppendFormat("/threads/%S", chatId); - - this << CHAR_PARAM("view", "msnp24Equivalent"); - } -}; - struct InviteUserToChatRequest : public AsyncHttpRequest { InviteUserToChatRequest(const char *chatId, const char *skypename, const char *role) : diff --git a/protocols/Teams/src/teams_avatars.cpp b/protocols/Teams/src/teams_avatars.cpp index 533aa62d08..a535cab005 100644 --- a/protocols/Teams/src/teams_avatars.cpp +++ b/protocols/Teams/src/teams_avatars.cpp @@ -125,22 +125,12 @@ INT_PTR CTeamsProto::SvcGetMyAvatar(WPARAM wParam, LPARAM lParam) ///////////////////////////////////////////////////////////////////////////////////////// // Avatars' receiving -struct GetAvatarRequest : public AsyncHttpRequest -{ - GetAvatarRequest(const char *url, MCONTACT hContact) : - AsyncHttpRequest(REQUEST_GET, HOST_OTHER, url, &CTeamsProto::OnReceiveAvatar) - { - flags |= NLHRF_REDIRECT; - pUserInfo = (void *)hContact; - } -}; - void CTeamsProto::OnReceiveAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest) { if (response == nullptr || response->body.IsEmpty()) return; - MCONTACT hContact = (DWORD_PTR)pRequest->pUserInfo; + MCONTACT hContact = pRequest->hContact; if (response->resultCode != 200) return; @@ -167,7 +157,11 @@ bool CTeamsProto::ReceiveAvatar(MCONTACT hContact) if (!mir_strlen(szUrl)) return false; - PushRequest(new GetAvatarRequest(szUrl, hContact)); + auto *pReq = new AsyncHttpRequest(REQUEST_GET, HOST_OTHER, szUrl, &CTeamsProto::OnReceiveAvatar); + pReq->hContact = hContact; + pReq->flags |= NLHRF_REDIRECT; + PushRequest(pReq); + debugLogA("Requested to read an avatar from '%s'", szUrl.get()); return true; } @@ -175,20 +169,6 @@ bool CTeamsProto::ReceiveAvatar(MCONTACT hContact) ///////////////////////////////////////////////////////////////////////////////////////// // Setting my own avatar -struct SetAvatarRequest : public AsyncHttpRequest -{ - SetAvatarRequest(const uint8_t *data, int dataSize, const char *szMime, CTeamsProto *ppro) : - AsyncHttpRequest(REQUEST_PUT, HOST_API, 0, &CTeamsProto::OnSentAvatar) - { - m_szUrl.AppendFormat("/users/%s/profile/avatar", ppro->m_szSkypename.MakeLower().c_str()); - - AddHeader("Content-Type", szMime); - - m_szParam.Truncate(dataSize); - memcpy(m_szParam.GetBuffer(), data, dataSize); - } -}; - void CTeamsProto::OnSentAvatar(MHttpResponse *response, AsyncHttpRequest*) { TeamsReply root(response); @@ -215,7 +195,13 @@ INT_PTR CTeamsProto::SvcSetMyAvatar(WPARAM, LPARAM lParam) if (data != NULL && fread(data, sizeof(uint8_t), length, hFile) == length) { const char *szMime = FreeImage_GetFIFMimeType(FreeImage_GetFIFFromFilenameU(path)); - PushRequest(new SetAvatarRequest(data, (int)length, szMime, this)); + auto *pReq = new AsyncHttpRequest(REQUEST_PUT, HOST_API, 0, &CTeamsProto::OnSentAvatar); + pReq->m_szUrl.AppendFormat("/users/%s/profile/avatar", m_szSkypename.MakeLower().c_str()); + pReq->AddHeader("Content-Type", szMime); + pReq->m_szParam.Truncate((int)length); + memcpy(pReq->m_szParam.GetBuffer(), data, (int)length); + PushRequest(pReq); + fclose(hFile); return 0; } diff --git a/protocols/Teams/src/teams_chatrooms.cpp b/protocols/Teams/src/teams_chatrooms.cpp index 436a3a196b..3f8593c5e0 100644 --- a/protocols/Teams/src/teams_chatrooms.cpp +++ b/protocols/Teams/src/teams_chatrooms.cpp @@ -52,7 +52,7 @@ SESSION_INFO* CTeamsProto::StartChatRoom(const wchar_t *tid, const wchar_t *tnam Chat_AddGroup(si, TranslateT("Admin")); Chat_AddGroup(si, TranslateT("User")); - PushRequest(new GetChatInfoRequest(tid)); + GetChatInfo(tid); } // Finish initialization @@ -252,7 +252,7 @@ bool CTeamsProto::OnChatEvent(const JSONNode &node) if (!AddChatContact(si, Utf2T(pszTarget), L"User")) { OBJLIST<char> arIds(1); arIds.insert(newStr(pszTarget)); - PushRequest(new GetChatMembersRequest(arIds, si)); + GetChatMembers(arIds, si); } } } @@ -352,6 +352,20 @@ void CTeamsProto::SendChatMessage(SESSION_INFO *si, const wchar_t *tszMessage) ///////////////////////////////////////////////////////////////////////////////////////// +void CTeamsProto::GetChatMembers(const LIST<char> &ids, SESSION_INFO *si) +{ + auto *pReq = new AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, "/profiles", &CTeamsProto::OnGetChatMembers); + + JSONNode node, mris(JSON_ARRAY); mris.set_name("mris"); + for (auto &it : ids) + mris.push_back(JSONNode("", it)); + node << mris << CHAR_PARAM("locale", "en-US"); + pReq->m_szParam = node.write().c_str(); + + pReq->pUserInfo = si; + PushRequest(pReq); +}; + void CTeamsProto::OnGetChatMembers(MHttpResponse *response, AsyncHttpRequest *pRequest) { TeamsReply reply(response); @@ -374,6 +388,8 @@ void CTeamsProto::OnGetChatMembers(MHttpResponse *response, AsyncHttpRequest *pR g_chatApi.OnChangeNick(si); } +///////////////////////////////////////////////////////////////////////////////////////// + void CTeamsProto::OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest*) { TeamsReply reply(response); @@ -401,11 +417,20 @@ void CTeamsProto::OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest*) } if (arIds.getCount()) - PushRequest(new GetChatMembersRequest(arIds, si)); + GetChatMembers(arIds, si); GetServerHistory(si->hContact, 100, 0, true); } +void CTeamsProto::GetChatInfo(const wchar_t *chatId) +{ + auto *pReq = new AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, 0, &CTeamsProto::OnGetChatInfo); + pReq->m_szUrl.AppendFormat("/threads/%S", chatId); + pReq << CHAR_PARAM("view", "msnp24Equivalent"); + PushRequest(pReq); +} + + wchar_t* CTeamsProto::GetChatContactNick(SESSION_INFO *si, const wchar_t *id, const wchar_t *name, bool *isQualified) { if (isQualified) diff --git a/protocols/Teams/src/teams_endpoint.cpp b/protocols/Teams/src/teams_endpoint.cpp index 18ae90d816..b84494f8bd 100644 --- a/protocols/Teams/src/teams_endpoint.cpp +++ b/protocols/Teams/src/teams_endpoint.cpp @@ -79,9 +79,3 @@ void CTeamsProto::OnEndpointCreated(MHttpResponse *response, AsyncHttpRequest*) LoggedIn(); } - -void CTeamsProto::OnEndpointDeleted(MHttpResponse *, AsyncHttpRequest *) -{ - m_szEndpoint.Empty(); - m_szRegToken.Empty(); -} diff --git a/protocols/Teams/src/teams_http.cpp b/protocols/Teams/src/teams_http.cpp index 50b73d6750..66562ab2a0 100644 --- a/protocols/Teams/src/teams_http.cpp +++ b/protocols/Teams/src/teams_http.cpp @@ -126,8 +126,13 @@ MHttpResponse* CTeamsProto::DoSend(AsyncHttpRequest *pReq) pReq->AddHeader("ms-ic3-additional-product", "Sfl"); break; - case HOST_TEAMS: case HOST_TEAMS_API: + pReq->AddHeader("X-MS-Client-Type", "maglev"); + pReq->AddHeader("referer", "https://teams.live.com/v2/"); + pReq->AddHeader("Cookie", mir_urlEncode(m_szApiCookie)); + __fallthrough; + + case HOST_TEAMS: if (!pReq->FindHeader("Authorization")) pReq->AddHeader("Authorization", "Bearer " + m_szAccessToken); if (m_szSkypeToken) diff --git a/protocols/Teams/src/teams_proto.h b/protocols/Teams/src/teams_proto.h index 3cbf00003a..2b6ad246d8 100644 --- a/protocols/Teams/src/teams_proto.h +++ b/protocols/Teams/src/teams_proto.h @@ -70,47 +70,6 @@ class CTeamsProto : public PROTO<CTeamsProto> } } m_impl; - // http queue - bool m_isTerminated = true; - mir_cs m_requestQueueLock; - LIST<AsyncHttpRequest> m_requests; - MEventHandle m_hRequestQueueEvent; - HANDLE m_hRequestQueueThread; - CMStringA m_szAccessToken, m_szSubstrateToken; - - void __cdecl WorkerThread(void *); - - void StartQueue(); - void StopQueue(); - - MHttpResponse* DoSend(AsyncHttpRequest *request); - - void Execute(AsyncHttpRequest *request); - void PushRequest(AsyncHttpRequest *request); - - // login - CMStringW m_wszUserCode; - CMStringA m_szDeviceCode, m_szDeviceCookie, m_szVerificationUrl; - time_t m_iLoginExpires; - - void Login(); - void LoggedIn(); - void LoginPoll(); - void LoginError(); - - void SendCreateEndpoint(); - void SendPresence(); - - void OauthRefreshServices(); - void RefreshToken(const char *pszScope, AsyncHttpRequest::MTHttpRequestHandler pFunc); - - void OnReceiveSkypeToken(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnReceiveDevicePoll(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnReceiveDeviceToken(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnRefreshAccessToken(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnRefreshSkypeToken(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnRefreshSubstrate(MHttpResponse *response, AsyncHttpRequest *pRequest); - public: // constructor CTeamsProto(const char *protoName, const wchar_t *userName); @@ -172,44 +131,13 @@ public: int m_iPollingId, m_iMessageId = 1; ptrA m_szOwnSkypeId; - CMStringA m_szSkypename, m_szMyname, m_szRegToken, m_szSkypeToken, m_szEndpoint; + CMStringA m_szSkypename, m_szMyname, m_szRegToken, m_szSkypeToken, m_szEndpoint, m_szApiCookie; MCONTACT m_hMyContact; __forceinline CMStringA getId(MCONTACT hContact) { return getMStringA(hContact, DBKEY_ID); } - void OnSearch(MHttpResponse *response, AsyncHttpRequest *pRequest); - - // login - - void OnCapabilitiesSended(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnStatusChanged(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnEndpointCreated(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnEndpointDeleted(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnASMObjectCreated(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void LoadContactsAuth(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnGotContactsInfo(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnBlockContact(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnUnblockContact(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnReceiveAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnSentAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnGetChatMembers(MHttpResponse *response, AsyncHttpRequest *pRequest); - - void OnGetProfileInfo(MHttpResponse *response, AsyncHttpRequest *pRequest); - - static INT_PTR __cdecl GlobalParseSkypeUriService(WPARAM, LPARAM lParam); - private: bool m_bHistorySynced; @@ -218,14 +146,19 @@ private: LIST<void> m_PopupClasses; // avatars - void SetAvatarUrl(MCONTACT hContact, const CMStringW &tszUrl); bool ReceiveAvatar(MCONTACT hContact); + void OnReceiveAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest); + + void SetAvatarUrl(MCONTACT hContact, const CMStringW &tszUrl); + void ReloadAvatarInfo(MCONTACT hContact); void GetAvatarFileName(MCONTACT hContact, wchar_t *pszDest, size_t cbLen); INT_PTR __cdecl SvcGetAvatarInfo(WPARAM, LPARAM); INT_PTR __cdecl SvcGetAvatarCaps(WPARAM, LPARAM); INT_PTR __cdecl SvcGetMyAvatar(WPARAM, LPARAM); + + void OnSentAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest); INT_PTR __cdecl SvcSetMyAvatar(WPARAM, LPARAM); // chats @@ -236,6 +169,12 @@ private: INT_PTR __cdecl OnJoinChatRoom(WPARAM hContact, LPARAM); INT_PTR __cdecl OnLeaveChatRoom(WPARAM hContact, LPARAM); + void OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest *pRequest); + void GetChatInfo(const wchar_t *chatId); + + void OnGetChatMembers(MHttpResponse *response, AsyncHttpRequest *pRequest); + void GetChatMembers(const LIST<char> &ids, SESSION_INFO *si); + SESSION_INFO *StartChatRoom(const wchar_t *tid, const wchar_t *tname, const char *pszVersion = nullptr); bool OnChatEvent(const JSONNode &node); @@ -252,6 +191,9 @@ private: bool ParseMessage(const JSONNode &node, DB::EventInfo &dbei); // contacts + void LoadContactsAuth(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnGotContactsInfo(MHttpResponse *response, AsyncHttpRequest *pRequest); + void GetShortInfo(const OBJLIST<char> &ids); void RefreshContactsInfo(); void SetContactStatus(MCONTACT hContact, uint16_t status); @@ -263,8 +205,16 @@ private: MCONTACT GetContactFromAuthEvent(MEVENT hEvent); + INT_PTR __cdecl BlockContact(WPARAM hContact, LPARAM); + void OnBlockContact(MHttpResponse *response, AsyncHttpRequest *pRequest); + + INT_PTR __cdecl UnblockContact(WPARAM hContact, LPARAM); + void OnUnblockContact(MHttpResponse *response, AsyncHttpRequest *pRequest); + // files void SendFile(CFileUploadParam *fup); + void OnASMObjectCreated(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest *pRequest); void __cdecl ReceiveFileThread(void *param); @@ -278,6 +228,51 @@ private: void OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest *pRequest); void OnSyncConversations(MHttpResponse *response, AsyncHttpRequest *pRequest); + // http queue + bool m_isTerminated = true; + mir_cs m_requestQueueLock; + LIST<AsyncHttpRequest> m_requests; + MEventHandle m_hRequestQueueEvent; + HANDLE m_hRequestQueueThread; + CMStringA m_szAccessToken, m_szSubstrateToken; + + void __cdecl WorkerThread(void *); + + void StartQueue(); + void StopQueue(); + + MHttpResponse *DoSend(AsyncHttpRequest *request); + + void Execute(AsyncHttpRequest *request); + void PushRequest(AsyncHttpRequest *request); + + // login + CMStringW m_wszUserCode; + CMStringA m_szDeviceCode, m_szDeviceCookie, m_szVerificationUrl; + time_t m_iLoginExpires; + + void Login(); + void LoggedIn(); + void LoginPoll(); + void LoginError(); + + void OnEndpointCreated(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnReceiveApiCookie(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnCapabilitiesSended(MHttpResponse *response, AsyncHttpRequest *pRequest); + + void SendCreateEndpoint(); + void SendPresence(); + + void OauthRefreshServices(); + void RefreshToken(const char *pszScope, AsyncHttpRequest::MTHttpRequestHandler pFunc); + + void OnReceiveSkypeToken(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnReceiveDevicePoll(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnReceiveDeviceToken(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnRefreshAccessToken(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnRefreshSkypeToken(MHttpResponse *response, AsyncHttpRequest *pRequest); + void OnRefreshSubstrate(MHttpResponse *response, AsyncHttpRequest *pRequest); + // menus static HGENMENU ContactMenuItems[CMI_MAX]; int OnPrebuildContactMenu(WPARAM hContact, LPARAM); @@ -287,6 +282,7 @@ private: mir_cs m_lckOutMessagesList; LIST<COwnMessage> m_OutMessages; + void OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequest); int SendServerMsg(MCONTACT hContact, const char *szMessage, int64_t iMessageId = 0); int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam); @@ -298,6 +294,9 @@ private: int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam); // profile + void OnGetProfileInfo(MHttpResponse *response, AsyncHttpRequest *pRequest); + void GetProfileInfo(MCONTACT hContact); + void UpdateProfileDisplayName(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileGender(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileBirthday(const JSONNode &root, MCONTACT hContact = NULL); @@ -305,9 +304,11 @@ private: void UpdateProfileEmails(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileAvatar(const JSONNode &root, MCONTACT hContact = NULL); - // server requests - void GetProfileInfo(MCONTACT hContact); + // search + void OnSearch(MHttpResponse *response, AsyncHttpRequest *pRequest); + // server requests + void OnStatusChanged(MHttpResponse *response, AsyncHttpRequest *pRequest); void SetServerStatus(int iStatus); void CreateContactSubscription(); @@ -336,8 +337,6 @@ private: CMStringW ChangeTopicForm(); // services - INT_PTR __cdecl BlockContact(WPARAM hContact, LPARAM); - INT_PTR __cdecl UnblockContact(WPARAM hContact, LPARAM); INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM); INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM); INT_PTR __cdecl SvcLoadHistory(WPARAM hContact, LPARAM); diff --git a/protocols/Teams/src/teams_server.cpp b/protocols/Teams/src/teams_server.cpp index 36bf297ac5..fd3cd3f6cb 100644 --- a/protocols/Teams/src/teams_server.cpp +++ b/protocols/Teams/src/teams_server.cpp @@ -19,6 +19,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ///////////////////////////////////////////////////////////////////////////////////////// +void CTeamsProto::OnReceiveApiCookie(MHttpResponse *response, AsyncHttpRequest *) +{ + if (response == nullptr) { + ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, 1001); + SetStatus(ID_STATUS_OFFLINE); + return; + } + + m_szApiCookie = response->GetCookies(); +} + void CTeamsProto::OnCapabilitiesSended(MHttpResponse *response, AsyncHttpRequest *) { if (response == nullptr || response->body.IsEmpty()) { @@ -36,6 +47,8 @@ void CTeamsProto::OnCapabilitiesSended(MHttpResponse *response, AsyncHttpRequest m_szOwnSkypeId = UrlToSkypeId(root["selfLink"].as_string().c_str()).Detach(); GetProfileInfo(0); + + PushRequest(new AsyncHttpRequest(REQUEST_POST, HOST_TEAMS_API, "/imageauth/cookie", &CTeamsProto::OnReceiveApiCookie)); } void CTeamsProto::SendPresence() diff --git a/protocols/Teams/src/teams_utils.cpp b/protocols/Teams/src/teams_utils.cpp index 72603c84d1..4fcc168a34 100644 --- a/protocols/Teams/src/teams_utils.cpp +++ b/protocols/Teams/src/teams_utils.cpp @@ -772,12 +772,3 @@ INT_PTR CTeamsProto::ParseSkypeUriService(WPARAM, LPARAM lParam) return 1; } - -INT_PTR CTeamsProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam) -{ - for (auto &it : CMPlugin::g_arInstances) - if (it->IsOnline()) - return it->ParseSkypeUriService(wParam, lParam); - - return 1; -} |
