diff options
Diffstat (limited to 'plugins/SendScreenshotPlus/CSend.cpp')
-rw-r--r-- | plugins/SendScreenshotPlus/CSend.cpp | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/plugins/SendScreenshotPlus/CSend.cpp b/plugins/SendScreenshotPlus/CSend.cpp new file mode 100644 index 0000000000..4e48ecb2b4 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSend.cpp @@ -0,0 +1,416 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSend.cpp $
+Revision : $Revision: 19 $
+Last change on : $Date: 2010-04-09 03:24:04 +0400 (Пт, 09 апр 2010) $
+Last change by : $Author: ing.u.horn $
+
+*/
+
+#include "CSend.h"
+
+//---------------------------------------------------------------------------
+CSend::CSend(HWND Owner, HANDLE hContact, bool bFreeOnExit) {
+ m_hWndO = Owner;
+ m_bFreeOnExit = bFreeOnExit;
+ m_pszFile = NULL;
+ m_pszFileDesc = NULL;
+ m_pszProto = NULL;
+ m_ChatRoom = NULL;
+ m_PFflag = NULL;
+ m_hContact = NULL;
+ if (hContact) SetContact(hContact);
+ m_hOnSend = NULL;
+ m_szEventMsg = NULL;
+ m_szEventMsgT = NULL;
+ m_pszSendTyp = NULL;
+
+ m_ErrorMsg = NULL;
+ m_ErrorTitle = NULL;
+}
+
+CSend::~CSend(){
+ mir_free(m_pszFile);
+ mir_free(m_pszFileDesc);
+ mir_free(m_szEventMsg);
+ mir_free(m_szEventMsgT);
+ mir_free(m_ErrorMsg);
+ mir_free(m_ErrorTitle);
+ if (m_hOnSend) UnhookEvent(m_hOnSend);
+}
+
+//---------------------------------------------------------------------------
+void CSend::SetContact(HANDLE hContact) {
+ m_hContact = hContact;
+ m_pszProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+ m_ChatRoom = DBGetContactSettingByte(hContact, m_pszProto, "ChatRoom", 0);
+ m_PFflag = hasCap(PF1_URLSEND);
+ m_PFflag = hasCap(PF1_CHAT);
+ m_PFflag = hasCap(PF1_IMSEND);
+}
+
+//---------------------------------------------------------------------------
+bool CSend::hasCap(unsigned int Flag) {
+ return (Flag & CallContactService(m_hContact, PS_GETCAPS, (WPARAM)PFLAGNUM_1, NULL)) == Flag;
+}
+
+//---------------------------------------------------------------------------
+void CSend::svcSendMsg(const char* szMessage) {
+ mir_freeAndNil(m_szEventMsg);
+ m_cbEventMsg=lstrlenA(szMessage)+1;
+ m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg);
+ ZeroMemory(m_szEventMsg, m_cbEventMsg);
+ lstrcpyA(m_szEventMsg,szMessage);
+ if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
+ char *temp = mir_t2a(m_pszFileDesc);
+ mir_stradd(m_szEventMsg, "\r\n");
+ mir_stradd(m_szEventMsg, temp);
+ m_cbEventMsg = lstrlenA(m_szEventMsg)+1;
+ mir_free(temp);
+ }
+ //create a HookEventObj on ME_PROTO_ACK
+ if (!m_hOnSend) {
+ int (__cdecl CSend::*hookProc)(WPARAM, LPARAM);
+ hookProc = &CSend::OnSend;
+ m_hOnSend = HookEventObj(ME_PROTO_ACK, (MIRANDAHOOKOBJ)*(void **)&hookProc, this);
+ }
+ //start PSS_MESSAGE service
+ m_hSend = (HANDLE)CallContactService(m_hContact, PSS_MESSAGE, NULL, (LPARAM)m_szEventMsg);
+ // check we actually got an ft handle back from the protocol
+ if (!m_hSend) {
+ Unhook();
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED);
+ }
+}
+
+void CSend::svcSendUrl(const char* url) {
+//szMessage should be encoded as the URL followed by the description, the
+//separator being a single nul (\0). If there is no description, do not forget
+//to end the URL with two nuls.
+ mir_freeAndNil(m_szEventMsg)
+ m_cbEventMsg=lstrlenA(url)+2;
+ m_szEventMsg=(char*)mir_realloc(m_szEventMsg, m_cbEventMsg);
+ ZeroMemory(m_szEventMsg, m_cbEventMsg);
+ lstrcpyA(m_szEventMsg,url);
+ if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
+ char *temp = mir_t2a(m_pszFileDesc);
+ m_cbEventMsg += lstrlenA(temp);
+ m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg);
+ lstrcpyA(m_szEventMsg+lstrlenA(url)+1,temp);
+ m_szEventMsg[m_cbEventMsg-1] = 0;
+ mir_free(temp);
+ }
+ //create a HookEventObj on ME_PROTO_ACK
+ if (!m_hOnSend) {
+ int (__cdecl CSend::*hookProc)(WPARAM, LPARAM);
+ hookProc = &CSend::OnSend;
+ m_hOnSend = HookEventObj(ME_PROTO_ACK, (MIRANDAHOOKOBJ)*(void **)&hookProc, this);
+ }
+ //start PSS_URL service
+ m_hSend = (HANDLE)CallContactService(m_hContact, PSS_URL, NULL, (LPARAM)m_szEventMsg);
+ // check we actually got an ft handle back from the protocol
+ if (!m_hSend) {
+ //SetFtStatus(hwndDlg, LPGENT("Unable to initiate transfer."), FTS_TEXT);
+ //dat->waitingForAcceptance=0;
+ Unhook();
+ }
+}
+
+void CSend::svcSendChat() {
+ LPTSTR dirtyFix = NULL;
+ GC_INFO gci = {0};
+ GCDEST gcd = {0};
+ GCEVENT gce = {0};
+ int res = GC_RESULT_NOSESSION;
+ int cnt = (int)CallService(MS_GC_GETSESSIONCOUNT, 0, (LPARAM)m_pszProto);
+
+ //loop on all gc session to get the right (save) ptszID for the chatroom from m_hContact
+ gci.pszModule = m_pszProto;
+ for (int i = 0; i < cnt ; i++ ) {
+ gci.iItem = i;
+ gci.Flags = BYINDEX | HCONTACT | ID; //need dirty fix
+ CallService(MS_GC_GETINFO, 0, (LPARAM)(GC_INFO *) &gci);
+ if (gci.hContact == m_hContact) {
+ gcd.pszModule = m_pszProto;
+ gcd.iType = GC_EVENT_SENDMESSAGE; //GC_EVENT_MESSAGE ???;
+#ifdef _UNICODE
+ gcd.ptszID = gci.pszID;
+#else //dirty fix coz MS_GC_GETINFO dont know if caller is ansi or unicode.
+ //result from MS_GC_GETINFO only depend on type of chat.dll and not of caller type
+ if (mir_is_unicode()) {
+ dirtyFix = mir_u2t((wchar_t*)gci.pszID);
+ }
+ else {
+ dirtyFix = mir_tstrdup(gci.pszID);
+ }
+ gcd.ptszID = dirtyFix; //fixed gci.pszID;
+#endif
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ gce.bIsMe = TRUE;
+ gce.dwFlags = GC_TCHAR|GCEF_ADDTOLOG;
+ gce.ptszText = m_szEventMsgT;
+ gce.time = time(NULL);
+
+ //* returns 0 on success or error code on failure
+ res = 200 + (int)CallService(MS_GC_EVENT, 0, (LPARAM)(GCEVENT *) &gce);
+ mir_freeAndNil(dirtyFix);
+ break;
+ }
+ }
+ Exit(res);
+}
+
+void CSend::svcSendChat(const char* szMessage) {
+ if (!m_ChatRoom) {
+ svcSendMsg(szMessage);
+ return;
+ }
+ mir_freeAndNil(m_szEventMsgT);
+ m_szEventMsgT = mir_a2t(szMessage);
+ if (m_pszFileDesc) {
+ mir_tcsadd(m_szEventMsgT, _T("\r\n"));
+ mir_tcsadd(m_szEventMsgT, m_pszFileDesc);
+ }
+ svcSendChat();
+}
+
+void CSend::svcSendFile() {
+//szMessage should be encoded as the File followed by the description, the
+//separator being a single nul (\0). If there is no description, do not forget
+//to end the File with two nuls.
+ mir_freeAndNil(m_szEventMsg)
+ char *szFile = mir_t2a(m_pszFile);
+ m_cbEventMsg=lstrlenA(szFile)+2;
+ m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg);
+ ZeroMemory(m_szEventMsg, m_cbEventMsg);
+ lstrcpyA(m_szEventMsg,szFile);
+ if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
+ char* temp = mir_t2a(m_pszFileDesc);
+ m_cbEventMsg += lstrlenA(temp);
+ m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg);
+ lstrcpyA(m_szEventMsg+lstrlenA(szFile)+1,temp);
+ m_szEventMsg[m_cbEventMsg-1] = 0;
+ mir_freeAndNil(temp);
+ }
+ mir_freeAndNil(szFile);
+
+ //create a HookEventObj on ME_PROTO_ACK
+ if (!m_hOnSend) {
+ int (__cdecl CSend::*hookProc)(WPARAM, LPARAM);
+ hookProc = &CSend::OnSend;
+ m_hOnSend = HookEventObj(ME_PROTO_ACK, (MIRANDAHOOKOBJ)*(void **)&hookProc, this);
+ }
+ // Start miranda PSS_FILE based on mir ver (T)
+ if ((CallService(MS_SYSTEM_GETVERSION,0,0) >= 0x090000) && mir_is_unicode()) {
+ TCHAR *ppFile[2]={0,0};
+ TCHAR *pDesc = mir_tstrdup(m_pszFileDesc);
+ ppFile[0] = mir_tstrdup (m_pszFile);
+/* #if defined( _UNICODE )
+ TCHAR *ppFile[2]={0,0};
+ TCHAR *pDesc = mir_tstrdup(m_pszFileDesc);
+ ppFile[0] = mir_tstrdup (m_pszFile);
+ #else
+ wchar_t *ppFile[2]={0,0};
+ wchar_t *pDesc = mir_t2u (m_pszFileDesc);
+ ppFile[0] = mir_t2u (m_pszFile);
+ #endif */
+ ppFile[1] = NULL;
+ m_hSend = (HANDLE)CallContactService(m_hContact, PSS_FILET, (WPARAM)pDesc, (LPARAM)ppFile);
+ mir_free(pDesc);
+ mir_free(ppFile[0]);
+ }
+ else {
+ char *pDesc = mir_t2a(m_pszFileDesc);
+ char *ppFile[2]={0};
+ ppFile[0] = mir_t2a(m_pszFile);
+ ppFile[1] = NULL;
+ m_hSend = (HANDLE)CallContactService(m_hContact, PSS_FILE, (WPARAM)pDesc, (LPARAM)ppFile);
+ mir_free(pDesc);
+ mir_free(ppFile[0]);
+ }
+ // check we actually got an ft handle back from the protocol
+ if (!m_hSend) {
+ Unhook();
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED);
+ }
+}
+
+//---------------------------------------------------------------------------
+int __cdecl CSend::OnSend(WPARAM wParam, LPARAM lParam){
+ ACKDATA *ack=(ACKDATA*)lParam;
+ if(ack->hProcess!= m_hSend) return 0;
+ /* if(dat->waitingForAcceptance) {
+ SetTimer(hwndDlg,1,1000,NULL);
+ dat->waitingForAcceptance=0;
+ }
+ */
+
+ switch(ack->result) {
+ case ACKRESULT_INITIALISING: //SetFtStatus(hwndDlg, LPGENT("Initialising..."), FTS_TEXT); break;
+ case ACKRESULT_CONNECTING: //SetFtStatus(hwndDlg, LPGENT("Connecting..."), FTS_TEXT); break;
+ case ACKRESULT_CONNECTPROXY: //SetFtStatus(hwndDlg, LPGENT("Connecting to proxy..."), FTS_TEXT); break;
+ case ACKRESULT_LISTENING: //SetFtStatus(hwndDlg, LPGENT("Waiting for connection..."), FTS_TEXT); break;
+ case ACKRESULT_CONNECTED: //SetFtStatus(hwndDlg, LPGENT("Connected"), FTS_TEXT); break;
+ case ACKRESULT_SENTREQUEST: //SetFtStatus(hwndDlg, LPGENT("Decision sent"), FTS_TEXT); break;
+ case ACKRESULT_NEXTFILE: //SetFtStatus(hwndDlg, LPGENT("Moving to next file..."), FTS_TEXT);
+ case ACKRESULT_FILERESUME: //
+ case ACKRESULT_DATA: //transfer is on progress
+ break;
+ case ACKRESULT_DENIED:
+ Unhook();
+ Exit(ack->result);
+ break;
+ case ACKRESULT_FAILED:
+ Unhook();
+ Exit(ack->result);
+ //type=ACKTYPE_MESSAGE, result=success/failure, (char*)lParam=error message or NULL.
+ //type=ACKTYPE_URL, result=success/failure, (char*)lParam=error message or NULL.
+ //type=ACKTYPE_FILE, result=ACKRESULT_FAILED then lParam=(LPARAM)(const char*)szReason
+ break;
+ case ACKRESULT_SUCCESS:
+ Unhook();
+ switch(ack->type) {
+ case ACKTYPE_CHAT:
+ break;
+ case ACKTYPE_MESSAGE:
+ DB_EventAdd((WORD)EVENTTYPE_MESSAGE);
+ break;
+ case ACKTYPE_URL:
+ DB_EventAdd((WORD)EVENTTYPE_URL);
+ break;
+ case ACKTYPE_FILE:
+ //MS_DB_EVENT_ADD need 4byte extra at the beginning of m_szEventMsg for ACKTYPE_FILE
+ m_szEventMsg = (char*) mir_realloc(m_szEventMsg, sizeof(DWORD) + m_cbEventMsg);
+ //memmove_s(m_szEventMsg+sizeof(DWORD), m_cbEventMsg, m_szEventMsg, m_cbEventMsg);
+ memmove(m_szEventMsg+sizeof(DWORD), m_szEventMsg, m_cbEventMsg);
+ m_cbEventMsg += sizeof(DWORD);
+ DB_EventAdd((WORD)EVENTTYPE_FILE);
+ break;
+ default:
+ break;
+ }
+ Exit(ack->result);
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return 0;
+}
+
+void CSend::DB_EventAdd(WORD EventType) {
+ DBEVENTINFO dbei={0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = m_pszProto;
+ dbei.eventType = EventType;
+ dbei.flags = DBEF_SENT;
+ dbei.timestamp = time(NULL);
+ #if defined( _UNICODE )
+ dbei.flags |= DBEF_UTF;
+ #endif
+ dbei.cbBlob= m_cbEventMsg;
+ dbei.pBlob=(PBYTE)m_szEventMsg;
+
+ CallService(MS_DB_EVENT_ADD,(WPARAM)m_hContact,(LPARAM)&dbei);
+}
+
+//---------------------------------------------------------------------------
+void CSend::AfterSendDelete() {
+ if (m_pszFile && m_bDeleteAfterSend && (m_EnableItem & SS_DLG_DELETEAFTERSSEND) == SS_DLG_DELETEAFTERSSEND) {
+ DeleteFile(m_pszFile);
+ }
+}
+
+//---------------------------------------------------------------------------
+void CSend::Exit(unsigned int Result) {
+ bool err = true;
+ if (m_hWndO && IsWindow(m_hWndO)){
+ ;
+ }
+ switch(Result) {
+ case ACKRESULT_SUCCESS:
+ case GC_RESULT_SUCCESS:
+ SkinPlaySound("FileDone");
+ err = false;
+ break;
+ case ACKRESULT_DENIED:
+ SkinPlaySound("FileDenied");
+ Error(_T("%s (%i):\nFile transfer denied."),TranslateTS(m_pszSendTyp),Result);
+ MsgBoxService(NULL, (LPARAM)&m_box);
+ err = false;
+ break;
+ case GC_RESULT_WRONGVER: //.You appear to be using the wrong version of GC API.
+ Error(_T("%s (%i):\nYou appear to be using the wrong version of GC API"),TranslateT("GCHAT error"),Result);
+ break;
+ case GC_RESULT_ERROR: // An internal GC error occurred.
+ Error(_T("%s (%i):\nAn internal GC error occurred."),TranslateT("GCHAT error"),Result);
+ break;
+ case GC_RESULT_NOSESSION: // contact has no open GC session
+ Error(_T("%s (%i):\nContact has no open GC session."),TranslateT("GCHAT error"),Result);
+ break;
+ case ACKRESULT_FAILED:
+ default:
+ break;
+ }
+ if (err){
+ SkinPlaySound("FileFailed");
+ if(m_ErrorMsg && m_ErrorMsg[0] != 0) MsgBoxService(NULL, (LPARAM)&m_box);
+ else MsgErr(NULL, LPGENT("An unknown error has occured."));
+ }
+
+ AfterSendDelete();
+ if(m_bFreeOnExit) delete this;
+}
+
+void CSend::Error(LPCTSTR pszFormat, ...) {
+ if(!pszFormat) return;
+
+ TCHAR tszTemp[MAX_SECONDLINE];
+ va_list vl;
+
+ mir_sntprintf(tszTemp, SIZEOF(tszTemp),_T("%s - %s") ,_T(MODNAME), TranslateT("Error"));
+ mir_freeAndNil(m_ErrorTitle);
+ m_ErrorTitle = mir_tstrdup(tszTemp);
+
+ va_start(vl, pszFormat);
+ mir_vsntprintf(tszTemp, SIZEOF(tszTemp), TranslateTS(pszFormat), vl);
+ va_end(vl);
+ mir_freeAndNil(m_ErrorMsg);
+ m_ErrorMsg = mir_tstrdup(tszTemp);
+
+ ZeroMemory(&m_box, sizeof(m_box));
+ m_box.cbSize = sizeof(MSGBOX);
+ m_box.hParent = NULL;
+ m_box.hiLogo = IcoLib_GetIcon(ICO_PLUG_SSWINDOW1);
+ m_box.hiMsg = NULL;
+ m_box.ptszTitle = m_ErrorTitle;
+ m_box.ptszMsg = m_ErrorMsg;
+ m_box.uType = MB_OK|MB_ICON_ERROR;
+}
+
|