// sertransplg.cpp : Defines the entry point for the DLL application.
//
#include "windows.h"
#include "fsplugin.h"
#include "utils.h"
#include "resource.h"
#include "sftpfunc.h"
#include "multiserver.h"
#include "cunicode.h"
HINSTANCE hinst;
HWND hWndMain=NULL;
#define defininame "sftpplug.ini"
#define templatefile "sftpplug.tpl"
char inifilename[MAX_PATH]=defininame;
char pluginname[]="SFTP";
char defrootname[]="Secure FTP";
char s_f7newconnection[32];
char s_quickconnect[32];
WCHAR s_f7newconnectionW[32];
WCHAR s_quickconnectW[32];
BOOL disablereading=false; // disable reading of subdirs to delete whole drives
BOOL freportconnect=true; // report connect to caller only on first connect
BOOL CryptCheckPass=false; // check 'store password encrypted' by default
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call==DLL_PROCESS_ATTACH) {
hinst=(HINSTANCE)hModule;
LoadString(hinst, IDS_F7NEW, s_f7newconnection, sizeof(s_f7newconnection)-1);
awlcopy(s_f7newconnectionW,s_f7newconnection,countof(s_f7newconnectionW)-1);
LoadString(hinst, IDS_QUICKCONNECT, s_quickconnect, sizeof(s_quickconnect)-1);
awlcopy(s_quickconnectW,s_quickconnect,countof(s_quickconnectW)-1);
} else if (ul_reason_for_call==DLL_PROCESS_DETACH) {
}
return TRUE;
}
int PluginNumber=0;
int CryptoNumber=0;
DWORD mainthreadid=0;
tProgressProc ProgressProc=NULL;
tProgressProcW ProgressProcW=NULL;
tLogProc LogProc=NULL;
tLogProcW LogProcW=NULL;
tRequestProc RequestProc=NULL;
tRequestProcW RequestProcW=NULL;
tCryptProc CryptProc=NULL;
BOOL IsMainThread()
{
return GetCurrentThreadId()==mainthreadid;
}
BOOL MessageLoop(void* serverid)
{
BOOL aborted=false;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings && ProgressProc && abs(GetCurrentTime()-ConnectSettings->lastpercenttime)>250) {
// important: also call AFTER soft_aborted is true!!!
aborted=0!=ProgressProc(PluginNumber,NULL,NULL,ConnectSettings->lastpercent);
// allow abort with Escape when there is no progress dialog!
ConnectSettings->lastpercenttime=GetCurrentTime();
}
return aborted;
}
void ShowStatus(char* status)
{
if (LogProc)
LogProc(PluginNumber,MSGTYPE_DETAILS,status);
}
void ShowStatusW(WCHAR* status)
{
LogProcT(PluginNumber,MSGTYPE_DETAILS,status);
}
BOOL UpdatePercentBar(void* serverid,int percent)
{
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=percent; // used for MessageLoop below
return MessageLoop(serverid); // This actually sets the percent bar!
}
SERVERID GetServerIdAndRelativePathFromPath(char* Path,char* RelativePath,int maxlen)
{
char DisplayName[wdirtypemax];
GetDisplayNameFromPath(Path,DisplayName,sizeof(DisplayName)-1);
SERVERID serverid=GetServerIdFromName(DisplayName,GetCurrentThreadId());
if (serverid) {
RelativePath[0]=0;
char* p=Path;
while (p[0]=='\\' || p[0]=='/') // skip initial slash
p++;
while (p[0]!=0 && p[0]!='\\' && p[0]!='/') // skip path
p++;
strlcat(RelativePath,p,maxlen);
if (RelativePath[0]==0)
strlcpy(RelativePath,"\\",maxlen-1);
} else if (maxlen)
strlcpy(RelativePath,"\\",maxlen-1);
return serverid;
}
SERVERID GetServerIdAndRelativePathFromPathW(WCHAR* Path,WCHAR* RelativePath,int maxlen)
{
char DisplayName[wdirtypemax],PathA[wdirtypemax];
walcopy(PathA,Path,sizeof(PathA)-1);
GetDisplayNameFromPath(PathA,DisplayName,sizeof(DisplayName)-1);
SERVERID serverid=GetServerIdFromName(DisplayName,GetCurrentThreadId());
if (serverid) {
RelativePath[0]=0;
WCHAR* p=Path;
while (p[0]=='\\' || p[0]=='/') // skip initial slash
p++;
while (p[0]!=0 && p[0]!='\\' && p[0]!='/') // skip path
p++;
wcslcat(RelativePath,p,maxlen);
if (RelativePath[0]==0)
wcslcpy(RelativePath,L"\\",maxlen-1);
} else if (maxlen)
wcslcpy(RelativePath,L"\\",maxlen-1);
return serverid;
}
int __stdcall FsInit(int PluginNr,tProgressProc pProgressProc,tLogProc pLogProc,tRequestProc pRequestProc)
{
ProgressProc=pProgressProc;
LogProc=pLogProc;
RequestProc=pRequestProc;
PluginNumber=PluginNr;
mainthreadid=GetCurrentThreadId();
InitMultiServer();
return 0;
}
int __stdcall FsInitW(int PluginNr,tProgressProcW pProgressProcW,tLogProcW pLogProcW,tRequestProcW pRequestProcW)
{
ProgressProcW=pProgressProcW;
LogProcW=pLogProcW;
RequestProcW=pRequestProcW;
PluginNumber=PluginNr;
mainthreadid=GetCurrentThreadId();
InitMultiServer();
return 0;
}
void __stdcall FsSetCryptCallback(tCryptProc pCryptProc,int CryptoNr,int Flags)
{
CryptProc=pCryptProc;
CryptCheckPass=(Flags & FS_CRYPTOPT_MASTERPASS_SET)!=0;
CryptoNumber=CryptoNr;
}
typedef struct {
void* sftpdataptr;
SERVERID serverid;
SERVERHANDLE rootfindhandle;
BOOL rootfindfirst;
} tLastFindStuct,*pLastFindStuct;
BOOL __stdcall FsDisconnect(char* DisconnectRoot)
{
char DisplayName[wdirtypemax];
GetDisplayNameFromPath(DisconnectRoot,DisplayName,sizeof(DisplayName)-1);
SERVERID serverid=GetServerIdFromName(DisplayName,GetCurrentThreadId());
if (serverid) {
char connbuf[wdirtypemax];
strlcpy(connbuf,"DISCONNECT \\",sizeof(connbuf)-1);
strlcat(connbuf,DisplayName,sizeof(connbuf)-1);
LogProc(PluginNumber,MSGTYPE_DISCONNECT,connbuf);
SftpCloseConnection(serverid);
SetServerIdForName(DisplayName,NULL); // this frees it too!
}
return TRUE;
}
HANDLE __stdcall FsFindFirstW(WCHAR* Path,WIN32_FIND_DATAW *FindData)
{
WCHAR remotedir[wdirtypemax];
char DisplayName[wdirtypemax],PathA[wdirtypemax];
pLastFindStuct lf;
void* sftpdataptr=NULL;
BOOL wasconnected=true;
if (wcscmp(Path,L"\\")==0) { // in the root!
char s_helptext[256];
LoadString(hinst, IDS_HELPTEXT, s_helptext, sizeof(s_helptext));
LoadServersFromIni(inifilename,s_quickconnect);
memset(FindData,0,sizeof(WIN32_FIND_DATA));
awlcopy(FindData->cFileName,s_f7newconnection,countof(FindData->cFileName)-1);
FindData->dwFileAttributes=0;
FindData->ftLastWriteTime.dwHighDateTime=0xFFFFFFFF;
FindData->ftLastWriteTime.dwLowDateTime=0xFFFFFFFE;
FindData->nFileSizeLow=(DWORD)strlen(s_helptext);
lf=(pLastFindStuct)malloc(sizeof(tLastFindStuct));
memset(lf,0,sizeof(tLastFindStuct));
lf->rootfindfirst=true;
return lf;
} else {
// load server list if user connects directly via URL
LoadServersFromIni(inifilename,s_quickconnect);
// only disable the reading within a server!
if (disablereading && IsMainThread()) {
SetLastError(ERROR_NO_MORE_FILES);
return INVALID_HANDLE_VALUE;
}
walcopy(PathA,Path,wdirtypemax-1);
GetDisplayNameFromPath(PathA,DisplayName,sizeof(DisplayName)-1);
SERVERID serverid=GetServerIdFromName(DisplayName,GetCurrentThreadId());
if (serverid==NULL) {
wasconnected=false;
serverid=SftpConnectToServer(DisplayName,inifilename,NULL);
if (serverid)
SetServerIdForName(DisplayName,serverid);
else {
SetLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE;
}
}
// we are connected to server DisplayName now!
memset(FindData,0,sizeof(WIN32_FIND_DATAW));
GetServerIdAndRelativePathFromPathW(Path,remotedir,wdirtypemax-1);
// Retrieve the directory
BOOL ok=SFTP_OK==SftpFindFirstFileW(serverid,remotedir,&sftpdataptr);
if (wcslen(remotedir)<=1 || wcscmp(remotedir+1,L"home")==0) { // root -> add ~ link to home dir
SYSTEMTIME st;
FindData->dwFileAttributes=0;
wcslcpy(FindData->cFileName,L"~",countof(FindData->cFileName)-1);
FindData->cAlternateFileName[0]=0;
FindData->ftCreationTime.dwHighDateTime=0;
FindData->ftCreationTime.dwLowDateTime=0;
FindData->ftLastAccessTime.dwHighDateTime=0;
FindData->ftLastAccessTime.dwLowDateTime=0;
GetSystemTime(&st);
SystemTimeToFileTime(&st,&FindData->ftLastWriteTime);
FindData->nFileSizeHigh=0;
FindData->nFileSizeLow=0;
FindData->dwFileAttributes|=0x80000000;
FindData->dwReserved0=LIBSSH2_SFTP_S_IFLNK | 0555; //attributes and format mask
lf=(pLastFindStuct)malloc(sizeof(tLastFindStuct));
memset(lf,0,sizeof(tLastFindStuct));
if (ok)
lf->sftpdataptr=sftpdataptr;
lf->serverid=serverid;
return (HANDLE)lf;
}
if (!ok) {
if (!wasconnected) { // initial connect failed
SftpCloseConnection(serverid);
SetServerIdForName(DisplayName,NULL); // this frees it too!
freportconnect=false;
}
SetLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE;
}
if (SFTP_OK==SftpFindNextFileW(serverid,sftpdataptr,FindData)) {
lf=(pLastFindStuct)malloc(sizeof(tLastFindStuct));
memset(lf,0,sizeof(tLastFindStuct));
lf->sftpdataptr=sftpdataptr;
lf->serverid=serverid;
return (HANDLE)lf;
} else {
SftpFindClose(serverid,sftpdataptr);
SetLastError(ERROR_NO_MORE_FILES);
return INVALID_HANDLE_VALUE;
}
}
return INVALID_HANDLE_VALUE;
}
HANDLE __stdcall FsFindFirst(char* Path,WIN32_FIND_DATA *FindData)
{
WIN32_FIND_DATAW FindDataW;
WCHAR PathW[wdirtypemax];
HANDLE retval=FsFindFirstW(awfilenamecopy(PathW,Path),&FindDataW);
if (retval!=INVALID_HANDLE_VALUE)
copyfinddatawa(FindData,&FindDataW);
return retval;
}
BOOL __stdcall FsFindNextW(HANDLE Hdl,WIN32_FIND_DATAW *FindData)
{
pLastFindStuct lf;
char name[wdirtypemax];
if ((int)Hdl==1)
return false;
lf=(pLastFindStuct)Hdl;
if (lf!=INVALID_HANDLE_VALUE) {
if (lf->rootfindfirst) {
name[0]=0;
SERVERHANDLE hdl=FindFirstServer(name,sizeof(name)-1);
if (hdl) {
awlcopy(FindData->cFileName,name,countof(FindData->cFileName)-1);
lf->rootfindhandle=hdl;
lf->rootfindfirst=false;
FindData->dwFileAttributes=0x80000000;
FindData->dwReserved0=LIBSSH2_SFTP_S_IFLNK; //it's a link
FindData->ftLastWriteTime.dwHighDateTime=0xFFFFFFFF;
FindData->ftLastWriteTime.dwLowDateTime=0xFFFFFFFE;
FindData->nFileSizeLow=0;
return true;
} else
return false;
} else if (lf->rootfindhandle) {
name[0]=0;
lf->rootfindhandle=FindNextServer(lf->rootfindhandle,name,sizeof(name)-1);
if (lf->rootfindhandle) {
awlcopy(FindData->cFileName,name,countof(FindData->cFileName)-1);
FindData->dwFileAttributes=0x80000000;
FindData->dwReserved0=LIBSSH2_SFTP_S_IFLNK; //it's a link
}
return lf->rootfindhandle!=NULL;
} else if (lf->sftpdataptr)
return SftpFindNextFileW(lf->serverid,lf->sftpdataptr,FindData)==SFTP_OK;
}
return false;
}
BOOL __stdcall FsFindNext(HANDLE Hdl,WIN32_FIND_DATA *FindData)
{
WIN32_FIND_DATAW FindDataW;
copyfinddataaw(&FindDataW,FindData);
BOOL retval=FsFindNextW(Hdl,&FindDataW);
if (retval)
copyfinddatawa(FindData,&FindDataW);
return retval;
}
int __stdcall FsFindClose(HANDLE Hdl)
{
if (Hdl==INVALID_HANDLE_VALUE)
return 0;
pLastFindStuct lf;
lf=(pLastFindStuct)Hdl;
if (lf->sftpdataptr) {
SftpFindClose(lf->serverid,lf->sftpdataptr);
lf->sftpdataptr=NULL;
}
free(lf);
return 0;
}
BOOL __stdcall FsMkDirW(WCHAR* Path)
{
WCHAR* p=wcschr(Path+1,'\\');
if (p) {
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(Path,remotedir,countof(remotedir)-1);
if (serverid)
return SftpCreateDirectoryW(serverid,remotedir)==SFTP_OK;
else
return false;
} else { // new connection
char remotedir[wdirtypemax];
walcopy(remotedir,Path+1,sizeof(remotedir)-1);
if (strcmp(remotedir,s_quickconnect)!=0 &&
strcmp(remotedir,s_f7newconnection)!=0) {
LoadServersFromIni(inifilename,s_quickconnect);
if (SftpConfigureServer(remotedir,inifilename)) {
LoadServersFromIni(inifilename,s_quickconnect);
return true;
} else
return false;
} else
return false;
}
}
BOOL __stdcall FsMkDir(char* Path)
{
WCHAR wbuf[wdirtypemax];
return FsMkDirW(awfilenamecopy(wbuf,Path));
}
int __stdcall FsExecuteFileW(HWND MainWin,WCHAR* RemoteName,WCHAR* Verb)
{
char remoteserver[wdirtypemax];
WCHAR remotedir[wdirtypemax];
if (_wcsicmp(Verb,L"open")==0) { // follow symlink
if (RemoteName[1] && wcschr(RemoteName+1,'\\')!=0) {
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (SftpLinkFolderTargetW(serverid,remotedir,wdirtypemax-1)) {
// now build the target name: server name followed by new path
WCHAR* p;
p=wcschr(RemoteName+1,'\\');
if (p) {
p[0]=0;
// make sure that we can reach the path!!!
wcslcat(RemoteName,remotedir,wdirtypemax-1);
ReplaceSlashByBackslashW(RemoteName);
return FS_EXEC_SYMLINK;
}
return FS_EXEC_ERROR;
}
} else {
if (_wcsicmp(RemoteName+1,s_f7newconnectionW)!=0) {
WCHAR* p=RemoteName+wcslen(RemoteName);
walcopy(remoteserver,RemoteName+1,sizeof(remoteserver)-1);
SERVERID serverid=GetServerIdFromName(remoteserver,GetCurrentThreadId());
if (serverid) {
SftpGetLastActivePathW(serverid,p,wdirtypemax-(DWORD)(p-RemoteName)-1);
} else {
// Quick connect: We must connect here, otherwise we
// cannot switch to the subpath chosen by the user!
walcopy(remoteserver,RemoteName+1,sizeof(remoteserver)-1);
if (_stricmp(remoteserver,s_quickconnect)==0) {
serverid=SftpConnectToServer(remoteserver,inifilename,NULL);
if (serverid) {
SetServerIdForName(remoteserver,serverid);
SftpGetLastActivePathW(serverid,p,wdirtypemax-(DWORD)(p-RemoteName)-1);
} else
return FS_EXEC_ERROR;
} else
SftpGetServerBasePathW(RemoteName+1,p,wdirtypemax-(DWORD)(p-RemoteName)-1,inifilename);
}
if (p[0]==0)
wcslcat(RemoteName,L"/",wdirtypemax-1);
ReplaceSlashByBackslashW(RemoteName);
return FS_EXEC_SYMLINK;
}
}
return FS_EXEC_YOURSELF;
} else if (_wcsicmp(Verb,L"properties")==0) {
if (RemoteName[1] && wcschr(RemoteName+1,'\\')==0) {
walcopy(remoteserver,RemoteName+1,sizeof(remoteserver)-1);
if (_stricmp(remoteserver,s_f7newconnection)!=0 && _stricmp(remoteserver,s_quickconnect)!=0) {
if (SftpConfigureServer(remoteserver,inifilename)) {
LoadServersFromIni(inifilename,s_quickconnect);
}
}
return FS_EXEC_OK;
} else {
WCHAR remotenameW[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotenameW,countof(remotenameW)-1);
SftpShowPropertiesW(serverid,remotenameW);
return FS_EXEC_OK;
}
} else if (_wcsnicmp(Verb,L"chmod ",6)==0) {
if (RemoteName[1] && wcschr(RemoteName+1,'\\')!=0) {
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (SftpChmodW(serverid,remotedir,Verb+6))
return FS_EXEC_OK;
}
return FS_EXEC_ERROR;
} else if (_wcsnicmp(Verb,L"quote ",6)==0) {
if (wcsncmp(Verb+6,L"cd ",3)==0) {
// first get the start path within the plugin
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (Verb[9]!='\\' && Verb[9]!='/') { // relative path?
wcslcatbackslash(remotedir,countof(remotedir)-1);
wcslcat(remotedir,Verb+9,countof(remotedir)-1);
} else
wcslcpy(remotedir,Verb+9,countof(remotedir)-1);
ReplaceSlashByBackslashW(remotedir);
WCHAR* p;
p=wcschr(RemoteName+1,'\\');
if (p) {
p[0]=0;
// make sure that we can reach the path!!!
wcslcat(RemoteName,remotedir,wdirtypemax-1);
ReplaceSlashByBackslashW(RemoteName);
return FS_EXEC_SYMLINK;
}
} else {
if (RemoteName[1] && wcschr(RemoteName+1,'\\')!=0) {
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (SftpQuoteCommand2W(serverid,remotedir,Verb+6,NULL,0))
return FS_EXEC_OK;
}
}
} else if (_wcsnicmp(Verb,L"mode ",5)==0) { // Binary/Text/Auto
SftpSetTransferModeW(Verb+5);
}
return FS_EXEC_ERROR;
}
int __stdcall FsExecuteFile(HWND MainWin,char* RemoteName,char* Verb)
{
WCHAR RemoteNameW[wdirtypemax],VerbW[wdirtypemax];
int ret=FsExecuteFileW(MainWin,awfilenamecopy(RemoteNameW,RemoteName),awfilenamecopy(VerbW,Verb));
if (ret==FS_EXEC_SYMLINK)
walcopy(RemoteName,RemoteNameW,MAX_PATH-1);
return ret;
}
BOOL CopyMoveEncryptedPassword(char* OldName,char* NewName,BOOL Move)
{
if (CryptProc)
return CryptProc(PluginNumber,CryptoNumber,Move ? FS_CRYPT_MOVE_PASSWORD:FS_CRYPT_COPY_PASSWORD,
OldName,NewName,0)==FS_FILE_OK;
else
return false;
}
int __stdcall FsRenMovFileW(WCHAR* OldName,WCHAR* NewName,BOOL Move,BOOL OverWrite,RemoteInfoStruct* ri)
{
WCHAR olddir[wdirtypemax],newdir[wdirtypemax];
// Rename or copy a server?
WCHAR* p1=wcschr(OldName+1,'\\');
WCHAR* p2=wcschr(NewName+1,'\\');
if (p1==NULL && p2==NULL) {
char OldNameA[MAX_PATH],NewNameA[MAX_PATH];
walcopy(OldNameA,OldName+1,sizeof(OldNameA)-1);
walcopy(NewNameA,NewName+1,sizeof(NewNameA)-1);
switch (CopyMoveServerInIni(OldNameA,NewNameA,Move,OverWrite,inifilename)) {
case 0:
CopyMoveEncryptedPassword(OldNameA,NewNameA,Move);
return FS_FILE_OK;
break;
case 1:
return FS_FILE_EXISTS;
break;
}
return FS_FILE_NOTFOUND;
}
SERVERID serverid1=GetServerIdAndRelativePathFromPathW(OldName,olddir,countof(olddir)-1);
SERVERID serverid2=GetServerIdAndRelativePathFromPathW(NewName,newdir,countof(newdir)-1);
// must be on same server!
if (serverid1!=serverid2 || serverid1==NULL)
return FS_FILE_NOTFOUND;
pConnectSettings ConnectSettings=(pConnectSettings)serverid1;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
BOOL isdir=false;
if (ri)
isdir=(ri->Attr & FILE_ATTRIBUTE_DIRECTORY)!=0;
switch (SftpRenameMoveFileW(serverid1,olddir,newdir,Move,OverWrite,isdir)) {
case SFTP_OK:
return FS_FILE_OK;
case SFTP_EXISTS:
return FS_FILE_EXISTS;
default:
return FS_FILE_NOTFOUND;
}
}
int __stdcall FsRenMovFile(char* OldName,char* NewName,BOOL Move,BOOL OverWrite,RemoteInfoStruct* ri)
{
WCHAR OldNameW[wdirtypemax],NewNameW[wdirtypemax];
return FsRenMovFileW(awfilenamecopy(OldNameW,OldName),awfilenamecopy(NewNameW,NewName),Move,OverWrite,ri);
}
BOOL FileExistsT(WCHAR* LocalName)
{
WIN32_FIND_DATAW s;
HANDLE findhandle;
findhandle=FindFirstFileT(LocalName,&s);
if (findhandle==INVALID_HANDLE_VALUE)
return false;
else {
FindClose(findhandle);
return true;
}
}
void RemoveInalidChars(char* p)
{
while (p[0]) {
if ((unsigned char)(p[0])<32)
p[0]=' ';
else if (p[0]==':' || p[0]=='|' || p[0]=='*' || p[0]=='?' || p[0]=='\\' || p[0]=='/' || p[0]=='"')
p[0]='_';
p++;
}
}
void RemoveInalidCharsW(WCHAR* p)
{
while (p[0]) {
if ((unsigned int)(p[0])<32)
p[0]=' ';
else if (p[0]==':' || p[0]=='|' || p[0]=='*' || p[0]=='?' || p[0]=='\\' || p[0]=='/' || p[0]=='"')
p[0]='_';
p++;
}
}
int __stdcall FsGetFileW(WCHAR* RemoteName,WCHAR* LocalName,int CopyFlags,RemoteInfoStruct* ri)
{
int err;
BOOL OverWrite,Resume,Move;
OverWrite=CopyFlags & FS_COPYFLAGS_OVERWRITE;
Resume=CopyFlags & FS_COPYFLAGS_RESUME;
Move=CopyFlags & FS_COPYFLAGS_MOVE;
if (wcslen(RemoteName)<3)
return FS_FILE_NOTFOUND;
if (wcscmp(RemoteName+1,s_f7newconnectionW)==0) {
HANDLE houtfile=CreateFileT(LocalName,GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,
OverWrite ? CREATE_ALWAYS : CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (houtfile!=INVALID_HANDLE_VALUE) {
DWORD written;
char s_helptext[256];
LoadString(hinst, IDS_HELPTEXT, s_helptext, sizeof(s_helptext));
BOOL ret=WriteFile(houtfile,s_helptext,(DWORD)strlen(s_helptext),&written,NULL);
CloseHandle(houtfile);
if (ret)
return FS_FILE_OK;
} else
if (OverWrite)
return FS_FILE_EXISTS;
return FS_FILE_WRITEERROR;
}
WCHAR* p=wcsrchr(LocalName,'\\');
if (p)
RemoveInalidCharsW(p+1); // Changes the name passed in!
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (serverid==NULL)
return FS_FILE_READERROR;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
err=ProgressProcT(PluginNumber,RemoteName,LocalName,0);
if (err)
return FS_FILE_USERABORT;
if (OverWrite)
DeleteFileT(LocalName);
else {
if (!Resume && FileExistsT(LocalName)) {
// Resume isn't possible because we cannot know
// which <CR> characters were already in the original
// file, and which were added during the download
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
BOOL TextMode=(ConnectSettings->unixlinebreaks==1) && SftpDetermineTransferModeW(RemoteName);
if (TextMode)
return SFTP_FAILED;
else
return FS_FILE_EXISTSRESUMEALLOWED;
}
}
_int64 filesize=(((_int64)ri->SizeHigh)<<32)+ri->SizeLow;
switch (SftpDownloadFileW(serverid,remotedir,LocalName,true,filesize,&ri->LastWriteTime,Resume)) {
case SFTP_OK:return FS_FILE_OK;
case SFTP_EXISTS:return FS_FILE_EXISTS;
case SFTP_READFAILED:return FS_FILE_READERROR;
case SFTP_WRITEFAILED:return FS_FILE_WRITEERROR;
case SFTP_ABORT:return FS_FILE_USERABORT;
}
return FS_FILE_OK;
}
int __stdcall FsGetFile(char* RemoteName,char* LocalName,int CopyFlags,RemoteInfoStruct* ri)
{
WCHAR RemoteNameW[wdirtypemax],LocalNameW[wdirtypemax];
return FsGetFileW(awfilenamecopy(RemoteNameW,RemoteName),awfilenamecopy(LocalNameW,LocalName),CopyFlags,ri);
}
int __stdcall FsPutFileW(WCHAR* LocalName,WCHAR* RemoteName,int CopyFlags)
{
int err;
BOOL OverWrite,Resume,Move;
OverWrite=CopyFlags & FS_COPYFLAGS_OVERWRITE;
Resume=CopyFlags & FS_COPYFLAGS_RESUME;
Move=CopyFlags & FS_COPYFLAGS_MOVE;
// Auto-overwrites files -> return error if file exists
if ((CopyFlags & (FS_COPYFLAGS_EXISTS_SAMECASE | FS_COPYFLAGS_EXISTS_DIFFERENTCASE)) &&
!(OverWrite | Resume))
return FS_FILE_EXISTSRESUMEALLOWED;
if (wcslen(RemoteName)<3)
return FS_FILE_WRITEERROR;
err=ProgressProcT(PluginNumber,LocalName,RemoteName,0);
if (err)
return FS_FILE_USERABORT;
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (serverid==NULL)
return FS_FILE_READERROR;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
switch (SftpUploadFileW(serverid,LocalName,remotedir,Resume,(CopyFlags & FS_COPYFLAGS_EXISTS_SAMECASE)==0)) {
case SFTP_OK:return FS_FILE_OK;
case SFTP_EXISTS:return SftpSupportsResume(serverid)?FS_FILE_EXISTSRESUMEALLOWED:FS_FILE_EXISTS;
case SFTP_READFAILED:return FS_FILE_READERROR;
case SFTP_WRITEFAILED:return FS_FILE_WRITEERROR;
case SFTP_ABORT:return FS_FILE_USERABORT;
}
return FS_FILE_NOTFOUND;
}
int __stdcall FsPutFile(char* LocalName,char* RemoteName,int CopyFlags)
{
WCHAR LocalNameW[wdirtypemax],RemoteNameW[wdirtypemax];
return FsPutFileW(awfilenamecopy(LocalNameW,LocalName),awfilenamecopy(RemoteNameW,RemoteName),CopyFlags);
}
BOOL __stdcall FsDeleteFileW(WCHAR* RemoteName)
{
if (wcslen(RemoteName)<3)
return false;
WCHAR* p=wcschr(RemoteName+1,'\\');
if (p) {
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (serverid==NULL)
return false;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
return SftpDeleteFileW(serverid,remotedir,false)==SFTP_OK;
} else { // delete server
char remotedir[wdirtypemax];
walcopy(remotedir,RemoteName+1,sizeof(remotedir)-1);
if (_stricmp(remotedir,s_f7newconnection)!=0 && _stricmp(remotedir,s_quickconnect)!=0) {
if (DeleteServerFromIni(remotedir,inifilename)) {
if (CryptProc)
CryptProc(PluginNumber,CryptoNumber,FS_CRYPT_DELETE_PASSWORD,
remotedir,NULL,0);
return true;
} else
return false;
}
}
return false;
}
BOOL __stdcall FsDeleteFile(char* RemoteName)
{
WCHAR RemoteNameW[wdirtypemax];
return FsDeleteFileW(awfilenamecopy(RemoteNameW,RemoteName));
}
BOOL __stdcall FsRemoveDirW(WCHAR* RemoteName)
{
if (wcslen(RemoteName)<1)
return false;
WCHAR* p=wcschr(RemoteName+1,'\\');
if (p) {
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (serverid==NULL)
return FS_FILE_READERROR;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
return (SftpDeleteFileW(serverid,remotedir,true)==SFTP_OK);
}
return false;
}
BOOL __stdcall FsRemoveDir(char* RemoteName)
{
WCHAR RemoteNameW[wdirtypemax];
return FsRemoveDirW(awfilenamecopy(RemoteNameW,RemoteName));
}
BOOL __stdcall FsSetAttr(char* RemoteName,int NewAttr)
{
char remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPath(RemoteName,remotedir,sizeof(remotedir)-1);
if (serverid==NULL)
return FS_FILE_READERROR;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
return SftpSetAttr(serverid,remotedir,NewAttr)==SFTP_OK;
}
BOOL __stdcall FsSetTimeW(WCHAR* RemoteName,FILETIME *CreationTime,
FILETIME *LastAccessTime,FILETIME *LastWriteTime)
{
WCHAR remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPathW(RemoteName,remotedir,countof(remotedir)-1);
if (serverid==NULL)
return FS_FILE_READERROR;
pConnectSettings ConnectSettings=(pConnectSettings)serverid;
if (ConnectSettings)
ConnectSettings->lastpercent=0;
return SftpSetDateTimeW(serverid,remotedir,LastWriteTime)==SFTP_OK;
}
BOOL __stdcall FsSetTime(char* RemoteName,FILETIME *CreationTime,
FILETIME *LastAccessTime,FILETIME *LastWriteTime)
{
WCHAR RemoteNameW[wdirtypemax];
return FsSetTimeW(awfilenamecopy(RemoteNameW,RemoteName),CreationTime,
LastAccessTime,LastWriteTime);
}
void __stdcall FsStatusInfo(char* RemoteDir,int InfoStartEnd,int InfoOperation)
{
if (strlen(RemoteDir)<2)
if (InfoOperation==FS_STATUS_OP_DELETE || InfoOperation==FS_STATUS_OP_RENMOV_MULTI)
if (InfoStartEnd==FS_STATUS_START)
disablereading=true;
else
disablereading=false;
if (InfoOperation==FS_STATUS_OP_GET_MULTI_THREAD || InfoOperation==FS_STATUS_OP_PUT_MULTI_THREAD) {
if (InfoStartEnd==FS_STATUS_START) {
char DisplayName[MAX_PATH];
char* oldpass=NULL;
GetDisplayNameFromPath(RemoteDir,DisplayName,sizeof(DisplayName)-1);
// get password from main thread
void* oldserverid=GetServerIdFromName(DisplayName,mainthreadid);
pConnectSettings ConnectSettings=(pConnectSettings)oldserverid;
if (ConnectSettings) {
oldpass=ConnectSettings->password;
if (!oldpass[0])
oldpass=NULL;
}
void* serverid=SftpConnectToServer(DisplayName,inifilename,oldpass);
if (serverid)
SetServerIdForName(DisplayName,serverid);
} else {
FsDisconnect(RemoteDir);
}
}
}
void __stdcall FsGetDefRootName(char* DefRootName,int maxlen)
{
strlcpy(DefRootName,defrootname,maxlen);
}
// use default location, but our own ini file name!
void __stdcall FsSetDefaultParams(FsDefaultParamStruct* dps)
{
strlcpy(inifilename,dps->DefaultIniName,MAX_PATH-1);
char* p=strrchr(inifilename,'\\');
if (p)
p[1]=0;
else
inifilename[0]=0;
strlcat(inifilename,defininame,sizeof(inifilename)-1);
// copy ini template from plugin dir to ini location if it exists!
char templatename[MAX_PATH];
if (GetModuleFileName(hinst,templatename,sizeof(templatename)-1)) {
char* p=strrchr(templatename,'\\');
if (p) {
p[1]=0;
strlcat(templatename,templatefile,sizeof(templatename)-1);
}
CopyFile(templatename,inifilename,true); // only copy if target doesn't exist
}
}
int __stdcall FsExtractCustomIcon(char* RemoteName,int ExtractFlags,HICON* TheIcon)
{
if (strlen(RemoteName)>1) {
char* p=strchr(RemoteName+1,'\\');
if (p==NULL) { // a server!
if (_stricmp(RemoteName+1,s_f7newconnection)!=0) {
bool sm;
char remotedir[wdirtypemax];
SERVERID serverid=GetServerIdAndRelativePathFromPath(RemoteName,remotedir,sizeof(remotedir)-1);
sm=(ExtractFlags & FS_ICONFLAG_SMALL)!=0;
// show different icon when connected!
if (serverid==NULL)
*TheIcon=LoadIcon(hinst,MAKEINTRESOURCE(sm?IDI_ICON1SMALL:IDI_ICON1));
else
*TheIcon=LoadIcon(hinst,MAKEINTRESOURCE(sm?IDI_ICON2SMALL:IDI_ICON2));
return FS_ICON_EXTRACTED;
}
}
}
return FS_ICON_USEDEFAULT;
}
int __stdcall FsGetBackgroundFlags(void)
{
return BG_DOWNLOAD | BG_UPLOAD | BG_ASK_USER;
}
Detected encoding: UTF-8 | 0
|