util.cpp

来自「很好用的ftp源码」· C++ 代码 · 共 1,997 行 · 第 1/5 页

CPP
1,997
字号
        pidl = _ILNext(pidl);

    return pidl;
}


LPCITEMIDLIST ILGetLastNonFragID(LPCITEMIDLIST pidlIn)
{
    LPITEMIDLIST pidl = (LPITEMIDLIST) pidlIn;

    while (!ILIsEmpty(_ILNext(pidl)) && !FtpItemID_IsFragment(_ILNext(pidl)))
        pidl = _ILNext(pidl);

    return pidl;
}



SAFEARRAY * MakeSafeArrayFromData(LPCBYTE pData,DWORD cbData)
{
    SAFEARRAY * psa;

    if (!pData || 0 == cbData)
        return NULL;  // nothing to do

    // create a one-dimensional safe array
    psa = SafeArrayCreateVector(VT_UI1,0,cbData);
    ASSERT(psa);

    if (psa) {
        // copy data into the area in safe array reserved for data
        // Note we party directly on the pointer instead of using locking/
        // unlocking functions.  Since we just created this and no one
        // else could possibly know about it or be using it, this is OK.

        ASSERT(psa->pvData);
        memcpy(psa->pvData,pData,cbData);
    }

    return psa;
}


//
// PARAMETER:
//    pvar - Allocated by caller and filled in by this function.
//    pidl - Allocated by caller and caller needs to free.
//
// This function will take the PIDL parameter and COPY it
// into the Variant data structure.  This allows the pidl
// to be freed and the pvar to be used later, however, it
// is necessary to call VariantClear(pvar) to free memory
// that this function allocates.

BOOL InitVariantFromIDList(VARIANT* pvar, LPCITEMIDLIST pidl)
{
    UINT cb = ILGetSize(pidl);
    SAFEARRAY* psa = MakeSafeArrayFromData((LPCBYTE)pidl, cb);
    if (psa) {
        ASSERT(psa->cDims == 1);
        // ASSERT(psa->cbElements == cb);
        ASSERT(ILGetSize((LPCITEMIDLIST)psa->pvData)==cb);
        VariantInit(pvar);
        pvar->vt = VT_ARRAY|VT_UI1;
        pvar->parray = psa;
        return TRUE;
    }

    return FALSE;
}



BSTR BStrFromStr(LPCTSTR pszStr)
{
    BSTR bStr = NULL;

#ifdef UNICODE
    bStr = SysAllocString(pszStr);

#else // UNICODE
    DWORD cchSize = (lstrlen(pszStr) + 2);
    bStr = SysAllocStringLen(NULL, cchSize);
    if (EVAL(bStr))
        SHAnsiToUnicode(pszStr, bStr, cchSize);

#endif // UNICODE

    return bStr;
}


HRESULT IUnknown_IWebBrowserNavigate2(IUnknown * punk, LPCITEMIDLIST pidl, BOOL fHistoryEntry)
{
    HRESULT hr = E_FAIL;
    IWebBrowser2 * pwb2;

    // punk will be NULL on Browser Only installs because the old
    // shell32 doesn't do ::SetSite().
    IUnknown_QueryService(punk, SID_SWebBrowserApp, IID_IWebBrowser2, (LPVOID *) &pwb2);
    if (pwb2)
    {
        VARIANT varThePidl;

        if (InitVariantFromIDList(&varThePidl, pidl))
        {
            VARIANT varFlags;
            VARIANT * pvarFlags = PVAREMPTY;

            if (!fHistoryEntry)
            {
                varFlags.vt = VT_I4;
                varFlags.lVal = navNoHistory;
                pvarFlags = &varFlags;
            }

            hr = pwb2->Navigate2(&varThePidl, pvarFlags, PVAREMPTY, PVAREMPTY, PVAREMPTY);
            VariantClear(&varThePidl);
        }
        pwb2->Release();
    }
    else
    {
        IShellBrowser * psb;

        // Maybe we are in comdlg32.
        hr = IUnknown_QueryService(punk, SID_SCommDlgBrowser, IID_IShellBrowser, (LPVOID *) &psb);
        if (SUCCEEDED(hr))
        {
            CFtpView * pfv = GetCFtpViewFromDefViewSite(punk);

            AssertMsg((NULL != pfv), TEXT("IUnknown_IWebBrowserNavigate2() defview gave us our IShellFolderViewCB so it needs to support this interface."));
            if (pfv)
            {
                // Are we on the forground thread?
                if (pfv->IsForegroundThread())
                {
                    // Yes, so this will be easy.  This is the case
                    // where "Login As..." was chosen from the background context menu item.
                    hr = psb->BrowseObject(pidl, 0);
                }
                else
                {
                    // No, so this is the case where we failed to login with the original
                    // UserName/Password and we will try again with the corrected Username/Password.

                    // Okay, we are talking to the ComDlg code but we don't want to use
                    // IShellBrowse::BrowseObject() because we are on a background thread. (NT #297732)
                    // Therefore, we want to have the IShellFolderViewCB (CFtpView) cause
                    // the redirect on the forground thread.  Let's inform
                    // CFtpView now to do this.
                    hr = pfv->SetRedirectPidl(pidl);
                }

                pfv->Release();
            }
            
            AssertMsg(SUCCEEDED(hr), TEXT("IUnknown_IWebBrowserNavigate2() defview needs to support QS(SID_ShellFolderViewCB) on all platforms that hit this point"));
            psb->Release();
        }
    }

    return hr;
}


HRESULT IUnknown_PidlNavigate(IUnknown * punk, LPCITEMIDLIST pidl, BOOL fHistoryEntry)
{
    HRESULT hrOle = SHCoInitialize();
    HRESULT hr = IUnknown_IWebBrowserNavigate2(punk, pidl, fHistoryEntry);

    // Try a pre-NT5 work around.
    // punk will be NULL on Browser Only installs because the old
    // shell32 doesn't do ::SetSite().
    if (FAILED(hr))
    {
        IWebBrowserApp * pauto = NULL;
        
        hr = SHGetIDispatchForFolder(pidl, &pauto);
        if (EVAL(pauto))
        {
            hr = IUnknown_IWebBrowserNavigate2(pauto, pidl, fHistoryEntry);
            ASSERT(SUCCEEDED(hr));
            pauto->Release();
        }
    }

    ASSERT(SUCCEEDED(hrOle));
    SHCoUninitialize(hrOle);
    return hr;
}


/*****************************************************************************\

    HIDACREATEINFO

    Structure that collects all information needed when building
    an ID List Array.

\*****************************************************************************/

typedef struct tagHIDACREATEINFO
{
    HIDA hida;            /* The HIDA being built */
    UINT ipidl;            /* Who we are */
    UINT ib;            /* Where we are */
    UINT cb;            /* Where we're going */
    UINT cpidl;            /* How many we're doing */
    LPCITEMIDLIST pidlFolder;        /* The parent all these LPITEMIDLISTs live in */
    CFtpPidlList * pflHfpl;            /* The pidl list holding all the kids */
} HIDACREATEINFO, * LPHIDACREATEINFO;

#define pidaPhci(phci) ((LPIDA)(phci)->hida)    /* no need to lock */


/*****************************************************************************\
    Misc_SfgaoFromFileAttributes

    AIGH!

    UNIX and Win32 semantics on file permissions are different.

    On UNIX, the ability to rename or delete a file depends on
    your permissions on the parent folder.

    On Win32, the ability to rename or delete a file depends on
    your permissions on the file itself.

    Note that there is no such thing as "deny-read" attributes
    on Win32...  I wonder how WinINet handles that...

    I'm going to hope that WinINet does the proper handling of this,
    so I'll just proceed with Win32 semantics... I'm probably assuming too much...
\*****************************************************************************/
DWORD Misc_SfgaoFromFileAttributes(DWORD dwFAFLFlags)
{
    DWORD sfgao = SFGAO_CANLINK;    // You can always link

    sfgao |= SFGAO_HASPROPSHEET;    // You can always view properties

    sfgao |= SFGAO_CANCOPY;        // Deny-read?  No such thing! (Yet)

    if (dwFAFLFlags & FILE_ATTRIBUTE_READONLY)
    {        /* Can't delete it, sorry */
#ifdef _SOMEDAY_ASK_FRANCISH_WHAT_THIS_IS
        if (SHELL_VERSION_NT5 == GetShellVersion())
            sfgao |= SFGAO_READONLY;
#endif
    }
    else
    {
        sfgao |= (SFGAO_CANRENAME | SFGAO_CANDELETE);
#ifdef FEATURE_CUT_MOVE
        sfgao |= SFGAO_CANMOVE;
#endif // FEATURE_CUT_MOVE
    }

    if (dwFAFLFlags & FILE_ATTRIBUTE_DIRECTORY)
    {
        //Since FTP connections are expensive, assume SFGAO_HASSUBFOLDER
        sfgao |= SFGAO_DROPTARGET | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
    }
    else
    {
        // We always return the
        // SFGAO_BROWSABLE because we always want to do the navigation
        // using our IShellFolder::CreateViewObject().  In the case of
        // files, the CreateViewObject() that we create is for URLMON
        // which will do the download.  This is especially true for
        // Folder Shortcuts.
        sfgao |= SFGAO_BROWSABLE;
    }

    return sfgao;
}

/*****************************************************************************\
    FUNCTION: Misc_StringFromFileTime

    DESCRIPTION:
        Get the date followed by the time.  flType can be DATE_SHORTDATE
    (for defview's details list) or DATE_LONGDATE for the property sheet.
\*****************************************************************************/
HRESULT Misc_StringFromFileTime(LPTSTR pszDateTime, DWORD cchSize, LPFILETIME pft, DWORD flType)
{
    if (EVAL(pft && pft->dwHighDateTime))
    {
	SHFormatDateTime(pft, &flType, pszDateTime, cchSize);
    }
    else
        pszDateTime[0] = 0;

    return S_OK;
}


LPITEMIDLIST GetPidlFromFtpFolderAndPidlList(CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    LPCITEMIDLIST pidlBase = pff->GetPrivatePidlReference();
    LPCITEMIDLIST pidlRelative = ((0 == pflHfpl->GetCount()) ? c_pidlNil : pflHfpl->GetPidl(0));

    return ILCombine(pidlBase, pidlRelative);
}


IProgressDialog * CProgressDialog_CreateInstance(UINT idTitle, UINT idAnimation)
{
    IProgressDialog * ppd = NULL;
    
    if (EVAL(SUCCEEDED(CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC_SERVER, IID_IProgressDialog, (void **)&ppd))))
    {
        WCHAR wzTitle[MAX_PATH];

        if (EVAL(LoadStringW(HINST_THISDLL, idTitle, wzTitle, ARRAYSIZE(wzTitle))))
            EVAL(SUCCEEDED(ppd->SetTitle(wzTitle)));

        EVAL(SUCCEEDED(ppd->SetAnimation(HINST_THISDLL, idAnimation)));
    }

    return ppd;
}


BOOL_PTR CALLBACK ProxyDlgWarningWndProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_INITDIALOG)
    {
        LPCTSTR pszUrl = (LPCTSTR)lParam;
        TCHAR szMessage[MAX_PATH*3];
        TCHAR szTemplate[MAX_PATH*3];

        ASSERT(pszUrl);

        EVAL(LoadString(HINST_THISDLL, IDS_FTP_PROXY_WARNING, szTemplate, ARRAYSIZE(szTemplate)));
        wnsprintf(szMessage, ARRAYSIZE(szMessage), szTemplate, pszUrl);
        EVAL(SetWindowText(GetDlgItem(hDlg, IDC_PROXY_MESSAGE), szMessage));
    }

    return FALSE;
}


/*****************************************************************************\
    FUNCTION:   DisplayBlockingProxyDialog

    DESCRIPTION:
        Inform user that their CERN style proxy is blocking real FTP access so
    they can do something about it.

    Inform the user so they can: 
    A) Change proxies,
    B) Annoy their administrator to install real proxies,
    C) Install Remote WinSock themselves,
    D) or settle for their sorry situation in life and use the
       limited CERN proxy support and dream about the abilitity
       to rename, delete, and upload.

    This will be a no-op if the user clicks "Don't display this
    message again" check box.
\*****************************************************************************/
HRESULT DisplayBlockingProxyDialog(LPCITEMIDLIST pidl, HWND hwnd)
{
    // Did the IBindCtx provide information to allow us to do UI?
    if (hwnd)
    {
        TCHAR szUrl[MAX_PATH];

        UrlCreateFromPidl(pidl, SHGDN_FORPARSING, szUrl, ARRAYSIZE(szUrl), 0, TRUE);

        // Make it modal while the dialog is being displayed.
//        IUnknown_EnableModless(punkSite, FALSE);
        SHMessageBoxCheckEx(hwnd, HINST_THISDLL, MAKEINTRESOURCE(IDD_PROXYDIALOG), ProxyDlgWarningWndProc, (LPVOID) szUrl, IDOK, SZ_REGVALUE_WARN_ABOUT_PROXY);
//        IUnknown_EnableModless(punkSite, TRUE);
    }

    return S_OK;
}


HRESULT CreateFromToStr(LPWSTR pwzStrOut, DWORD cchSize, ...)
{
    CHAR szStatusText[MAX_PATH];
    CHAR szTemplate[MAX_PATH];
    va_list vaParamList;
    
    va_start(vaParamList, cchSize);
    // Generate the string "From <SrcFtpUrlDir> to <DestFileDir>" status string
    EVAL(LoadStringA(HINST_THISDLL, IDS_DL_SRC_DEST, szTemplate, ARRAYSIZE(szTemplate)));
    if (EVAL(FormatMessageA(FORMAT_MESSAGE_FROM_STRING, szTemplate, 0, 0, szStatusText, ARRAYSIZE(szStatusText), &vaParamList)))
        SHAnsiToUnicode(szStatusText, pwzStrOut, cchSize);

    va_end(vaParamList);
    return S_OK;
}

/****************************************************\
    FUNCTION: FtpProgressInternetStatusCB

    DESCRIPTION: 

⌨️ 快捷键说明

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