Ticket #1457: patch6.diff

File patch6.diff, 71.3 KB (added by tropics, 20 years ago)

patch v1

  • source/ControlSocket.cpp

     
    522522                op->op = USERCONTROL_CONNOP_MODIFY;
    523523                conndata->userid = m_userid;
    524524                conndata->pThread = m_pOwner;
     525                conndata->bytes_total = 0;
     526                conndata->bytes_transferred = 0;
     527                conndata->speed = 0;
     528                conndata->mode = 0;
    525529               
    526530                SOCKADDR_IN sockAddr;
    527531                memset(&sockAddr, 0, sizeof(sockAddr));
     
    829833            }
    830834           
    831835            t_dirlisting *pResult;
    832             int error = m_pOwner->m_pPermissions->GetDirectoryListing(m_status.user, m_CurrentServerDir, dirToList, pResult);
     836            int error = m_pOwner->m_pPermissions->GetDirectoryListing(m_status.user, m_CurrentServerDir, dirToList, pResult, localname, ftpname);
    833837            if (error & 1)
    834838            {
    835839                Send("550 Permission denied");
     
    842846            }
    843847            else
    844848            {
     849                // let the interface know we list a directory
     850                m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERINIT, m_userid);
    845851                if (!m_transferstatus.pasv)
    846852                {
    847853                    if (m_transferstatus.socket)
     
    948954
    949955       
    950956            CStdString result;
    951             int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,FOP_READ,result);
     957            int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,FOP_READ,localname,ftpname);
     958            result = localname;
    952959            if (error & 1)
    953960            {
    954961                Send("550 Permission denied");
     
    961968            }
    962969            else
    963970            {
     971                // let the interface know a file is downloaded
     972                m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERINIT, m_userid);
    964973                if (!m_transferstatus.pasv)
    965974                {
    966975                    if (m_transferstatus.socket)
     
    10231032            }
    10241033
    10251034            CStdString result;
    1026             int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,m_transferstatus.rest?FOP_APPEND:FOP_WRITE,result);
     1035            int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,m_transferstatus.rest?FOP_APPEND:FOP_WRITE,localname,ftpname);
     1036            result = localname;
    10271037            if (error & 1)
    10281038            {
    10291039                Send("550 Permission denied");
     
    10361046            }
    10371047            else
    10381048            {
     1049                // let the interface know a file is uploaded
     1050                m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERINIT, m_userid);
    10391051                if (!m_transferstatus.pasv)
    10401052                {
    10411053                    CTransferSocket *transfersocket=new CTransferSocket(this);
     
    10831095            }
    10841096
    10851097            CStdString result;
    1086             int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_READ, result);
     1098            int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_READ, localname, ftpname);
     1099            result = localname;
    10871100            if (error & 1)
    10881101                Send("550 Permission denied");
    10891102            else if (error)
     
    11101123            }
    11111124
    11121125            CStdString result;
    1113             int error=m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,FOP_DELETE,result);
     1126            int error=m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,FOP_DELETE,localname,ftpname);
     1127            result = localname;
    11141128            if (error & 1)
    11151129                Send("550 Permission denied");
    11161130            else if (error)
     
    11351149            }
    11361150
    11371151            CStdString result;
    1138             int error = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user,args,m_CurrentServerDir,DOP_DELETE,result);
     1152            int error = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user,args,m_CurrentServerDir,DOP_DELETE,localname,ftpname);
     1153            result = localname;
    11391154            if (error & 1)
    11401155                Send("550 Permission denied");
    11411156            else if (error)
     
    11651180            }
    11661181
    11671182            CStdString result;
    1168             int error = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user, args, m_CurrentServerDir, DOP_CREATE, result);
     1183            int error = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user, args, m_CurrentServerDir, DOP_CREATE, localname, ftpname);
     1184            result = localname;
    11691185            if (error & PERMISSION_DENIED)
    11701186                Send("550 Can't create directory. Permission denied");
    11711187            else if (error & PERMISSION_DOESALREADYEXIST && (error & PERMISSION_FILENOTDIR)!=PERMISSION_FILENOTDIR)
     
    12181234            RenName = "";
    12191235
    12201236            CStdString result;
    1221             int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_DELETE, result);
     1237            int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_DELETE, localname, ftpname);
     1238            result = localname;
    12221239            if (!error)
    12231240            {
    12241241                RenName = result;
     
    12301247                Send("550 Permission denied");
    12311248            else
    12321249            {
    1233                 int error2 = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user, args,m_CurrentServerDir, DOP_DELETE, result);
     1250                int error2 = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user, args,m_CurrentServerDir, DOP_DELETE, localname, ftpname);
     1251                result = localname;
    12341252                if (!error2)
    12351253                {
    12361254                    RenName=result;
     
    12631281            if (bRenFile)
    12641282            {
    12651283                CStdString result;
    1266                 int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_CREATENEW, result);
     1284                int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_CREATENEW, localname, ftpname);
     1285                result = localname;
    12671286                if (error)
    12681287                    RenName = "";
    12691288                if (error & 1)
     
    12831302            else
    12841303            {
    12851304                CStdString result;
    1286                 int error = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user, args, m_CurrentServerDir, DOP_CREATE, result);
     1305                int error = m_pOwner->m_pPermissions->CheckDirectoryPermissions(m_status.user, args, m_CurrentServerDir, DOP_CREATE, localname, ftpname);
     1306                result = localname;
    12871307                if (error)
    12881308                    RenName = "";
    12891309                if (error & 1)
     
    13111331            }
    13121332            Send("226 ABOR command successful");
    13131333            ResetTransferstatus();
     1334
     1335            // send msg to interface
     1336            t_connectiondata *conndata = new t_connectiondata;
     1337            t_connop *op = new t_connop;
     1338            op->data = conndata;
     1339            op->op = USERCONTROL_CONNOP_MODIFY;
     1340            conndata->userid = m_userid;
     1341            conndata->user = GetUserName();
     1342            strncpy(conndata->ip,m_RemoteIP,16);
     1343            conndata->mode = 0;
     1344            conndata->pThread = m_pOwner;
     1345            m_pOwner->SendNotification(FSM_CONNECTIONDATA, (LPARAM)op);
    13141346        break;
    13151347        }
    13161348    case COMMAND_SYST:
     
    13421374            }
    13431375
    13441376            CStdString result;
    1345             int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,FOP_APPEND,result);
     1377            int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user,args,m_CurrentServerDir,FOP_APPEND,localname,ftpname);
     1378            result = localname;
    13461379            if (error & 1)
    13471380            {
    13481381                Send("550 Permission denied");
     
    13611394
    13621395                m_transferstatus.rest = size;
    13631396
     1397                // let the interface know a file is uploaded
     1398                m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERINIT, m_userid);
    13641399                if (!m_transferstatus.pasv)
    13651400                {
    13661401                    CTransferSocket *transfersocket = new CTransferSocket(this);
     
    14681503            }
    14691504           
    14701505            t_dirlisting *pResult;
    1471             int error = m_pOwner->m_pPermissions->GetShortDirectoryListing(m_status.user, m_CurrentServerDir, args, pResult);
     1506            int error = m_pOwner->m_pPermissions->GetShortDirectoryListing(m_status.user, m_CurrentServerDir, args, pResult, localname, ftpname);
    14721507            if (error & 1)
    14731508            {
    14741509                Send("550 Permission denied");
     
    14811516            }
    14821517            else
    14831518            {
     1519                // let the interface know we list a directory
     1520                m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERINIT, m_userid);
    14841521                if (!m_transferstatus.pasv)
    14851522                {
    14861523                    CTransferSocket *transfersocket = new CTransferSocket(this);
     
    15291566            }
    15301567
    15311568            CStdString result;
    1532             int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_READ, result);
     1569            int error = m_pOwner->m_pPermissions->CheckFilePermissions(m_status.user, args, m_CurrentServerDir, FOP_READ, localname, ftpname);
     1570            result = localname;
    15331571            if (error & 1)
    15341572                Send("550 Permission denied");
    15351573            else if (error & 2)
     
    22762314    op->op = USERCONTROL_CONNOP_MODIFY;
    22772315    conndata->userid = m_userid;
    22782316    conndata->user = m_status.user;
     2317    conndata->mode = 0;
    22792318    conndata->pThread = m_pOwner;
    22802319
    22812320    memset(&sockAddr, 0, sizeof(sockAddr));
     
    22922331    return TRUE;
    22932332}
    22942333
     2334CStdString CControlSocket::GetUserName() const
     2335{
     2336    return m_status.loggedon ? m_status.user : "";
     2337}
     2338
    22952339void CControlSocket::Continue()
    22962340{
    22972341    if (m_SlQuota.bContinueDownload)
  • source/ControlSocket.h

    
          
     
    5656    void SendStatus(LPCTSTR status,int type);
    5757    BOOL GetCommand(CStdString &command,CStdString &args);
    5858
     59    CStdString GetUserName() const;
     60
     61    CStdString ftpname; // the current transferred data like /C/files or /C/file.txt
     62    CStdString localname; // the current transferred data like c:\files or c:\file.txt
     63
    5964    virtual void OnReceive(int nErrorCode);
    6065    virtual void OnClose(int nErrorCode);
    6166    virtual void OnSend(int nErrorCode);
  • source/FileZilla

    
          
     
    103103                OmitFramePointers="TRUE"
    104104                OptimizeForProcessor="0"
    105105                OptimizeForWindowsApplication="TRUE"
    106                 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
     106                PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x410"
    107107                StringPooling="TRUE"
    108108                RuntimeLibrary="0"
    109109                BufferSecurityCheck="FALSE"
     
    176176            <Tool
    177177                Name="VCCLCompilerTool"
    178178                Optimization="0"
    179                 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
     179                PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;WINVER=0x410"
    180180                MinimalRebuild="TRUE"
    181181                BasicRuntimeChecks="3"
    182182                RuntimeLibrary="1"
     
    10171017        </Filter>
    10181018    </Files>
    10191019    <Globals>
     1020        <Global
     1021            Name="RESOURCE_FILE"
     1022            Value="FileZilla server.rc"/>
    10201023    </Globals>
    10211024</VisualStudioProject>
  • source/Permissions.cpp

    
          
     
    254254    pDir->buffer[pDir->len++] = '\n';
    255255}
    256256
    257 int CPermissions::GetDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult)
     257int CPermissions::GetDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult, CStdString& localdir, CStdString& ftpdir)
    258258{
    259259    // Get user
    260260    CUser user;
     
    262262        return PERMISSION_DENIED;
    263263
    264264    CStdString dir = CanonifyServerDir(currentDir, dirToDisplay);
     265    ftpdir = dir;
    265266
    266267    // Get directory from directory name
    267268    t_directory directory;
     
    372373            AddListingEntry(pDir, iter->second.name, true, 0, 0, directory);
    373374    }
    374375
     376    // prepare the result, the local directory this is referring to
     377    localdir = directory.dir + sFileSpec;
     378    if (localdir.Right(3) == "*.*")
     379        localdir = localdir.Left(localdir.GetLength()-3);
     380    else
     381    if (localdir.Right(1) == "*")
     382        localdir = localdir.Left(localdir.GetLength()-1);
     383
    375384    hFind = FindFirstFile(directory.dir + sFileSpec, &NextFindFileData);
    376385    while (hFind != INVALID_HANDLE_VALUE)
    377386    {
     
    406415    return 0;
    407416}
    408417
    409 int CPermissions::CheckDirectoryPermissions(LPCTSTR username, CStdString dirname, CStdString currentdir, int op, CStdString &result)
     418int CPermissions::CheckDirectoryPermissions(LPCTSTR username, CStdString dirname, CStdString currentdir, int op, CStdString& localdir, CStdString& ftpdir)
    410419{
    411420    //Get user from username
    412421    CUser user;
     
    421430    int pos = dir.ReverseFind('/');
    422431    if (pos == -1 || !dir[pos + 1])
    423432        return PERMISSION_NOTFOUND;
     433    ftpdir = dir;
    424434    dirname = dir.Mid(pos + 1);
    425435    dir = dir.Left(pos + 1);
    426436
     
    465475
    466476    //Check if dir + dirname is a valid path
    467477    int res2 = GetRealDirectory(dir + dirname + "/", user, directory, truematch);
    468     result = directory.dir;
     478    localdir = directory.dir; // ??? overwritten 6 lines below !!!
    469479    if (!res2 && op&DOP_CREATE)
    470480        res |= PERMISSION_DOESALREADYEXIST;
    471481    else if (!(res2 & PERMISSION_NOTFOUND))
    472482        return res | res2;
    473483    realDirname.Replace("/", "\\");
    474     result = realDir + realDirname + "\\";
     484    localdir = realDir + realDirname + "\\";
    475485   
    476486    // check dir attributes
    477487    dir.TrimRight("\\");
    478     DWORD nAttributes = GetFileAttributes(result);
     488    DWORD nAttributes = GetFileAttributes(localdir);
    479489    if (nAttributes==0xFFFFFFFF && !(op&DOP_CREATE))
    480490        res |= PERMISSION_NOTFOUND;
    481491    else if (!(nAttributes&FILE_ATTRIBUTE_DIRECTORY))
     
    485495    return res;
    486496}
    487497
    488 int CPermissions::CheckFilePermissions(LPCTSTR username, CStdString filename, CStdString currentdir, int op, CStdString &result)
     498int CPermissions::CheckFilePermissions(LPCTSTR username, CStdString filename, CStdString currentdir, int op, CStdString& localfile, CStdString& ftpfile)
    489499{
    490500    //Get user from username
    491501    CUser user;
     
    497507    int pos = dir.ReverseFind('/');
    498508    if (pos == -1)
    499509        return PERMISSION_NOTFOUND;
     510    ftpfile = dir;
    500511   
    501512    filename = dir.Mid(pos + 1);
    502513    dir = dir.Left(pos + 1);
     
    518529    if (!directory.bFileWrite && op&(FOP_CREATENEW|FOP_WRITE|FOP_APPEND))
    519530        res |= PERMISSION_DENIED;
    520531
    521     result = directory.dir + filename;
    522     DWORD nAttributes = GetFileAttributes(result);
     532    localfile = directory.dir + filename;
     533    DWORD nAttributes = GetFileAttributes(localfile);
    523534    if (nAttributes==0xFFFFFFFF)
    524535    {
    525536        if (!(op&(FOP_WRITE|FOP_APPEND|FOP_CREATENEW)))
     
    749760    return FALSE;
    750761}
    751762
    752 int CPermissions::GetShortDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult)
     763int CPermissions::GetShortDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult, CStdString& localdir, CStdString& ftpdir)
    753764{
    754765    // Get user from username
    755766    CUser user;
     
    757768        return PERMISSION_DENIED; // No user found
    758769
    759770    CStdString dir = CanonifyServerDir(currentDir, dirToDisplay);
     771    ftpdir = dir;
    760772
    761773    t_directory directory;
    762774    BOOL bTruematch;
     
    876888        pDir->buffer[pDir->len++] = '\n';
    877889    }
    878890
     891    // prepare secondary result, the local directory this is referring to
     892    localdir = directory.dir + "\\" + sFileSpec;
     893    if (localdir.Right(3) == "*.*")
     894        localdir = localdir.Left(localdir.GetLength()-3);
     895    else
     896    if (localdir.Right(1) == "*")
     897        localdir = localdir.Left(localdir.GetLength()-1);
     898
    879899    WIN32_FIND_DATA FindFileData;
    880900    WIN32_FIND_DATA NextFindFileData;
    881901    HANDLE hFind;
  • source/Permissions.h

    
          
     
    9999    int ChangeCurrentDir(LPCTSTR username, CStdString& currentdir, CStdString &dir);
    100100   
    101101    // Full directory listing with all details. Used by LIST command
    102     int GetDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult);
     102    int GetDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult, CStdString& localdir, CStdString& ftpdir);
    103103
    104104    // Directory listing with just the filenames. Used by NLST command
    105     int GetShortDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult);
     105    int GetShortDirectoryListing(LPCTSTR username, CStdString currentDir, CStdString dirToDisplay, t_dirlisting *&pResult, CStdString& localdir, CStdString& ftpdir);
    106106
    107107    CStdString GetHomeDir(LPCTSTR username, bool physicalPath = false) const;
    108108    CStdString GetHomeDir(const CUser &user, bool physicalPath = false) const;
    109109
    110     int CheckDirectoryPermissions(LPCTSTR username, CStdString dirname, CStdString currentdir, int op, CStdString &result);
    111     int CheckFilePermissions(LPCTSTR username, CStdString filename, CStdString currentdir, int op, CStdString &result);
     110    int CheckDirectoryPermissions(LPCTSTR username, CStdString dirname, CStdString currentdir, int op, CStdString& localdir, CStdString& ftpdir);
     111    int CheckFilePermissions(LPCTSTR username, CStdString filename, CStdString currentdir, int op, CStdString& localfile, CStdString& ftpfile);
    112112
    113113    BOOL GetUser(CStdString username, CUser &userdata) const;
    114114    BOOL CheckUserLogin(LPCTSTR username, LPCTSTR pass, CUser &userdata, BOOL noPasswordCheck = FALSE);
  • source/Server.cpp

    
    diff -u -w -b -b -B -w -B -Iregexp -b -r1.29 Server.cpp
     
    259259        }
    260260        USES_CONVERSION;
    261261        int userlen = pConnOp->data->user ? strlen(pConnOp->data->user) : 0;
    262         int len = 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2;
     262        int ftpfilenamelen = pConnOp->data->ftp_filename ? strlen(pConnOp->data->ftp_filename) : 0;
     263        int localfilenamelen = pConnOp->data->local_filename ? strlen(pConnOp->data->local_filename) : 0;
     264        int len = 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2 + localfilenamelen+2 + 8 + 8 + 4;
    263265        unsigned char *buffer = new unsigned char[len];
    264266        buffer[0] = USERCONTROL_CONNOP;
    265267        buffer[1] = pConnOp->op;
     
    272274        buffer[2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + 1]= userlen%256;
    273275        if (pConnOp->data->user)
    274276            memcpy(buffer + 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + 2, T2CA(pConnOp->data->user), userlen);
     277        buffer[2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2] = pConnOp->data->mode;
     278        buffer[2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1] = ftpfilenamelen/256;
     279        buffer[2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 2] = ftpfilenamelen%256;
     280        if (pConnOp->data->ftp_filename)
     281            memcpy(buffer + 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + 2, T2CA(pConnOp->data->ftp_filename), ftpfilenamelen);
     282        buffer[2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2] = localfilenamelen/256;
     283        buffer[2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2 + 1] = localfilenamelen%256;
     284        if (pConnOp->data->local_filename)
     285            memcpy(buffer + 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2 + 2, T2CA(pConnOp->data->local_filename), localfilenamelen);
     286        memcpy(buffer + 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2 + localfilenamelen+2,&pConnOp->data->bytes_total,8);
     287        memcpy(buffer + 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2 + localfilenamelen+2 + 8,&pConnOp->data->bytes_transferred,8);
     288        memcpy(buffer + 2 + 4 + strlen(pConnOp->data->ip)+2 + 4 + userlen+2 + 1 + ftpfilenamelen+2 + localfilenamelen+2 + 8 + 8,&pConnOp->data->speed,4);
    275289        m_pAdminInterface->SendCommand(2, 3, buffer, len);
    276290        delete [] buffer;
    277291        delete pConnOp->data;
  • source/ServerThread.cpp

    
          
     
    320320        else if (wParam==FTM_TRANSFERMSG)
    321321        {
    322322            CControlSocket *socket=GetControlSocket(lParam);
    323             if (socket)
     323            if (socket) {
    324324                socket->ProcessTransferMsg();
     325                // end of transfer
     326                t_connectiondata *conndata = new t_connectiondata;
     327                t_connop *op = new t_connop;
     328                op->data = conndata;
     329                op->op = USERCONTROL_CONNOP_MODIFY;
     330                conndata->userid = lParam;
     331                conndata->user = socket->GetUserName();
     332                strncpy(conndata->ip,socket->m_RemoteIP,16);
     333                conndata->mode = 0;
     334                conndata->pThread = this;
     335                SendNotification(FSM_CONNECTIONDATA, (LPARAM)op);
     336            }
     337        }
     338        else if (wParam==FTM_TRANSFERINIT)
     339        {
     340            CControlSocket *socket=GetControlSocket(lParam);
     341            if (socket) {
     342                t_connectiondata *conndata = new t_connectiondata;
     343                t_connop *op = new t_connop;
     344                op->data = conndata;
     345                op->op = USERCONTROL_CONNOP_MODIFY;
     346                conndata->userid = lParam;
     347                conndata->user = socket->GetUserName();
     348                strncpy(conndata->ip,socket->m_RemoteIP,16);
     349                conndata->mode = socket->GetTransferSocket()->GetMode();
     350                conndata->local_filename = socket->localname;
     351                conndata->ftp_filename = socket->ftpname;
     352                conndata->bytes_total = socket->GetTransferSocket()->GetTotalSize();
     353                conndata->bytes_transferred = 0;
     354                conndata->speed = 0;
     355                conndata->pThread = this;
     356                SendNotification(FSM_CONNECTIONDATA, (LPARAM)op);
     357            }
    325358        }
    326359        else if (wParam==FTM_GOOFFLINE)
    327360        {
     
    361394    if (wParam==m_timerid)
    362395    {
    363396        EnterCritSection(m_threadsync);
     397        __int64 last_bytes, bytes;
     398        CTransferSocket* transf;
    364399        for (std::map<int, CControlSocket *>::iterator iter=m_LocalUserIDs.begin(); iter!=m_LocalUserIDs.end(); iter++)
     400        {
     401            transf = iter->second->GetTransferSocket();
     402            if (transf != 0 && transf->Started() != 0) {
     403                transf->GetTransferInfo(last_bytes,bytes);
     404                if (bytes != 0) {
     405                    t_connectiondata *conndata = new t_connectiondata;
     406                    t_connop *op = new t_connop;
     407                    op->data = conndata;
     408                    op->op = USERCONTROL_CONNOP_MODIFY;
     409                    conndata->userid = iter->first;
     410                    conndata->user = iter->second->GetUserName();
     411                    strncpy(conndata->ip,iter->second->m_RemoteIP,16);
     412                    conndata->mode = transf->GetMode();
     413                    conndata->local_filename = iter->second->localname;
     414                    conndata->ftp_filename = iter->second->ftpname;
     415                    conndata->bytes_total = transf->GetTotalSize();
     416                    conndata->bytes_transferred = last_bytes+bytes;
     417                    conndata->speed = (unsigned int) bytes;
     418                    conndata->pThread = this;
     419                    SendNotification(FSM_CONNECTIONDATA, (LPARAM)op);
     420                }
     421            }
    365422            iter->second->CheckForTimeout();
     423        }
    366424        LeaveCritSection(m_threadsync);
    367425
    368426        if (m_bIsMaster && !m_pExternalIpCheck)
  • source/StdAfx.h

    
    diff -u -w -b -b -B -w -B -Iregexp -b -r1.21 StdAfx.h
     
    7272#define FTM_TRANSFERMSG 3
    7373#define FTM_GOOFFLINE 4
    7474#define FTM_CONTROL 5
     75#define FTM_TRANSFERINIT 6
    7576
    7677#define USERCONTROL_GETLIST 0
    7778#define USERCONTROL_CONNOP 1
     
    105106    CStdString user;
    106107    TCHAR ip[16];
    107108    unsigned int port;
     109    unsigned char mode; // data transfer mode
     110    CStdString local_filename; // like c:\file.txt
     111    CStdString ftp_filename; // like /C/file.txt
     112    __int64 bytes_total;
     113    __int64 bytes_transferred;
     114    unsigned int speed;
    108115    CServerThread *pThread;
    109116} t_connectiondata;
    110117
  • source/TransferSocket.cpp

     
    6666    m_zlibBytesOut = 0;
    6767
    6868    m_pBuffer2 = 0;
     69
     70    m_nTotalSize = 0;
     71    m_nLastTransferred = 0;
     72    m_nBytesSinceThen = 0;
    6973}
    7074
    7175void CTransferSocket::Init(t_dirlisting *pDir, int nMode)
     
    8892    if (m_hFile != INVALID_HANDLE_VALUE)
    8993        CloseHandle(m_hFile);
    9094    m_nBufferPos = 0;
     95
     96    m_nTotalSize = 0;
     97    m_nLastTransferred = 0;
     98    m_nBytesSinceThen = 0;
    9199}
    92100
    93101void CTransferSocket::Init(CStdString filename, int nMode, _int64 rest, BOOL bBinary /*=TRUE*/)
     
    104112    if (m_pBuffer2)
    105113        delete [] m_pBuffer2;
    106114    m_pBuffer2 = 0;
     115
     116    m_nTotalSize = 0;
     117    m_nLastTransferred = rest;
     118    m_nBytesSinceThen = 0;
    107119}
    108120
    109121CTransferSocket::~CTransferSocket()
     
    449461                ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
    450462                GetSystemTime(&m_LastActiveTime);
    451463                m_nBufferPos += numsent;
     464                m_nBytesSinceThen += numsent;
    452465
    453466                if (!m_zlibStream.avail_in && m_hFile == INVALID_HANDLE_VALUE && m_zlibStream.avail_out &&
    454467                    m_zlibStream.avail_out + m_nBufferPos == m_nBufSize && res == Z_STREAM_END)
     
    546559                    m_pOwner->m_SlQuota.nDownloaded += numsent;
    547560   
    548561                ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
     562                m_nBytesSinceThen += numsent;
    549563                GetSystemTime(&m_LastActiveTime);
    550564
    551565                //Check if there are other commands in the command queue.
     
    783797            return;
    784798        }
    785799        ((CServerThread *)m_pOwner->m_pOwner)->IncRecvCount(numread);
     800        m_nBytesSinceThen += numread;
    786801
    787802        if (nLimit != -1 && GetState() != aborted)
    788803            m_pOwner->m_SlQuota.nUploaded += numread;
     
    972987            Close();
    973988            return FALSE;
    974989        }
     990        ((PLARGE_INTEGER)&m_nTotalSize)->LowPart = GetFileSize(m_hFile,(LPDWORD)&((PLARGE_INTEGER)&m_nTotalSize)->HighPart);
    975991        DWORD low=(DWORD)(m_nRest&0xFFFFFFFF);
    976992        LONG high=(LONG)(m_nRest>>32);
    977993        if (SetFilePointer(m_hFile, low, &high, FILE_BEGIN)==0xFFFFFFFF && GetLastError()!=NO_ERROR)
     
    10261042    return m_nMode;
    10271043}
    10281044
     1045CStdString CTransferSocket::GetFilename() const
     1046{
     1047    return m_Filename;
     1048}
     1049
    10291050void CTransferSocket::UseGSS(CAsyncGssSocketLayer *pGssLayer)
    10301051{
    10311052    m_pGssLayer = new CAsyncGssSocketLayer;
     
    10701091   
    10711092    return true;
    10721093}
     1094 No newline at end of file
     1095
     1096void CTransferSocket::GetTransferInfo( __int64& lastTransferred, __int64& bytesSinceThen)
     1097{
     1098    lastTransferred = m_nLastTransferred;
     1099    m_nLastTransferred += (bytesSinceThen = m_nBytesSinceThen);
     1100    m_nBytesSinceThen = 0;
     1101}
  • source/TransferSocket.h

    +
    
    
     
    5656// Überschreibungen
    5757public:
    5858    int GetMode() const;
     59    CStdString GetFilename() const;
    5960    BOOL Started() const;
    6061    BOOL CheckForTimeout();
    6162    void PasvTransfer();
     
    6364    bool InitZLib(int level);
    6465    bool GetZlibStats(_int64 &bytesIn, _int64 &bytesOut) const;
    6566
     67    void GetTransferInfo( __int64& lastTransferred, __int64& bytesSinceThen);
     68    inline __int64 GetTotalSize() const { return m_nTotalSize; }
     69
    6670    BOOL pasv;
    6771// Implementierung
    6872protected:
     
    98102    __int64 m_zlibBytesIn;
    99103    __int64 m_zlibBytesOut;
    100104
     105    volatile __int64 m_nTotalSize;
     106    volatile __int64 m_nLastTransferred; // for statistics
     107    volatile __int64 m_nBytesSinceThen; // for statistics
     108
    101109};
    102110
    103111
  • source/GFtp/GFtp.vcproj

     
    2222                Name="VCCLCompilerTool"
    2323                Optimization="2"
    2424                InlineFunctionExpansion="1"
    25                 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;GFTP_EXPORTS"
     25                PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;GFTP_EXPORTS;WINVER=0x410"
    2626                StringPooling="TRUE"
    2727                RuntimeLibrary="0"
    2828                EnableFunctionLevelLinking="TRUE"
     
    9393                Name="VCCLCompilerTool"
    9494                Optimization="0"
    9595                AdditionalIncludeDirectories="c:\pismere\pismere\athena\auth\krb5\src\include"
    96                 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;GFTP_EXPORTS"
     96                PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;GFTP_EXPORTS;WINVER=0x410"
    9797                BasicRuntimeChecks="3"
    9898                RuntimeLibrary="1"
    9999                UsePrecompiledHeader="2"
  • source/Interface/FileZilla

    
          
     
    2222            <Tool
    2323                Name="VCCLCompilerTool"
    2424                Optimization="0"
    25                 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
     25                PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;WINVER=0x410"
    2626                BasicRuntimeChecks="3"
    2727                RuntimeLibrary="1"
    2828                UsePrecompiledHeader="3"
     
    9090                Name="VCCLCompilerTool"
    9191                Optimization="1"
    9292                InlineFunctionExpansion="1"
    93                 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
     93                PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x410"
    9494                StringPooling="TRUE"
    9595                RuntimeLibrary="0"
    9696                EnableFunctionLevelLinking="TRUE"
     
    109109            <Tool
    110110                Name="VCLinkerTool"
    111111                AdditionalDependencies="Shlwapi.lib version.lib ws2_32.lib"
    112                 OutputFile=".\Release/FileZilla Server Interface.exe"
     112                OutputFile="..\..\FileZilla Server Interface.exe"
    113113                LinkIncremental="1"
    114114                SuppressStartupBanner="TRUE"
    115115                GenerateDebugInformation="TRUE"
     
    127127                TypeLibraryName=".\Release/FileZilla Server Interface.tlb"
    128128                HeaderFileName=""/>
    129129            <Tool
    130                 Name="VCPostBuildEventTool"/>
     130                Name="VCPostBuildEventTool"
     131                Description="copying..."
     132                CommandLine="copy &quot;..\..\FileZilla Server Interface.exe&quot; &quot;c:\progra~1\filezilla server&quot;"/>
    131133            <Tool
    132134                Name="VCPreBuildEventTool"/>
    133135            <Tool
  • source/Interface/FileZilla

    
          
     
    10891089IDR_MAINFRAME           BITMAP                  "res\\Toolbar.bmp"
    10901090IDB_LEDS                BITMAP                  "res\\leds.bmp"
    10911091IDB_DONATE              BITMAP                  "res\\donate.bmp"
     1092IDB_TRANSFERINFO        BITMAP                  "res\\transfer_modes.bmp"
     1093IDR_TRANSFER_TOOLS      BITMAP                  "res\\transfer_toolbar.bmp"
    10921094
    10931095/////////////////////////////////////////////////////////////////////////////
    10941096//
     
    11061108    BUTTON      ID_APP_ABOUT
    11071109END
    11081110
     1111IDR_TRANSFER_TOOLS TOOLBAR  16, 15
     1112BEGIN
     1113    BUTTON      ID_DISPLAY_HORIZONTALSPLITTER
     1114    BUTTON      ID_DISPLAY_VERTICALSPLITTER
     1115    SEPARATOR
     1116    BUTTON      ID_DISPLAY_FTPNAMES
     1117    BUTTON      ID_DISPLAY_LOCALNAMES
     1118    SEPARATOR
     1119    BUTTON      ID_DISPLAY_SORT
     1120END
     1121
    11091122
    11101123/////////////////////////////////////////////////////////////////////////////
    11111124//
     
    11891202    END
    11901203END
    11911204
     1205IDR_SORTMENU MENU
     1206BEGIN
     1207    POPUP "popup"
     1208    BEGIN
     1209        MENUITEM "Sort by Account",             ID_DISPLAY_SORTBYACCOUNT
     1210        MENUITEM "Sort by IP",                  ID_DISPLAY_SORTBYIP
     1211        MENUITEM SEPARATOR
     1212        MENUITEM "Show Groups",                 ID_DISPLAY_GROUPED
     1213    END
     1214END
     1215
    11921216
    11931217/////////////////////////////////////////////////////////////////////////////
    11941218//
     
    14031427                            "Enter directory aliases|You have to enter the full physical path for each alias.\nExample: C:\\pub\\somedir will create the alias somedir in the folder c:\\pub\\ to the target folder.\nSeparate multiple aliases with the pipe character |"
    14041428END
    14051429
    14061430#endif    // Deutsch (Deutschland) resources
     1431STRINGTABLE
     1432BEGIN
     1433    ID_DISPLAY_FTPNAMES     "Displays FTP names"
     1434    ID_DISPLAY_LOCALNAMES   "Displays local filenames"
     1435    ID_DISPLAY_VERTICALSPLITTER "Use horizontal layout"
     1436    ID_DISPLAY_HORIZONTALSPLITTER "Use vertical layout"
     1437    ID_DISPLAY_SORT         "Select how to sort the user display"
     1438END
     1439
    14071440/////////////////////////////////////////////////////////////////////////////
    14081441
    14091442
    14101443/////////////////////////////////////////////////////////////////////////////
    14111444// Englisch (USA) resources
    14121445
    14131446#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    14141447#ifdef _WIN32
  • source/Interface/MainFrm.cpp

    
          
     
    7777    ON_COMMAND(ID_MENU_EDIT_USERS, OnMenuEditUsers)
    7878    ON_COMMAND(ID_MENU_EDIT_GROUPS, OnMenuEditGroups)
    7979    ON_WM_DESTROY()
     80
     81    ON_COMMAND(ID_DISPLAY_FTPNAMES,OnDisplayFTPNames)
     82    ON_COMMAND(ID_DISPLAY_LOCALNAMES,OnDisplayLocalNames)
     83    ON_UPDATE_COMMAND_UI(ID_DISPLAY_FTPNAMES,OnUpdateDisplayFTPNames)
     84    ON_UPDATE_COMMAND_UI(ID_DISPLAY_LOCALNAMES,OnUpdateDisplayLocalNames)
     85   
     86    ON_COMMAND(ID_DISPLAY_HORIZONTALSPLITTER,OnDisplayHorizontalSplitter)
     87    ON_UPDATE_COMMAND_UI(ID_DISPLAY_HORIZONTALSPLITTER,OnUpdateDisplayHorizontalSplitter)
     88    ON_COMMAND(ID_DISPLAY_VERTICALSPLITTER,OnDisplayVerticalSplitter)
     89    ON_UPDATE_COMMAND_UI(ID_DISPLAY_VERTICALSPLITTER,OnUpdateDisplayVerticalSplitter)
     90   
     91    ON_COMMAND(ID_DISPLAY_SORT,OnDisplaySortMenu)
     92    ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)
     93
     94    ON_COMMAND(ID_DISPLAY_SORTBYACCOUNT,OnDisplaySortByAccount)
     95    ON_COMMAND(ID_DISPLAY_SORTBYIP,OnDisplaySortByIP)
     96    ON_COMMAND(ID_DISPLAY_GROUPED,OnDisplayGrouped)
     97    ON_UPDATE_COMMAND_UI(ID_DISPLAY_SORTBYACCOUNT,OnUpdateDisplaySortByAccount)
     98    ON_UPDATE_COMMAND_UI(ID_DISPLAY_SORTBYIP,OnUpdateDisplaySortByIP)
     99    ON_UPDATE_COMMAND_UI(ID_DISPLAY_GROUPED,OnUpdateDisplayGrouped)
    80100    //}}AFX_MSG_MAP
    81101    ON_WM_ERASEBKGND()
     102    ON_WM_ENDSESSION()
    82103END_MESSAGE_MAP()
    83104
    84105static UINT indicators[] =
     
    135156   
    136157    SetupTrayIcon();
    137158
    138     if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
    139         | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
     159    if (!m_wndReBar.Create(this)) return -1;
     160
     161    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT| TBSTYLE_TRANSPARENT , WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP
     162        | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    140163        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    141164    {
    142165        TRACE0("Symbolleiste konnte nicht erstellt werden\n");
    143166        return -1;      // Fehler bei Erstellung
    144167    }
    145168
     169    if (!m_wndTransferTools.CreateEx(this,TBSTYLE_FLAT|TBSTYLE_TRANSPARENT,WS_CHILD|WS_VISIBLE|CBRS_ALIGN_TOP
     170        |CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC) ||
     171        !m_wndTransferTools.LoadToolBar(IDR_TRANSFER_TOOLS))
     172    {
     173        TRACE0("Symbolleiste 2 konnte nicht erstellt werden\n");
     174        return -1;      // Fehler bei Erstellung
     175    }
     176    m_wndTransferTools.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
     177    DWORD dwStyle = m_wndToolBar.GetButtonStyle(m_wndTransferTools.CommandToIndex(ID_DISPLAY_SORT));
     178    dwStyle |= TBSTYLE_DROPDOWN;
     179    m_wndTransferTools.SetButtonStyle(m_wndTransferTools.CommandToIndex(ID_DISPLAY_SORT), dwStyle);
     180
    146181    if (!m_wndStatusBar.Create(this) ||
    147182        !m_wndStatusBar.SetIndicators(indicators,
    148183          sizeof(indicators)/sizeof(UINT)))
     
    169204    m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVLED),ID_INDICATOR_RECVLED,SBPS_NOBORDERS,6);
    170205    m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED),ID_INDICATOR_SENDLED,SBPS_NOBORDERS,6);
    171206
    172     // ZU ERLEDIGEN: Löschen Sie diese drei Zeilen, wenn Sie nicht wollen, dass die Symbolleiste
    173     //  andockbar ist.
    174     m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    175     EnableDocking(CBRS_ALIGN_ANY);
    176     DockControlBar(&m_wndToolBar);
     207    m_wndReBar.AddBar(&m_wndToolBar);
     208    m_wndReBar.AddBar(&m_wndTransferTools);
    177209
    178210    ShowStatus(GetVersionString(), 0);
    179211    ShowStatus("Copyright 2001 by Tim Kosse (Tim.Kosse@gmx.de)", 0);
     
    294325
    295326BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    296327{
     328    int rows=2, cols=1;
     329    if (m_pOptions->GetOptionVal(IOPTION_PANELAYOUT)) {
     330        rows=1; cols=2;
     331    }
     332
    297333    // Unterteiltes Fenster erstellen
    298     if (!m_wndSplitter.CreateStatic(this, 1, 2))
     334    if (!m_wndSplitter.CreateStatic(this, rows, cols))
    299335        return FALSE;
     336    LARGE_INTEGER sizes;
     337    sizes.QuadPart = m_pOptions->GetOptionVal(IOPTION_PANESIZES);
     338    int s1,s2;
     339    if (sizes.QuadPart == 0) {
    300340    CRect rect;
    301     GetWindowRect(rect);
    302     if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CStatusView), CSize(rect.Width() - 225, 95), pContext))
     341        GetClientRect(rect);
     342        s2 = rect.Height()/3;
     343        s1 = s2*2;
     344    }
     345    else
     346    {
     347        s1 = sizes.HighPart;
     348        s2 = sizes.LowPart;
     349    }
     350    if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CStatusView), CSize(s1,s1), pContext))
    303351    {
    304352        m_wndSplitter.DestroyWindow();
    305353        return FALSE;
    306354    }
    307     if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CUsersView), CSize(100, 95), pContext))
     355    m_pStatusPane = (CStatusView*) m_wndSplitter.GetPane(0,0);
     356    if (!m_wndSplitter.CreateView(rows-1, cols-1, RUNTIME_CLASS(CUsersView), CSize(s2,s2), pContext))
    308357    {
    309358        m_wndSplitter.DestroyWindow();
    310359        return FALSE;
    311360    }
     361    m_pUsersPane = (CUsersView*) m_wndSplitter.GetPane(rows-1,cols-1);
     362
     363    // filename display option
     364    GetUsersPane()->m_pListCtrl->SetDisplayLocalNames(m_pOptions->GetOptionVal(IOPTION_FILENAMEDISPLAY));
     365
     366    // set layout options
     367    unsigned char usersorting = (unsigned char) m_pOptions->GetOptionVal(IOPTION_USERSORTING);
     368    if (usersorting != 0) {
     369        GetUsersPane()->m_pListCtrl->SetReportStyle(usersorting&0xF);
     370        GetUsersPane()->m_pListCtrl->SetReportGrouping(((usersorting&0x10)!=0)?TRUE:FALSE);
     371    }
     372
    312373    return CFrameWnd::OnCreateClient(lpcs, pContext);
    313374}
    314375
    315376CStatusView* CMainFrame::GetStatusPane()
    316377{
    317     CWnd* pWnd = m_wndSplitter.GetPane(0, 0);
    318     CStatusView* pView = DYNAMIC_DOWNCAST(CStatusView, pWnd);
    319     return pView;
     378    return m_pStatusPane;
    320379}
    321380
    322381CUsersView* CMainFrame::GetUsersPane()
    323382{
    324     CWnd* pWnd = m_wndSplitter.GetPane(0, 1);
    325     CUsersView* pView = DYNAMIC_DOWNCAST(CUsersView, pWnd);
    326     return pView;
     383    return m_pUsersPane;
    327384}
    328385
    329386void CMainFrame::OnSize(UINT nType, int cx, int cy)
     
    336393            m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED),ID_INDICATOR_SENDLED,SBPS_NOBORDERS,10);
    337394    }
    338395
    339     if (m_wndSplitter.GetSafeHwnd())
    340     {
    341         //Hide the queue if visible
    342         m_wndSplitter.HideColumn(1, 0);
    343     }
    344396    //Now only the main splitter gets resized
    345397    CFrameWnd::OnSize(nType, cx, cy);
    346     if (m_wndSplitter.GetSafeHwnd())
    347     {
    348         //Restore the queue
    349         m_wndSplitter.ShowColumn(1);
    350     }
    351398   
    352399    if (m_wndStatusBar.GetSafeHwnd())
    353400    {
     
    11481195    pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
    11491196}
    11501197
     1198// this function gets called whenever the user decides to quit the app
     1199// (by pressing the 'x' for example
    11511200void CMainFrame::OnDestroy()
    11521201{
     1202    // save pane position
     1203    m_pOptions->SetOption(IOPTION_PANESIZES,m_wndSplitter.GetSizes());
     1204
    11531205    CloseAdminSocket(false);
    11541206    CFrameWnd::OnDestroy();
    11551207}
    11561208
     1209// when the system is shutdown while this app is running, we will not
     1210// get the OnDestroy message. in that case, this function is called
     1211// so we can still save settings.
     1212void CMainFrame::OnEndSession(BOOL bEnding)
     1213{
     1214    CFrameWnd::OnEndSession(bEnding);
     1215
     1216    if (bEnding) {
     1217        // save pane position
     1218        m_pOptions->SetOption(IOPTION_PANESIZES,m_wndSplitter.GetSizes());
     1219    }
     1220}
     1221
    11571222BOOL CMainFrame::OnEraseBkgnd(CDC* pDC)
    11581223{
    11591224    return TRUE;
     
    12361301        CloseAdminSocket();
    12371302    }
    12381303}
     1304
     1305void CMainFrame::OnDisplayFTPNames()
     1306{
     1307    GetUsersPane()->m_pListCtrl->SetDisplayLocalNames(false);
     1308    m_pOptions->SetOption(IOPTION_FILENAMEDISPLAY,0);
     1309}
     1310
     1311void CMainFrame::OnDisplayLocalNames()
     1312{
     1313    GetUsersPane()->m_pListCtrl->SetDisplayLocalNames(true);
     1314    m_pOptions->SetOption(IOPTION_FILENAMEDISPLAY,1);
     1315}
     1316
     1317void CMainFrame::OnUpdateDisplayFTPNames(CCmdUI* pCmdUI)
     1318{
     1319    pCmdUI->SetRadio(!GetUsersPane()->m_pListCtrl->GetDisplayLocalNames());
     1320}
     1321
     1322void CMainFrame::OnUpdateDisplayLocalNames(CCmdUI* pCmdUI)
     1323{
     1324    pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetDisplayLocalNames());
     1325}
     1326
     1327void CMainFrame::OnDisplayHorizontalSplitter()
     1328{
     1329    if (!m_wndSplitter.BarIsHorizontal()) {
     1330        m_wndSplitter.ToggleLayout();
     1331        m_pOptions->SetOption(IOPTION_PANELAYOUT,0);
     1332    }
     1333}
     1334
     1335void CMainFrame::OnUpdateDisplayHorizontalSplitter(CCmdUI* pCmdUI)
     1336{
     1337    pCmdUI->SetRadio(m_wndSplitter.BarIsHorizontal());
     1338}
     1339
     1340void CMainFrame::OnDisplayVerticalSplitter()
     1341{
     1342    if (m_wndSplitter.BarIsHorizontal()) {
     1343        m_wndSplitter.ToggleLayout();
     1344        m_pOptions->SetOption(IOPTION_PANELAYOUT,1);
     1345    }
     1346}
     1347
     1348void CMainFrame::OnUpdateDisplayVerticalSplitter(CCmdUI* pCmdUI)
     1349{
     1350    pCmdUI->SetRadio(!m_wndSplitter.BarIsHorizontal());
     1351}
     1352
     1353void CMainFrame::OnDisplaySortMenu()
     1354{
     1355    // load and display popup menu
     1356    CMenu menu;
     1357    menu.LoadMenu(IDR_SORTMENU);
     1358    CMenu* pPopup = menu.GetSubMenu(0);
     1359    ASSERT(pPopup);
     1360
     1361    CRect rc;
     1362    m_wndTransferTools.GetItemRect(m_wndTransferTools.CommandToIndex(ID_DISPLAY_SORT),&rc);
     1363    m_wndTransferTools.ClientToScreen(&rc);
     1364
     1365    pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
     1366        rc.left, rc.bottom, this, &rc);
     1367}
     1368
     1369void CMainFrame::OnToolbarDropDown(NMHDR* pnmh, LRESULT* plRes)
     1370{
     1371    NMTOOLBAR* pnmtb = (NMTOOLBAR*)pnmh;
     1372    if (pnmtb->iItem == ID_DISPLAY_SORT)
     1373        OnDisplaySortMenu();
     1374}
     1375
     1376void CMainFrame::OnDisplaySortByAccount()
     1377{
     1378    GetUsersPane()->m_pListCtrl->SetReportStyle(1);
     1379    bool grp = (GetUsersPane()->m_pListCtrl->IsGroupViewEnabled() != 0);
     1380    m_pOptions->SetOption(IOPTION_USERSORTING,(grp?0x10:0)+1);
     1381}
     1382
     1383void CMainFrame::OnDisplaySortByIP()
     1384{
     1385    GetUsersPane()->m_pListCtrl->SetReportStyle(2);
     1386    bool grp = (GetUsersPane()->m_pListCtrl->IsGroupViewEnabled() != 0);
     1387    m_pOptions->SetOption(IOPTION_USERSORTING,(grp?0x10:0)+2);
     1388}
     1389
     1390void CMainFrame::OnDisplayGrouped()
     1391{
     1392    if (GetUsersPane()->m_pListCtrl->IsGroupViewPossible()) {
     1393        bool grp = GetUsersPane()->m_pListCtrl->ToggleGroupView();
     1394        int sort = GetUsersPane()->m_pListCtrl->GetReportSorting();
     1395        m_pOptions->SetOption(IOPTION_USERSORTING,(grp?0x10:0)+sort);
     1396    }
     1397}
     1398
     1399void CMainFrame::OnUpdateDisplaySortByAccount(CCmdUI* pCmdUI)
     1400{
     1401    pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetReportSorting()==1);
     1402}
     1403
     1404void CMainFrame::OnUpdateDisplaySortByIP(CCmdUI* pCmdUI)
     1405{
     1406    pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetReportSorting()==2);
     1407}
     1408
     1409void CMainFrame::OnUpdateDisplayGrouped(CCmdUI* pCmdUI)
     1410{
     1411    if (GetUsersPane()->m_pListCtrl->IsGroupViewPossible())
     1412        pCmdUI->SetCheck(GetUsersPane()->m_pListCtrl->IsGroupViewEnabled());
     1413    else
     1414        pCmdUI->Enable(FALSE);
     1415}
     1416
     1417
  • source/Interface/MainFrm.h

    
          
     
    8585protected:  // Eingebundene Elemente der Steuerleiste
    8686    CAdminSocket *m_pAdminSocket;
    8787    int m_nServerState;
     88    CStatusView* m_pStatusPane;
     89    CUsersView* m_pUsersPane;
    8890
    8991    void CMainFrame::SetStatusbarText(int nIndex,CString str);
    9092    CLed m_SendLed;
    9193    CLed m_RecvLed;
     94    CReBar      m_wndReBar;
    9295    CStatusBar  m_wndStatusBar;
    9396    CToolBar    m_wndToolBar;
     97    CToolBar    m_wndTransferTools;
    9498    CSplitterWndEx m_wndSplitter;
    9599
    96100    //// Internal support functions
     
    147151    afx_msg void OnUpdateUsers(CCmdUI* pCmdUI);
    148152    afx_msg void OnUpdateGroups(CCmdUI* pCmdUI);
    149153    afx_msg void OnDestroy();
     154    afx_msg void OnDisplayFTPNames();
     155    afx_msg void OnDisplayLocalNames();
     156    afx_msg void OnUpdateDisplayFTPNames(CCmdUI* pCmdUI);
     157    afx_msg void OnUpdateDisplayLocalNames(CCmdUI* pCmdUI);
     158    afx_msg void OnDisplayHorizontalSplitter();
     159    afx_msg void OnUpdateDisplayHorizontalSplitter(CCmdUI* pCmdUI);
     160    afx_msg void OnDisplayVerticalSplitter();
     161    afx_msg void OnUpdateDisplayVerticalSplitter(CCmdUI* pCmdUI);
     162    afx_msg void OnDisplaySortMenu();
     163    afx_msg void OnToolbarDropDown(NMHDR* pnmh, LRESULT* plRes);
     164    afx_msg void OnDisplaySortByAccount();
     165    afx_msg void OnDisplaySortByIP();
     166    afx_msg void OnDisplayGrouped();
     167    afx_msg void OnUpdateDisplaySortByAccount(CCmdUI* pCmdUI);
     168    afx_msg void OnUpdateDisplaySortByIP(CCmdUI* pCmdUI);
     169    afx_msg void OnUpdateDisplayGrouped(CCmdUI* pCmdUI);
    150170    //}}AFX_MSG
    151171    DECLARE_MESSAGE_MAP()
    152172public:
    153173    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    154174protected:
    155175    virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
     176public:
     177    afx_msg void OnEndSession(BOOL bEnding);
    156178};
    157179
    158180/////////////////////////////////////////////////////////////////////////////
  • source/Interface/Options.cpp

    
          
     
    5656                                                _T("Last Server Address"),      0,
    5757                                                _T("Last Server Port"),         1,
    5858                                                _T("Last Server Password"),     0,
    59                                                 _T("Always use last server"),   1
     59                                                _T("Always use last server"),   1,
     60                                                _T("Pane Layout"),              1,
     61                                                _T("Pane Sizes"),               1,
     62                                                _T("User Sorting"),             1,
     63                                                _T("Filename Display"),         1
    6064                                                };
    6165
    6266void COptions::SetOption(int nOptionID, __int64 value)
  • source/Interface/Options.h

    
          
     
    3333#define IOPTION_LASTSERVERPORT 3
    3434#define IOPTION_LASTSERVERPASS 4
    3535#define IOPTION_ALWAYS 5
     36#define IOPTION_PANELAYOUT 6
     37#define IOPTION_PANESIZES 7
     38#define IOPTION_USERSORTING 8
     39#define IOPTION_FILENAMEDISPLAY 9
    3640
    37 #define IOPTIONS_NUM 5
     41#define IOPTIONS_NUM 9
    3842
    3943class CMarkupSTL;
    4044class COptionsDlg;
  • source/Interface/StdAfx.h

    
          
     
    6565#define USERCONTROL_CONNOP_MODIFY 1
    6666#define USERCONTROL_CONNOP_REMOVE 2
    6767
     68#define SPEED_MEAN_SECONDS 10
     69
    6870typedef struct
    6971{
    7072    int userid;
    7173    CString user;
    7274    CString ip;
    7375    unsigned int port;
     76    unsigned char mode; // data transfer mode
     77    CString local_filename; // like c:\file.txt
     78    CString ftp_filename; // like /C/file.txt
     79    __int64 bytes_total;
     80    __int64 bytes_transferred;
     81    unsigned int speed;
     82
     83    inline void init_speed_mean()
     84        { for (int i=0;i<SPEED_MEAN_SECONDS;++i) speed_mean[i]=0;
     85        current_speed = speed_mean; }
     86    inline void insert_speed( unsigned int speed )
     87        { ++current_speed; if (current_speed >= speed_mean+SPEED_MEAN_SECONDS) current_speed = speed_mean;
     88        *current_speed = speed; }
     89    inline unsigned int get_current_speed() const
     90        { return *current_speed; }
     91    inline double get_mean_speed() const
     92        { double speed = 0;
     93        for (int i=0;i<SPEED_MEAN_SECONDS;++i) speed += speed_mean[i];
     94        return speed / SPEED_MEAN_SECONDS; }
     95
     96private:
     97    unsigned int speed_mean [SPEED_MEAN_SECONDS];
     98    unsigned int *current_speed;
     99
    74100} t_connectiondata;
    75101
    76102//{{AFX_INSERT_LOCATION}}
  • source/Interface/UsersListCtrl.cpp

    
          
     
    2424#include "UsersListCtrl.h"
    2525#include "mainfrm.h"
    2626
     27#include <set>
     28#include <string>
     29using namespace std;
     30
    2731#ifdef _DEBUG
    2832#define new DEBUG_NEW
    2933#undef THIS_FILE
    3034static char THIS_FILE[] = __FILE__;
    3135#endif
    3236
     37
     38// to allow mixed windows 2k/xp controls, we need some definitions from
     39// windows xp controls that we cannot include
     40
     41typedef struct tagLVITEMW_XP
     42{
     43    UINT mask;
     44    int iItem;
     45    int iSubItem;
     46    UINT state;
     47    UINT stateMask;
     48    LPTSTR pszText;
     49    int cchTextMax;
     50    int iImage;
     51    LPARAM lParam;
     52    int iIndent;
     53    int iGroupId;
     54    UINT cColumns; // tile view columns
     55    PUINT puColumns;
     56} LVITEM_XP, *LPLVITEM_XP;
     57
     58// mask
     59#define LVIF_GROUPID_XP 0x0100
     60
     61// style
     62#define LVGF_HEADER_XP  0x00000001
     63#define LVGF_GROUPID_XP 0x00000010
     64
     65typedef struct tagLVGROUP_XP
     66{
     67    UINT    cbSize;
     68    UINT    mask;
     69    LPWSTR  pszHeader;
     70    int     cchHeader;
     71
     72    LPWSTR  pszFooter;
     73    int     cchFooter;
     74
     75    int     iGroupId;
     76
     77    UINT    stateMask;
     78    UINT    state;
     79    UINT    uAlign;
     80} LVGROUP_XP, *PLVGROUP_XP;
     81
     82
     83// code to get the common controls version
     84// from: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/versions.asp
     85
     86#define PACKVERSION(major,minor) MAKELONG(minor,major)
     87DWORD GetDllVersion(LPCTSTR lpszDllName)
     88{
     89    HINSTANCE hinstDll;
     90    DWORD dwVersion = 0;
     91
     92    /* For security purposes, LoadLibrary should be provided with a
     93       fully-qualified path to the DLL. The lpszDllName variable should be
     94       tested to ensure that it is a fully qualified path before it is used. */
     95    hinstDll = LoadLibrary(lpszDllName);
     96   
     97    if(hinstDll)
     98    {
     99        DLLGETVERSIONPROC pDllGetVersion;
     100        pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll,
     101                          "DllGetVersion");
     102
     103        /* Because some DLLs might not implement this function, you
     104        must test for it explicitly. Depending on the particular
     105        DLL, the lack of a DllGetVersion function can be a useful
     106        indicator of the version. */
     107
     108        if(pDllGetVersion)
     109        {
     110            DLLVERSIONINFO dvi;
     111            HRESULT hr;
     112
     113            ZeroMemory(&dvi, sizeof(dvi));
     114            dvi.cbSize = sizeof(dvi);
     115
     116            hr = (*pDllGetVersion)(&dvi);
     117
     118            if(SUCCEEDED(hr))
     119            {
     120               dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
     121            }
     122        }
     123
     124        FreeLibrary(hinstDll);
     125    }
     126    return dwVersion;
     127}
     128
    33129/////////////////////////////////////////////////////////////////////////////
    34130// CUsersListCtrl
    35131
     
    37133{
    38134    ASSERT(pOwner);
    39135    m_pOwner = pOwner;
     136    localnames = false;
     137
     138    m_bGroupViewPossible = (GetDllVersion(TEXT("comctl32.dll")) >= PACKVERSION(6,00));
    40139}
    41140
    42141CUsersListCtrl::~CUsersListCtrl()
     
    53152    ON_WM_CONTEXTMENU()
    54153    ON_WM_SIZE()
    55154    //}}AFX_MSG_MAP
     155    ON_WM_SIZE()
    56156END_MESSAGE_MAP()
    57157
    58158/////////////////////////////////////////////////////////////////////////////
     
    63163    if (CListCtrl::OnCreate(lpCreateStruct) == -1)
    64164        return -1;
    65165   
     166    CImageList* transfer_images = new CImageList;
     167    transfer_images->Create(IDB_TRANSFERINFO,16,4,RGB(255,0,255));
     168    SetImageList(transfer_images,LVSIL_SMALL);
     169   
     170    SetExtendedStyle(LVS_EX_SUBITEMIMAGES|LVS_EX_FULLROWSELECT);
    66171    InsertColumn(0, "ID", LVCFMT_RIGHT, -1, 0);
    67172    InsertColumn(1, "Account", LVCFMT_LEFT, -1, 1);
    68     InsertColumn(2, "IP", LVCFMT_RIGHT, -1, 2);
     173    InsertColumn(2,"IP/DNS",LVCFMT_RIGHT,-1,2);
     174    InsertColumn(3,"Progress",LVCFMT_RIGHT,-1,3);
     175    InsertColumn(4,"Bytes/s",LVCFMT_RIGHT,-1,4);
     176    InsertColumn(5,"Transfer",LVCFMT_LEFT,-1,5);
     177
     178    EnableGroupView(true);
     179    m_iSort = 1;
     180    m_pCurrentSortFunc = SortByAccount;
    69181    AutoResizeColumns();
     182    SetColumnWidth(3,LVSCW_AUTOSIZE_USEHEADER);
     183    SetColumnWidth(4,LVSCW_AUTOSIZE_USEHEADER);
    70184
    71185    return 0;
    72186}
     
    74188void CUsersListCtrl::AutoResizeColumns()
    75189{
    76190    SetColumnWidth(0,LVSCW_AUTOSIZE_USEHEADER);
    77     SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);
    78     SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER);
     191    if ((m_iSort==1) && IsGroupViewEnabled()) SetColumnWidth(1,0);
     192    else SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);
     193    if ((m_iSort==2) && IsGroupViewEnabled()) SetColumnWidth(2,0);
     194    else SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER);
     195    SetColumnWidth(5,LVSCW_AUTOSIZE_USEHEADER);
     196}
     197
     198int GetHostName( const CString& ip, CString& hostname )
     199{
     200#if 0
     201    // this generates an error under win2k: getnameinfo not found
     202    // TODO: use this route but allow dynamic loading of the winsock dll so
     203    // we can fallback on win2k. alternatively, we could drop win2k support ;-)
     204    sockaddr_in saHost;
     205    // Set up the sockaddr structure
     206    saHost.sin_family = AF_INET;
     207    saHost.sin_addr.s_addr = inet_addr(ip);
     208    int err = getnameinfo((sockaddr*)&saHost,sizeof(saHost),hostname.GetBuffer(NI_MAXHOST),NI_MAXHOST,0,0,NI_NAMEREQD);
     209    hostname.ReleaseBuffer();
     210    return err;
     211#else
     212    // this alternative route works under win2k+win9x, but does not allow IPv6
     213    hostent* remoteHost;
     214    unsigned int addr;
     215    addr = inet_addr(ip);
     216    remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
     217    if (remoteHost == 0) return WSAGetLastError();
     218    hostname = remoteHost->h_name;
     219    return 0;
     220#endif
    79221}
    80222
    81223void CUsersListCtrl::ProcessConnOp(int op, const t_connectiondata &connectionData)
    82224{
    83225    if (op == USERCONTROL_CONNOP_ADD)
    84226    {
     227        // get the hostname for that ip
     228        CString hostname;
     229        int err = GetHostName(connectionData.ip,hostname);
     230        if (err == 0)
     231            hostname += " (" + connectionData.ip + ")";
     232        else
     233            hostname = connectionData.ip;
     234        int group_id = GenerateGroupID(connectionData);
     235
    85236        CString str_id;
    86237        str_id.Format("%06d", connectionData.userid);
    87         int index = InsertItem(GetItemCount(), str_id);
     238        t_connectiondata *pData = new t_connectiondata;
     239        *pData = connectionData;
     240        pData->init_speed_mean();
     241        int index;
     242        if (IsGroupViewPossible()) {
     243            LVITEM_XP lvitem;
     244            lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_GROUPID_XP | LVIF_PARAM;
     245            lvitem.iItem = GetItemCount();
     246            lvitem.iSubItem = 0;
     247            lvitem.pszText = (LPTSTR) (LPCTSTR) str_id;
     248            lvitem.iImage = 4;
     249            lvitem.lParam = (DWORD) pData;
     250            lvitem.iGroupId = group_id;
     251            index = InsertItem((LVITEM*)&lvitem);
     252        } else {
     253            LVITEM lvitem;
     254            lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
     255            lvitem.iItem = GetItemCount();
     256            lvitem.iSubItem = 0;
     257            lvitem.pszText = (LPTSTR) (LPCTSTR) str_id;
     258            lvitem.iImage = 4;
     259            lvitem.lParam = (DWORD) pData;
     260            index = InsertItem(&lvitem);
     261        }
    88262        if (connectionData.user == "")
    89263            SetItemText(index,1,"(not logged in)");
    90264        else
    91265        SetItemText(index,1,connectionData.user);
    92         SetItemText(index,2,connectionData.ip);
    93         t_connectiondata *pData = new t_connectiondata;
    94         *pData = connectionData;
    95         SetItemData(index, (DWORD)pData);
     266        SetItemText(index,2,hostname);
     267
     268        SortItems(m_pCurrentSortFunc,0);
    96269        AutoResizeColumns();
    97270
    98271        if (GetItemCount() == 1)
     
    105278            t_connectiondata *pData = (t_connectiondata *)GetItemData(i);
    106279            if (pData->userid == connectionData.userid)
    107280            {
    108                 *pData = connectionData;
    109 
    110                 CString str_id;
    111                 str_id.Format("%06d",connectionData.userid);
    112                 SetItemText(i,0,str_id);
    113                 if (connectionData.user=="")
    114                     SetItemText(i,1,"(not logged in)");
    115                 else
     281                bool must_be_sorted = false;
     282                if ((pData->user == "") && (connectionData.user!="")) {
     283                    // this seems to be the first "modify" message after logging in,
     284                    // so set the account name and generate a group id if the current sort mode is "ip"
     285                    if ((m_iSort == 1) && IsGroupViewPossible()) {
     286                        LVITEM_XP lvitem;
     287                        lvitem.mask = LVIF_GROUPID_XP;
     288                        lvitem.iItem = i;
     289                        lvitem.iSubItem = 0;
     290                        lvitem.iGroupId = GenerateGroupID(connectionData);
     291                        SetItem((LVITEM*)&lvitem);
     292                        must_be_sorted = true;
     293                    }
    116294                    SetItemText(i,1,connectionData.user);
    117                 AutoResizeColumns();
     295                    if ((m_iSort!=1) || !IsGroupViewEnabled()) SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);
     296                    pData->user = connectionData.user;
     297                }
    118298
     299                if (connectionData.mode==0) {
     300                    SetItem(i,5,LVIF_TEXT|LVIF_IMAGE,"",0,0,0,0);
     301                    SetItemText(i,3,"");
     302                    SetItemText(i,4,"");
     303                    if (pData->mode != 0) {
     304                        SetColumnWidth(5,LVSCW_AUTOSIZE_USEHEADER);
     305                        pData->mode = 0;
     306                        pData->ftp_filename = "";
     307                        pData->local_filename = "";
     308                        pData->init_speed_mean();
     309                    }
     310                }
     311                else {
     312                    pData->mode = connectionData.mode;
     313                    pData->bytes_total = connectionData.bytes_total;
     314                    pData->bytes_transferred = connectionData.bytes_transferred;
     315                    if (pData->local_filename != connectionData.local_filename) {
     316                        SetItem(i,5,LVIF_TEXT|LVIF_IMAGE,
     317                            localnames?connectionData.local_filename:connectionData.ftp_filename,
     318                            connectionData.mode,0,0,0);
     319                        SetColumnWidth(5,LVSCW_AUTOSIZE_USEHEADER);
     320                        pData->local_filename = connectionData.local_filename;
     321                        pData->ftp_filename   = connectionData.ftp_filename;
     322                    }
     323                    double percent = 0;
     324                    if (connectionData.bytes_total != 0 && connectionData.bytes_transferred != 0)
     325                        percent = 100.0 * ((double)connectionData.bytes_transferred / connectionData.bytes_total);
     326                    CString transfer;
     327                    transfer.Format("%2.1f%%",percent);
     328                    CString speed;
     329                    pData->insert_speed(connectionData.speed);
     330                    double speed_mean = pData->get_mean_speed();
     331                    if (speed_mean > 1024*1024)
     332                        speed.Format("%2.1fM",speed_mean/(1024*1024));
     333                    else if (speed_mean > 1024)
     334                        speed.Format("%2.1fK",speed_mean/1024.0);
     335                    else
     336                        speed.Format("%1.0f",speed_mean);
     337                    SetItemText(i,3,transfer);
     338                    SetItemText(i,4,speed);
     339                }
     340                if (must_be_sorted) SortItems(m_pCurrentSortFunc,0);
    119341                break;
    120342            }
    121343        }
     
    228450                connectionData.user.ReleaseBuffer(len);
    229451                pos+=len;
    230452
     453                connectionData.mode = 0;
     454
    231455                ProcessConnOp(USERCONTROL_CONNOP_ADD, connectionData);
    232456            }
    233457        }
     
    263487            memcpy(connectionData.user.GetBuffer(len), pData + pos, len);
    264488            connectionData.user.ReleaseBuffer(len);
    265489            pos += len;
     490
     491            if (pos + 3 > dwDataLength)
     492                return FALSE;
     493            connectionData.mode = pData[pos];
     494            len = pData[pos+1] * 256 + pData[pos+2];
     495            pos += 3;
     496            if (pos + len > dwDataLength)
     497                return FALSE;
     498            memcpy(connectionData.ftp_filename.GetBuffer(len), pData + pos, len);
     499            connectionData.ftp_filename.ReleaseBuffer(len);
     500            pos += len;
     501
     502            if (pos + 2 > dwDataLength)
     503                return FALSE;
     504            len = pData[pos] * 256 + pData[pos+1];
     505            pos += 2;
     506            if (pos + len > dwDataLength)
     507                return FALSE;
     508            memcpy(connectionData.local_filename.GetBuffer(len), pData + pos, len);
     509            connectionData.local_filename.ReleaseBuffer(len);
     510            pos += len;
     511
     512            if (pos+8+8+4 > dwDataLength)
     513                return FALSE;
     514            memcpy(&connectionData.bytes_total,pData+pos,8);
     515            memcpy(&connectionData.bytes_transferred,pData+pos+8,8);
     516            memcpy(&connectionData.speed,pData+pos+8+8,4);
     517            pos += 8 + 8 + 4;
    266518            ProcessConnOp(pData[1], connectionData);
    267519        }
    268520        else
     
    284536
    285537    AutoResizeColumns();
    286538}
     539
     540void CUsersListCtrl::SetDisplayLocalNames( bool show_localnames )
     541{
     542    localnames = show_localnames;
     543    // iterate through all items and set column 3 (transfer) to
     544    // the appropriate value
     545    for (int i=0;i<GetItemCount();i++)
     546    {
     547        t_connectiondata *pData=(t_connectiondata *)GetItemData(i);
     548        SetItemText(i,5,localnames?pData->local_filename:pData->ftp_filename);
     549    }
     550}
     551
     552bool CUsersListCtrl::GetDisplayLocalNames()
     553{
     554    return localnames;
     555}
     556
     557int CUsersListCtrl::GenerateGroupID(const t_connectiondata& connectionData)
     558{
     559    int group_id;
     560    switch (m_iSort) {
     561        case 1:
     562            // sort by account
     563            group_id = (int) &*accounts.insert((const char*)connectionData.user).first;
     564            if (!HasGroup(group_id)) {
     565                // we have to create this group
     566                USES_CONVERSION;
     567                LVGROUP_XP group;
     568                group.cbSize = sizeof(LVGROUP_XP);
     569                group.mask = LVGF_GROUPID_XP | LVGF_HEADER_XP;
     570                group.iGroupId = group_id;
     571                if (connectionData.user=="") {
     572                    group.pszHeader = T2W( "Not Logged In" );
     573                    group.cchHeader = 13;
     574                } else {
     575                    group.pszHeader = T2W( "Account: "+connectionData.user );
     576                    group.cchHeader = 9+connectionData.user.GetLength();
     577                }
     578                InsertGroup(-1,&group);
     579            }
     580            return group_id;
     581        case 2:
     582            // sort by ip
     583            group_id = inet_addr(connectionData.ip);
     584            if (!HasGroup(group_id)) {
     585                // get the hostname for that ip
     586                CString hostname;
     587                int err = GetHostName(connectionData.ip,hostname);
     588                if (err == 0)
     589                    hostname += " (" + connectionData.ip + ")";
     590                else
     591                    hostname = connectionData.ip;
     592                // we have to create this group
     593                USES_CONVERSION;
     594                LVGROUP_XP group;
     595                group.cbSize = sizeof(LVGROUP_XP);
     596                group.mask = LVGF_GROUPID_XP | LVGF_HEADER_XP;
     597                group.pszHeader = T2W( "Connections to "+hostname );
     598                group.cchHeader = 15+hostname.GetLength();
     599                group.iGroupId = group_id;
     600                InsertGroup(-1,&group);
     601            }
     602            return group_id;
     603    }
     604    return 0;
     605}
     606
     607int CUsersListCtrl::SortByAccount(LPARAM lParam1, LPARAM lParam2, LPARAM /*lParamSort*/)
     608{
     609    t_connectiondata *item1 = (t_connectiondata*) lParam1;
     610    t_connectiondata *item2 = (t_connectiondata*) lParam2;
     611    return item1->user.Compare(item2->user);
     612}
     613
     614int CUsersListCtrl::SortByIP     (LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
     615{
     616    t_connectiondata *item1 = (t_connectiondata*) lParam1;
     617    t_connectiondata *item2 = (t_connectiondata*) lParam2;
     618    return inet_addr(item1->ip) - inet_addr(item2->ip);
     619}
     620
     621void CUsersListCtrl::SetReportStyle( int sort )
     622{
     623    // skip if nothing changes
     624    if (sort == GetReportSorting()) return;
     625    m_iSort = sort;
     626
     627    // sort the list
     628    switch (sort) {
     629        case 1:
     630            // sort by account
     631            m_pCurrentSortFunc = SortByAccount;
     632            break;
     633        case 2:
     634            // sort by ip
     635            m_pCurrentSortFunc = SortByIP;
     636            break;
     637    }
     638    SortItems(m_pCurrentSortFunc,0);
     639
     640    if (IsGroupViewPossible()) {
     641        // recreate groups
     642        BOOL grouped = IsGroupViewEnabled(); // RemoveAllGroups seems to kill that flag, so we'll reset it later
     643        RemoveAllGroups();
     644        LVITEM_XP item;
     645        item.mask = LVIF_GROUPID_XP;
     646        item.iSubItem = 0;
     647        for (int i=0;i<GetItemCount();i++)
     648        {
     649            t_connectiondata *pData=(t_connectiondata *)GetItemData(i);
     650            item.iGroupId = GenerateGroupID(*pData);
     651            item.iItem = i;
     652            SetItem((LVITEM*)&item);
     653        }
     654        EnableGroupView(grouped);
     655    }
     656
     657    AutoResizeColumns();
     658}
     659
     660
     661
     662BOOL CUsersListCtrl::IsGroupViewEnabled() const
     663{
     664    if (IsGroupViewPossible()) {
     665        return (BOOL)SNDMSG(*this, LVM_FIRST+175, 0, 0);
     666    }
     667    return FALSE;
     668}
     669
     670LRESULT CUsersListCtrl::EnableGroupView(BOOL fEnable)
     671{
     672    if (IsGroupViewPossible()) {
     673        return SNDMSG(*this, LVM_FIRST+157, (WPARAM)fEnable, 0);
     674    }
     675    return 0L;
     676}
     677
     678BOOL CUsersListCtrl::HasGroup(int iGroupId) const
     679{
     680    if (IsGroupViewPossible()) {
     681        return SNDMSG(*this, LVM_FIRST+161, iGroupId, 0);
     682    }
     683    return FALSE;
     684}
     685
     686void CUsersListCtrl::RemoveAllGroups()
     687{
     688    if (IsGroupViewPossible()) {
     689        SNDMSG(*this, LVM_FIRST+160, 0, 0);
     690    }
     691}
     692
     693LRESULT CUsersListCtrl::InsertGroup(int index, void* pgrp)
     694{
     695    if (IsGroupViewPossible()) {
     696        return SNDMSG(*this, LVM_FIRST+145, (WPARAM)index, (LPARAM)pgrp);
     697    }
     698    return 0L;
     699}
     700
     701
     702
     703
     704
     705
     706
     707
     708
     709
  • source/Interface/UsersListCtrl.h

    
          
     
    1919#if !defined(AFX_USERSLISTCTRL_H__C939FF91_7A57_4E36_927B_00B917F6ECED__INCLUDED_)
    2020#define AFX_USERSLISTCTRL_H__C939FF91_7A57_4E36_927B_00B917F6ECED__INCLUDED_
    2121
     22#include <set>
     23#include <string>
     24
    2225#if _MSC_VER > 1000
    2326#pragma once
    2427#endif // _MSC_VER > 1000
     
    4346public:
    4447    BOOL ParseUserControlCommand(unsigned char *pData, DWORD dwDataLength);
    4548    void AutoResizeColumns();
     49    void SetDisplayLocalNames( bool show_localnames );
     50    bool GetDisplayLocalNames();
     51
     52    // these work only in win xp, they do nothing for win 2k
     53    BOOL IsGroupViewEnabled() const;
     54    LRESULT EnableGroupView(BOOL fEnable);
     55    BOOL HasGroup(int iGroupId) const;
     56    void RemoveAllGroups();
     57    LRESULT InsertGroup(int index, void* pgrp);
     58    // true if win >= xp, false for win <= 2k
     59    inline bool IsGroupViewPossible() const { return m_bGroupViewPossible; }
     60
     61    void SetReportStyle( int sort );
     62    inline int GetReportSorting() const { return m_iSort; }
     63    inline void SetReportGrouping( BOOL grp )
     64        { if ((IsGroupViewEnabled()-grp) != 0) ToggleGroupView(); }
     65    inline bool ToggleGroupView()
     66        { bool ret; EnableGroupView(ret=!IsGroupViewEnabled());
     67        AutoResizeColumns(); return ret; }
    4668
    4769// Überschreibungen
    4870    // Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen
     
    5274// Implementierung
    5375protected:
    5476    void ProcessConnOp(int op, const t_connectiondata &connectionData);
     77    int GenerateGroupID(const t_connectiondata& connectionData);
    5578
    5679    CMainFrame *m_pOwner;
     80    bool localnames; // true: display local filenames, false: display ftp names
     81    int m_iSort; // 1: sort by account; 2: sort by ip
     82
     83private:
     84    std::set<std::string> accounts; // used to give every account name a unique id
     85    PFNLVCOMPARE m_pCurrentSortFunc;
     86    static int CALLBACK SortByAccount(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
     87    static int CALLBACK SortByIP     (LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
     88    bool m_bGroupViewPossible;
     89
    5790
    5891    // Generierte Nachrichtenzuordnungsfunktionen
    5992protected:
  • source/Interface/UsersView.cpp

    
          
     
    9595   
    9696    CMainFrame *pMainFrame = (CMainFrame *)AfxGetMainWnd();
    9797    m_pListCtrl=new CUsersListCtrl(pMainFrame);
    98     m_pListCtrl->Create(LVS_REPORT | WS_CHILD | WS_VISIBLE | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | WS_VSCROLL, CRect(0,0,0,0), this, 0);
     98    m_pListCtrl->Create( WS_CHILD | WS_VISIBLE | WS_VSCROLL |
     99        LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER,
     100        CRect(0,0,0,0), this, 0);
    99101   
    100102    return 0;
    101103}
  • source/Interface/resource.h

    
          
     
    7373#define IDS_OPTIONSPAGE_COMPRESSION     156
    7474#define IDS_OPTIONSPAGE_GENERAL_IPBINDINGS 157
    7575#define IDS_OPTIONSPAGE_GENERAL_IPFILTER 158
     76#define IDB_TRANSFERINFO                158
     77#define IDR_TRANSFER_TOOLS              161
     78#define IDR_SORTMENU                    163
    7679#define IDC_CAPTION_BAR                 1000
    7780#define IDS_SHAREDFOLDERS_ENTERALIASES  1000
    7881#define IDC_CHECK_DAY1                  1001
     
    264267#define ID_USERVIEWCONTEXT_KICK         32799
    265268#define ID_DIRMENU_EDITALIASES          32800
    266269#define ID_DIRMENU_SETASHOMEDIR         32801
     270#define ID_DISPLAY_FTPNAMES             32802
     271#define ID_DISPLAY_LOCALNAMES           32803
     272#define ID_DISPLAY_VERTICALSPLITTER     32805
     273#define ID_DISPLAY_HORIZONTALSPLITTER   32806
     274#define ID_DISPLAY_SORT                 32807
     275#define ID_DISPLAY_GROUPED              32811
     276#define ID_DISPLAY_SORTBYIP             32812
     277#define ID_DISPLAY_SORTBYACCOUNT        32813
    267278
    268279// Next default values for new objects
    269280//
    270281#ifdef APSTUDIO_INVOKED
    271282#ifndef APSTUDIO_READONLY_SYMBOLS
    272283#define _APS_3D_CONTROLS                     1
    273 #define _APS_NEXT_RESOURCE_VALUE        157
    274 #define _APS_NEXT_COMMAND_VALUE         32802
     284#define _APS_NEXT_RESOURCE_VALUE        164
     285#define _APS_NEXT_COMMAND_VALUE         32814
    275286#define _APS_NEXT_CONTROL_VALUE         1162
    276287#define _APS_NEXT_SYMED_VALUE           1227
    277288#endif
  • source/Interface/splitex.cpp

    
          
     
    77#include "stdafx.h"
    88#include "splitex.h"
    99
     10#include <algorithm>
     11using namespace std;
     12
    1013#ifdef _DEBUG
    1114#define new DEBUG_NEW
    1215#undef THIS_FILE
     
    444447        cyMin=0;
    445448    }
    446449}
     450
     451void CSplitterWndEx::ToggleLayout()
     452{
     453    ASSERT( m_nRows <= 2 );
     454    ASSERT( m_nCols <= 2 );
     455    int cur0, cur1, min0, min1;
     456    CRect rc;
     457    float w_relative_h;
     458    GetClientRect(rc);
     459    w_relative_h = (float)rc.Width()/rc.Height();
     460
     461    if ( BarIsHorizontal() )
     462    {
     463        GetRowInfo( 0, cur0, min0 );
     464        GetRowInfo( 1, cur1, min1 );
     465        SetWindowLong( GetPane( 1, 0 )->m_hWnd, GWL_ID, AFX_IDW_PANE_FIRST + 1 );
     466        m_nRows = m_nMaxRows = 1;
     467        m_nCols = m_nMaxCols = 2;
     468        swap(m_pRowInfo,m_pColInfo);
     469        SetColumnInfo( 0, int(cur0*w_relative_h), int(min0*w_relative_h) );
     470        SetColumnInfo( 1, int(cur1*w_relative_h), int(min1*w_relative_h) );
     471    }
     472    else
     473    {
     474        GetColumnInfo( 0, cur0, min0 );
     475        GetColumnInfo( 1, cur1, min1 );
     476        SetWindowLong( GetPane( 0, 1 )->m_hWnd, GWL_ID, AFX_IDW_PANE_FIRST + 16 );
     477        m_nRows = m_nMaxRows = 2;
     478        m_nCols = m_nMaxCols = 1;
     479        swap(m_pRowInfo,m_pColInfo);
     480        SetRowInfo( 0, int(cur0/w_relative_h), int(min0/w_relative_h) );
     481        SetRowInfo( 1, int(cur1/w_relative_h), int(min1/w_relative_h) );
     482    }
     483    RecalcLayout();
     484}
     485
     486__int64 CSplitterWndEx::GetSizes() const
     487{
     488    LARGE_INTEGER v;
     489    int dummy;
     490    int s1,s2;
     491    if (BarIsHorizontal())
     492    {
     493        GetRowInfo(0,s1,dummy);
     494        GetRowInfo(1,s2,dummy);
     495        v.HighPart = s1;
     496        v.LowPart = s2;
     497    }
     498    else
     499    {
     500        GetColumnInfo(0,s1,dummy);
     501        GetColumnInfo(1,s2,dummy);
     502        v.HighPart = s1;
     503        v.LowPart = s2;
     504    }
     505    return v.QuadPart;
     506}
     507
     508
     509
  • source/Interface/splitex.h

    
          
     
    2424
    2525    virtual ~CSplitterWndEx();
    2626
     27    inline BOOL BarIsHorizontal() const { return m_nCols < m_nRows; }
     28    void ToggleLayout();
     29    __int64 GetSizes() const;
    2730
    2831    void ShowRow(int row);
    2932    void ShowColumn(int row);