⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftppidl.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    /*****************************************************************************\
    ftppidl.cpp - Pointers to Item ID Lists

    This is the only file that knows the internal format of our IDLs.
\*****************************************************************************/

#include "priv.h"
#include "ftppidl.h"
#include "ftpurl.h"
#include "cookie.h"

#define NOT_INITIALIZED         10
DWORD g_fNoPasswordsInAddressBar = NOT_INITIALIZED;

#define SESSIONKEY      FILETIME

// Private FtpServerID Helpers
HRESULT FtpServerID_GetServer(LPCITEMIDLIST pidl, LPTSTR szServer, DWORD cchSize);
DWORD FtpItemID_GetTypeID(LPCITEMIDLIST pidl);

// v0 never went to customers but was used in NT5 before 1799       - Shipped in: Never.
// v1 This switch was to use password cookies for a security fix.   - Shipped in: Never.
// v2 this was done to not use the IDelegate's IMalloc for non-first ItemIDs  - Shipped in: Never (5/15/98)
// v3 add extra padding to ItemIDs so their dwType matches that of ServerIDs - Shipped in: IE5b1, IE5b2, NT5b2 (5/25/98)
// v4 add wzDisplayName to FtpItemID                                - Shipped in: IE5 RTM & NT5 b3  (11/16/98)

#define PIDL_VERSION_NUMBER_UPGRADE 3
#define PIDL_VERSION_NUMBER 4



#define     SIZE_ITEMID_SIZEFIELD        (sizeof(DWORD) + sizeof(WORD))
#define     SIZE_ITEMID_TERMINATOR       (sizeof(DWORD))


/****************************************************\
    IDType

    DESCRIPTION:
        These bits go into FTPIDLIST.dwIDType and describe
    what type of pidl it is AND which areas of the
    data structure have been verified by getting the
    data directly from the server.
\****************************************************/

#define IDTYPE_ISVALID           0x00000001    // Set if TYPE is valid
#define IDTYPE_SERVER            (0x00000002 | IDTYPE_ISVALID)    // Server
#define IDTYPE_DIR               (0x00000004 | IDTYPE_ISVALID)    // Folder/Dir
#define IDTYPE_FILE              (0x00000008 | IDTYPE_ISVALID)    // File
#define IDTYPE_FILEORDIR         (0x00000010 | IDTYPE_ISVALID)    // File or Dir.  Wasn't specified.
#define IDTYPE_FRAGMENT          (0x00000020 | IDTYPE_ISVALID)    // File Fragment (i.e. foobar.htm#SECTION_3)

// These are bits that indicate
// For Server ItemIDs
#define IDVALID_PORT_NUM         0x00000100     // Was the port number specified
#define IDVALID_USERNAME         0x00000200     // Was the login name specified
#define IDVALID_PASSWORD         0x00000400     // Was the password specified
#define IDVALID_DLTYPE           0x00000800     // Download Type is specified.
#define IDVALID_DL_ASCII         0x00001000     // Download as ASCII if set, otherwise, download as BINARY.
#define IDVALID_HIDE_PASSWORD    0x00002000     // The Password entry is invalid so use the sessionkey to look it up.

#define VALID_SERVER_BITS (IDTYPE_ISVALID|IDTYPE_SERVER|IDVALID_PORT_NUM|IDVALID_USERNAME|IDVALID_PASSWORD|IDVALID_DLTYPE|IDVALID_DL_ASCII|IDVALID_HIDE_PASSWORD)
#define IS_VALID_SERVER_ITEMID(pItemId) (!(pItemId & ~VALID_SERVER_BITS))

// For Dir/File ItemIDs
#define IDVALID_FILESIZE         0x00010000     // Did we get the file size from the server?
#define IDVALID_MOD_DATE         0x00020000     // Did we get the modification date from the server?

#define VALID_DIRORFILE_BITS (IDTYPE_ISVALID|IDTYPE_DIR|IDTYPE_FILE|IDTYPE_FILEORDIR|IDTYPE_FRAGMENT|IDVALID_FILESIZE|IDVALID_MOD_DATE)
#define IS_VALID_DIRORFILE_ITEMID(pItemId) (!(pItemId & (~VALID_DIRORFILE_BITS & ~IDTYPE_ISVALID)))


