📄 ftpapi.cpp
字号:
}
return hr;
}
/*****************************************************************************\
FUNCTION: FtpFindFirstFileWrap
DESCRIPTION:
PERF Notes:
[Direct Net Connection]
To: shapitst <Down the Hall>: 166ms - 189ms
To: rigel.cyberpass.net <San Diego, CA>: 550ms - 815ms
To: ftp.rz.uni-frankfurt.de <Germany>: 1925ms - 11,390ms
\*****************************************************************************/
HRESULT FtpFindFirstFileWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFilterStr, LPFTP_FIND_DATA pwfd, DWORD dwINetFlags, DWORD_PTR dwContext, HINTERNET * phFindHandle)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(StrCpyNA(pwfd->cFileName, "<Not Found>", ARRAYSIZE(pwfd->cFileName)));
ASSERT(phFindHandle);
DEBUG_CODE(DebugStartWatch());
// _UNDOCUMENTED_: If you pass NULL as the second argument, it's the
// same as passing TEXT("*.*"), but much faster.
// PERF: Status
// FtpFindFirstFile() takes 500-700ms on ftp.microsoft.com on average.
// takes 2-10 secs on ftp://ftp.tu-clausthal.de/ on average
// takes 150-250 secs on ftp://shapitst/ on average
*phFindHandle = FtpFindFirstFileA(hConnect, pwFilterStr, pwfd, dwINetFlags, dwContext);
if (!*phFindHandle)
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpFindFirstFile(\"%hs\")==\"%hs\" atrb=%#08lx, hr=%#08lx, Time=%lums", EMPTYSTR_FOR_NULLA(pwFilterStr), pwfd->cFileName, pwfd->dwFileAttributes, hr, DebugStopWatch()));
if (fAssertOnFailure)
{
// This fails in normal cases when we are checking if files exist.
// WININET_ASSERT(SUCCEEDED(hr));
}
ASSERT_POINTER_MATCHES_HRESULT(*phFindHandle, hr);
return hr;
}
// Do not localize this because it's always returned from the server in english.g
#define SZ_FINDFIRSTFILE_FAILURESTR ": No such file or directory"
/**************************************************************\
FUNCTION: FtpDoesFileExist
DESCRIPTION:
IE #34868 is the fact that some FTP servers erronous
results on find requests:
[The file does not exist in the following cases]
Request: "foo.txt" result: SUCCEEDED & "foo.txt: No such file or directory"
Request: "foo bat.txt" result: SUCCEEDED & "foo: No such file or directory"
\**************************************************************/
HRESULT FtpDoesFileExist(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFilterStr, LPFTP_FIND_DATA pwfd, DWORD dwINetFlags)
{
FTP_FIND_DATA wfd;
HINTERNET hIntFind;
HRESULT hr;
if (!pwfd) // pwfd is optional
pwfd = &wfd;
// Some servers like "ftp://wired/" will fail to find "BVTBaby.gif" even
// though it exists. It will find it if "BVTBaby.gif*" is used.
// Wininet should fix this or implement this hack but they probably won't.
WIRECHAR wFilterStr[MAX_PATH];
StrCpyNA(wFilterStr, pwFilterStr, ARRAYSIZE(wFilterStr));
// WININET BUGBUG: Wininet won't find "BVTBaby.gif" on an IIS server (ftp://wired/)
// unless it has an "*" behind it. So add one if it doesn't exist.
if ('*' != wFilterStr[lstrlenA(wFilterStr) - 1])
{
// We need to add it.
StrCatBuffA(wFilterStr, "*", ARRAYSIZE(wFilterStr));
}
hr = FtpFindFirstFileWrap(hConnect, fAssertOnFailure, wFilterStr, pwfd, dwINetFlags, 0, &hIntFind);
if (S_OK == hr)
{
do
{
// is it an exact match?
// #248535: Make sure we get what we asked for. Either WININET or
// some weird FTP servers are screwing up. If we ask for
// foobar.gif as the filter string, sometimes we get back
// ".".
if (!StrCmpIA(pwfd->cFileName, pwFilterStr))
{
// Yes it "Should"
hr = S_OK;
break;
}
else
{
// However, wininet will return TRUE but the display name will be "One: No such file or directory"
// if the file name is "One Two.htm"
// This is a work around for bug #34868 because UNIX servers sometimes return success
// and a file name of "thefile.txt: No such file or directory"
if ((lstrlenA(pwfd->cFileName) > (ARRAYSIZE(SZ_FINDFIRSTFILE_FAILURESTR) - 1)) &&
!StrCmpA(&(pwfd->cFileName[lstrlenA(pwfd->cFileName) - (ARRAYSIZE(SZ_FINDFIRSTFILE_FAILURESTR) - 1)]), SZ_FINDFIRSTFILE_FAILURESTR))
{
hr = S_OK;
break;
}
else
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
// Next...
hr = InternetFindNextFileWrap(hIntFind, TRUE, pwfd);
}
while (S_OK == hr);
InternetCloseHandle(hIntFind);
}
return hr;
}
/*****************************************************************************\
FUNCTION: FtpCommandWrap
DESCRIPTION:
PERF Notes:
[Direct Net Connection]
To: shapitst <Down the Hall>: 1ms - 12ms
To: rigel.cyberpass.net <San Diego, CA>: 133ms - 184ms
To: ftp.rz.uni-frankfurt.de <Germany>: 1711ms - 2000ms
\*****************************************************************************/
HRESULT FtpCommandWrap(HINTERNET hConnect, BOOL fAssertOnFailure, BOOL fExpectResponse, DWORD dwFlags, LPCWIRESTR pszCommand,
DWORD_PTR dwContext, HINTERNET *phFtpCommand)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(DebugStartWatch());
if (!FtpCommandA(hConnect, fExpectResponse, dwFlags, pszCommand, dwContext, phFtpCommand))
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpCommand(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pszCommand, dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
/*** TODO
INTERNETAPI
DWORD
WINAPI
FtpGetFileSize(
IN HINTERNET hFile,
OUT LPDWORD lpdwFileSizeHigh OPTIONAL
);
******/
/*****************************************************************************\
FUNCTION: InternetOpenWrap
DESCRIPTION:
PERF Notes:
[Direct Net Connection]
Destination not applicable. 677-907ms
\*****************************************************************************/
HRESULT InternetOpenWrap(BOOL fAssertOnFailure, LPCTSTR pszAgent, DWORD dwAccessType, LPCTSTR pszProxy, LPCTSTR pszProxyBypass, DWORD dwFlags, HINTERNET * phFileHandle)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(DebugStartWatch());
*phFileHandle = InternetOpen(pszAgent, dwAccessType, pszProxy, pszProxyBypass, dwFlags);
if (!*phFileHandle)
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetOpen(\"%ls\") returned %u. Time=%lums", pszAgent, dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
HRESULT InternetCloseHandleWrap(HINTERNET hInternet, BOOL fAssertOnFailure)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(DebugStartWatch());
if (!InternetCloseHandle(hInternet))
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetCloseHandle(%#08lx) returned %u. Time=%lums", hInternet, dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
/*****************************************************************************\
FUNCTION: InternetConnectWrap
DESCRIPTION:
PERF Notes:
[Direct Net Connection]
To: shapitst <Down the Hall>: 144ms - 250ms (Min: 2; Max: 1,667ms)
To: rigel.cyberpass.net <San Diego, CA>: 717ms - 1006ms
To: ftp.rz.uni-frankfurt.de <Germany>: 2609ms - 14,012ms
COMMON ERROR VALUES:
These are the return values in these different cases:
ERROR_INTERNET_NAME_NOT_RESOLVED: No Proxy & DNS Lookup failed.
ERROR_INTERNET_CANNOT_CONNECT: Some Auth Proxies and Netscape's Web/Auth Proxy
ERROR_INTERNET_NAME_NOT_RESOLVED: Web Proxy
ERROR_INTERNET_TIMEOUT: Invalid or Web Proxy blocked IP Address
ERROR_INTERNET_INCORRECT_PASSWORD: IIS & UNIX, UserName may not exist or password for the user may be incorrect on.
ERROR_INTERNET_LOGIN_FAILURE: Too many Users on IIS.
ERROR_INTERNET_INCORRECT_USER_NAME: I haven't seen it.
ERROR_INTERNET_EXTENDED_ERROR: yahoo.com exists, but ftp.yahoo.com doesn't.
\*****************************************************************************/
HRESULT InternetConnectWrap(HINTERNET hInternet, BOOL fAssertOnFailure, LPCTSTR pszServerName, INTERNET_PORT nServerPort,
LPCTSTR pszUserName, LPCTSTR pszPassword, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext, HINTERNET * phFileHandle)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
// Call BryanSt if this assert fires.
// Did the user turn off FTP Folders?
// If so, don't connect. This will fix NT #406423 where the user turned
// of FTP Folders because they have a firewall (CISCO filtering Router)
// that will kill packets in such a way the caller (WinSock/Wininet) needs
// to wait for a timeout. During this timeout, the browser will hang causing
// the user to think it crashed.
AssertMsg(!SHRegGetBoolUSValue(SZ_REGKEY_FTPFOLDER, SZ_REGKEY_USE_OLD_UI, FALSE, FALSE), TEXT("BUG: We can't hit this code or we will hang the browser for 45 seconds if the user is using a certain kind of proxy. Call BryanSt."));
DEBUG_CODE(DebugStartWatch());
*phFileHandle = InternetConnect(hInternet, pszServerName, nServerPort, pszUserName, pszPassword, dwService, dwFlags | FEATURE_PASSIVE_ON_OR_OFF, dwContext);
if (!*phFileHandle)
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetConnect(%#08lx, \"%ls\", \"%ls\", \"%ls\") returned %u. Time=%lums", hInternet, pszServerName, EMPTYSTR_FOR_NULL(pszUserName), EMPTYSTR_FOR_NULL(pszPassword), dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
// ERROR_INTERNET_NAME_NOT_RESOLVED happens when we are blocked by the
// proxy.
WININET_ASSERT(SUCCEEDED(hr) ||
(HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED) == hr) ||
(HRESULT_FROM_WIN32(ERROR_INTERNET_LOGIN_FAILURE) == hr) ||
(HRESULT_FROM_WIN32(ERROR_INTERNET_INCORRECT_PASSWORD) == hr) ||
(HRESULT_FROM_WIN32(ERROR_INTERNET_INCORRECT_USER_NAME) == hr));
}
return hr;
}
/*****************************************************************************\
FUNCTION: InternetOpenUrlWrap
DESCRIPTION:
PERF Notes:
[Direct Net Connection]
To: shapitst <Down the Hall>: 29ms
To: rigel.cyberpass.net <San Diego, CA>: ???????
To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT InternetOpenUrlWrap(HINTERNET hInternet, BOOL fAssertOnFailure, LPCTSTR pszUrl, LPCTSTR pszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext, HINTERNET * phFileHandle)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
DEBUG_CODE(DebugStartWatch());
*phFileHandle = InternetOpenUrl(hInternet, pszUrl, pszHeaders, dwHeadersLength, dwFlags | FEATURE_PASSIVE_ON_OR_OFF, dwContext);
if (!*phFileHandle)
{
dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
}
DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "InternetOpenUrl(%#08lx, \"%ls\") returned %u. Time=%lums", hInternet, pszUrl, dwError, DebugStopWatch()));
if (fAssertOnFailure)
{
WININET_ASSERT(SUCCEEDED(hr));
}
return hr;
}
HRESULT InternetReadFileWrap(HINTERNET hFile, BOOL fAssertOnFailure, LPVOID pvBuffer, DWORD dwNumberOfBytesToRead, LPDWORD pdwNumberOfBytesRead)
{
HRESULT hr = S_OK;
DWORD dwError = 0;
// DEBUG_CODE(DebugStartWatch());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -