From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/srfile/file.cpp | 392 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 src/modules/srfile/file.cpp (limited to 'src/modules/srfile/file.cpp') diff --git a/src/modules/srfile/file.cpp b/src/modules/srfile/file.cpp new file mode 100644 index 0000000000..85eb99a7bc --- /dev/null +++ b/src/modules/srfile/file.cpp @@ -0,0 +1,392 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ +#include "commonheaders.h" +#include "file.h" + +TCHAR* PFTS_StringToTchar( int flags, const PROTOCHAR* s ); +int PFTS_CompareWithTchar( PROTOFILETRANSFERSTATUS* ft, const PROTOCHAR* s, TCHAR* r ); + +static HANDLE hSRFileMenuItem; + +static INT_PTR SendFileCommand(WPARAM wParam, LPARAM) +{ + struct FileSendData fsd; + fsd.hContact=(HANDLE)wParam; + fsd.ppFiles=NULL; + CreateDialogParam(hMirandaInst,MAKEINTRESOURCE(IDD_FILESEND),NULL,DlgProcSendFile,(LPARAM)&fsd); + return 0; +} + +static INT_PTR SendSpecificFiles(WPARAM wParam,LPARAM lParam) +{ + FileSendData fsd; + fsd.hContact=(HANDLE)wParam; + #if defined( _UNICODE ) + char** ppFiles = ( char** )lParam; + int count = 0; + while ( ppFiles[count] != NULL ) + count++; + + fsd.ppFiles = (const TCHAR**)alloca(( count+1 ) * sizeof( void* )); + for ( int i=0; i < count; i++ ) + fsd.ppFiles[i] = ( const TCHAR* )mir_a2t( ppFiles[i] ); + fsd.ppFiles[ count ] = NULL; + #else + fsd.ppFiles=(const char**)lParam; + #endif + CreateDialogParam(hMirandaInst,MAKEINTRESOURCE(IDD_FILESEND),NULL,DlgProcSendFile,(LPARAM)&fsd); + #if defined( _UNICODE ) + for ( int j=0; j < count; j++ ) + mir_free(( void* )fsd.ppFiles[j] ); + #endif + return 0; +} + +static INT_PTR SendSpecificFilesT(WPARAM wParam,LPARAM lParam) +{ + FileSendData fsd; + fsd.hContact=(HANDLE)wParam; + fsd.ppFiles=(const TCHAR**)lParam; + CreateDialogParam(hMirandaInst,MAKEINTRESOURCE(IDD_FILESEND),NULL,DlgProcSendFile,(LPARAM)&fsd); + return 0; +} + +static INT_PTR GetReceivedFilesFolder(WPARAM wParam,LPARAM lParam) +{ + TCHAR buf[MAX_PATH]; + GetContactReceivedFilesDir((HANDLE)wParam,buf,MAX_PATH,TRUE); + char* dir = mir_t2a(buf); + lstrcpynA((char*)lParam,dir,MAX_PATH); + mir_free(dir); + return 0; +} + +static INT_PTR RecvFileCommand(WPARAM, LPARAM lParam) +{ + CreateDialogParam(hMirandaInst,MAKEINTRESOURCE(IDD_FILERECV),NULL,DlgProcRecvFile,lParam); + return 0; +} + +void PushFileEvent( HANDLE hContact, HANDLE hdbe, LPARAM lParam ) +{ + CLISTEVENT cle={0}; + cle.cbSize = sizeof(cle); + cle.hContact = hContact; + cle.hDbEvent = hdbe; + cle.lParam = lParam; + if ( DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0) && !DBGetContactSettingByte(hContact,"CList","NotOnList",0)) { + CreateDialogParam(hMirandaInst,MAKEINTRESOURCE(IDD_FILERECV),NULL,DlgProcRecvFile,(LPARAM)&cle); + } + else { + SkinPlaySound("RecvFile"); + + TCHAR szTooltip[256]; + mir_sntprintf(szTooltip,SIZEOF(szTooltip),TranslateT("File from %s"), cli.pfnGetContactDisplayName( hContact, 0 )); + cle.ptszTooltip = szTooltip; + + cle.flags |= CLEF_TCHAR; + cle.hIcon = LoadSkinIcon( SKINICON_EVENT_FILE ); + cle.pszService = "SRFile/RecvFile"; + CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); +} } + +static int FileEventAdded(WPARAM wParam,LPARAM lParam) +{ + DWORD dwSignature; + + DBEVENTINFO dbei={0}; + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = sizeof( DWORD ); + dbei.pBlob = ( PBYTE )&dwSignature; + CallService( MS_DB_EVENT_GET, lParam, ( LPARAM )&dbei ); + if ( dbei.flags&(DBEF_SENT|DBEF_READ) || dbei.eventType != EVENTTYPE_FILE || dwSignature == 0 ) + return 0; + + PushFileEvent(( HANDLE )wParam, ( HANDLE )lParam, 0 ); + return 0; +} + +int SRFile_GetRegValue(HKEY hKeyBase,const TCHAR *szSubKey,const TCHAR *szValue,TCHAR *szOutput,int cbOutput) +{ + HKEY hKey; + DWORD cbOut=cbOutput; + + if ( RegOpenKeyEx( hKeyBase,szSubKey,0,KEY_QUERY_VALUE,&hKey ) != ERROR_SUCCESS) + return 0; + + if ( RegQueryValueEx( hKey,szValue,NULL,NULL,(PBYTE)szOutput, &cbOut ) != ERROR_SUCCESS ) { + RegCloseKey(hKey); + return 0; + } + + RegCloseKey(hKey); + return 1; +} + +void GetSensiblyFormattedSize(__int64 size,TCHAR *szOut,int cchOut,int unitsOverride,int appendUnits,int *unitsUsed) +{ + if(!unitsOverride) { + if(size<1000) unitsOverride=UNITS_BYTES; + else if(size<100*1024) unitsOverride=UNITS_KBPOINT1; + else if(size<1024*1024) unitsOverride=UNITS_KBPOINT0; + else if(size<1024*1024*1024) unitsOverride=UNITS_MBPOINT2; + else unitsOverride=UNITS_GBPOINT3; + } + if(unitsUsed) *unitsUsed=unitsOverride; + switch(unitsOverride) { + case UNITS_BYTES: mir_sntprintf(szOut,cchOut,_T("%u%s%s"),(int)size,appendUnits?_T(" "):_T(""),appendUnits?TranslateT("bytes"):_T("")); break; + case UNITS_KBPOINT1: mir_sntprintf(szOut,cchOut,_T("%.1lf%s"),size/1024.0,appendUnits?_T(" KB"):_T("")); break; + case UNITS_KBPOINT0: mir_sntprintf(szOut,cchOut,_T("%u%s"),(int)(size/1024),appendUnits?_T(" KB"):_T("")); break; + case UNITS_GBPOINT3: mir_sntprintf(szOut,cchOut,_T("%.3f%s"),(size >> 20)/1024.0,appendUnits?_T(" GB"):_T("")); break; + default: mir_sntprintf(szOut,cchOut,_T("%.2lf%s"),size/1048576.0,appendUnits?_T(" MB"):_T("")); break; + } +} + +// Tripple redirection sucks but is needed to nullify the array pointer +void FreeFilesMatrix(TCHAR ***files) +{ + if (*files == NULL) + return; + + // Free each filename in the pointer array + TCHAR **pFile = *files; + while (*pFile != NULL) + { + mir_free(*pFile); + *pFile = NULL; + pFile++; + } + + // Free the array itself + mir_free(*files); + *files = NULL; +} + +void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts) +{ + mir_free(fts->tszCurrentFile); + if(fts->ptszFiles) { + for( int i=0;itotalFiles;i++) mir_free(fts->ptszFiles[i]); + mir_free(fts->ptszFiles); + } + mir_free(fts->tszWorkingDir); +} + +void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src) +{ + *dest=*src; + if ( src->tszCurrentFile ) dest->tszCurrentFile = PFTS_StringToTchar(src->flags, src->tszCurrentFile); + if ( src->ptszFiles ) { + dest->ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)*src->totalFiles); + for( int i=0; i < src->totalFiles; i++ ) + dest->ptszFiles[i] = PFTS_StringToTchar(src->flags, src->ptszFiles[i] ); + } + if ( src->tszWorkingDir ) dest->tszWorkingDir = PFTS_StringToTchar(src->flags, src->tszWorkingDir ); + dest->flags &= ~PFTS_UTF; + dest->flags |= PFTS_TCHAR; +} + +void UpdateProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src) +{ + if (src->cbSize == sizeof(PROTOFILETRANSFERSTATUS_V1)) + { + PROTOFILETRANSFERSTATUS_V1 *src1 = (PROTOFILETRANSFERSTATUS_V1*)src; + src = (PROTOFILETRANSFERSTATUS*)alloca(sizeof(PROTOFILETRANSFERSTATUS)); + + src->cbSize = sizeof(PROTOFILETRANSFERSTATUS); + src->hContact = src1->hContact; + src->flags = src1->sending ? PFTS_SENDING : 0; + src->pszFiles = src1->files; + src->totalFiles = src1->totalFiles; + src->currentFileNumber = src1->currentFileNumber; + src->totalBytes = src1->totalBytes; + src->totalProgress = src1->totalProgress; + src->szWorkingDir = src1->workingDir; + src->szCurrentFile = src1->currentFile; + src->currentFileSize = src1->currentFileSize; + src->currentFileProgress = src1->currentFileProgress; + src->currentFileTime = src1->currentFileTime; + } + + dest->hContact = src->hContact; + dest->flags = src->flags; + if ( dest->totalFiles != src->totalFiles ) { + for( int i=0;itotalFiles;i++) mir_free(dest->ptszFiles[i]); + mir_free(dest->ptszFiles); + dest->ptszFiles = NULL; + dest->totalFiles = src->totalFiles; + } + if ( src->ptszFiles ) { + if ( !dest->ptszFiles ) + dest->ptszFiles = ( TCHAR** )mir_calloc( sizeof(TCHAR*)*src->totalFiles); + for ( int i=0; i < src->totalFiles; i++ ) + if ( !dest->ptszFiles[i] || !src->ptszFiles[i] || PFTS_CompareWithTchar( src, src->ptszFiles[i], dest->ptszFiles[i] )) { + mir_free( dest->ptszFiles[i] ); + if ( src->ptszFiles[i] ) + dest->ptszFiles[i] = PFTS_StringToTchar( src->flags, src->ptszFiles[i] ); + else + dest->ptszFiles[i] = NULL; + } + } + else if (dest->ptszFiles) { + for( int i=0; i < dest->totalFiles; i++ ) + mir_free(dest->ptszFiles[i]); + mir_free( dest->ptszFiles ); + dest->ptszFiles = NULL; + } + + dest->currentFileNumber = src->currentFileNumber; + dest->totalBytes = src->totalBytes; + dest->totalProgress = src->totalProgress; + if (src->tszWorkingDir && (!dest->tszWorkingDir || PFTS_CompareWithTchar( src, src->tszWorkingDir, dest->tszWorkingDir))) { + mir_free( dest->tszWorkingDir ); + if ( src->tszWorkingDir ) + dest->tszWorkingDir = PFTS_StringToTchar( src->flags, src->tszWorkingDir ); + else + dest->tszWorkingDir = NULL; + } + + if ( !dest->tszCurrentFile || !src->tszCurrentFile || PFTS_CompareWithTchar( src, src->tszCurrentFile, dest->tszCurrentFile )) { + mir_free( dest->tszCurrentFile ); + if ( src->tszCurrentFile ) + dest->tszCurrentFile = PFTS_StringToTchar( src->flags, src->tszCurrentFile ); + else + dest->tszCurrentFile = NULL; + } + dest->currentFileSize = src->currentFileSize; + dest->currentFileProgress = src->currentFileProgress; + dest->currentFileTime = src->currentFileTime; + dest->flags &= ~PFTS_UTF; + dest->flags |= PFTS_TCHAR; +} + +static void RemoveUnreadFileEvents(void) +{ + DBEVENTINFO dbei={0}; + HANDLE hDbEvent,hContact; + + dbei.cbSize=sizeof(dbei); + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact) { + hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0); + while(hDbEvent) { + dbei.cbBlob=0; + CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei); + if(!(dbei.flags&(DBEF_SENT|DBEF_READ)) && dbei.eventType==EVENTTYPE_FILE) + CallService(MS_DB_EVENT_MARKREAD,(WPARAM)hContact,(LPARAM)hDbEvent); + hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); + } + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } +} + +static int SRFilePreBuildMenu(WPARAM wParam, LPARAM) +{ + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + if (szProto != NULL) { + if ( CallProtoService(szProto, PS_GETCAPS,PFLAGNUM_1, 0 ) & PF1_FILESEND) { + if ( CallProtoService(szProto, PS_GETCAPS,PFLAGNUM_4, 0 ) & PF4_OFFLINEFILES ) + mi.flags = CMIM_FLAGS; + else if ( DBGetContactSettingWord(( HANDLE )wParam, szProto, "Status", ID_STATUS_OFFLINE ) != ID_STATUS_OFFLINE ) + mi.flags = CMIM_FLAGS; + } } + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hSRFileMenuItem, (LPARAM)&mi); + return 0; +} + +static int SRFileModulesLoaded(WPARAM, LPARAM) +{ + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.position = -2000020000; + mi.icolibItem = GetSkinIconHandle( SKINICON_EVENT_FILE ); + mi.pszName = LPGEN("&File"); + mi.pszService = MS_FILE_SENDFILE; + mi.flags = CMIF_ICONFROMICOLIB; + hSRFileMenuItem = ( HANDLE )CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi); + + RemoveUnreadFileEvents(); + return 0; +} + +INT_PTR FtMgrShowCommand(WPARAM, LPARAM) +{ + FtMgr_Show(true, true); + return 0; +} + +INT_PTR openContRecDir(WPARAM wparam, LPARAM) +{ + TCHAR szContRecDir[MAX_PATH]; + HANDLE hContact = (HANDLE)wparam; + GetContactReceivedFilesDir(hContact, szContRecDir, SIZEOF(szContRecDir),TRUE); + ShellExecute(0, _T("open"), szContRecDir, 0, 0, SW_SHOW); + return 0; +} + +INT_PTR openRecDir(WPARAM, LPARAM) +{ + TCHAR szContRecDir[MAX_PATH]; + GetReceivedFilesDir(szContRecDir, SIZEOF(szContRecDir)); + ShellExecute(0, _T("open"), szContRecDir, 0, 0, SW_SHOW); + return 0; +} + +int LoadSendRecvFileModule(void) +{ + CreateServiceFunction("FtMgr/Show", FtMgrShowCommand); + + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.flags = CMIF_ICONFROMICOLIB; + mi.icolibItem = GetSkinIconHandle( SKINICON_EVENT_FILE ); + mi.position = 1900000000; + mi.pszName = LPGEN("File &Transfers..."); + mi.pszService = "FtMgr/Show"; //MS_PROTO_SHOWFTMGR; + CallService( MS_CLIST_ADDMAINMENUITEM, 0, ( LPARAM )&mi ); + + HookEvent(ME_SYSTEM_MODULESLOADED,SRFileModulesLoaded); + HookEvent(ME_DB_EVENT_ADDED,FileEventAdded); + HookEvent(ME_OPT_INITIALISE,FileOptInitialise); + HookEvent(ME_CLIST_PREBUILDCONTACTMENU, SRFilePreBuildMenu); + + CreateServiceFunction(MS_FILE_SENDFILE,SendFileCommand); + CreateServiceFunction(MS_FILE_SENDSPECIFICFILES,SendSpecificFiles); + CreateServiceFunction(MS_FILE_SENDSPECIFICFILEST,SendSpecificFilesT); + CreateServiceFunction(MS_FILE_GETRECEIVEDFILESFOLDER,GetReceivedFilesFolder); + CreateServiceFunction("SRFile/RecvFile",RecvFileCommand); + + CreateServiceFunction("SRFile/OpenContRecDir",openContRecDir); + CreateServiceFunction("SRFile/OpenRecDir",openRecDir); + + SkinAddNewSoundEx("RecvFile", "File", "Incoming"); + SkinAddNewSoundEx("FileDone", "File", "Complete"); + SkinAddNewSoundEx("FileFailed", "File", "Error"); + SkinAddNewSoundEx("FileDenied", "File", "Denied"); + return 0; +} -- cgit v1.2.3