#define IS_FRAGMENT(pFtpIDList)       (IDTYPE_ISVALID != (IDTYPE_FRAGMENT & pFtpIDList->dwIDType))

///////////////////////////////////////////////////////////
// FTP Pidl Helper Functions 
///////////////////////////////////////////////////////////

/*****************************************************************************\
    FUNCTION: UrlGetAbstractPathFromPidl

    DESCRIPTION:
        pszUrlPath will be UNEscaped and in Wire Bytes.
\*****************************************************************************/
HRESULT UrlGetAbstractPathFromPidl(LPCITEMIDLIST pidl, BOOL fDirsOnly, BOOL fInWireBytes, void * pvPath, DWORD cchUrlPathSize)
{
    HRESULT hr = S_OK;
    LPWIRESTR pwWirePath = (LPWIRESTR) pvPath;
    LPWSTR pwzDisplayPath = (LPWSTR) pvPath;

    if (!EVAL(FtpPidl_IsValid(pidl)))
        return E_INVALIDARG;

    ASSERT(pvPath && (0 < cchUrlPathSize));
    ASSERT(IsValidPIDL(pidl));

    if (fInWireBytes)
    {
        pwWirePath[0] = '/';
        pwWirePath[1] = '\0'; // Make this path absolute.
    }
    else
    {
        pwzDisplayPath[0] = L'/';
        pwzDisplayPath[1] = L'\0'; // Make this path absolute.
    }

    if (!ILIsEmpty(pidl) && FtpID_IsServerItemID(pidl))       // If it's not a server, we are screwed.
        pidl = _ILNext(pidl);   // Skip past the Server Pidl.

    for (; !ILIsEmpty(pidl); pidl = _ILNext(pidl))
    {
        if (!fDirsOnly || FtpItemID_IsDirectory(pidl, TRUE) || !ILIsEmpty(_ILNext(pidl)))
        {
            if (!FtpItemID_IsFragment(pidl))
            {
                if (fInWireBytes)
                {
                    LPCWIRESTR pwWireName = FtpItemID_GetWireNameReference(pidl);

                    if (pwWireName)
                    {
                        // The caller should never need the URL Path escaped because
                        // that will happen when it's converted into an URL.
                        WirePathAppend(pwWirePath, cchUrlPathSize, pwWireName);
                    }
                }
                else
                {
                    LPCWSTR pwzDisplayName = FtpItemID_GetDisplayNameReference(pidl);

                    if (pwzDisplayName)
                    {
                        // The caller should never need the URL Path escaped because
                        // that will happen when it's converted into an URL.
                        DisplayPathAppend(pwzDisplayPath, cchUrlPathSize, pwzDisplayName);
                    }
                }
            }
        }

        if (SUCCEEDED(hr) && (FtpItemID_IsDirectory(pidl, FALSE) || (FtpItemID_GetCompatFlags(pidl) & COMPAT_WEBBASEDDIR)))
        {
            if (fInWireBytes)
                WirePathAppendSlash(pwWirePath, cchUrlPathSize); // Always make sure dirs end in '/'.
            else
                DisplayPathAppendSlash(pwzDisplayPath, cchUrlPathSize); // Always make sure dirs end in '/'.
        }
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: GetDisplayPathFromPidl

    DESCRIPTION:
        pwzDisplayPath will be UNEscaped and in display unicode.
\*****************************************************************************/
HRESULT GetDisplayPathFromPidl(LPCITEMIDLIST pidl, LPWSTR pwzDisplayPath, DWORD cchUrlPathSize, BOOL fDirsOnly)
{
    return UrlGetAbstractPathFromPidl(pidl, fDirsOnly, FALSE, (void *) pwzDisplayPath, cchUrlPathSize);
}


/*****************************************************************************\
    FUNCTION: GetWirePathFromPidl

    DESCRIPTION:
        pszUrlPath will be UNEscaped and in Wire Bytes.
\*****************************************************************************/
HRESULT GetWirePathFromPidl(LPCITEMIDLIST pidl, LPWIRESTR pwWirePath, DWORD cchUrlPathSize, BOOL fDirsOnly)
{
    return UrlGetAbstractPathFromPidl(pidl, fDirsOnly, TRUE, (void *) pwWirePath, cchUrlPathSize);
}


/*****************************************************************************\
    FUNCTION: UrlGetFileNameFromPidl

    DESCRIPTION:
        pszFileName will be filled with the file name if it exists.  If it doesn't,
    S_FALSE will be returned if the PIDL only points to a directory and not
    a file.
HRESULT UrlGetFileNameFromPidl(LPCITEMIDLIST pidl, LPTSTR pszFileName, DWORD cchSize)
{
    HRESULT hr = S_FALSE;

    if (!EVAL(FtpPidl_IsValid(pidl)))
        return E_INVALIDARG;

    ASSERT(pszFileName && (0 < cchSize));
    ASSERT(IsValidPIDL(pidl));
    pszFileName[0] = TEXT('\0');

    if (EVAL(FtpID_IsServerItemID(pidl)))       // If it's not a server, we are screwed.
        pidl = _ILNext(pidl);   // Skip past the Server Pidl.

    for (; !ILIsEmpty(pidl); pidl = _ILNext(pidl))
    {
        if (!FtpItemID_IsDirectory(pidl, FALSE))
        {
            // This isn't a directory, so the only time it's valid to not
            // be the last ItemID is if this is a file ItemID and the next
            // ItemID is a Fragment.
            ASSERT(ILIsEmpty(_ILNext(pidl)) || FtpItemID_IsFragment(_ILNext(pidl)));
            SHAnsiToTChar(FtpItemID_GetFileName(pidl), pszFileName, cchSize);
            hr = S_OK;
            break;
        }
    }

    return hr;
}
\*****************************************************************************/


#ifndef UNICODE
/*****************************************************************************\
    FUNCTION: UrlCreateFromPidlW

    DESCRIPTION:
        x.
\*****************************************************************************/
HRESULT UrlCreateFromPidlW(LPCITEMIDLIST pidl, DWORD shgno, LPWSTR pwzUrl, DWORD cchSize, DWORD dwFlags, BOOL fHidePassword)
{
    HRESULT hr;
    TCHAR szUrl[MAX_URL_STRING];

    hr = UrlCreateFromPidl(pidl, shgno, szUrl, ARRAYSIZE(szUrl), dwFlags, fHidePassword);
    if (SUCCEEDED(hr))
        SHTCharToUnicode(szUrl, pwzUrl, cchSize);

    return hr;
}

#else // UNICODE

/*****************************************************************************\
    FUNCTION: UrlCreateFromPidlA

    DESCRIPTION:
        x.
\*****************************************************************************/
HRESULT UrlCreateFromPidlA(LPCITEMIDLIST pidl, DWORD shgno, LPSTR pszUrl, DWORD cchSize, DWORD dwFlags, BOOL fHidePassword)
{
    HRESULT hr;
    TCHAR szUrl[MAX_URL_STRING];

    hr = UrlCreateFromPidl(pidl, shgno, szUrl, ARRAYSIZE(szUrl), dwFlags, fHidePassword);
    if (SUCCEEDED(hr))
        SHTCharToAnsi(szUrl, pszUrl, cchSize);

    return hr;
}

#endif // UNICODE


BOOL IncludePassword(void)
{
    if (NOT_INITIALIZED == g_fNoPasswordsInAddressBar)
        g_fNoPasswordsInAddressBar = !SHRegGetBoolUSValue(SZ_REGKEY_FTPFOLDER, SZ_REGVALUE_PASSWDSIN_ADDRBAR, FALSE, TRUE);

    return g_fNoPasswordsInAddressBar;
}


HRESULT ParseUrlCreateFromPidl(LPCITEMIDLIST pidl, LPTSTR pszUrl, DWORD cchSize, DWORD dwFlags, BOOL fHidePassword)
{
    HRESULT hr = S_OK;
    TCHAR szServer[INTERNET_MAX_HOST_NAME_LENGTH];
    TCHAR szUrlPath[MAX_URL_STRING];
    TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH];
    TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH];
    TCHAR szFragment[MAX_PATH];
    TCHAR szDownloadType[MAX_PATH] = TEXT("");
    INTERNET_PORT ipPortNum = INTERNET_DEFAULT_FTP_PORT;

    if (ILIsEmpty(pidl))
    {
        ASSERT(0); // BUGBUG: Work around until we can figure out why CFtpFolder has ILIsEmpty(m_pidlHere).
        szServer[0] = szUrlPath[0] = szUserName[0] = szPassword[0] = TEXT('\0');
        hr = E_FAIL;
    }
    else
    {
        FtpPidl_GetServer(pidl, szServer, ARRAYSIZE(szServer));
        GetDisplayPathFromPidl(pidl, szUrlPath, ARRAYSIZE(szUrlPath), FALSE);
        FtpPidl_GetUserName(pidl, szUserName, ARRAYSIZE(szUserName));
        if (FAILED(FtpPidl_GetPassword(pidl, szPassword, ARRAYSIZE(szPassword), !fHidePassword)))
            szPassword[0] = 0;

        FtpPidl_GetFragment(pidl, szFragment, ARRAYSIZE(szPassword));
        FtpPidl_GetDownloadTypeStr(pidl, szDownloadType, ARRAYSIZE(szDownloadType));
        UrlPathAdd(szUrlPath, ARRAYSIZE(szUrlPath), szDownloadType);
        ipPortNum = FtpPidl_GetPortNum(pidl);
    }

    if (SUCCEEDED(hr))
    {
        TCHAR szUserNameEscaped[INTERNET_MAX_USER_NAME_LENGTH];

        szUserNameEscaped[0] = 0;
        if (szUserName[0])
            EscapeString(szUserName, szUserNameEscaped, ARRAYSIZE(szUserNameEscaped));

        hr = UrlCreateEx(szServer, NULL_FOR_EMPTYSTR(szUserNameEscaped), szPassword, szUrlPath, szFragment, ipPortNum, szDownloadType, pszUrl, cchSize, dwFlags);
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: GetFullPrettyName
    
    DESCRIPTION:
        The user wants a pretty name so these are the cases we need to worry
    about:
    URL:                                               Pretty Name:
    ----------------------------------                 ---------------------
    ftp://joe:psswd@serv/                              serv
    ftp://joe:psswd@serv/dir1/                         dir1 on serv
    ftp://joe:psswd@serv/dir1/dir2/                    dir2 on serv
    ftp://joe:psswd@serv/dir1/dir2/file.txt            file.txt on serv
\*****************************************************************************/
HRESULT GetFullPrettyName(LPCITEMIDLIST pidl, LPTSTR pszUrl, DWORD cchSize)
{
    HRESULT hr = S_OK;
    TCHAR szServer[INTERNET_MAX_HOST_NAME_LENGTH];

    FtpPidl_GetServer(pidl, szServer, ARRAYSIZE(szServer));
    // Is there anything after the ServerItemID?
    if (!ILIsEmpty(_ILNext(pidl)))
    {
        // Yes, so let's get the name of the last item and
        // make the string "<LastItemName> on <Server>".
        LPCWSTR pwzLastItem = FtpItemID_GetDisplayNameReference(ILFindLastID(pidl));
        LPTSTR pszStrArray[] = {szServer, (LPTSTR)pwzLastItem};
        TCHAR szTemplate[MAX_PATH];
        
        EVAL(LoadString(HINST_THISDLL, IDS_PRETTYNAMEFORMAT, szTemplate, ARRAYSIZE(szTemplate)));
        EVAL(FormatMessage((FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY), (LPVOID)szTemplate,
                            0, 0, pszUrl, cchSize, (va_list*)pszStrArray));
    }
    else
    {
        // No, so we are done.
        StrCpyN(pszUrl, szServer, cchSize);
    }

    return hr;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -