📄 ftpurl.cpp
字号:
{
hr = S_OK;
// Is it a directory?
if (FILE_ATTRIBUTE_DIRECTORY & pwfd->dwFileAttributes)
{
// Yes, so make sure it has a trailing slash to disambiguate it from
// a file.
UrlPathAppendSlash(pszFullUrl);
}
}
}
return hr;
}
\*****************************************************************************/
/*****************************************************************************\
FUNCTION: GetLastSegment
DESCRIPTION:
\*****************************************************************************/
LPTSTR GetLastSegment(LPCTSTR pszUrl)
{
LPTSTR pszLastSeg = (LPTSTR) pszUrl;
LPTSTR pszNextPossibleSeg;
while (pszNextPossibleSeg = StrChr(pszLastSeg, TEXT('/')))
{
if (TEXT('\0') != CharNext(pszNextPossibleSeg))
pszLastSeg = CharNext(pszNextPossibleSeg);
else
break; // We are done.
}
if (TEXT('/') == pszLastSeg[0])
pszLastSeg = CharNext(pszLastSeg);
return pszLastSeg;
}
/*****************************************************************************\
FUNCTION: UrlPathGetLastSegment
DESCRIPTION:
HRESULT UrlPathGetLastSegment(LPCTSTR pszUrl, LPTSTR pszSegment, DWORD cchSegSize)
{
HRESULT hr = S_FALSE;
TCHAR szTemp[MAX_URL_STRING];
LPTSTR pszLastSeg;
StrCpyN(szTemp, pszUrl, ARRAYSIZE(szTemp));
UrlPathRemoveSlash(szTemp);
pszLastSeg = GetLastSegment(szTemp);
StrCpyN(pszSegment, pszLastSeg, cchSegSize);
return hr;
}
\*****************************************************************************/
/*****************************************************************************\
FUNCTION: UrlPathRemoveLastSegment
DESCRIPTION:
HRESULT UrlPathRemoveLastSegment(LPTSTR pszUrl)
{
HRESULT hr = S_FALSE;
LPTSTR pszLastSeg;
UrlPathRemoveSlash(pszUrl);
pszLastSeg = GetLastSegment(pszUrl);
pszLastSeg[0] = TEXT('\0');
return hr;
}
\*****************************************************************************/
/*****************************************************************************\
FUNCTION: UrlRemoveDownloadType
DESCRIPTION:
\*****************************************************************************/
HRESULT UrlRemoveDownloadType(LPTSTR pszUrlPath, BOOL * pfTypeSpecified, BOOL * pfType)
{
HRESULT hr = S_FALSE; // Specified? (Not yet)
LPTSTR pszDownloadType;
if (pfTypeSpecified)
*pfTypeSpecified = TRUE;
// Did the user specify a download type. szPath="Dir1/Dir2/file.txt;type=a".
// TODO: Search Recursively because each segment in the path can have a
// type.
// Example Url="ftp://server/Dir1;type=a/Dir2;type=a/File.txt;type=b
if (pszDownloadType = StrStrI(pszUrlPath, SZ_FTP_URL_TYPE))
{
TCHAR chType;
if (pfTypeSpecified)
*pfTypeSpecified = TRUE;
pszDownloadType[0] = TEXT('\0'); // Terminate pszUrlPath and remove this junk.
chType = pszDownloadType[ARRAYSIZE(SZ_FTP_URL_TYPE) - 1];
if (pfType)
{
if ((TEXT('a') == chType) || (TEXT('A') == chType))
*pfType = TRUE;
else
*pfType = TRUE;
}
hr = S_OK;
}
return hr;
}
/*****************************************************************************\
FUNCTION: IsIPAddressStr
DESCRIPTION:
This function exists to detect an IP Address server name ("124.42.3.53") vs.
a DNS domain name ("foobar", or "ftp.foobar.com"). I current accept more than
4 segments because of 6-bit IP address. (BUGBUG: Valid?)
TODO: To be thurough, I should probably made sure each segment is
smaller than 256.
\*****************************************************************************/
BOOL IsIPAddressStr(LPTSTR pszServer)
{
BOOL fIsIPAddressStr = TRUE;
LPTSTR pszCurrentChar = pszServer;
int nDigits = 0;
int nSegments = 1;
while (fIsIPAddressStr && pszCurrentChar[0])
{
if (TEXT('.') == pszCurrentChar[0])
{
nSegments++;
if ((0 == nDigits) || (4 < nDigits))
fIsIPAddressStr = FALSE; // it started with a '.', ie, ".xxxxx"
nDigits = 0;
}
nDigits++;
if (nDigits > 4)
fIsIPAddressStr = FALSE; // To many digits, ie "12345.xxxx"
if (((TEXT('0') > pszCurrentChar[0]) || (TEXT('9') < pszCurrentChar[0])) &&
(TEXT('.') != pszCurrentChar[0]))
{
fIsIPAddressStr = FALSE; // it's outside of the 0-9 range.
}
pszCurrentChar++; // Next character.
}
if (nSegments != 4)
fIsIPAddressStr = FALSE; // Needs to have at least 4 segments ("1.2.3.4", "1.2.3.4.5")
return fIsIPAddressStr;
}
/*****************************************************************************\
FUNCTION: PidlGenerateSiteLookupStr
DESCRIPTION:
Sample Input: "ftp://user:password@ftp.server.com:69/Dir1/Dir2/File.txt"
Sample Output: "ftp://user:password@ftp.server.com:69/"
This is used to keep track of unique servers for CFtpSite. A CFtpSite needs
to be created for each unique site, which includes different users that are
logged onto the same site because of rooted directories.
\*****************************************************************************/
HRESULT PidlGenerateSiteLookupStr(LPCITEMIDLIST pidl, LPTSTR pszLookupStr, DWORD cchSize)
{
HRESULT hr = E_FAIL;
// Some strange clients pass in non-Server IDs, like comdlg.
if (FtpID_IsServerItemID(pidl))
{
LPITEMIDLIST pidlServer = FtpCloneServerID(pidl);
if (pidlServer)
{
hr = UrlCreateFromPidlW(pidlServer, SHGDN_FORPARSING, pszLookupStr, cchSize, (ICU_ESCAPE | ICU_USERNAME), FALSE);
ILFree(pidlServer);
}
else
hr = E_OUTOFMEMORY;
}
return hr;
}
/*
HRESULT PidlReplaceUrlPath(LPCITEMIDLIST pidlIn, LPITEMIDLIST * ppidlOut, IMalloc * pm, LPCTSTR pszUrlPath)
{
HRESULT hr;
TCHAR szUrl[MAX_URL_STRING];
*ppidlOut = NULL;
hr = UrlCreateFromPidl(pidlIn, SHGDN_FORPARSING, szUrl, ARRAYSIZE(szUrl), ICU_ESCAPE, FALSE);
if (SUCCEEDED(hr))
{
hr = UrlReplaceUrlPath(szUrl, ARRAYSIZE(szUrl), pszUrlPath);
if (SUCCEEDED(hr))
{
LPITEMIDLIST pidlWithPath;
hr = CreateFtpPidlFromUrlEx(szUrl, NULL, &pidlWithPath, pm, FALSE, TRUE, FtpPidl_IsDirectory(pidlIn, TRUE));
if (EVAL(SUCCEEDED(hr)))
{
LPITEMIDLIST pidlServer = ILClone(pidlIn);
if (pidlServer)
{
if (_ILNext(pidlServer))
_ILNext(pidlServer)->mkid.cb = 0; // We need the first original itemID because it contains the password information.
*ppidlOut = ILCombine(pidlServer, _ILNext(pidlWithPath)); // Original ServerID, plus the itemIDs from the new dest.
ILFree(pidlServer);
}
ILFree(pidlWithPath);
}
}
}
return hr;
}
// BUGBUG: pszUrlPath won't work with fragments
HRESULT UrlReplaceUrlPath(LPTSTR pszUrl, DWORD cchSize, LPCTSTR pszUrlPath)
{
HRESULT hr = E_FAIL;
URL_COMPONENTS urlComps = {0};
TCHAR szServer[INTERNET_MAX_HOST_NAME_LENGTH];
TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH];
TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH];
TCHAR szExtraInfo[MAX_PATH]; // Includes Port Number and download type (ASCII, Binary, Detect)
INTERNET_PORT ipPortNum = INTERNET_DEFAULT_FTP_PORT;
BOOL fResult;
urlComps.dwStructSize = sizeof(urlComps);
urlComps.lpszHostName = szServer;
urlComps.dwHostNameLength = ARRAYSIZE(szServer);
urlComps.lpszUrlPath = NULL;
urlComps.dwUrlPathLength = 0;
urlComps.lpszUserName = szUserName;
urlComps.dwUserNameLength = ARRAYSIZE(szUserName);
urlComps.lpszPassword = szPassword;
urlComps.dwPasswordLength = ARRAYSIZE(szPassword);
urlComps.lpszExtraInfo = szExtraInfo;
urlComps.dwExtraInfoLength = ARRAYSIZE(szExtraInfo);
fResult = InternetCrackUrl(pszUrl, 0, ICU_DECODE, &urlComps);
if (fResult)
{
urlComps.dwStructSize = sizeof(urlComps);
urlComps.lpszUrlPath = (LPTSTR)pszUrlPath;
urlComps.dwUrlPathLength = (pszUrlPath ? lstrlen(pszUrlPath) : 0);
fResult = InternetCreateUrl(&urlComps, (ICU_ESCAPE | ICU_USERNAME), pszUrl, &cchSize);
if (fResult)
{
hr = S_OK;
}
}
return hr;
}
*/
HRESULT PidlReplaceUserPassword(LPCITEMIDLIST pidlIn, LPITEMIDLIST * ppidlOut, IMalloc * pm, LPCTSTR pszUserName, LPCTSTR pszPassword)
{
TCHAR szServer[INTERNET_MAX_HOST_NAME_LENGTH];
TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH];
HRESULT hr = FtpPidl_GetServer(pidlIn, szServer, ARRAYSIZE(szServer));
if (!pszUserName) // May be NULL.
{
pszUserName = szUserName;
EVAL(SUCCEEDED(FtpPidl_GetUserName(pidlIn, szUserName, ARRAYSIZE(szUserName))));
}
*ppidlOut = NULL;
if (SUCCEEDED(hr))
{
LPITEMIDLIST pidlServer;
hr = FtpServerID_Create(szServer, pszUserName, pszPassword, FtpServerID_GetTypeID(pidlIn), FtpServerID_GetPortNum(pidlIn), &pidlServer, pm, TRUE);
if (SUCCEEDED(hr))
{
LPITEMIDLIST pidlFtpPath = _ILNext(pidlIn);
*ppidlOut = ILCombine(pidlServer, pidlFtpPath);
ILFree(pidlServer);
}
}
return hr;
}
HRESULT UrlReplaceUserPassword(LPTSTR pszUrlPath, DWORD cchSize, LPCTSTR pszUserName, LPCTSTR pszPassword)
{
HRESULT hr = E_FAIL;
URL_COMPONENTS urlComps = {0};
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 szExtraInfo[MAX_PATH]; // Includes Port Number and download type (ASCII, Binary, Detect)
BOOL fResult;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -