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

📄 ftpdrop.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    return hr;
}


/****************************************************\
    FUNCTION: _GetFSSourcePaths

    DESCRIPTION:
\****************************************************/
HRESULT CFtpDrop::_GetFSSourcePaths(HGLOBAL hdrop, BOOL * pfAnsi)
{
    LPDROPFILES pdrop = (LPDROPFILES) GlobalLock(hdrop);
    HRESULT hr = E_INVALIDARG;

    *pfAnsi = TRUE;
    if (EVAL(pdrop))
    {
        //  Now to decide whether it is an old-style drop or a new-style
        // drop.  And if it's a new-style drop, to get the character set.
        if (LOWORD(pdrop->pFiles) == sizeof(DROPFILES16))
        {
            // Old style
            Str_StrAndThunkA((LPTSTR *) &m_pszzFSSource, (LPCSTR) pvByteIndexCb(pdrop, LOWORD(pdrop->pFiles)), TRUE);
        }
        else
        {
            if (pdrop->fWide)
            {
                Str_StrAndThunkW((LPTSTR *) &m_pszzFSSource, (LPCWSTR) pvByteIndexCb(pdrop, pdrop->pFiles), TRUE);
                *pfAnsi = FALSE;
            }
            else
                Str_StrAndThunkA((LPTSTR *) &m_pszzFSSource, (LPCSTR) pvByteIndexCb(pdrop, pdrop->pFiles), TRUE);
        }
        GlobalUnlock(pdrop);
        hr = S_OK;
    }

    return hr;
}


/****************************************************\
    FUNCTION: _GetFtpDestPaths

    DESCRIPTION:
\****************************************************/
HRESULT CFtpDrop::_GetFtpDestPaths(HGLOBAL hmap, BOOL fAnsi)
{
    HRESULT hr = E_INVALIDARG;
    LPVOID pmap = NULL;

    //  If we can't get a map, then just use the source file names.
    ASSERT(!m_pszzFtpDest);
    if (hmap)
    {
        pmap = GlobalLock(hmap);

        if (pmap)
        {
            if (fAnsi)
                Str_StrAndThunkA((LPTSTR *) &m_pszzFtpDest, (LPCSTR) pmap, TRUE);
            else
                Str_StrAndThunkW((LPTSTR *) &m_pszzFtpDest, (LPCWSTR) pmap, TRUE);

            GlobalUnlock(pmap);
        }
    }

    if (!m_pszzFtpDest)
    {
        // Just copy the Paths
        Str_StrAndThunk((LPTSTR *) &m_pszzFtpDest, m_pszzFSSource, TRUE);
    }

    if (m_pszzFtpDest)
        hr = S_OK;

    return hr;
}



/*****************************************************************************\
    CopyHdrop

    Copy an HDROP data object.

    Note also that when we use HDROP, we must also consult the
    FileNameMap otherwise dragging out of the recycle bin directly
    into an FTP folder will create files with the wrong name!

    Note further that the returned effect of an HDROP is always
    DROPEFFECT_COPY, because we will do the work of deleting the
    source files when finished.
\*****************************************************************************/
HRESULT CFtpDrop::CopyHdrop(IDataObject * pdto, STGMEDIUM *psm)
{
    BOOL fAnsi;
    HRESULT hr = _GetFSSourcePaths(psm->hGlobal, &fAnsi);

    if (EVAL(SUCCEEDED(hr)))
    {
        STGMEDIUM sm;

        // ZIP fails this.
        // Get the File name map, too, if one exists
        if (fAnsi)
            hr = pdto->GetData(&g_dropTypes[DROP_FNMA], &sm);
        else
            hr = pdto->GetData(&g_dropTypes[DROP_FNMW], &sm);

        if (FAILED(hr))       // Failure is ok
            sm.hGlobal = 0;

        hr = _GetFtpDestPaths(sm.hGlobal, fAnsi);
        if (EVAL(SUCCEEDED(hr)))
        {
            *m_pde = DROPEFFECT_COPY;
            // Count up how many things there are in the hdrop,
            // so that our confirmation dialog knows what the deal is.
            // We can ignore the error; it'll show up again when we copy.
            m_cobj = 0;
            hr = _DoCountIteration();
            ASSERT(SUCCEEDED(hr));
            TraceMsg(TF_FTPDRAGDROP, "CFtpDrop_CopyHdrop: %d file(s)", m_cobj);

            //  Now walk the lists with the appropriate enumerator.
            hr = _StartBackgroundInteration();
            ASSERT(SUCCEEDED(hr));
        }
        if (sm.hGlobal)
            ReleaseStgMedium(&sm);
    }

    return hr;
}


/*****************************************************************************\
    _CopyHglobal

    Copy a file contents received as an hglobal.

    If a FD_FILESIZE is provided, use it.  Otherwise, just use the size
    of the hglobal.
\*****************************************************************************/
HRESULT CFtpDrop::_CopyHglobal(IStream * pstm, DWORD dwFlags, DWORD dwFileSizeHigh, DWORD dwFileSizeLow, LPVOID pvSrc, ULARGE_INTEGER *pqw)
{
    LPVOID pv;
    HGLOBAL hglob = pvSrc;
    HRESULT hres;

    pqw->HighPart = 0;
    pv = GlobalLock(hglob);
    if (EVAL(pv))
    {
        UINT cb = (UINT) GlobalSize(hglob);
        if (dwFlags & FD_FILESIZE)
        {
            if (cb > dwFileSizeLow)
                cb = dwFileSizeHigh;
        }
        hres = pstm->Write(pv, cb, &pqw->LowPart);
        if (SUCCEEDED(hres))
        {
            if (pqw->LowPart != cb)
                hres = STG_E_MEDIUMFULL;
        }
        GlobalUnlock(pv);
    }
    else
        hres = E_INVALIDARG;

    return hres;
}


/*****************************************************************************
    FUNCTION: _GetRelativePidl

    DESCRIPTION:
        pszFullPath may come in this format: "dir1\dir2\dir3\file.txt".  We
    need to create *ppidl such that it will contain 4 itemIDs in this case and
    the last one (file.txt) will have the correct attributes and file size.
\*****************************************************************************/
CFtpDir * CFtpDrop::_GetRelativePidl(LPCWSTR pszFullPath, DWORD dwFileAttributes, DWORD dwFileSizeHigh, DWORD dwFileSizeLow, LPITEMIDLIST * ppidl)
{
    HRESULT hr = S_OK;
    WCHAR szFullPath[MAX_PATH];
    LPWSTR pszFileName;
    LPITEMIDLIST pidlFull;
    CFtpDir * pfd = m_pfd;  // Assume the Dir to create isn't in a subdir.

    // Find the File Name
    StrCpyNW(szFullPath, pszFullPath, ARRAYSIZE(szFullPath));   // Make a copy because the caller's is read only.
    pszFileName = PathFindFileName(szFullPath);                 // Find where the file begins.
    FilePathToUrlPathW(szFullPath);                             // Convert from "dir1\dir2\file.txt" to "dir1/dir2/file.txt"

    *ppidl = NULL;
    hr = CreateFtpPidlFromDisplayPath(szFullPath, m_pff->GetCWireEncoding(), NULL, &pidlFull, TRUE, FALSE);
    if (SUCCEEDED(hr))
    {
        LPITEMIDLIST pidlFile = ILFindLastID(pidlFull);
        SYSTEMTIME st;
        FILETIME ft;

        GetSystemTime(&st);
        SystemTimeToFileTime(&st, &ft);
        FtpPidl_SetAttributes(pidlFile, dwFileAttributes);
        FtpPidl_SetFileSize(pidlFile, dwFileSizeHigh, dwFileSizeLow);
        FtpItemID_SetFileTime(pidlFile, ft);

        // Is the file in a subdir?
        if (!ILIsEmpty(pidlFull) && !ILIsEmpty(_ILNext(pidlFull)))
        {
            // Yes, so generate a CFtpDir to the subdir.
            LPITEMIDLIST pidlPath = ILClone(pidlFull);

            if (pidlPath)
            {
                ILRemoveLastID(pidlPath);
                pfd = m_pfd->GetSubFtpDir(m_pff, pidlPath, FALSE);
                ILFree(pidlPath);
            }
        }

        if (pfd)
            *ppidl = ILClone(pidlFile);
        ILFree(pidlFull);
    }

    return pfd;
}


/*****************************************************************************
    FUNCTION: CopyAsStream

    DESCRIPTION:
        Copy a file contents received as a <mumble> to a stream.
\*****************************************************************************/
HRESULT CFtpDrop::CopyAsStream(LPCWSTR pszName, DWORD dwFileAttributes, DWORD dwFlags, DWORD dwFileSizeHigh, DWORD dwFileSizeLow, STREAMCOPYPROC pfn, LPVOID pv)
{
    BOOL fFireChangeNotify;
    HRESULT hr = ConfirmCopy(pszName, pszName, &m_ops, m_hwnd, m_pff, m_pfd, m_pde, m_cobj, &fFireChangeNotify);

    if (EVAL(SUCCEEDED(hr)))
    {
        LPITEMIDLIST pidlRelative;
        CFtpDir * pfd = _GetRelativePidl(pszName, dwFileAttributes, dwFileSizeHigh, dwFileSizeLow, &pidlRelative);

        if (EVAL(pfd))
        {
            LPITEMIDLIST pidlFull = ILCombine(pfd->GetPidlReference(), pidlRelative);

            if (pidlFull)
            {
                IStream * pstm;
                ULARGE_INTEGER uliTemp = {0};

                hr = CFtpStm_Create(pfd, pidlFull, GENERIC_WRITE, &pstm, uliTemp, uliTemp, NULL, FALSE);
                if (SUCCEEDED(hr))
                {
                    ULARGE_INTEGER uli = {dwFileSizeLow, dwFileSizeHigh};

                    hr = pfn(pstm, dwFlags, dwFileSizeHigh, dwFileSizeLow, pv, &uli);
                    if (SUCCEEDED(hr))
                    {
                        // Only fire change notify if we didn't replace a file on 
                        // browser only. (Because we hack the defview and it doesn't
                        // check for duplicates)
                        if (fFireChangeNotify)
                        {
                            FtpPidl_SetFileSize(pidlRelative, uli.HighPart, uli.LowPart);

                            // This time date stamp may be incorrect.
                            FtpChangeNotify(m_hwnd, SHCNE_CREATE, m_pff, pfd, pidlRelative, NULL, TRUE);
                        }
                    }
                    else
                    {
                        ASSERT(0);      // BUGBUG - Is there an orphaned file we need to delete?
                        DisplayWininetError(m_hwnd, TRUE, HRESULT_CODE(hr), IDS_FTPERR_TITLE_ERROR, IDS_FTPERR_DROPFAIL, IDS_FTPERR_WININET, MB_OK, NULL);
                        hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
                    }

                    pstm->Release();
                }
                else
                {
                    DisplayWininetError(m_hwnd, TRUE, HRESULT_CODE(hr), IDS_FTPERR_TITLE_ERROR, IDS_FTPERR_DROPFAIL, IDS_FTPERR_WININET, MB_OK, NULL);
                    hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
                }

                ILFree(pidlFull);
            }
            else
                hr = E_OUTOFMEMORY;

            if (pfd != m_pfd)
                pfd->Release();

            ILFree(pidlRelative);
        }
        else
            hr = E_FAIL;
    }
    else
    {
        // BUGBUG -- need to stat the file to generate a local WFDA
        // BUGBUG -- check the return value and do something
        ASSERT(0);      // Handle appropriately.
    }

    return hr;
}


/*****************************************************************************\
    CopyStream

    Copy a file contents received as a stream.
    We ignore the file size in the fgd.
\*****************************************************************************/
HRESULT CFtpDrop::CopyStream(IStream * pstm, DWORD dwFlags, DWORD dwFileSizeHigh, DWORD dwFileSizeLow, LPVOID pvSrc, ULARGE_INTEGER *pqw)
{
    IStream * pstmSrc = (IStream *) pvSrc;
    ULARGE_INTEGER qwMax = {0xFFFFFFFF, 0xFFFFFFFF};
    HRESULT hres;

    hres = pstmSrc->CopyTo(pstm, qwMax, 0, pqw);
    ASSERT(SUCCEEDED(hres));

    return hres;
}


/*****************************************************************************\
    FUNCTION: CFtpDrop::CopyStorage

    DESCRIPTION:
        Copy a file contents provided as an IStorage.  Gack.
    We have to do this only because Exchange is a moron.

    Since there is no way to tell OLE to create a .doc file
    into an existing stream, we need to create the .doc file
    on disk, and then copy the file into the stream, then delete
    the .doc file.

    Note that CDropOperation::DoOperation() (_CopyOneHdrop) will do the ConfirmCopy
    and the FtpDropNotifyCreate(), too!  However, we want to fake
    it out and fool it into thinking we are doing a DROPEFFECT_COPY,
    so that it doesn't delete the "source" file.  *We* will delete
    the source file, because we created it.  (No need to tell the
    shell about disk size changes that don't affect it.)
\*****************************************************************************/
HRESULT CFtpDrop::CopyStorage(LPCWSTR pszFile, IStorage

⌨️ 快捷键说明

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