📄 ftpapi.cpp
字号:
if (!InternetReadFile(hFile, pvBuffer, dwNumberOfBytesToRead, pdwNumberOfBytesRead))
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
// DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetReadFile(%#08lx, ToRead=%d, Read=%d) returned %u. Time=%lums", hFile, dwNumberOfBytesToRead, (pdwNumberOfBytesRead ? *pdwNumberOfBytesRead : -1), dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
HRESULT InternetWriteFileWrap(HINTERNET hFile, BOOL fAssertOnFailure, LPCVOID pvBuffer, DWORD dwNumberOfBytesToWrite, LPDWORD pdwNumberOfBytesWritten)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
// DEBUG_CODE(DebugStartWatch());
if (!InternetWriteFile(hFile, pvBuffer, dwNumberOfBytesToWrite, pdwNumberOfBytesWritten))
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
// DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetWriteFile(%#08lx, ToWrite=%d, Writen=%d) returned %u. Time=%lums", hFile, dwNumberOfBytesToWrite, (pdwNumberOfBytesWritten ? *pdwNumberOfBytesWritten : -1), dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
/*****************************************************************************\
FUNCTION: InternetGetLastResponseInfoWrap
DESCRIPTION:
PERF Notes:
Always takes 0 (zero) ms because it doesn't have to hit the net.
\*****************************************************************************/
HRESULT InternetGetLastResponseInfoWrap(BOOL fAssertOnFailure, LPDWORD pdwError, LPWIRESTR pwBuffer, LPDWORD pdwBufferLength)
{
HRESULT hr = S_OK;
DWORD dwDummyError;
if (!pdwError)
pdwError = &dwDummyError;
if (pwBuffer)
pwBuffer[0] = 0;
DEBUG_CODE(DebugStartWatch());
InternetGetLastResponseInfoA(pdwError, pwBuffer, pdwBufferLength);
if (pwBuffer)
{
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetGetLastResponseInfo(\"%hs\") took %lu milliseconds", pwBuffer, DebugStopWatch()));
}
else
{
DEBUG_CODE(DebugStopWatch());
}
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
HRESULT InternetGetLastResponseInfoDisplayWrap(BOOL fAssertOnFailure, LPDWORD pdwError, LPWSTR pwzBuffer, DWORD cchBufferSize)
{
LPWIRESTR pwWireResponse;
DWORD dwError = 0;
DWORD cchResponse = 0;
HRESULT hr = InternetGetLastResponseInfoWrap(TRUE, &dwError, NULL, &cchResponse);
cchResponse++; /* +1 for the terminating 0 */
pwWireResponse = (LPWIRESTR)LocalAlloc(LPTR, cchResponse * sizeof(WIRECHAR));
if (pwWireResponse)
{
hr = InternetGetLastResponseInfoWrap(TRUE, &dwError, pwWireResponse, &cchResponse);
if (SUCCEEDED(hr))
{
CWireEncoding cWireEncoding;
hr = cWireEncoding.WireBytesToUnicode(NULL, pwWireResponse, WIREENC_IMPROVE_ACCURACY, pwzBuffer, cchBufferSize);
}
LocalFree(pwWireResponse);
}
else
hr = E_OUTOFMEMORY;
return hr;
}
INTERNET_STATUS_CALLBACK InternetSetStatusCallbackWrap(HINTERNET hInternet, BOOL fAssertOnFailure, INTERNET_STATUS_CALLBACK pfnInternetCallback)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
INTERNET_STATUS_CALLBACK pfnCallBack;
DEBUG_CODE(DebugStartWatch());
pfnCallBack = InternetSetStatusCallback(hInternet, pfnInternetCallback);
if (!pfnCallBack)
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetSetStatusCallback(%#08lx) returned %u. Time=%lums", hInternet, dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return pfnCallBack;
}
HRESULT InternetCheckConnectionWrap(BOOL fAssertOnFailure, LPCTSTR pszUrl, DWORD dwFlags, DWORD dwReserved)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(DebugStartWatch());
if (!InternetCheckConnection(pszUrl, dwFlags, dwReserved))
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetCheckConnection(\"%ls\") returned %u. Time=%lums", pszUrl, dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
//#define FEATURE_OFFLINE
HRESULT InternetAttemptConnectWrap(BOOL fAssertOnFailure, DWORD dwReserved)
{
HRESULT hr = S_OK;
#ifdef FEATURE_OFFLINE
DEBUG_CODE(DebugStartWatch());
hr = HRESULT_FROM_WIN32(InternetAttemptConnect(dwReserved));
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetAttemptConnect() returned hr=%#08lx. Time=%lums", hr, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
#endif // FEATURE_OFFLINE
return hr;
}
/*****************************************************************************\
FUNCTION: InternetFindNextFileWrap
DESCRIPTION:
PERF Notes:
Always takes 0 (zero) ms because all the work is done in FtpFindFirstFile()
\*****************************************************************************/
HRESULT InternetFindNextFileWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPFTP_FIND_DATA pwfd)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(StrCpyNA(pwfd->cFileName, "<Not Found>", ARRAYSIZE(pwfd->cFileName)));
DEBUG_CODE(DebugStartWatch());
// BUGBUG: Bug #206068
// We need to treat dwFileAttributes = 0x00000000 as a directory
// link. We can do this by FtpChangeDirectory() into it, call FtpGetDirectory(),
// and then creating a pidl with UrlPath and navigating to it w/o creating history entry if needed.
// This will solve the problem that going to ftp://ftp.cdrom.com/pub/ and clicking
// on any of the soft links will change into that directory and update the address
// bar to show the real destination directory.
// PERF: The perf of this function normally is nothing because the enum of the entire directory
// is done in the FtpFindFirstFile(). It will also cache the results.
if (!InternetFindNextFileA(hConnect, pwfd))
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetFindNextFile(%#08lx)==\"%hs\", atrbs=%#08lx, hr=%#08lx, Time=%lums",
hConnect, pwfd->cFileName, pwfd->dwFileAttributes, hr, DebugStopWatch()));
if (fAssertOnFailure && (HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES) != hr))
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////////////////
// 2. FTP STRs to PIDLs: These wrappers will take ftp filenames and file paths
// that come in from the server and turn them into pidls. These pidls contain
// both a unicode display string and the filename/path in wire bytes for future
// server requests.
///////////////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************\
FUNCTION: FtpSetCurrentDirectoryPidlWrap
DESCRIPTION:
Change the current directory to the one specified.
PARAMETERS:
pidlFtpPath: If this is NULL, then go to "\".
\*****************************************************************************/
HRESULT FtpSetCurrentDirectoryPidlWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCITEMIDLIST pidlFtpPath, BOOL fAbsolute, BOOL fOnlyDirs)
{
WIRECHAR wFtpPath[MAX_PATH];
LPWIRESTR pwFtpPath = wFtpPath;
HRESULT hr = S_OK;
// If pidlFtpPath is NULL, then go to "\".
if (pidlFtpPath)
{
hr = GetWirePathFromPidl(pidlFtpPath, wFtpPath, ARRAYSIZE(wFtpPath), fOnlyDirs);
if (!fAbsolute)
pwFtpPath++; // Skip past the starting '\'
}
else
StrCpyNA(wFtpPath, SZ_URL_SLASHA, ARRAYSIZE(wFtpPath));
if (SUCCEEDED(hr))
hr = FtpSetCurrentDirectoryWrap(hConnect, fAssertOnFailure, pwFtpPath);
return hr;
}
HRESULT FtpGetCurrentDirectoryPidlWrap(HINTERNET hConnect, BOOL fAssertOnFailure, CWireEncoding * pwe, LPITEMIDLIST * ppidlFtpPath)
{
WIRECHAR wFtpPath[MAX_PATH];
HRESULT hr = FtpGetCurrentDirectoryWrap(hConnect, fAssertOnFailure, wFtpPath, ARRAYSIZE(wFtpPath));
*ppidlFtpPath = NULL;
if (SUCCEEDED(hr))
hr = CreateFtpPidlFromFtpWirePath(wFtpPath, pwe, NULL, ppidlFtpPath, TRUE, TRUE);
return hr;
}
HRESULT FtpFindFirstFilePidlWrap(HINTERNET hConnect, BOOL fAssertOnFailure, CMultiLanguageCache * pmlc,
CWireEncoding * pwe, LPCWIRESTR pwFilterStr, LPITEMIDLIST * ppidlFtpItem, DWORD dwINetFlags, DWORD_PTR dwContext, HINTERNET * phFindHandle)
{
FTP_FIND_DATA wfd;
*phFindHandle = NULL;
HRESULT hr = FtpFindFirstFileWrap(hConnect, fAssertOnFailure, pwFilterStr, &wfd, dwINetFlags, dwContext, phFindHandle);
*ppidlFtpItem = NULL;
if (SUCCEEDED(hr))
{
// Skip "." and ".." entries.
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || IS_VALID_FILE(wfd.cFileName))
hr = pwe->CreateFtpItemID(pmlc, &wfd, ppidlFtpItem);
else
hr = InternetFindNextFilePidlWrap(*phFindHandle, fAssertOnFailure, pmlc, pwe, ppidlFtpItem);
if (FAILED(hr) && *phFindHandle)
{
InternetCloseHandle(*phFindHandle);
*phFindHandle = NULL;
}
}
return hr;
}
HRESULT InternetFindNextFilePidlWrap(HINTERNET hConnect, BOOL fAssertOnFailure, CMultiLanguageCache * pmlc, CWireEncoding * pwe, LPITEMIDLIST * ppidlFtpItem)
{
FTP_FIND_DATA wfd;
HRESULT hr = InternetFindNextFileWrap(hConnect, fAssertOnFailure, &wfd);
*ppidlFtpItem = NULL;
if (SUCCEEDED(hr))
{
ASSERT(pmlc); // We use this often enought that this might as well exist.
// Skip "." and ".." entries.
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || IS_VALID_FILE(wfd.cFileName))
hr = pwe->CreateFtpItemID(pmlc, &wfd, ppidlFtpItem);
else
hr = InternetFindNextFilePidlWrap(hConnect, fAssertOnFailure, pmlc, pwe, ppidlFtpItem);
}
return hr;
}
HRESULT FtpRenameFilePidlWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCITEMIDLIST pidlExisting, LPCITEMIDLIST pidlNew)
{
return FtpRenameFileWrap(hConnect, fAssertOnFailure, FtpPidl_GetLastItemWireName(pidlExisting), FtpPidl_GetLastItemWireName(pidlNew));
}
HRESULT FtpGetFileExPidlWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCITEMIDLIST pidlFtpPath/*Src*/, LPCWSTR pwzFilePath/*Dest*/, BOOL fFailIfExists,
DWORD dwFlagsAndAttributes, DWORD dwFlags, DWORD_PTR dwContext)
{
return FtpGetFileExWrap(hConnect, fAssertOnFailure, FtpPidl_GetLastItemWireName(pidlFtpPath), pwzFilePath, fFailIfExists, dwFlagsAndAttributes, dwFlags, dwContext);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -