diff options
Diffstat (limited to 'miranda-wine/src/modules/srfile')
-rw-r--r-- | miranda-wine/src/modules/srfile/file.c | 287 | ||||
-rw-r--r-- | miranda-wine/src/modules/srfile/file.h | 88 | ||||
-rw-r--r-- | miranda-wine/src/modules/srfile/fileexistsdlg.c | 331 | ||||
-rw-r--r-- | miranda-wine/src/modules/srfile/fileopts.c | 227 | ||||
-rw-r--r-- | miranda-wine/src/modules/srfile/filerecvdlg.c | 431 | ||||
-rw-r--r-- | miranda-wine/src/modules/srfile/filesenddlg.c | 380 | ||||
-rw-r--r-- | miranda-wine/src/modules/srfile/filexferdlg.c | 562 |
7 files changed, 2306 insertions, 0 deletions
diff --git a/miranda-wine/src/modules/srfile/file.c b/miranda-wine/src/modules/srfile/file.c new file mode 100644 index 0000000..f69ccbf --- /dev/null +++ b/miranda-wine/src/modules/srfile/file.c @@ -0,0 +1,287 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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"
+
+static HANDLE *hFileMenu;
+static int hFileMenuCount = 0;
+
+static int SendFileCommand(WPARAM wParam,LPARAM lParam)
+{
+ struct FileSendData fsd;
+ fsd.hContact=(HANDLE)wParam;
+ fsd.ppFiles=NULL;
+ CreateDialogParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILESEND),NULL,DlgProcSendFile,(LPARAM)&fsd);
+ return 0;
+}
+
+static int SendSpecificFiles(WPARAM wParam,LPARAM lParam)
+{
+ struct FileSendData fsd;
+ fsd.hContact=(HANDLE)wParam;
+ fsd.ppFiles=(const char**)lParam;
+ CreateDialogParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILESEND),NULL,DlgProcSendFile,(LPARAM)&fsd);
+ return 0;
+}
+
+static int GetReceivedFilesFolder(WPARAM wParam,LPARAM lParam)
+{
+ GetContactReceivedFilesDir((HANDLE)wParam,(char*)lParam,MAX_PATH);
+ return 0;
+}
+
+static int RecvFileCommand(WPARAM wParam,LPARAM lParam)
+{
+ CreateDialogParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILERECV),NULL,DlgProcRecvFile,lParam);
+ return 0;
+}
+
+static int FileEventAdded(WPARAM wParam,LPARAM lParam)
+{
+ DBEVENTINFO dbei={0};
+ CLISTEVENT cle={0};
+
+ dbei.cbSize=sizeof(dbei);
+ dbei.cbBlob=0;
+ CallService(MS_DB_EVENT_GET,lParam,(LPARAM)&dbei);
+ if(dbei.flags&(DBEF_SENT|DBEF_READ) || dbei.eventType!=EVENTTYPE_FILE) return 0;
+
+ cle.cbSize=sizeof(cle);
+ cle.hContact=(HANDLE)wParam;
+ cle.hDbEvent=(HANDLE)lParam;
+ if(DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0) && !DBGetContactSettingByte((HANDLE)wParam,"CList","NotOnList",0)) {
+ CreateDialogParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILERECV),NULL,DlgProcRecvFile,(LPARAM)&cle);
+ }
+ else {
+ char *contactName;
+ char szTooltip[256];
+
+ SkinPlaySound("RecvFile");
+ cle.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE);
+ cle.pszService="SRFile/RecvFile";
+ contactName=(char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,wParam,0);
+ mir_snprintf(szTooltip,SIZEOF(szTooltip),Translate("File from %s"),contactName);
+ cle.pszTooltip=szTooltip;
+ CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle);
+ }
+ return 0;
+}
+
+void CreateDirectoryTree(char *szDir)
+{
+ DWORD dwAttributes;
+ char *pszLastBackslash,szTestDir[MAX_PATH];
+
+ lstrcpynA(szTestDir,szDir,SIZEOF(szTestDir));
+ if((dwAttributes=GetFileAttributesA(szTestDir))!=0xffffffff
+ && dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return;
+ pszLastBackslash=strrchr(szTestDir,'\\');
+ if(pszLastBackslash==NULL) {GetCurrentDirectoryA(MAX_PATH,szDir); return;}
+ *pszLastBackslash='\0';
+ CreateDirectoryTree(szTestDir);
+ CreateDirectoryA(szTestDir,NULL);
+}
+
+int SRFile_GetRegValue(HKEY hKeyBase,const char *szSubKey,const char *szValue,char *szOutput,int cbOutput)
+{
+ HKEY hKey;
+ DWORD cbOut=cbOutput;
+
+ if(RegOpenKeyExA(hKeyBase,szSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS) return 0;
+ if(RegQueryValueExA(hKey,szValue,NULL,NULL,(PBYTE)szOutput,&cbOut)!=ERROR_SUCCESS) {RegCloseKey(hKey); return 0;}
+ RegCloseKey(hKey);
+ return 1;
+}
+
+void GetSensiblyFormattedSize(DWORD 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 unitsOverride=UNITS_MBPOINT2;
+ }
+ if(unitsUsed) *unitsUsed=unitsOverride;
+ switch(unitsOverride) {
+ case UNITS_BYTES: mir_sntprintf(szOut,cchOut,_T("%u%s%s"),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"),size/1024,appendUnits?_T(" KB"):_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(char ***files)
+{
+
+ char **pFile;
+
+ if (*files == NULL)
+ return;
+
+ // Free each filename in the pointer array
+ pFile = *files;
+ while (*pFile != NULL)
+ {
+ mir_free(*pFile);
+ *pFile = NULL;
+ pFile++;
+ }
+
+ // Free the array itself
+ mir_free(*files);
+ *files = NULL;
+
+}
+
+void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts)
+{
+ if(fts->currentFile) mir_free(fts->currentFile);
+ if(fts->files) {
+ int i;
+ for(i=0;i<fts->totalFiles;i++) mir_free(fts->files[i]);
+ mir_free(fts->files);
+ }
+ if(fts->workingDir) mir_free(fts->workingDir);
+}
+
+void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest,PROTOFILETRANSFERSTATUS *src)
+{
+ *dest=*src;
+ if(src->currentFile) dest->currentFile=mir_strdup(src->currentFile);
+ if(src->files) {
+ int i;
+ dest->files=(char**)mir_alloc(sizeof(char*)*src->totalFiles);
+ for(i=0;i<src->totalFiles;i++)
+ dest->files[i]=mir_strdup(src->files[i]);
+ }
+ if(src->workingDir) dest->workingDir=mir_strdup(src->workingDir);
+}
+
+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 SRFileModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ CLISTMENUITEM mi;
+ PROTOCOLDESCRIPTOR **protocol;
+ int protoCount,i;
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=-2000020000;
+ mi.flags=CMIF_NOTOFFLINE;
+ mi.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE);
+ mi.pszName=Translate("&File");
+ mi.pszService=MS_FILE_SENDFILE;
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&protocol);
+ for(i=0;i<protoCount;i++) {
+ if(protocol[i]->type!=PROTOTYPE_PROTOCOL) continue;
+ if(CallProtoService(protocol[i]->szName,PS_GETCAPS,PFLAGNUM_1,0)&PF1_FILESEND) {
+ mi.pszContactOwner=protocol[i]->szName;
+ hFileMenu = (HANDLE*)mir_realloc(hFileMenu,sizeof(HANDLE)*(hFileMenuCount+1));
+ hFileMenu[hFileMenuCount] = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+ hFileMenuCount++;
+ }
+ }
+ RemoveUnreadFileEvents();
+ return 0;
+}
+
+static int hUpdateIcons = 0;
+int FilePreBuildContactMenu(WPARAM wParam,LPARAM lParam) {
+ if (hUpdateIcons) {
+ CLISTMENUITEM mi;
+ int i;
+
+ hUpdateIcons = 0;
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS|CMIM_ICON;
+ mi.hIcon = LoadSkinnedIcon(SKINICON_EVENT_FILE);
+
+ for(i=0;i<hFileMenuCount;i++)
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hFileMenu[i], (LPARAM)&mi);
+ }
+ return 0;
+}
+
+int FileIconsChanged(WPARAM wParam,LPARAM lParam) {
+ hUpdateIcons = 1;
+ return 0;
+}
+
+int FileShutdownProc(WPARAM wParam,LPARAM lParam) {
+ mir_free(hFileMenu);
+ return 0;
+}
+
+int LoadSendRecvFileModule(void)
+{
+ HookEvent(ME_SYSTEM_MODULESLOADED,SRFileModulesLoaded);
+ HookEvent(ME_DB_EVENT_ADDED,FileEventAdded);
+ HookEvent(ME_OPT_INITIALISE,FileOptInitialise);
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU,FilePreBuildContactMenu);
+ HookEvent(ME_SKIN_ICONSCHANGED,FileIconsChanged);
+ HookEvent(ME_SYSTEM_SHUTDOWN,FileShutdownProc);
+ CreateServiceFunction(MS_FILE_SENDFILE,SendFileCommand);
+ CreateServiceFunction(MS_FILE_SENDSPECIFICFILES,SendSpecificFiles);
+ CreateServiceFunction(MS_FILE_GETRECEIVEDFILESFOLDER,GetReceivedFilesFolder);
+ CreateServiceFunction("SRFile/RecvFile",RecvFileCommand);
+ SkinAddNewSoundEx("RecvFile",Translate("File"),Translate("Incoming"));
+ SkinAddNewSoundEx("FileDone",Translate("File"),Translate("Complete"));
+ SkinAddNewSoundEx("FileFailed",Translate("File"),Translate("Error"));
+ SkinAddNewSoundEx("FileDenied",Translate("File"),Translate("Denied"));
+ // Upgrade Routine for File Received Path - Remove me after 0.3.4
+ {
+ DBVARIANT dbv;
+
+ if(!DBGetContactSetting(NULL,"SRFile","RecvFilesDir",&dbv)) {
+ char szPath[MAX_PATH];
+
+ mir_snprintf(szPath, SIZEOF(szPath), "%s%s%s", dbv.pszVal, dbv.pszVal[strlen(dbv.pszVal)-1]=='\\'?"":"\\" , "%userid%");
+ DBFreeVariant(&dbv);
+ DBWriteContactSettingString(NULL,"SRFile","RecvFilesDirAdv",szPath);
+ DBDeleteContactSetting(NULL,"SRFile","RecvFilesDir");
+ }
+ }
+ // End Upgrade
+ return 0;
+}
diff --git a/miranda-wine/src/modules/srfile/file.h b/miranda-wine/src/modules/srfile/file.h new file mode 100644 index 0000000..2c578b4 --- /dev/null +++ b/miranda-wine/src/modules/srfile/file.h @@ -0,0 +1,88 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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.
+*/
+
+#define VIRUSSCAN_DISABLE 0
+#define VIRUSSCAN_AFTERDL 1
+#define VIRUSSCAN_DURINGDL 2
+
+#define FILERESUME_ASK 0
+//1,2,3,4: resume, overwrite, rename, skip: from proto library
+#define FILERESUMEF_ALL 0x80
+#define FILERESUME_RESUMEALL (FILERESUME_RESUME|FILERESUMEF_ALL)
+#define FILERESUME_OVERWRITEALL (FILERESUME_OVERWRITE|FILERESUMEF_ALL)
+#define FILERESUME_RENAMEALL (FILERESUME_RENAME|FILERESUMEF_ALL)
+#define FILERESUME_CANCEL 0xFFFFFFFF
+
+#define M_FILEEXISTSDLGREPLY (WM_USER+200)
+#define M_PRESHUTDOWN (WM_USER+201)
+
+struct FileSendData {
+ HANDLE hContact;
+ const char **ppFiles;
+};
+
+#define BYTESRECVEDHISTORYCOUNT 10 //the number of bytes recved is sampled once a second and the last 10 are used to get the transfer speed
+struct FileDlgData {
+ HWND hwndTransfer;
+ HANDLE fs;
+ HANDLE hContact;
+ HANDLE hDbEvent;
+ HANDLE hNotifyEvent;
+ char **files;
+ HICON hUIIcons[4];
+ int send;
+ int closeIfFileChooseCancelled;
+ int resumeBehaviour;
+ int bytesRecvedHistory[BYTESRECVEDHISTORYCOUNT];
+ int bytesRecvedHistorySize;
+ int waitingForAcceptance;
+ PROTOFILETRANSFERSTATUS transferStatus;
+ int *fileVirusScanned;
+ HANDLE hPreshutdownEvent;
+ DWORD dwTicks;
+};
+
+//file.c
+void CreateDirectoryTree(char *szDir);
+#define UNITS_BYTES 1 // 0<=size<1000: "%d bytes"
+#define UNITS_KBPOINT1 2 // 1000<=size<100*1024: "%.1f KB"
+#define UNITS_KBPOINT0 3 // 100*1024<=size<1024*1024: "%d KB"
+#define UNITS_MBPOINT2 4 // 1024*1024<=size: "%.2f MB"
+void GetSensiblyFormattedSize(DWORD size,TCHAR *szOut,int cchOut,int unitsOverride,int appendUnits,int *unitsUsed);
+void FreeFilesMatrix(char ***files); //loving that triple indirection
+void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts);
+void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest,PROTOFILETRANSFERSTATUS *src);
+int SRFile_GetRegValue(HKEY hKeyBase,const char *szSubKey,const char *szValue,char *szOutput,int cbOutput);
+//filesenddlg.c
+BOOL CALLBACK DlgProcSendFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+//filerecv.c
+BOOL CALLBACK DlgProcRecvFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+void GetContactReceivedFilesDir(HANDLE hContact,char *szDir,int cchDir);
+int BrowseForFolder(HWND hwnd,char *szPath);
+//fileexistsdlg.c
+BOOL CALLBACK DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+//filexferdlg.c
+BOOL CALLBACK DlgProcFileTransfer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+//fileopts.c
+int FileOptInitialise(WPARAM wParam,LPARAM lParam);
+
diff --git a/miranda-wine/src/modules/srfile/fileexistsdlg.c b/miranda-wine/src/modules/srfile/fileexistsdlg.c new file mode 100644 index 0000000..73d2bf3 --- /dev/null +++ b/miranda-wine/src/modules/srfile/fileexistsdlg.c @@ -0,0 +1,331 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 <shlobj.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "file.h"
+
+static void SetControlToUnixTime(HWND hwndDlg, UINT idCtrl, time_t unixTime)
+{
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+ char szTime[64],szDate[64],szOutput[128];
+
+ liFiletime.QuadPart=(BIGI(11644473600)+(__int64)unixTime)*10000000;
+ filetime.dwHighDateTime=liFiletime.HighPart;
+ filetime.dwLowDateTime=liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime,&st);
+ GetTimeFormatA(LOCALE_USER_DEFAULT,0,&st,NULL,szTime,SIZEOF(szTime));
+ GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,szDate,SIZEOF(szDate));
+ wsprintfA(szOutput,"%s %s",szDate,szTime);
+ SetDlgItemTextA(hwndDlg,idCtrl,szOutput);
+}
+
+#define C_CONTEXTMENU 0
+#define C_PROPERTIES 1
+// not defined in VC++ 6.0 SE
+#ifndef CMF_EXTENDEDVERBS
+#define CMF_EXTENDEDVERBS 0x00000100
+#endif
+static void DoAnnoyingShellCommand(HWND hwnd,const char *szFilename,int cmd,POINT *ptCursor)
+{
+ IMalloc *pShellMalloc;
+
+ OleInitialize(NULL);
+ if(SHGetMalloc(&pShellMalloc)==NOERROR) {
+ IShellFolder *pDesktopFolder;
+ if(SHGetDesktopFolder(&pDesktopFolder)==NOERROR) {
+ WCHAR wszFilename[MAX_PATH];
+ ITEMIDLIST *pCurrentIdl;
+ MultiByteToWideChar(CP_ACP,0,szFilename,-1,wszFilename,SIZEOF(wszFilename));
+ if(pDesktopFolder->lpVtbl->ParseDisplayName(pDesktopFolder,NULL,NULL,wszFilename,NULL,&pCurrentIdl,NULL)==NOERROR) {
+ if(pCurrentIdl->mkid.cb) {
+ ITEMIDLIST *pidl,*pidlNext,*pidlFilename;
+ IShellFolder *pFileFolder;
+
+ for(pidl=pCurrentIdl;;) {
+ pidlNext=(ITEMIDLIST*)((PBYTE)pidl+pidl->mkid.cb);
+ if(pidlNext->mkid.cb==0) {
+ pidlFilename=pShellMalloc->lpVtbl->Alloc(pShellMalloc,pidl->mkid.cb+sizeof(pidl->mkid.cb));
+ CopyMemory(pidlFilename,pidl,pidl->mkid.cb+sizeof(pidl->mkid.cb));
+ pidl->mkid.cb=0;
+ break;
+ }
+ pidl=pidlNext;
+ }
+ if(pDesktopFolder->lpVtbl->BindToObject(pDesktopFolder,pCurrentIdl,NULL,&IID_IShellFolder,&pFileFolder)==NOERROR) {
+ IContextMenu *pContextMenu;
+ if(pFileFolder->lpVtbl->GetUIObjectOf(pFileFolder,NULL,1,&pidlFilename,&IID_IContextMenu,NULL,&pContextMenu)==NOERROR) {
+ switch(cmd) {
+ case C_PROPERTIES:
+ { CMINVOKECOMMANDINFO ici={0};
+ ici.cbSize=sizeof(ici);
+ ici.hwnd=hwnd;
+ ici.lpVerb="properties";
+ ici.nShow=SW_SHOW;
+ pContextMenu->lpVtbl->InvokeCommand(pContextMenu,&ici);
+ break;
+ }
+ case C_CONTEXTMENU:
+ { HMENU hMenu;
+ hMenu=CreatePopupMenu();
+ if(SUCCEEDED(pContextMenu->lpVtbl->QueryContextMenu(pContextMenu,hMenu,0,1000,65535,(GetKeyState(VK_SHIFT)&0x8000?CMF_EXTENDEDVERBS:0)|CMF_NORMAL))) {
+ int cmd;
+ cmd=TrackPopupMenu(hMenu,TPM_RETURNCMD,ptCursor->x,ptCursor->y,0,hwnd,NULL);
+ if(cmd) {
+ CMINVOKECOMMANDINFO ici={0};
+ ici.cbSize=sizeof(ici);
+ ici.hwnd=hwnd;
+ ici.lpVerb=MAKEINTRESOURCEA(cmd-1000);
+ ici.nShow=SW_SHOW;
+ pContextMenu->lpVtbl->InvokeCommand(pContextMenu,&ici);
+ }
+ }
+ DestroyMenu(hMenu);
+ break;
+ }
+ }
+ pContextMenu->lpVtbl->Release(pContextMenu);
+ }
+ pFileFolder->lpVtbl->Release(pFileFolder);
+ }
+ pShellMalloc->lpVtbl->Free(pShellMalloc,pidlFilename);
+ }
+ pShellMalloc->lpVtbl->Free(pShellMalloc,pCurrentIdl);
+ }
+ pDesktopFolder->lpVtbl->Release(pDesktopFolder);
+ }
+ pShellMalloc->lpVtbl->Release(pShellMalloc);
+ }
+ OleUninitialize();
+}
+
+static WNDPROC pfnIconWindowProc;
+static LRESULT CALLBACK IconCtrlSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_LBUTTONDBLCLK:
+ ShellExecuteA(hwnd,NULL,((PROTOFILETRANSFERSTATUS*)GetWindowLong(GetParent(hwnd),GWL_USERDATA))->currentFile,NULL,NULL,SW_SHOW);
+ break;
+ case WM_RBUTTONUP:
+ { POINT pt;
+ pt.x=(short)LOWORD(lParam); pt.y=(short)HIWORD(lParam);
+ ClientToScreen(hwnd,&pt);
+ DoAnnoyingShellCommand(hwnd,((PROTOFILETRANSFERSTATUS*)GetWindowLong(GetParent(hwnd),GWL_USERDATA))->currentFile,C_CONTEXTMENU,&pt);
+ return 0;
+ }
+ }
+ return CallWindowProc(pfnIconWindowProc,hwnd,msg,wParam,lParam);
+}
+
+struct loadiconsstartinfo {
+ HWND hwndDlg;
+ char *szFilename;
+};
+void __cdecl LoadIconsAndTypesThread(struct loadiconsstartinfo *info)
+{
+ SHFILEINFOA fileInfo;
+
+ OleInitialize(NULL);
+ if(SHGetFileInfoA(info->szFilename,0,&fileInfo,sizeof(fileInfo),SHGFI_TYPENAME|SHGFI_ICON|SHGFI_LARGEICON)) {
+ char *pszExtension,*pszFilename;
+ char szExtension[64];
+ char szIconFile[MAX_PATH];
+
+ pszFilename=strrchr(info->szFilename,'\\');
+ if(pszFilename==NULL) pszFilename=info->szFilename;
+ pszExtension=strrchr(pszFilename,'.');
+ if(pszExtension) lstrcpynA(szExtension,pszExtension+1,SIZEOF(szExtension));
+ else {pszExtension="."; szExtension[0]='\0';}
+ CharUpperA(szExtension);
+ if(fileInfo.szTypeName[0]=='\0')
+ wsprintfA(fileInfo.szTypeName,Translate("%s File"),szExtension);
+ SetDlgItemTextA(info->hwndDlg,IDC_EXISTINGTYPE,fileInfo.szTypeName);
+ SetDlgItemTextA(info->hwndDlg,IDC_NEWTYPE,fileInfo.szTypeName);
+ SendDlgItemMessage(info->hwndDlg,IDC_EXISTINGICON,STM_SETICON,(WPARAM)fileInfo.hIcon,0);
+ szIconFile[0]='\0';
+ if(!lstrcmpA(szExtension,"EXE")) {
+ SRFile_GetRegValue(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons","2",szIconFile,SIZEOF(szIconFile));
+ }
+ else {
+ char szTypeName[MAX_PATH];
+ if(SRFile_GetRegValue(HKEY_CLASSES_ROOT,pszExtension,NULL,szTypeName,SIZEOF(szTypeName))) {
+ lstrcatA(szTypeName,"\\DefaultIcon");
+ if(SRFile_GetRegValue(HKEY_CLASSES_ROOT,szTypeName,NULL,szIconFile,SIZEOF(szIconFile))) {
+ if(strstr(szIconFile,"%1"))
+ SRFile_GetRegValue(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons","0",szIconFile,SIZEOF(szIconFile));
+ else szIconFile[0]='\0';
+ }
+ }
+ }
+ if(szIconFile[0]) {
+ int iconIndex;
+ HICON hIcon;
+ char *pszComma=strrchr(szIconFile,',');
+ if(pszComma==NULL) iconIndex=0;
+ else {iconIndex=atoi(pszComma+1); *pszComma='\0';}
+ hIcon=ExtractIconA(GetModuleHandle(NULL),szIconFile,iconIndex);
+ if(hIcon) fileInfo.hIcon=hIcon;
+ }
+ SendDlgItemMessage(info->hwndDlg,IDC_NEWICON,STM_SETICON,(WPARAM)fileInfo.hIcon,0);
+ }
+ OleUninitialize();
+ mir_free(info->szFilename);
+ mir_free(info);
+}
+
+BOOL CALLBACK DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ PROTOFILETRANSFERSTATUS *fts;
+
+ fts=(PROTOFILETRANSFERSTATUS*)GetWindowLong(hwndDlg,GWL_USERDATA);
+ switch(msg) {
+ case WM_INITDIALOG:
+ { TCHAR szSize[64];
+ struct _stat statbuf;
+ struct loadiconsstartinfo *lisi;
+ HWND hwndFocus;
+
+ SetPropA(hwndDlg,"Miranda.Preshutdown",HookEventMessage(ME_SYSTEM_PRESHUTDOWN,hwndDlg,M_PRESHUTDOWN));
+
+ TranslateDialogDefault(hwndDlg);
+ fts=(PROTOFILETRANSFERSTATUS*)mir_alloc(sizeof(PROTOFILETRANSFERSTATUS));
+ CopyProtoFileTransferStatus(fts,(PROTOFILETRANSFERSTATUS*)lParam);
+ SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)fts);
+ SetDlgItemTextA(hwndDlg,IDC_FILENAME,fts->currentFile);
+ SetControlToUnixTime(hwndDlg,IDC_NEWDATE,fts->currentFileTime);
+ GetSensiblyFormattedSize(fts->currentFileSize,szSize,SIZEOF(szSize),0,1,NULL);
+ SetDlgItemText(hwndDlg,IDC_NEWSIZE,szSize);
+
+ pfnIconWindowProc=(WNDPROC)SetWindowLong(GetDlgItem(hwndDlg,IDC_EXISTINGICON),GWL_WNDPROC,(LONG)IconCtrlSubclassProc);
+
+ hwndFocus=GetDlgItem(hwndDlg,IDC_RESUME);
+ if(_stat(fts->currentFile,&statbuf)==0) {
+ SetControlToUnixTime(hwndDlg,IDC_EXISTINGDATE,statbuf.st_mtime);
+ GetSensiblyFormattedSize(statbuf.st_size,szSize,SIZEOF(szSize),0,1,NULL);
+ SetDlgItemText(hwndDlg,IDC_EXISTINGSIZE,szSize);
+ if(statbuf.st_size>(int)fts->currentFileSize) {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_RESUME),FALSE);
+ hwndFocus=GetDlgItem(hwndDlg,IDC_OVERWRITE);
+ }
+ }
+ lisi=(struct loadiconsstartinfo*)mir_alloc(sizeof(struct loadiconsstartinfo));
+ lisi->hwndDlg=hwndDlg;
+ lisi->szFilename=mir_strdup(fts->currentFile);
+ //can be a little slow, so why not?
+ forkthread(LoadIconsAndTypesThread,0,lisi);
+ SetFocus(hwndFocus);
+ SetWindowLong(hwndFocus,GWL_STYLE,GetWindowLong(hwndFocus,GWL_STYLE)|BS_DEFPUSHBUTTON);
+ return FALSE;
+ }
+ case WM_COMMAND:
+ { PROTOFILERESUME pfr={0};
+ switch(LOWORD(wParam)) {
+ case IDC_OPENFILE:
+ ShellExecuteA(hwndDlg,NULL,fts->currentFile,NULL,NULL,SW_SHOW);
+ return FALSE;
+ case IDC_OPENFOLDER:
+ { char szFile[MAX_PATH];
+ char *pszLastBackslash;
+ lstrcpynA(szFile,fts->currentFile,SIZEOF(szFile));
+ pszLastBackslash=strrchr(szFile,'\\');
+ if(pszLastBackslash) *pszLastBackslash='\0';
+ ShellExecuteA(hwndDlg,NULL,szFile,NULL,NULL,SW_SHOW);
+ return FALSE;
+ }
+ case IDC_PROPERTIES:
+ DoAnnoyingShellCommand(hwndDlg,fts->currentFile,C_PROPERTIES,NULL);
+ return FALSE;
+ case IDC_RESUME:
+ pfr.action=FILERESUME_RESUME;
+ break;
+ case IDC_RESUMEALL:
+ pfr.action=FILERESUME_RESUMEALL;
+ break;
+ case IDC_OVERWRITE:
+ pfr.action=FILERESUME_OVERWRITE;
+ break;
+ case IDC_OVERWRITEALL:
+ pfr.action=FILERESUME_OVERWRITEALL;
+ break;
+ case IDC_SAVEAS:
+ { OPENFILENAMEA ofn={0};
+ char filter[512],*pfilter;
+ char str[MAX_PATH];
+
+ lstrcpynA(str,fts->currentFile,SIZEOF(str));
+ ofn.lStructSize=OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner=hwndDlg;
+ ofn.Flags=OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY;
+ strcpy(filter,Translate("All Files"));
+ strcat(filter," (*)");
+ pfilter=filter+strlen(filter)+1;
+ strcpy(pfilter,"*");
+ pfilter=pfilter+strlen(pfilter)+1;
+ *pfilter='\0';
+ ofn.lpstrFilter=filter;
+ ofn.lpstrFile=str;
+ ofn.nMaxFile=SIZEOF(str);
+ ofn.nMaxFileTitle=MAX_PATH;
+ if(!GetSaveFileNameA(&ofn)) break;
+ pfr.szFilename=mir_strdup(str);
+ pfr.action=FILERESUME_RENAME;
+ break;
+ }
+ case IDC_SKIP:
+ pfr.action=FILERESUME_SKIP;
+ break;
+ case IDCANCEL:
+ pfr.action=FILERESUME_CANCEL;
+ break;
+ default:
+ return FALSE;
+ }
+ { PROTOFILERESUME *pfrCopy;
+ pfrCopy=(PROTOFILERESUME*)mir_alloc(sizeof(pfr));
+ CopyMemory(pfrCopy,&pfr,sizeof(pfr));
+ PostMessage(GetParent(hwndDlg),M_FILEEXISTSDLGREPLY,(WPARAM)mir_strdup(fts->currentFile),(LPARAM)pfrCopy);
+ DestroyWindow(hwndDlg);
+ }
+ break;
+ }
+ case WM_CLOSE:
+ PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDCANCEL,BN_CLICKED),(LPARAM)GetDlgItem(hwndDlg,IDCANCEL));
+ break;
+ case M_PRESHUTDOWN:
+ {
+ PostMessage(hwndDlg,WM_CLOSE,0,0);
+ break;
+ }
+ case WM_DESTROY:
+ UnhookEvent(GetPropA(hwndDlg,"Miranda.Preshutdown")); // GetProp() will return NULL if it couldnt find anything
+ DestroyIcon((HICON)SendDlgItemMessage(hwndDlg,IDC_EXISTINGICON,STM_GETICON,0,0));
+ DestroyIcon((HICON)SendDlgItemMessage(hwndDlg,IDC_NEWICON,STM_GETICON,0,0));
+ FreeProtoFileTransferStatus(fts);
+ mir_free(fts);
+ break;
+ }
+ return FALSE;
+}
diff --git a/miranda-wine/src/modules/srfile/fileopts.c b/miranda-wine/src/modules/srfile/fileopts.c new file mode 100644 index 0000000..3208f89 --- /dev/null +++ b/miranda-wine/src/modules/srfile/fileopts.c @@ -0,0 +1,227 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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"
+
+#define VSCAN_MCAFEE 1
+#define VSCAN_DRSOLOMON 2
+#define VSCAN_NORTON 3
+#define VSCAN_CA 4
+
+struct virusscannerinfo {
+ char *szProductName;
+ char *szExeRegPath;
+ char *szExeRegValue;
+ char *szCommandLine;
+};
+
+static struct virusscannerinfo virusScanners[]={
+ {"Network Associates/McAfee VirusScan","SOFTWARE\\McAfee\\VirusScan","Scan32EXE","\"%s\" %%f /nosplash /comp /autoscan /autoexit /noboot"},
+ {"Dr Solomon's VirusScan (Network Associates)","SOFTWARE\\Network Associates\\TVD\\VirusScan\\AVConsol\\General","szScannerExe","\"%s\" %%f /uinone /noboot /comp /prompt /autoexit"},
+ {"Norton AntiVirus","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Navw32.exe",NULL,"\"%s\" %%f /b- /m- /s+ /noresults"},
+ {"Computer Associates/Inoculate IT","Software\\Antivirus","ImageFilename","\"%s\" %%f /display=progress /exit"},
+ {"Computer Associates eTrust","SOFTWARE\\ComputerAssociates\\Anti-Virus\\Resident","VetPath","\"%s\" %%f /display=progress /exit"},
+ {"Kaspersky Anti-Virus","SOFTWARE\\KasperskyLab\\Components\\101","EXEName","\"%s\" /S /Q %%f"},
+};
+
+#define M_UPDATEENABLING (WM_USER+100)
+#define M_SCANCMDLINESELCHANGE (WM_USER+101)
+static BOOL CALLBACK DlgProcFileOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_INITDIALOG:
+ { DBVARIANT dbv;
+
+ TranslateDialogDefault(hwndDlg);
+ {
+ char str[MAX_PATH];
+ GetContactReceivedFilesDir(NULL,str,SIZEOF(str));
+ SetDlgItemTextA(hwndDlg,IDC_FILEDIR,str);
+ }
+ { HRESULT (STDAPICALLTYPE *MySHAutoComplete)(HWND,DWORD);
+
+ MySHAutoComplete=(HRESULT (STDAPICALLTYPE*)(HWND,DWORD))GetProcAddress(GetModuleHandleA("shlwapi"),"SHAutoComplete");
+ if(MySHAutoComplete) MySHAutoComplete(GetWindow(GetDlgItem(hwndDlg,IDC_FILEDIR),GW_CHILD),1);
+ }
+ CheckDlgButton(hwndDlg, IDC_AUTOACCEPT, DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOMIN, DBGetContactSettingByte(NULL,"SRFile","AutoMin",0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOCLOSE, DBGetContactSettingByte(NULL,"SRFile","AutoClose",0) ? BST_CHECKED : BST_UNCHECKED);
+ switch(DBGetContactSettingByte(NULL,"SRFile","UseScanner",VIRUSSCAN_DISABLE)) {
+ case VIRUSSCAN_AFTERDL: CheckDlgButton(hwndDlg, IDC_SCANAFTERDL, BST_CHECKED); break;
+ case VIRUSSCAN_DURINGDL: CheckDlgButton(hwndDlg, IDC_SCANDURINGDL, BST_CHECKED); break;
+ default: CheckDlgButton(hwndDlg, IDC_NOSCANNER, BST_CHECKED); break;
+ }
+ CheckDlgButton(hwndDlg, IDC_WARNBEFOREOPENING, DBGetContactSettingByte(NULL,"SRFile","WarnBeforeOpening",1) ? BST_CHECKED : BST_UNCHECKED);
+ { char szScanExe[MAX_PATH];
+ int i,iItem;
+ for( i=0; i < SIZEOF(virusScanners); i++ ) {
+ if(SRFile_GetRegValue(HKEY_LOCAL_MACHINE,virusScanners[i].szExeRegPath,virusScanners[i].szExeRegValue,szScanExe,SIZEOF(szScanExe))) {
+ iItem=SendDlgItemMessageA(hwndDlg,IDC_SCANCMDLINE,CB_ADDSTRING,0,(LPARAM)virusScanners[i].szProductName);
+ SendDlgItemMessage(hwndDlg,IDC_SCANCMDLINE,CB_SETITEMDATA,iItem,i);
+ }
+ }
+ }
+ if(DBGetContactSetting(NULL,"SRFile","ScanCmdLine",&dbv)==0) {
+ SetDlgItemTextA(hwndDlg,IDC_SCANCMDLINE,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else {
+ if(SendDlgItemMessage(hwndDlg,IDC_SCANCMDLINE,CB_GETCOUNT,0,0)) {
+ SendDlgItemMessage(hwndDlg,IDC_SCANCMDLINE,CB_SETCURSEL,0,0);
+ PostMessage(hwndDlg,M_SCANCMDLINESELCHANGE,0,0);
+ }
+ }
+ switch(DBGetContactSettingByte(NULL,"SRFile","IfExists",FILERESUME_ASK)) {
+ case FILERESUME_RESUMEALL: CheckDlgButton(hwndDlg, IDC_RESUME, BST_CHECKED); break;
+ case FILERESUME_OVERWRITEALL: CheckDlgButton(hwndDlg, IDC_OVERWRITE, BST_CHECKED); break;
+ case FILERESUME_RENAMEALL: CheckDlgButton(hwndDlg, IDC_RENAME, BST_CHECKED); break;
+ default: CheckDlgButton(hwndDlg, IDC_ASK, BST_CHECKED); break;
+ }
+ SendMessage(hwndDlg,M_UPDATEENABLING,0,0);
+ return TRUE;
+ }
+ case M_UPDATEENABLING:
+ { int on=!IsDlgButtonChecked(hwndDlg,IDC_NOSCANNER);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_ST_CMDLINE),on);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_SCANCMDLINE),on);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_SCANCMDLINEBROWSE),on);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_ST_CMDLINEHELP),on);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AUTOMIN),IsDlgButtonChecked(hwndDlg,IDC_AUTOACCEPT));
+ break;
+ }
+ case M_SCANCMDLINESELCHANGE:
+ { char str[512],szScanExe[MAX_PATH];
+ int iScanner=SendDlgItemMessage(hwndDlg,IDC_SCANCMDLINE,CB_GETITEMDATA,SendDlgItemMessage(hwndDlg,IDC_SCANCMDLINE,CB_GETCURSEL,0,0),0);
+ if(iScanner >= SIZEOF(virusScanners) || iScanner<0) break;
+ str[0]='\0';
+ if(SRFile_GetRegValue(HKEY_LOCAL_MACHINE,virusScanners[iScanner].szExeRegPath,virusScanners[iScanner].szExeRegValue,szScanExe,SIZEOF(szScanExe)))
+ wsprintfA(str,virusScanners[iScanner].szCommandLine,szScanExe);
+ SetDlgItemTextA(hwndDlg,IDC_SCANCMDLINE,str);
+ break;
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_FILEDIR:
+ if((HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus())) return 0;
+ break;
+ case IDC_FILEDIRBROWSE:
+ { char str[MAX_PATH];
+ GetDlgItemTextA(hwndDlg,IDC_FILEDIR,str,SIZEOF(str));
+ if(BrowseForFolder(hwndDlg,str))
+ SetDlgItemTextA(hwndDlg,IDC_FILEDIR,str);
+ break;
+ }
+ case IDC_AUTOACCEPT:
+ case IDC_NOSCANNER:
+ case IDC_SCANAFTERDL:
+ case IDC_SCANDURINGDL:
+ SendMessage(hwndDlg,M_UPDATEENABLING,0,0);
+ break;
+ case IDC_SCANCMDLINE:
+ if(HIWORD(wParam)==CBN_SELCHANGE) PostMessage(hwndDlg,M_SCANCMDLINESELCHANGE,0,0);
+ else if(HIWORD(wParam)!=CBN_EDITCHANGE) return 0;
+ break;
+ case IDC_SCANCMDLINEBROWSE:
+ { char str[MAX_PATH+2];
+ OPENFILENAMEA ofn={0};
+ char filter[512],*pfilter;
+
+ GetDlgItemTextA(hwndDlg,IDC_SCANCMDLINE,str,SIZEOF(str));
+ ofn.lStructSize=OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner=hwndDlg;
+ ofn.Flags=OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
+ strcpy(filter,Translate("Executable Files"));
+ strcat(filter," (*.exe)");
+ pfilter=filter+strlen(filter)+1;
+ strcpy(pfilter,"*.exe");
+ pfilter=pfilter+strlen(pfilter)+1;
+ strcpy(pfilter,Translate("All Files"));
+ strcat(pfilter," (*)");
+ pfilter=pfilter+strlen(pfilter)+1;
+ strcpy(pfilter,"*");
+ pfilter=pfilter+strlen(pfilter)+1;
+ *pfilter='\0';
+ ofn.lpstrFilter=filter;
+ ofn.lpstrFile=str;
+ ofn.nMaxFile=SIZEOF(str)-2;
+ if(str[0]=='"') {
+ char *pszQuote=strchr(str+1,'"');
+ if(pszQuote) *pszQuote='\0';
+ MoveMemory(str,str+1,lstrlenA(str));
+ }
+ else {
+ char *pszSpace=strchr(str,' ');
+ if(pszSpace) *pszSpace='\0';
+ }
+ ofn.nMaxFileTitle=MAX_PATH;
+ if(!GetOpenFileNameA(&ofn)) break;
+ if(strchr(str,' ')!=NULL) {
+ MoveMemory(str+1,str,SIZEOF(str)-2);
+ str[0]='"';
+ lstrcatA(str,"\"");
+ }
+ SetDlgItemTextA(hwndDlg,IDC_SCANCMDLINE,str);
+ break;
+ }
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ { char str[512];
+ GetDlgItemTextA(hwndDlg,IDC_FILEDIR,str,SIZEOF(str));
+ DBWriteContactSettingString(NULL,"SRFile","RecvFilesDirAdv",str);
+ DBWriteContactSettingByte(NULL,"SRFile","AutoAccept",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_AUTOACCEPT));
+ DBWriteContactSettingByte(NULL,"SRFile","AutoMin",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_AUTOMIN));
+ DBWriteContactSettingByte(NULL,"SRFile","AutoClose",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_AUTOCLOSE));
+ DBWriteContactSettingByte(NULL,"SRFile","UseScanner",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_SCANAFTERDL)?VIRUSSCAN_AFTERDL:(IsDlgButtonChecked(hwndDlg,IDC_SCANDURINGDL)?VIRUSSCAN_DURINGDL:VIRUSSCAN_DISABLE)));
+ GetDlgItemTextA(hwndDlg,IDC_SCANCMDLINE,str,SIZEOF(str));
+ DBWriteContactSettingString(NULL,"SRFile","ScanCmdLine",str);
+ DBWriteContactSettingByte(NULL,"SRFile","WarnBeforeOpening",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_WARNBEFOREOPENING));
+ DBWriteContactSettingByte(NULL,"SRFile","IfExists",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_ASK)?FILERESUME_ASK:(IsDlgButtonChecked(hwndDlg,IDC_RESUME)?FILERESUME_RESUMEALL:(IsDlgButtonChecked(hwndDlg,IDC_OVERWRITE)?FILERESUME_OVERWRITEALL:FILERESUME_RENAMEALL))));
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+int FileOptInitialise(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp={0};
+ odp.cbSize = sizeof(odp);
+ odp.position = 900000000;
+ odp.hInstance = GetModuleHandle(NULL);
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FILETRANSFER);
+ odp.pszTitle = "File Transfers";
+ odp.pszGroup = "Events";
+ odp.pfnDlgProc = DlgProcFileOpts;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.nIDBottomSimpleControl = IDC_VIRUSSCANNERGROUP;
+ CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp );
+ return 0;
+}
+
diff --git a/miranda-wine/src/modules/srfile/filerecvdlg.c b/miranda-wine/src/modules/srfile/filerecvdlg.c new file mode 100644 index 0000000..602cb2c --- /dev/null +++ b/miranda-wine/src/modules/srfile/filerecvdlg.c @@ -0,0 +1,431 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 <shlobj.h>
+#include "file.h"
+
+#define MAX_MRU_DIRS 5
+
+static BOOL CALLBACK ClipSiblingsChildEnumProc(HWND hwnd,LPARAM lParam)
+{
+ SetWindowLong(hwnd,GWL_STYLE,GetWindowLong(hwnd,GWL_STYLE)|WS_CLIPSIBLINGS);
+ return TRUE;
+}
+
+static void GetLowestExistingDirName(const char *szTestDir,char *szExistingDir,int cchExistingDir)
+{
+ DWORD dwAttributes;
+ char *pszLastBackslash;
+
+ lstrcpynA(szExistingDir,szTestDir,cchExistingDir);
+ while((dwAttributes=GetFileAttributesA(szExistingDir))!=0xffffffff && !(dwAttributes&FILE_ATTRIBUTE_DIRECTORY)) {
+ pszLastBackslash=strrchr(szExistingDir,'\\');
+ if(pszLastBackslash==NULL) {*szExistingDir='\0'; break;}
+ *pszLastBackslash='\0';
+ }
+ if(szExistingDir[0]=='\0') GetCurrentDirectoryA(cchExistingDir,szExistingDir);
+}
+
+static const char validFilenameChars[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!&{}-=#@~,. ";
+static void RemoveInvalidFilenameChars(char *szString)
+{
+ int i;
+ for(i=strspn(szString,validFilenameChars);szString[i];i+=strspn(szString+i+1,validFilenameChars)+1)
+ if(szString[i]>=0) szString[i]='%';
+}
+
+static INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData)
+{
+ char szDir[MAX_PATH];
+ switch(uMsg) {
+ case BFFM_INITIALIZED:
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
+ break;
+ case BFFM_SELCHANGED:
+ if (SHGetPathFromIDListA((LPITEMIDLIST) lp ,szDir))
+ SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
+ break;
+ }
+ return 0;
+}
+
+int BrowseForFolder(HWND hwnd,char *szPath)
+{
+ BROWSEINFOA bi={0};
+ LPMALLOC pMalloc;
+ ITEMIDLIST *pidlResult;
+ int result=0;
+
+ if(SUCCEEDED(OleInitialize(NULL))) {
+ if(SUCCEEDED(CoGetMalloc(1,&pMalloc))) {
+ bi.hwndOwner=hwnd;
+ bi.pszDisplayName=szPath;
+ bi.lpszTitle=Translate("Select Folder");
+ bi.ulFlags=BIF_NEWDIALOGSTYLE|BIF_EDITBOX|BIF_RETURNONLYFSDIRS; // Use this combo instead of BIF_USENEWUI
+ bi.lpfn=BrowseCallbackProc;
+ bi.lParam=(LPARAM)szPath;
+
+ pidlResult=SHBrowseForFolderA(&bi);
+ if(pidlResult) {
+ SHGetPathFromIDListA(pidlResult,szPath);
+ lstrcatA(szPath,"\\");
+ result=1;
+ }
+ pMalloc->lpVtbl->Free(pMalloc,pidlResult);
+ pMalloc->lpVtbl->Release(pMalloc);
+ }
+ OleUninitialize();
+ }
+ return result;
+}
+
+static void ReplaceStr(char str[], int len, char *from, char *to) {
+ char *tmp;
+
+ if (tmp=strstr(str, from)) {
+ int pos = tmp - str;
+ int tlen = lstrlenA(from);
+
+ tmp = mir_strdup(str);
+ if (lstrlenA(to)>tlen)
+ tmp = (char*)mir_realloc(tmp, lstrlenA(tmp)+1+lstrlenA(to)-tlen);
+
+ MoveMemory(tmp+pos+lstrlenA(to), tmp+pos+tlen, lstrlenA(tmp)+1-pos-tlen);
+ CopyMemory(tmp+pos, to, lstrlenA(to));
+ mir_snprintf(str, len, "%s", tmp);
+ mir_free(tmp);
+ }
+}
+
+void GetContactReceivedFilesDir(HANDLE hContact,char *szDir,int cchDir)
+{
+ DBVARIANT dbv;
+ char *szRecvFilesDir, szTemp[MAX_PATH];
+ int len;
+
+ if(DBGetContactSetting(NULL,"SRFile","RecvFilesDirAdv",&dbv)||lstrlenA(dbv.pszVal)==0) {
+ char szDbPath[MAX_PATH];
+
+ CallService(MS_DB_GETPROFILEPATH,(WPARAM)MAX_PATH,(LPARAM)szDbPath);
+ lstrcatA(szDbPath,"\\");
+ lstrcatA(szDbPath,Translate("Received Files"));
+ lstrcatA(szDbPath,"\\%userid%");
+ szRecvFilesDir=mir_strdup(szDbPath);
+ }
+ else {
+ char szDrive[_MAX_DRIVE];
+ _splitpath(dbv.pszVal, szDrive, NULL, NULL, NULL);
+ if ( szDrive[0] == 0 && memcmp( dbv.pszVal, "\\\\", 2 ) != 0 ) {
+ char szDbPath[MAX_PATH];
+ CallService(MS_DB_GETPROFILEPATH,(WPARAM)MAX_PATH,(LPARAM)szDbPath);
+ lstrcatA(szDbPath,"\\");
+ lstrcatA(szDbPath,dbv.pszVal);
+ szRecvFilesDir=mir_strdup(szDbPath);
+ }
+ else szRecvFilesDir=mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ lstrcpynA(szTemp,szRecvFilesDir,SIZEOF(szTemp));
+ if (hContact) {
+ CONTACTINFO ci;
+ char szNick[64];
+ char szUsername[64];
+ char szProto[64];
+
+ szNick[0] = '\0';
+ szUsername[0] = '\0';
+ szProto[0] = '\0';
+
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+ ci.szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+ ci.dwFlag = CNF_UNIQUEID;
+ mir_snprintf(szProto, SIZEOF(szProto), "%s", ci.szProto);
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_snprintf(szUsername, SIZEOF(szUsername), "%s", ci.pszVal);
+ miranda_sys_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(szUsername, SIZEOF(szUsername), "%u", ci.dVal);
+ break;
+ } }
+
+ mir_snprintf(szNick, SIZEOF(szNick), "%s", (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0));
+ if (lstrlenA(szUsername)==0)
+ mir_snprintf(szUsername, SIZEOF(szUsername), "%s", (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0));
+
+ RemoveInvalidFilenameChars(szNick);
+ RemoveInvalidFilenameChars(szUsername);
+ RemoveInvalidFilenameChars(szProto);
+ ReplaceStr(szTemp, SIZEOF(szTemp), "%nick%", szNick);
+ ReplaceStr(szTemp, SIZEOF(szTemp), "%userid%", szUsername);
+ ReplaceStr(szTemp, SIZEOF(szTemp), "%proto%", szProto);
+ }
+ lstrcpynA(szDir,szTemp,cchDir);
+ mir_free(szRecvFilesDir);
+ len=lstrlenA(szDir);
+ if(len+1<cchDir && szDir[len-1]!='\\') lstrcpyA(szDir+len,"\\");
+}
+
+BOOL CALLBACK DlgProcRecvFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct FileDlgData *dat;
+
+ dat=(struct FileDlgData*)GetWindowLong(hwndDlg,GWL_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG: {
+ TCHAR *contactName;
+ char szPath[450];
+
+ TranslateDialogDefault(hwndDlg);
+
+ dat=(struct FileDlgData*)mir_calloc(sizeof(struct FileDlgData));
+ SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)dat);
+ dat->hContact=((CLISTEVENT*)lParam)->hContact;
+ dat->hDbEvent=((CLISTEVENT*)lParam)->hDbEvent;
+ dat->hPreshutdownEvent=HookEventMessage(ME_SYSTEM_PRESHUTDOWN,hwndDlg,M_PRESHUTDOWN);
+ dat->dwTicks=GetTickCount();
+
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_EVENT_FILE));
+ EnumChildWindows(hwndDlg,ClipSiblingsChildEnumProc,0);
+ dat->hUIIcons[0]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ADDCONTACT),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ dat->hUIIcons[1]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_USERDETAILS),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ dat->hUIIcons[2]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_HISTORY),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ dat->hUIIcons[3]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_DOWNARROW),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ SendDlgItemMessage(hwndDlg,IDC_ADD,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[0]);
+ SendDlgItemMessage(hwndDlg,IDC_DETAILS,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[1]);
+ SendDlgItemMessage(hwndDlg,IDC_HISTORY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[2]);
+ SendDlgItemMessage(hwndDlg,IDC_USERMENU,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[3]);
+ SendDlgItemMessage(hwndDlg,IDC_ADD,BUTTONSETASFLATBTN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_DETAILS,BUTTONSETASFLATBTN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_HISTORY,BUTTONSETASFLATBTN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_USERMENU,BUTTONSETASFLATBTN,0,0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_ADD), BUTTONADDTOOLTIP, (WPARAM)Translate("Add Contact Permanently to List"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_USERMENU), BUTTONADDTOOLTIP, (WPARAM)Translate("User Menu"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_DETAILS), BUTTONADDTOOLTIP, (WPARAM)Translate("View User's Details"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_HISTORY), BUTTONADDTOOLTIP, (WPARAM)Translate("View User's History"), 0);
+
+ contactName=(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)dat->hContact,GCDNF_TCHAR);
+ SetDlgItemText(hwndDlg,IDC_FROM,contactName);
+ GetContactReceivedFilesDir(dat->hContact,szPath,SIZEOF(szPath));
+ SetDlgItemTextA(hwndDlg,IDC_FILEDIR,szPath);
+ { int i;
+ char idstr[32];
+ DBVARIANT dbv;
+ HRESULT (STDAPICALLTYPE *MySHAutoComplete)(HWND,DWORD);
+
+ MySHAutoComplete=(HRESULT (STDAPICALLTYPE*)(HWND,DWORD))GetProcAddress(GetModuleHandleA("shlwapi"),"SHAutoComplete");
+ if(MySHAutoComplete) MySHAutoComplete(GetWindow(GetDlgItem(hwndDlg,IDC_FILEDIR),GW_CHILD),1);
+ for(i=0;i<MAX_MRU_DIRS;i++) {
+ wsprintfA(idstr,"MruDir%d",i);
+ if(DBGetContactSetting(NULL,"SRFile",idstr,&dbv)) break;
+ SendDlgItemMessageA(hwndDlg,IDC_FILEDIR,CB_ADDSTRING,0,(LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ }
+
+ CallService(MS_DB_EVENT_MARKREAD,(WPARAM)dat->hContact,(LPARAM)dat->hDbEvent);
+
+ { DBEVENTINFO dbei={0};
+ DBTIMETOSTRINGT dbtts;
+ TCHAR datetimestr[64];
+
+ dbei.cbSize=sizeof(dbei);
+ dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)dat->hDbEvent,0);
+ dbei.pBlob=(PBYTE)mir_alloc(dbei.cbBlob);
+ CallService(MS_DB_EVENT_GET,(WPARAM)dat->hDbEvent,(LPARAM)&dbei);
+ dat->fs=(HANDLE)*(PDWORD)dbei.pBlob;
+ lstrcpynA(szPath, dbei.pBlob+4, min(dbei.cbBlob+1,SIZEOF(szPath)));
+ SetDlgItemTextA(hwndDlg,IDC_FILENAMES,szPath);
+ lstrcpynA(szPath, dbei.pBlob+4+strlen(dbei.pBlob+4)+1, min(dbei.cbBlob-4-strlen(dbei.pBlob+4),SIZEOF(szPath)));
+ SetDlgItemTextA(hwndDlg,IDC_MSG,szPath);
+ mir_free(dbei.pBlob);
+
+ dbtts.szFormat = _T("t d");
+ dbtts.szDest = datetimestr;
+ dbtts.cbDest = SIZEOF(datetimestr);
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, dbei.timestamp, ( LPARAM )&dbtts);
+ SetDlgItemText(hwndDlg, IDC_DATE, datetimestr);
+ }
+ { char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hContact, 0);
+ if (szProto) {
+ CONTACTINFO ci;
+ int hasName = 0;
+ char buf[128];
+ ZeroMemory(&ci,sizeof(ci));
+
+ ci.cbSize = sizeof(ci);
+ ci.hContact = dat->hContact;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_UNIQUEID;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&ci)) {
+ switch(ci.type) {
+ case CNFT_ASCIIZ:
+ hasName = 1;
+ mir_snprintf(buf, SIZEOF(buf), "%s", ci.pszVal);
+ mir_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ hasName = 1;
+ mir_snprintf(buf, SIZEOF(buf),"%u",ci.dVal);
+ break;
+ } }
+ if (hasName)
+ SetDlgItemTextA(hwndDlg, IDC_NAME, buf );
+ else
+ SetDlgItemText(hwndDlg, IDC_NAME, contactName);
+ } }
+
+ if(DBGetContactSettingByte(dat->hContact,"CList","NotOnList",0)) {
+ RECT rcBtn1,rcBtn2,rcDateCtrl;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_ADD),&rcBtn1);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rcBtn2);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DATE),&rcDateCtrl);
+ SetWindowPos(GetDlgItem(hwndDlg,IDC_DATE),0,0,0,rcDateCtrl.right-rcDateCtrl.left-(rcBtn2.left-rcBtn1.left),rcDateCtrl.bottom-rcDateCtrl.top,SWP_NOZORDER|SWP_NOMOVE);
+ }
+ else if(DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0)) {
+ //don't check auto-min here to fix BUG#647620
+ PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDOK,BN_CLICKED),(LPARAM)GetDlgItem(hwndDlg,IDOK));
+ }
+ if(!DBGetContactSettingByte(dat->hContact,"CList","NotOnList",0))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADD),SW_HIDE);
+ return TRUE;
+ }
+ case M_FILEEXISTSDLGREPLY:
+ return SendMessage(dat->hwndTransfer,msg,wParam,lParam);
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+ case WM_DRAWITEM:
+ { LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam;
+ if(dis->hwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) {
+ char *szProto;
+
+ szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0);
+ if (szProto) {
+ HICON hIcon;
+
+ hIcon=(HICON)CallProtoService(szProto,PS_LOADICON,PLI_PROTOCOL|PLIF_SMALL,0);
+ if (hIcon) {
+ DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
+ DestroyIcon(hIcon);
+ } } }
+
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+ }
+ case WM_COMMAND:
+ if ( CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), (LPARAM)dat->hContact ))
+ break;
+
+ switch ( LOWORD( wParam )) {
+ case IDC_FILEDIRBROWSE:
+ {
+ char szDirName[MAX_PATH],szExistingDirName[MAX_PATH];
+
+ GetDlgItemTextA(hwndDlg,IDC_FILEDIR,szDirName,SIZEOF(szDirName));
+ GetLowestExistingDirName(szDirName,szExistingDirName,SIZEOF(szExistingDirName));
+ if(BrowseForFolder(hwndDlg,szExistingDirName))
+ SetDlgItemTextA(hwndDlg,IDC_FILEDIR,szExistingDirName);
+ return TRUE;
+ }
+ case IDOK:
+ if(dat->hwndTransfer) return SendMessage(dat->hwndTransfer,msg,wParam,lParam);
+ { //most recently used directories
+ char szRecvDir[MAX_PATH],szDefaultRecvDir[MAX_PATH];
+ GetDlgItemTextA(hwndDlg,IDC_FILEDIR,szRecvDir,SIZEOF(szRecvDir));
+ GetContactReceivedFilesDir(NULL,szDefaultRecvDir,SIZEOF(szDefaultRecvDir));
+ if(_strnicmp(szRecvDir,szDefaultRecvDir,lstrlenA(szDefaultRecvDir))) {
+ char idstr[32];
+ int i;
+ DBVARIANT dbv;
+ for(i=MAX_MRU_DIRS-2;i>=0;i--) {
+ wsprintfA(idstr,"MruDir%d",i);
+ if(DBGetContactSetting(NULL,"SRFile",idstr,&dbv)) continue;
+ wsprintfA(idstr,"MruDir%d",i+1);
+ DBWriteContactSettingString(NULL,"SRFile",idstr,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ DBWriteContactSettingString(NULL,"SRFile",idstr,szRecvDir);
+ }
+ }
+ EnableWindow(GetDlgItem(hwndDlg,IDC_FILENAMES),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_MSG),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_FILEDIR),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_FILEDIRBROWSE),FALSE);
+ dat->hwndTransfer=CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILETRANSFERINFO),hwndDlg,DlgProcFileTransfer);
+ //check for auto-minimize here to fix BUG#647620
+ if(DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0) && DBGetContactSettingByte(NULL,"SRFile","AutoMin",0))
+ ShowWindow(hwndDlg,SW_SHOWMINIMIZED);
+ return TRUE;
+ case IDCANCEL:
+ if (dat->fs) CallContactService(dat->hContact,PSS_FILEDENY,(WPARAM)dat->fs,(LPARAM)Translate("Cancelled"));
+ dat->fs=NULL; /* the protocol will free the handle */
+ if(dat->hwndTransfer) return SendMessage(dat->hwndTransfer,msg,wParam,lParam);
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ case IDC_ADD:
+ { ADDCONTACTSTRUCT acs={0};
+
+ acs.handle=dat->hContact;
+ acs.handleType=HANDLE_CONTACT;
+ acs.szProto="";
+ CallService(MS_ADDCONTACT_SHOW,(WPARAM)hwndDlg,(LPARAM)&acs);
+ if(!DBGetContactSettingByte(dat->hContact,"CList","NotOnList",0))
+ ShowWindow(GetDlgItem(hwndDlg,IDC_ADD), SW_HIDE);
+ return TRUE;
+ }
+ case IDC_USERMENU:
+ { RECT rc;
+ HMENU hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)dat->hContact,0);
+ GetWindowRect((HWND)lParam,&rc);
+ TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL);
+ DestroyMenu(hMenu);
+ break;
+ }
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)dat->hContact,0);
+ return TRUE;
+ case IDC_HISTORY:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)dat->hContact,0);
+ return TRUE;
+ }
+ break;
+
+ case M_PRESHUTDOWN:
+ if (IsWindow(dat->hwndTransfer)) PostMessage(dat->hwndTransfer,WM_CLOSE,0,0);
+ break;
+
+ case WM_DESTROY:
+ if(dat->hPreshutdownEvent) UnhookEvent(dat->hPreshutdownEvent);
+ if(dat->hwndTransfer) DestroyWindow(dat->hwndTransfer);
+ DestroyIcon(dat->hUIIcons[3]);
+ DestroyIcon(dat->hUIIcons[2]);
+ DestroyIcon(dat->hUIIcons[1]);
+ DestroyIcon(dat->hUIIcons[0]);
+ mir_free(dat);
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/miranda-wine/src/modules/srfile/filesenddlg.c b/miranda-wine/src/modules/srfile/filesenddlg.c new file mode 100644 index 0000000..fe6ada6 --- /dev/null +++ b/miranda-wine/src/modules/srfile/filesenddlg.c @@ -0,0 +1,380 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 <sys/types.h>
+#include <sys/stat.h>
+#include "file.h"
+
+static void SetFileListAndSizeControls(HWND hwndDlg,struct FileDlgData *dat)
+{
+ int fileCount=0,dirCount=0,totalSize=0,i;
+ struct _stat statbuf;
+ TCHAR str[64];
+
+ for(i=0;dat->files[i];i++) {
+ if(_stat(dat->files[i],&statbuf)==0) {
+ if(statbuf.st_mode&_S_IFDIR) dirCount++;
+ else fileCount++;
+ totalSize+=statbuf.st_size;
+ }
+ }
+ GetSensiblyFormattedSize(totalSize,str,SIZEOF(str),0,1,NULL);
+ SetDlgItemText(hwndDlg,IDC_TOTALSIZE,str);
+ if(i>1) {
+ TCHAR szFormat[32];
+ if(fileCount && dirCount) {
+ mir_sntprintf(szFormat,SIZEOF(szFormat),_T("%s, %s"),TranslateTS(fileCount==1?_T("%d file"):_T("%d files")),TranslateTS(dirCount==1?_T("%d directory"):_T("%d directories")));
+ mir_sntprintf(str,SIZEOF(str),szFormat,fileCount,dirCount);
+ }
+ else if(fileCount) {
+ lstrcpy(szFormat,TranslateT("%d files"));
+ mir_sntprintf(str,SIZEOF(str),szFormat,fileCount);
+ }
+ else {
+ lstrcpy(szFormat,TranslateT("%d directories"));
+ mir_sntprintf(str,SIZEOF(str),szFormat,dirCount);
+ }
+ SetDlgItemText(hwndDlg,IDC_FILE,str);
+ }
+ else SetDlgItemTextA(hwndDlg,IDC_FILE,dat->files[0]);
+}
+
+static void FilenameToFileList(HWND hwndDlg, struct FileDlgData* dat, const TCHAR* buf)
+{
+ DWORD dwFileAttributes;
+
+ // Make sure that the file matrix is empty (the user may select files several times)
+ FreeFilesMatrix(&dat->files);
+
+ // Get the file attributes of selection
+ dwFileAttributes = GetFileAttributes( buf );
+ if (dwFileAttributes == INVALID_FILE_ATTRIBUTES)
+ return;
+
+ // Check if the selection is a directory or a file
+ if ( GetFileAttributes( buf ) & FILE_ATTRIBUTE_DIRECTORY ) {
+ const TCHAR* pBuf;
+ int nNumberOfFiles = 0;
+ int nTemp;
+ int fileOffset;
+
+ // :NOTE: The first string in the buffer is the directory, followed by a
+ // NULL separated list of all files
+
+ // fileOffset is the offset to the first file.
+ fileOffset = lstrlen(buf) + 1;
+
+ // Count number of files
+ pBuf = buf + fileOffset;
+ while ( *pBuf ) {
+ pBuf += lstrlen(pBuf) + 1;
+ nNumberOfFiles++;
+ }
+
+ // Allocate memory for a pointer array
+ if (( dat->files = (char**)mir_alloc((nNumberOfFiles + 1) * sizeof(char*))) == NULL )
+ return;
+
+ // Fill the array
+ pBuf = buf + fileOffset;
+ nTemp = 0;
+ while(*pBuf)
+ {
+ // Allocate space for path+filename
+ int cbFileNameLen = lstrlen( pBuf );
+ dat->files[nTemp] = mir_alloc(fileOffset + cbFileNameLen + 1);
+
+ // Add path to filename and copy into array
+ #if defined( _UNICODE )
+ WideCharToMultiByte( CP_ACP, 0, buf, fileOffset-1, dat->files[nTemp], fileOffset - 1, 0, 0 );
+ dat->files[nTemp][fileOffset-1] = '\\';
+ WideCharToMultiByte( CP_ACP, 0, pBuf, -1, dat->files[nTemp] + fileOffset - (buf[fileOffset-2]=='\\'?1:0), cbFileNameLen+1, 0, 0 );
+ #else
+ CopyMemory(dat->files[nTemp], buf, fileOffset-1 );
+ dat->files[nTemp][fileOffset-1] = '\\';
+ strcpy(dat->files[nTemp] + fileOffset - (buf[fileOffset-2]=='\\'?1:0), pBuf);
+ #endif
+ // Move pointers to next file...
+ pBuf += cbFileNameLen + 1;
+ nTemp++;
+ }
+ // Terminate array
+ dat->files[nNumberOfFiles] = NULL;
+ }
+ // ...the selection is a single file
+ else
+ {
+ if (( dat->files = (char**)mir_alloc(2 * sizeof(char*))) == NULL ) // Leaks when aborted
+ return;
+
+ #if defined( _UNICODE )
+ {
+ char szFileName[ MAX_PATH ];
+ BOOL bUsed;
+ WideCharToMultiByte( CP_ACP, 0, buf, -1, szFileName, MAX_PATH, NULL, &bUsed );
+ if ( bUsed ) {
+ WIN32_FIND_DATA dat;
+ HANDLE hSearch = FindFirstFile( buf, &dat );
+ if ( hSearch != INVALID_HANDLE_VALUE ) {
+ WideCharToMultiByte( CP_ACP, 0, dat.cAlternateFileName, -1, szFileName, MAX_PATH, 0, 0 );
+ FindClose( hSearch );
+ } }
+
+ dat->files[0] = mir_strdup(szFileName);
+ }
+ #else
+ dat->files[0] = mir_strdup(buf);
+ #endif
+
+ dat->files[1] = NULL;
+ }
+
+ // Update dialog text with new file selection
+ SetFileListAndSizeControls(hwndDlg, dat);
+}
+
+#define M_FILECHOOSEDONE (WM_USER+100)
+void __cdecl ChooseFilesThread(HWND hwndDlg)
+{
+ TCHAR filter[128], *pfilter;
+ TCHAR* buf = ( TCHAR* )mir_alloc( sizeof(TCHAR)*32767 );
+ if ( buf == NULL )
+ PostMessage( hwndDlg, M_FILECHOOSEDONE, 0, ( LPARAM )( TCHAR* )NULL );
+ else {
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ lstrcpy( filter, TranslateT( "All Files" ));
+ lstrcat( filter, _T(" (*)" ));
+ pfilter = filter + lstrlen( filter )+1;
+ lstrcpy( pfilter, _T( "*" ));
+ pfilter = filter + lstrlen( filter )+1;
+ pfilter[ 0 ] = '\0';
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = buf; *buf = 0;
+ ofn.nMaxFile = 32767;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_HIDEREADONLY;
+ if ( GetOpenFileName( &ofn ))
+ PostMessage( hwndDlg, M_FILECHOOSEDONE, 0, ( LPARAM )buf );
+ else {
+ mir_free( buf );
+ PostMessage( hwndDlg, M_FILECHOOSEDONE, 0, ( LPARAM )( TCHAR* )NULL );
+} } }
+
+static BOOL CALLBACK ClipSiblingsChildEnumProc(HWND hwnd,LPARAM lParam)
+{
+ SetWindowLong(hwnd,GWL_STYLE,GetWindowLong(hwnd,GWL_STYLE)|WS_CLIPSIBLINGS);
+ return TRUE;
+}
+
+static WNDPROC OldSendEditProc;
+static LRESULT CALLBACK SendEditSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_CHAR:
+ if(wParam=='\n' && GetKeyState(VK_CONTROL)&0x8000) {
+ PostMessage(GetParent(hwnd),WM_COMMAND,IDOK,0);
+ return 0;
+ }
+ break;
+ case WM_SYSCHAR:
+ if((wParam=='s' || wParam=='S') && GetKeyState(VK_MENU)&0x8000) {
+ PostMessage(GetParent(hwnd),WM_COMMAND,IDOK,0);
+ return 0;
+ }
+ break;
+ }
+ return CallWindowProc(OldSendEditProc,hwnd,msg,wParam,lParam);
+}
+
+BOOL CALLBACK DlgProcSendFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct FileDlgData *dat;
+
+ dat=(struct FileDlgData*)GetWindowLong(hwndDlg,GWL_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ struct FileSendData *fsd=(struct FileSendData*)lParam;
+
+ dat=(struct FileDlgData*)mir_alloc(sizeof(struct FileDlgData));
+ memset(dat,0,sizeof(struct FileDlgData));
+ SetWindowLong(hwndDlg,GWL_USERDATA,(long)dat);
+ dat->hContact=fsd->hContact;
+ dat->send=1;
+ dat->hPreshutdownEvent=HookEventMessage(ME_SYSTEM_PRESHUTDOWN,hwndDlg,M_PRESHUTDOWN);
+ dat->fs=NULL;
+ dat->dwTicks=GetTickCount();
+
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_EVENT_FILE));
+ EnumChildWindows(hwndDlg,ClipSiblingsChildEnumProc,0);
+ OldSendEditProc=(WNDPROC)SetWindowLong(GetDlgItem(hwndDlg,IDC_MSG),GWL_WNDPROC,(LONG)SendEditSubclassProc);
+
+ dat->hUIIcons[0]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_USERDETAILS),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ dat->hUIIcons[1]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_HISTORY),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ dat->hUIIcons[2]=LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_DOWNARROW),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+ SendDlgItemMessage(hwndDlg,IDC_DETAILS,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[0]);
+ SendDlgItemMessage(hwndDlg,IDC_HISTORY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[1]);
+ SendDlgItemMessage(hwndDlg,IDC_USERMENU,BM_SETIMAGE,IMAGE_ICON,(LPARAM)dat->hUIIcons[2]);
+ SendDlgItemMessage(hwndDlg,IDC_DETAILS,BUTTONSETASFLATBTN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_HISTORY,BUTTONSETASFLATBTN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_USERMENU,BUTTONSETASFLATBTN,0,0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_USERMENU), BUTTONADDTOOLTIP, (WPARAM)Translate("User Menu"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_DETAILS), BUTTONADDTOOLTIP, (WPARAM)Translate("View User's Details"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_HISTORY), BUTTONADDTOOLTIP, (WPARAM)Translate("View User's History"), 0);
+
+ if(fsd->ppFiles!=NULL && fsd->ppFiles[0]!=NULL) {
+ int totalCount,i;
+ for(totalCount=0;fsd->ppFiles[totalCount];totalCount++);
+ dat->files=(char**)mir_alloc(sizeof(char*)*(totalCount+1)); // Leaks
+ for(i=0;i<totalCount;i++)
+ dat->files[i]=mir_strdup(fsd->ppFiles[i]);
+ dat->files[totalCount]=NULL;
+ SetFileListAndSizeControls(hwndDlg,dat);
+ }
+ {
+ char *szProto;
+ TCHAR* contactName=(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)dat->hContact,GCDNF_TCHAR);
+ SetDlgItemText(hwndDlg,IDC_TO,contactName);
+
+ szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0);
+ if (szProto) {
+ CONTACTINFO ci;
+ int hasName = 0;
+ char buf[128];
+ ZeroMemory(&ci,sizeof(ci));
+
+ ci.cbSize = sizeof(ci);
+ ci.hContact = dat->hContact;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_UNIQUEID;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&ci)) {
+ switch(ci.type) {
+ case CNFT_ASCIIZ:
+ hasName = 1;
+ mir_snprintf(buf, SIZEOF(buf), "%s", ci.pszVal);
+ mir_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ hasName = 1;
+ mir_snprintf(buf, SIZEOF(buf),"%u",ci.dVal);
+ break;
+ }
+ }
+ if ( hasName )
+ SetDlgItemTextA(hwndDlg,IDC_NAME,buf);
+ else
+ SetDlgItemText(hwndDlg,IDC_NAME,contactName);
+ }
+ }
+ if(fsd->ppFiles==NULL) {
+ dat->closeIfFileChooseCancelled=1;
+ PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_CHOOSE,BN_CLICKED),(LPARAM)GetDlgItem(hwndDlg,IDC_CHOOSE));
+ }
+ return TRUE;
+ }
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+ case WM_DRAWITEM:
+ { LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam;
+ if(dis->hwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) {
+ char *szProto;
+
+ szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0);
+ if (szProto) {
+ HICON hIcon;
+
+ hIcon=(HICON)CallProtoService(szProto,PS_LOADICON,PLI_PROTOCOL|PLIF_SMALL,0);
+ if (hIcon) {
+ DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
+ DestroyIcon(hIcon);
+ }
+ }
+ }
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+ }
+ case M_FILECHOOSEDONE:
+ if( lParam != 0 ) {
+ FilenameToFileList( hwndDlg, dat, ( TCHAR* )lParam );
+ mir_free(( TCHAR* )lParam );
+ dat->closeIfFileChooseCancelled = 0;
+ }
+ else if(dat->closeIfFileChooseCancelled) DestroyWindow(hwndDlg);
+ EnableWindow(hwndDlg,TRUE);
+ break;
+ case WM_COMMAND:
+ if(CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU),(LPARAM)dat->hContact))
+ break;
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHOOSE:
+ EnableWindow(hwndDlg,FALSE);
+ //GetOpenFileName() creates its own message queue which prevents any incoming events being processed
+ forkthread(ChooseFilesThread,0,hwndDlg);
+ break;
+ case IDOK:
+ if(dat->hwndTransfer) return SendMessage(dat->hwndTransfer,msg,wParam,lParam);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_FILENAME),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_MSG),FALSE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHOOSE),FALSE);
+ dat->hwndTransfer=CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILETRANSFERINFO),hwndDlg,DlgProcFileTransfer);
+ return TRUE;
+ case IDCANCEL:
+ if(dat->hwndTransfer) return SendMessage(dat->hwndTransfer,msg,wParam,lParam);
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ case IDC_USERMENU:
+ { RECT rc;
+ HMENU hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)dat->hContact,0);
+ GetWindowRect((HWND)lParam,&rc);
+ TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL);
+ DestroyMenu(hMenu);
+ break;
+ }
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)dat->hContact,0);
+ return TRUE;
+ case IDC_HISTORY:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)dat->hContact,0);
+ return TRUE;
+ }
+ break;
+ case M_PRESHUTDOWN:
+ {
+ if (IsWindow(dat->hwndTransfer)) PostMessage(dat->hwndTransfer,WM_CLOSE,0,0);
+ break;
+ }
+ case WM_DESTROY:
+ if(dat->hPreshutdownEvent) UnhookEvent(dat->hPreshutdownEvent);
+ if(dat->hwndTransfer) DestroyWindow(dat->hwndTransfer);
+ FreeFilesMatrix(&dat->files);
+ SetWindowLong(GetDlgItem(hwndDlg,IDC_MSG),GWL_WNDPROC,(LONG)OldSendEditProc);
+ DestroyIcon(dat->hUIIcons[2]);
+ DestroyIcon(dat->hUIIcons[1]);
+ DestroyIcon(dat->hUIIcons[0]);
+ mir_free(dat);
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/miranda-wine/src/modules/srfile/filexferdlg.c b/miranda-wine/src/modules/srfile/filexferdlg.c new file mode 100644 index 0000000..468ce47 --- /dev/null +++ b/miranda-wine/src/modules/srfile/filexferdlg.c @@ -0,0 +1,562 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 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 <io.h>
+#include "file.h"
+
+#define HM_RECVEVENT (WM_USER+10)
+
+static int CheckVirusScanned(HWND hwnd,struct FileDlgData *dat,int i)
+{
+ if(dat->send) return 1;
+ if(dat->fileVirusScanned[i]) return 1;
+ if(DBGetContactSettingByte(NULL,"SRFile","WarnBeforeOpening",1)==0) return 1;
+ return IDYES==MessageBox(hwnd,TranslateT("This file has not yet been scanned for viruses. Are you certain you want to open it?"),TranslateT("File Received"),MB_YESNO|MB_DEFBUTTON2);
+}
+
+#define M_VIRUSSCANDONE (WM_USER+100)
+struct virusscanthreadstartinfo {
+ char *szFile;
+ int returnCode;
+ HWND hwndReply;
+};
+
+static void SetOpenFileButtonStyle(HWND hwndButton,int downarrow,int enabled)
+{
+ if(downarrow) {
+ SendMessage(hwndButton,BUTTONSETARROW,1,0);
+ }
+ else {
+ SendMessage(hwndButton,BUTTONSETARROW,0,0);
+ }
+ EnableWindow(hwndButton,enabled);
+}
+
+static void __cdecl RunVirusScannerThread(struct virusscanthreadstartinfo *info)
+{
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si={0};
+ DBVARIANT dbv;
+ char szCmdLine[768];
+
+ if(!DBGetContactSetting(NULL,"SRFile","ScanCmdLine",&dbv)) {
+ if(dbv.pszVal[0]) {
+ char *pszReplace;
+ si.cb=sizeof(si);
+ pszReplace=strstr(dbv.pszVal,"%f");
+ if(pszReplace) {
+ if(info->szFile[lstrlenA(info->szFile)-1]=='\\') info->szFile[lstrlenA(info->szFile)-1]='\0';
+ *pszReplace=0;
+ mir_snprintf(szCmdLine,SIZEOF(szCmdLine),"%s\"%s\"%s",dbv.pszVal,info->szFile,pszReplace+2);
+ }
+ else lstrcpynA(szCmdLine,dbv.pszVal,SIZEOF(szCmdLine));
+ if(CreateProcessA(NULL,szCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) {
+ if(WaitForSingleObject(pi.hProcess,3600*1000)==WAIT_OBJECT_0)
+ PostMessage(info->hwndReply,M_VIRUSSCANDONE,info->returnCode,0);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ mir_free(info->szFile);
+ mir_free(info);
+}
+
+static void SetFilenameControls(HWND hwndDlg,PROTOFILETRANSFERSTATUS *fts)
+{
+ char str[MAX_PATH];
+ HWND hwndFilename;
+
+ { TCHAR msg[MAX_PATH];
+ GetDlgItemText(hwndDlg,IDC_FILENAME,msg,SIZEOF(msg));
+ if(msg[0]) return;
+
+ wsprintf(msg,TranslateT("Current file (%d of %d)"),fts->currentFileNumber+1,fts->totalFiles);
+ SetDlgItemText(hwndDlg,IDC_CURRENTFILEGROUP,msg);
+ }
+
+ hwndFilename=GetDlgItem(hwndDlg,IDC_FILENAME);
+ lstrcpynA(str,fts->currentFile,SIZEOF(str));
+ if(strchr(str,'\\')) {
+ RECT rcFilename;
+ HDC hdc;
+ SIZE textSize;
+ HFONT hFont;
+ int driveNameLen,driveAndEllipsisLen=0;
+ char *pszBackslash;
+
+ GetClientRect(hwndFilename,&rcFilename);
+ hdc = GetDC(hwndFilename);
+ hFont = SelectObject(hdc,(HFONT)SendMessage(hwndFilename,WM_GETFONT,0,0));
+ if(str[0] && str[1]==':' && str[2]=='\\') driveNameLen=3;
+ else if(str[0]=='\\' && str[1]=='\\') {
+ if((pszBackslash=strchr(str+2,'\\'))!=NULL && (pszBackslash=strchr(pszBackslash+1,'\\'))!=NULL)
+ driveNameLen=pszBackslash-str+1;
+ else driveNameLen=2;
+ }
+ else driveNameLen=0;
+ for(;;) {
+ GetTextExtentPoint32A(hdc,str,lstrlenA(str),&textSize);
+ if(textSize.cx<rcFilename.right) break;
+ pszBackslash=strchr(str+(driveAndEllipsisLen?driveAndEllipsisLen:driveNameLen),'\\');
+ if(pszBackslash==NULL) {
+ lstrcpyA(str,strrchr(fts->currentFile,'\\')+1);
+ break;
+ }
+ if(driveAndEllipsisLen)
+ MoveMemory(str+driveAndEllipsisLen,pszBackslash+1,lstrlenA(pszBackslash));
+ else {
+ MoveMemory(str+driveNameLen+4,pszBackslash,lstrlenA(pszBackslash)+1);
+ CopyMemory(str+driveNameLen,"...\\",4);
+ driveAndEllipsisLen=driveNameLen+4;
+ }
+ }
+ SelectObject(hdc,hFont);
+ ReleaseDC(hwndFilename,hdc);
+ }
+ SetWindowTextA(hwndFilename,str);
+}
+
+BOOL CALLBACK DlgProcFileTransfer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct FileDlgData *dat=NULL;
+
+ dat=(struct FileDlgData*)GetWindowLong(GetParent(hwndDlg),GWL_USERDATA);
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ dat->hNotifyEvent=HookEventMessage(ME_PROTO_ACK,hwndDlg,HM_RECVEVENT);
+ dat->transferStatus.currentFileNumber=-1;
+ if(dat->send) {
+ char szMsg[450];
+ GetDlgItemTextA(GetParent(hwndDlg),IDC_MSG,szMsg,SIZEOF(szMsg));
+ dat->fs=(HANDLE)CallContactService(dat->hContact,PSS_FILE,(WPARAM)szMsg,(LPARAM)dat->files);
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Request sent, waiting for acceptance..."));
+ SetOpenFileButtonStyle(GetDlgItem(hwndDlg,IDC_OPENFILE),dat->files[1]!=NULL,1);
+ dat->waitingForAcceptance=1;
+ }
+ else { //recv
+ char szSavePath[MAX_PATH];
+
+ GetDlgItemTextA(GetParent(hwndDlg),IDC_FILEDIR,szSavePath,SIZEOF(szSavePath));
+ CreateDirectoryTree(szSavePath);
+ dat->fs=(HANDLE)CallContactService(dat->hContact,PSS_FILEALLOW,(WPARAM)dat->fs,(LPARAM)szSavePath);
+ dat->transferStatus.workingDir=mir_strdup(szSavePath);
+ if(DBGetContactSettingByte(dat->hContact,"CList","NotOnList",0)) dat->resumeBehaviour=FILERESUME_ASK;
+ else dat->resumeBehaviour=DBGetContactSettingByte(NULL,"SRFile","IfExists",FILERESUME_ASK);
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Waiting for connection..."));
+ }
+ {
+ /* check we actually got an fs handle back from the protocol */
+ if (!dat->fs) {
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Unable to initiate transfer."));
+ dat->waitingForAcceptance=0;
+ }
+ }
+ { LOGFONT lf;
+ HFONT hFont;
+ hFont=(HFONT)SendDlgItemMessage(hwndDlg,IDC_CURRENTFILEGROUP,WM_GETFONT,0,0);
+ GetObject(hFont,sizeof(lf),&lf);
+ lf.lfWeight=FW_BOLD;
+ hFont=CreateFontIndirect(&lf);
+ SendDlgItemMessage(hwndDlg,IDC_CURRENTFILEGROUP,WM_SETFONT,(WPARAM)hFont,0);
+ SendDlgItemMessage(hwndDlg,IDC_ALLFILESGROUP,WM_SETFONT,(WPARAM)hFont,0);
+ }
+ { RECT rcParentClient;
+ RECT rcThisDlg;
+ BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+
+ GetClientRect(GetParent(hwndDlg),&rcParentClient);
+ GetClientRect(hwndDlg,&rcThisDlg);
+ SetWindowPos(hwndDlg,HWND_TOP,0,rcParentClient.bottom-rcThisDlg.bottom,0,0,SWP_NOSIZE);
+ MyAnimateWindow=(BOOL (WINAPI*)(HWND,DWORD,DWORD))GetProcAddress(GetModuleHandleA("USER32"),"AnimateWindow");
+ if(MyAnimateWindow)
+ MyAnimateWindow(hwndDlg,200,AW_ACTIVATE|AW_SLIDE|AW_VER_NEGATIVE);
+ else ShowWindow(hwndDlg,SW_SHOW);
+ }
+ SendDlgItemMessage(hwndDlg,IDC_OPENFILE,BUTTONSETDEFAULT,1,0);
+ if(!dat->waitingForAcceptance) SetTimer(hwndDlg,1,1000,NULL);
+ return TRUE;
+ case WM_TIMER:
+ MoveMemory(dat->bytesRecvedHistory+1,dat->bytesRecvedHistory,sizeof(dat->bytesRecvedHistory)-sizeof(dat->bytesRecvedHistory[0]));
+ dat->bytesRecvedHistory[0]=dat->transferStatus.totalProgress;
+ if ( dat->bytesRecvedHistorySize < SIZEOF(dat->bytesRecvedHistory))
+ dat->bytesRecvedHistorySize++;
+
+ { TCHAR szSpeed[32], szTime[32], szDisplay[96];
+ SYSTEMTIME st;
+ ULARGE_INTEGER li;
+ FILETIME ft;
+
+ GetSensiblyFormattedSize((dat->bytesRecvedHistory[0]-dat->bytesRecvedHistory[dat->bytesRecvedHistorySize-1])/dat->bytesRecvedHistorySize,szSpeed,SIZEOF(szSpeed),0,1,NULL);
+ if(dat->bytesRecvedHistory[0]==dat->bytesRecvedHistory[dat->bytesRecvedHistorySize-1])
+ lstrcpy(szTime,_T("??:??:??"));
+ else {
+ li.QuadPart=BIGI(10000000)*(dat->transferStatus.currentFileSize-dat->transferStatus.currentFileProgress)*dat->bytesRecvedHistorySize/(dat->bytesRecvedHistory[0]-dat->bytesRecvedHistory[dat->bytesRecvedHistorySize-1]);
+ ft.dwHighDateTime=li.HighPart; ft.dwLowDateTime=li.LowPart;
+ FileTimeToSystemTime(&ft,&st);
+ GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT|TIME_NOTIMEMARKER,&st,NULL,szTime,SIZEOF(szTime));
+ }
+ mir_sntprintf(szDisplay,SIZEOF(szDisplay),_T("%s/%s (%s %s)"),szSpeed,TranslateT("sec"),szTime,TranslateT("remaining"));
+ SetDlgItemText(hwndDlg,IDC_CURRENTSPEED,szDisplay);
+ if(dat->bytesRecvedHistory[0]!=dat->bytesRecvedHistory[dat->bytesRecvedHistorySize-1]) {
+ li.QuadPart=BIGI(10000000)*(dat->transferStatus.totalBytes-dat->transferStatus.totalProgress)*dat->bytesRecvedHistorySize/(dat->bytesRecvedHistory[0]-dat->bytesRecvedHistory[dat->bytesRecvedHistorySize-1]);
+ ft.dwHighDateTime=li.HighPart; ft.dwLowDateTime=li.LowPart;
+ FileTimeToSystemTime(&ft,&st);
+ GetTimeFormat(LOCALE_USER_DEFAULT,TIME_FORCE24HOURFORMAT|TIME_NOTIMEMARKER,&st,NULL,szTime,SIZEOF(szTime));
+ }
+ mir_sntprintf(szDisplay,SIZEOF(szDisplay),_T("%s/%s (%s %s)"),szSpeed,TranslateT("sec"),szTime,TranslateT("remaining"));
+ SetDlgItemText(hwndDlg,IDC_ALLSPEED,szDisplay);
+ }
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDCANCEL:
+ case IDOK:
+ DestroyWindow(GetParent(hwndDlg));
+ break;
+ case IDC_OPENFOLDER:
+ ShellExecuteA(NULL,NULL,dat->transferStatus.workingDir,NULL,NULL,SW_SHOW);
+ break;
+
+ case IDC_OPENFILE:
+ {
+ char **files;
+
+ if (dat->send)
+ if (dat->files == NULL)
+ files = dat->transferStatus.files;
+ else
+ files = dat->files;
+ else
+ files=dat->files;
+
+ if (files == NULL || *files == NULL)
+ break;
+
+
+ // Only one single file
+ if (files[1] == NULL) {
+ if (!CheckVirusScanned(hwndDlg, dat, 0))
+ break;
+ ShellExecuteA(NULL, NULL, files[0], NULL, NULL, SW_SHOW);
+ }
+ // Multiple files
+ else {
+ RECT rc;
+ int i,limit;
+ char *pszFilename,*pszNewFileName;
+ HMENU hMenu = CreatePopupMenu();
+
+ if (dat->send)
+ limit = dat->transferStatus.totalFiles;
+ else
+ limit = dat->transferStatus.currentFileNumber;
+
+ // Loop over all transfered files and add them to the menu
+ for (i = 0; i < limit; i++) {
+ pszFilename = strrchr(files[i], '\\');
+ if (pszFilename == NULL)
+ pszFilename = files[i];
+ else
+ pszFilename++;
+ {
+ if (pszFilename) {
+ int pszlen;
+ char *p;
+
+ pszNewFileName = (char*)mir_alloc(strlen(pszFilename)*2);
+ p = pszNewFileName;
+ for (pszlen=0; pszlen<(int)strlen(pszFilename); pszlen++) {
+ *p++ = pszFilename[pszlen];
+ if (pszFilename[pszlen]=='&')
+ *p++ = '&';
+ }
+ *p = '\0';
+ AppendMenuA(hMenu, MF_STRING, i+1, pszNewFileName);
+ mir_free(pszNewFileName);
+ }
+ }
+ }
+
+ GetWindowRect((HWND)lParam, &rc);
+ i = TrackPopupMenu(hMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+
+ if (i && CheckVirusScanned(hwndDlg, dat, i))
+ ShellExecuteA(NULL, NULL, files[i-1], NULL, NULL, SW_SHOW);
+ }
+
+ break;
+ }
+
+ }
+ break;
+ case M_FILEEXISTSDLGREPLY:
+ { PROTOFILERESUME *pfr=(PROTOFILERESUME*)lParam;
+ char *szOriginalFilename=(char*)wParam;
+ char *szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0);
+
+ EnableWindow(hwndDlg,TRUE);
+ switch(pfr->action) {
+ case FILERESUME_CANCEL:
+ if (dat->fs) CallContactService(dat->hContact,PSS_FILECANCEL,(WPARAM)dat->fs,0);
+ dat->fs=NULL;
+ DestroyWindow(GetParent(hwndDlg));
+ mir_free(szOriginalFilename);
+ if(pfr->szFilename) mir_free((char*)pfr->szFilename);
+ mir_free(pfr);
+ return 0;
+ case FILERESUME_RESUMEALL:
+ case FILERESUME_OVERWRITEALL:
+ dat->resumeBehaviour=wParam;
+ pfr->action&=~FILERESUMEF_ALL;
+ break;
+ case FILERESUME_RENAMEALL:
+ pfr->action=FILERESUME_RENAME;
+ { char *pszExtension,*pszFilename;
+ int i;
+ if((pszFilename=strrchr(szOriginalFilename,'\\'))==NULL) pszFilename=szOriginalFilename;
+ if((pszExtension=strrchr(pszFilename+1,'.'))==NULL) pszExtension=pszFilename+lstrlenA(pszFilename);
+ if(pfr->szFilename) mir_free((char*)pfr->szFilename);
+ pfr->szFilename=(char*)mir_alloc((pszExtension-szOriginalFilename)+21+lstrlenA(pszExtension));
+ for(i=1;;i++) {
+ sprintf((char*)pfr->szFilename,"%.*s (%u)%s",pszExtension-szOriginalFilename,szOriginalFilename,i,pszExtension);
+ if(_access(pfr->szFilename,0)!=0) break;
+ }
+ }
+ break;
+ }
+ mir_free(szOriginalFilename);
+ CallProtoService(szProto,PS_FILERESUME,(WPARAM)dat->fs,(LPARAM)pfr);
+ if(pfr->szFilename) mir_free((char*)pfr->szFilename);
+ mir_free(pfr);
+ break;
+ }
+ case HM_RECVEVENT:
+ { ACKDATA *ack=(ACKDATA*)lParam;
+ if (ack->hProcess!=dat->fs) break; /* icq abuses this sometimes */
+ if(ack->hContact!=dat->hContact) break;
+ if(ack->type!=ACKTYPE_FILE) break;
+
+ if(dat->waitingForAcceptance) {
+ SetTimer(hwndDlg,1,1000,NULL);
+ dat->waitingForAcceptance=0;
+ }
+ switch(ack->result) {
+ case ACKRESULT_SENTREQUEST: SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Decision sent")); break;
+ case ACKRESULT_CONNECTING: SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Connecting...")); break;
+ case ACKRESULT_CONNECTED: SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Connected")); break;
+ case ACKRESULT_INITIALISING: SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Initialising...")); break;
+ case ACKRESULT_NEXTFILE:
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Moving to next file..."));
+ SetDlgItemTextA(hwndDlg,IDC_FILENAME,"");
+ if(dat->transferStatus.currentFileNumber==1 && dat->transferStatus.totalFiles>1 && !dat->send)
+ SetOpenFileButtonStyle(GetDlgItem(hwndDlg,IDC_OPENFILE),1,1);
+ if(dat->transferStatus.currentFileNumber!=-1 && dat->files && !dat->send && DBGetContactSettingByte(NULL,"SRFile","UseScanner",VIRUSSCAN_DISABLE)==VIRUSSCAN_DURINGDL) {
+ if(GetFileAttributesA(dat->files[dat->transferStatus.currentFileNumber])&FILE_ATTRIBUTE_DIRECTORY)
+ PostMessage(hwndDlg,M_VIRUSSCANDONE,dat->transferStatus.currentFileNumber,0);
+ else {
+ struct virusscanthreadstartinfo *vstsi;
+ vstsi=(struct virusscanthreadstartinfo*)mir_alloc(sizeof(struct virusscanthreadstartinfo));
+ vstsi->hwndReply=hwndDlg;
+ vstsi->szFile=mir_strdup(dat->files[dat->transferStatus.currentFileNumber]);
+ vstsi->returnCode=dat->transferStatus.currentFileNumber;
+ forkthread((void (*)(void*))RunVirusScannerThread,0,vstsi);
+ }
+ }
+ break;
+ case ACKRESULT_FILERESUME:
+ {
+ PROTOFILETRANSFERSTATUS *fts=(PROTOFILETRANSFERSTATUS*)ack->lParam;
+
+ FreeProtoFileTransferStatus(&dat->transferStatus);
+ CopyProtoFileTransferStatus(&dat->transferStatus,fts);
+ SetFilenameControls(hwndDlg,fts);
+ if(_access(fts->currentFile,0)!=0) break;
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("File already exists"));
+ if(dat->resumeBehaviour==FILERESUME_ASK) {
+ ShowWindow(hwndDlg,SW_SHOWNORMAL);
+ CreateDialogParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_FILEEXISTS),hwndDlg,DlgProcFileExists,(LPARAM)fts);
+ EnableWindow(hwndDlg,FALSE);
+ }
+ else {
+ PROTOFILERESUME *pfr;
+ pfr=(PROTOFILERESUME*)mir_alloc(sizeof(PROTOFILERESUME));
+ pfr->action=dat->resumeBehaviour;
+ pfr->szFilename=NULL;
+ PostMessage(hwndDlg,M_FILEEXISTSDLGREPLY,(WPARAM)mir_strdup(fts->currentFile),(LPARAM)pfr);
+ }
+ SetWindowLong(hwndDlg,DWL_MSGRESULT,1);
+ return TRUE;
+ }
+ case ACKRESULT_DATA:
+ {
+ PROTOFILETRANSFERSTATUS *fts=(PROTOFILETRANSFERSTATUS*)ack->lParam;
+ TCHAR str[256],szSizeDone[32],szSizeTotal[32],*contactName;
+ int units;
+
+ /* HACK: for 0.3.3, limit updates to around 1.1 ack per second */
+ if (fts->totalProgress!=fts->totalBytes && GetTickCount() - dat->dwTicks < 650) break; // the last update was less than a second ago!
+ dat->dwTicks=GetTickCount();
+
+/* FIXME: There is a leak with this, and a major performance issue with creating and freeing this list EVERY DAMN ACK! */
+ FreeProtoFileTransferStatus(&dat->transferStatus);
+ CopyProtoFileTransferStatus(&dat->transferStatus,fts);
+ if(dat->fileVirusScanned==NULL) dat->fileVirusScanned=(int*)mir_calloc(sizeof(int) * fts->totalFiles);
+ if(!dat->send) {
+ if(dat->files==NULL) dat->files=(char**)mir_calloc((fts->totalFiles+1)*sizeof(char*));
+ if(fts->currentFileNumber<fts->totalFiles) dat->files[fts->currentFileNumber]=mir_strdup(fts->currentFile);
+ }
+/* FIXME: There is a performance issue of creating this list here if it does not exist */
+
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateTS(fts->sending?_T("Sending..."):_T("Receiving...")));
+ SetFilenameControls(hwndDlg,fts);
+ SendDlgItemMessage(hwndDlg,IDC_CURRENTFILEPROGRESS, PBM_SETPOS, fts->currentFileSize?(WPARAM)(BIGI(100)*fts->currentFileProgress/fts->currentFileSize):0, 0);
+ SendDlgItemMessage(hwndDlg,IDC_ALLFILESPROGRESS, PBM_SETPOS, fts->totalBytes?(WPARAM)(BIGI(100)*fts->totalProgress/fts->totalBytes):0, 0);
+
+ GetSensiblyFormattedSize(fts->currentFileSize,szSizeTotal,SIZEOF(szSizeTotal),0,1,&units);
+ GetSensiblyFormattedSize(fts->currentFileProgress,szSizeDone,SIZEOF(szSizeTotal),units,0,NULL);
+ mir_sntprintf(str,SIZEOF(str),_T("%s / %s (%d%%)"),szSizeDone,szSizeTotal,fts->currentFileSize?(int)(BIGI(100)*fts->currentFileProgress/fts->currentFileSize):0);
+ SetDlgItemText(hwndDlg,IDC_CURRENTTRANSFERRED,str);
+
+ GetSensiblyFormattedSize(fts->totalBytes,szSizeTotal,SIZEOF(szSizeTotal),0,1,&units);
+ GetSensiblyFormattedSize(fts->totalProgress,szSizeDone,SIZEOF(szSizeTotal),units,0,NULL);
+ mir_sntprintf(str,SIZEOF(str),_T("%s / %s (%d%%)"),szSizeDone,szSizeTotal,fts->totalBytes?(int)(BIGI(100)*fts->totalProgress/fts->totalBytes):0);
+ SetDlgItemText(hwndDlg,IDC_ALLTRANSFERRED,str);
+
+ contactName=(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)dat->hContact,GCDNF_TCHAR);
+ mir_sntprintf(str,SIZEOF(str),_T("%d%%: %s: %s"),fts->totalBytes?(int)(BIGI(100)*fts->totalProgress/fts->totalBytes):0,contactName,TranslateTS(dat->send?(fts->totalFiles==1?_T("Sending file"):_T("Sending files")):(fts->totalFiles==1?_T("Receiving file"):_T("Receiving files"))));
+ SetWindowText(GetParent(hwndDlg),str);
+ break;
+ }
+ case ACKRESULT_SUCCESS:
+ {
+ dat->fs=NULL; /* protocol will free structure */
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Transfer completed"));
+ if (ack->result==ACKRESULT_SUCCESS) SkinPlaySound("FileDone");
+ if(!dat->send) { //receiving
+ int useScanner=DBGetContactSettingByte(NULL,"SRFile","UseScanner",VIRUSSCAN_DISABLE);
+ if(useScanner!=VIRUSSCAN_DISABLE) {
+ struct virusscanthreadstartinfo *vstsi;
+ vstsi=(struct virusscanthreadstartinfo*)mir_alloc(sizeof(struct virusscanthreadstartinfo));
+ vstsi->hwndReply=hwndDlg;
+ if(useScanner==VIRUSSCAN_DURINGDL) {
+ vstsi->returnCode=dat->transferStatus.currentFileNumber;
+ if(GetFileAttributesA(dat->files[dat->transferStatus.currentFileNumber])&FILE_ATTRIBUTE_DIRECTORY) {
+ PostMessage(hwndDlg,M_VIRUSSCANDONE,vstsi->returnCode,0);
+ mir_free(vstsi);
+ vstsi=NULL;
+ }
+ else vstsi->szFile=mir_strdup(dat->files[dat->transferStatus.currentFileNumber]);
+ }
+ else {
+ vstsi->szFile=mir_strdup(dat->transferStatus.workingDir);
+ vstsi->returnCode=-1;
+ }
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Scanning for viruses..."));
+ if(vstsi) forkthread((void (*)(void*))RunVirusScannerThread,0,vstsi);
+ }
+ dat->transferStatus.currentFileNumber=dat->transferStatus.totalFiles;
+ }
+ else { //sending
+ DBEVENTINFO dbei={0};
+ char szMsg[450],szFilenames[1024];
+ GetDlgItemTextA(GetParent(hwndDlg),IDC_FILE,szFilenames,SIZEOF(szFilenames));
+ GetDlgItemTextA(GetParent(hwndDlg),IDC_MSG,szMsg,SIZEOF(szMsg));
+ dbei.cbSize=sizeof(dbei);
+ dbei.szModule=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0);
+ dbei.eventType=EVENTTYPE_FILE;
+ dbei.flags=DBEF_SENT;
+ dbei.timestamp=time(NULL);
+ dbei.cbBlob=sizeof(DWORD)+lstrlenA(szFilenames)+lstrlenA(szMsg)+2;
+ dbei.pBlob=(PBYTE)mir_alloc(dbei.cbBlob);
+ *(PDWORD)dbei.pBlob=0;
+ lstrcpyA(dbei.pBlob+sizeof(DWORD),szFilenames);
+ lstrcpyA(dbei.pBlob+sizeof(DWORD)+lstrlenA(szFilenames)+1,szMsg);
+ CallService(MS_DB_EVENT_ADD,(WPARAM)dat->hContact,(LPARAM)&dbei);
+ if (dbei.pBlob)
+ mir_free(dbei.pBlob);
+ dat->files=NULL; //protocol library frees this
+ }
+ }
+ //fall through
+ case ACKRESULT_FAILED:
+ dat->fs=NULL; /* protocol will free structure */
+ KillTimer(hwndDlg,1);
+ if(!dat->send) SetOpenFileButtonStyle(GetDlgItem(hwndDlg,IDC_OPENFILE),dat->transferStatus.totalFiles>1,1);
+ SetDlgItemText(hwndDlg,IDCANCEL,TranslateT("Close"));
+ if (dat->hNotifyEvent) UnhookEvent(dat->hNotifyEvent);
+ dat->hNotifyEvent=NULL;
+ if(ack->result==ACKRESULT_FAILED) {
+ SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("File transfer failed"));
+ SkinPlaySound("FileFailed");
+ } else
+ if(DBGetContactSettingByte(NULL,"SRFile","AutoClose",0))
+ PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDCANCEL,BN_CLICKED),(LPARAM)GetDlgItem(hwndDlg,IDCANCEL));
+ break;
+
+ case ACKRESULT_DENIED:
+ dat->fs=NULL; /* protocol will free structure */
+ SkinPlaySound("FileDenied");
+ KillTimer(hwndDlg, 1);
+ if (!dat->send) SetOpenFileButtonStyle(GetDlgItem(hwndDlg, IDC_OPENFILE), dat->transferStatus.totalFiles > 1, 1);
+ SetDlgItemText(hwndDlg, IDCANCEL, TranslateT("Close"));
+ SetDlgItemText(hwndDlg, IDC_STATUS, TranslateT("File transfer denied"));
+ UnhookEvent(dat->hNotifyEvent);
+ dat->hNotifyEvent = NULL;
+ break;
+
+ }
+ break;
+ }
+ case M_VIRUSSCANDONE:
+ { int done=1,i;
+ if((int)wParam==-1) {
+ for(i=0;i<dat->transferStatus.totalFiles;i++) dat->fileVirusScanned[i]=1;
+ }
+ else {
+ dat->fileVirusScanned[wParam]=1;
+ for(i=0;i<dat->transferStatus.totalFiles;i++) if(!dat->fileVirusScanned[i]) {done=0; break;}
+ }
+ if(done) SetDlgItemText(hwndDlg,IDC_STATUS,TranslateT("Transfer and virus scan complete"));
+ break;
+ }
+ case WM_DESTROY:
+ KillTimer(hwndDlg,1);
+ if(dat->fs) CallContactService(dat->hContact,PSS_FILECANCEL,(WPARAM)dat->fs,0);
+ dat->fs=NULL;
+ if(dat->hNotifyEvent) {UnhookEvent(dat->hNotifyEvent); dat->hNotifyEvent=NULL;}
+ FreeProtoFileTransferStatus(&dat->transferStatus);
+ if(!dat->send) FreeFilesMatrix(&dat->files);
+ if(dat->fileVirusScanned) mir_free(dat->fileVirusScanned);
+ { HFONT hFont;
+ hFont=(HFONT)SendDlgItemMessage(hwndDlg,IDC_CURRENTFILEGROUP,WM_GETFONT,0,0);
+ DeleteObject(hFont);
+ }
+ break;
+ }
+ return FALSE;
+}
|