📄 ftpsite.cpp
字号:
m_fFeaturesQueried = TRUE;
}
return S_OK; // This shouldn't fail.
}
LPITEMIDLIST CFtpSite::GetPidl(void)
{
return ILClone(m_pidl);
}
/*****************************************************************************\
FUNCTION: _SetPidl
DESCRIPTION:
m_pidl contains the ServerID and the ItemIDs making up the path of where
m_hint is currently located. This function will take a new path in pidlFtpPath
and update m_pidl so it still has the server.
\*****************************************************************************/
HRESULT CFtpSite::_SetPidl(LPCITEMIDLIST pidlFtpPath)
{
HRESULT hr = E_FAIL;
LPITEMIDLIST pidlServer = FtpCloneServerID(m_pidl);
if (pidlServer)
{
LPITEMIDLIST pidlNew = ILCombine(pidlServer, pidlFtpPath);
if (pidlNew)
{
ILFree(m_pidl);
m_pidl = pidlNew;
hr = S_OK;
}
ILFree(pidlServer);
}
return hr;
}
/*****************************************************************************\
FUNCTION: QueryMotd
DESCRIPTION:
Determine whether there is a motd at all.
\*****************************************************************************/
BOOL CFtpSite::QueryMotd(void)
{
return m_fMotd;
}
HRESULT CFtpSite::GetVirtualRoot(LPITEMIDLIST * ppidl)
{
HRESULT hr = S_FALSE;
*ppidl = NULL;
if (m_pidlVirtualDir)
{
*ppidl = ILClone(m_pidlVirtualDir);
hr = S_OK;
}
return S_OK;
}
HRESULT CFtpSite::PidlInsertVirtualRoot(LPCITEMIDLIST pidlFtpPath, LPITEMIDLIST * ppidl)
{
HRESULT hr = S_OK;
if (!m_pidlVirtualDir)
*ppidl = ILClone(pidlFtpPath);
else
{
LPITEMIDLIST pidlTemp = NULL;
if (pidlFtpPath && FtpID_IsServerItemID(pidlFtpPath))
{
pidlTemp = FtpCloneServerID(pidlFtpPath);
pidlFtpPath = _ILNext(pidlFtpPath);
}
LPITEMIDLIST pidlWithVRoot = ILCombine(pidlTemp, m_pidlVirtualDir);
if (pidlWithVRoot)
{
*ppidl = ILCombine(pidlWithVRoot, pidlFtpPath);
ILFree(pidlWithVRoot);
}
ILFree(pidlTemp);
}
return S_OK;
}
BOOL CFtpSite::HasVirtualRoot(void)
{
return (m_pidlVirtualDir ? TRUE : FALSE);
}
/*****************************************************************************\
GetMotd
Returns the HFGLOB that babysits the motd. The refcount has been
incremented.
\*****************************************************************************/
CFtpGlob * CFtpSite::GetMotd(void)
{
if (m_pfgMotd)
m_pfgMotd->AddRef();
return m_pfgMotd;
}
/*****************************************************************************\
GetCFtpList
Return the CFtpList * that remembers which folders live in this CFtpSite *.
WARNING! The caller must own the critical section when calling
this routine, because the returned CFtpList * is not refcounted!
\*****************************************************************************/
CFtpList * CFtpSite::GetCFtpList(void)
{
return m_FtpDirList;
}
/*****************************************************************************\
_CompareSites
Callback during SiteCache_PrivSearch to see if the site is already in the
list.
\*****************************************************************************/
int CALLBACK _CompareSites(LPVOID pvStrSite, LPVOID pvFtpSite, LPARAM lParam)
{
CFtpSite * pfs = (CFtpSite *) pvFtpSite;
LPCTSTR pszLookupStrNew = (LPCTSTR) pvStrSite;
LPCTSTR pszLookupStr = (pfs->m_pszLookupStr ? pfs->m_pszLookupStr : TEXT(""));
ASSERT(pszLookupStr && pszLookupStr);
return StrCmpI(pszLookupStr, pszLookupStrNew);
}
/*****************************************************************************\
FUNCTION: SiteCache_PrivSearch
DESCRIPTION:
We cache information about an FTP Server to prevent hitting the net all
the time. This state is stored in CFtpSite objects and we use 'lookup strings'
to find them. This is what makes one server different from another. Since
we store password state in a CFtpSite object, we need to have one per
user/password combo.
\*****************************************************************************/
HRESULT SiteCache_PrivSearch(LPCTSTR pszLookup, LPCITEMIDLIST pidl, IMalloc * pm, CFtpSite ** ppfs)
{
CFtpSite * pfs = NULL;
HRESULT hr = S_OK;
ENTERCRITICAL;
// CFtpSite_Init() can fail in low memory
if (SUCCEEDED(CFtpSite_Init()))
{
pfs = (CFtpSite *) g_FtpSiteCache->Find(_CompareSites, (LPVOID)pszLookup); // Add CFtpSite:: ?
if (!pfs)
{
// We need to hold the critical section while setting up
// the new CFtpSite structure, lest somebody else come in
// and try to create the same CFtpSite while we are busy.
hr = CFtpSite_Create(pidl, pszLookup, pm, &pfs);
if (EVAL(SUCCEEDED(hr)))
{
hr = g_FtpSiteCache->AppendItem(pfs);
if (!(EVAL(SUCCEEDED(hr))))
IUnknown_Set(&pfs, NULL);
}
}
}
LEAVECRITICAL;
*ppfs = pfs;
if (pfs)
pfs->AddRef();
ASSERT_POINTER_MATCHES_HRESULT(*ppfs, hr);
return hr;
}
/*****************************************************************************\
FUNCTION: SiteCache_PidlLookupPrivHelper
DESCRIPTION:
We cache information about an FTP Server to prevent hitting the net all
the time. This state is stored in CFtpSite objects and we use 'lookup strings'
to find them. This is what makes one server different from another. Since
we store password state in a CFtpSite object, we need to have one per
user/password combo.
SiteCache_PidlLookup() does the high level work of deciding if we want
to do a password redirect. This function just wraps the creating of the
lookup string and the fetching of the site.
\*****************************************************************************/
HRESULT SiteCache_PidlLookupPrivHelper(LPCITEMIDLIST pidl, IMalloc * pm, CFtpSite ** ppfs)
{
HRESULT hr = E_FAIL;
TCHAR szLookup[MAX_PATH];
*ppfs = NULL;
hr = PidlGenerateSiteLookupStr(pidl, szLookup, ARRAYSIZE(szLookup));
// May fail w/Outofmemory
if (SUCCEEDED(hr))
hr = SiteCache_PrivSearch((pidl ? szLookup : TEXT('\0')), pidl, pm, ppfs);
ASSERT_POINTER_MATCHES_HRESULT(*ppfs, hr);
return hr;
}
/*****************************************************************************\
FUNCTION: SiteCache_PidlLookupPrivHelper
DESCRIPTION:
We cache information about an FTP Server to prevent hitting the net all
the time. This state is stored in CFtpSite objects and we use 'lookup strings'
to find them. This is what makes one server different from another. Since
we store password state in a CFtpSite object, we need to have one per
user/password combo.
\*****************************************************************************/
HRESULT SiteCache_PidlLookup(LPCITEMIDLIST pidl, BOOL fPasswordRedir, IMalloc * pm, CFtpSite ** ppfs)
{
HRESULT hr = E_FAIL;
if (pidl && !ILIsEmpty(pidl))
{
hr = SiteCache_PidlLookupPrivHelper(pidl, pm, ppfs);
// Okay, we found a site but we may need to redirect to another site
// because the password is wrong. This happens if a user goes to
// ServerA w/UserA and PasswordA but PasswordA is invalid. So,
// PasswordB is entered and the navigation completes successfully.
// Now either the navigation occurs again with PasswordA or w/o
// a password (because the addrbar removes it), then we need to
// look it up again and get it.
if (SUCCEEDED(hr) && (*ppfs)->m_pszRedirPassword && fPasswordRedir)
{
LPITEMIDLIST pidlNew; // with new (redirected) password
if (FtpPidl_IsAnonymous(pidl))
{
pidlNew = ILClone(pidl);
if (!pidlNew)
hr = E_OUTOFMEMORY;
}
else
{
// We need to redirect to get that CFtpSite.
hr = PidlReplaceUserPassword(pidl, &pidlNew, pm, NULL, (*ppfs)->m_pszRedirPassword);
}
(*ppfs)->Release();
*ppfs = NULL;
if (SUCCEEDED(hr))
{
hr = SiteCache_PidlLookupPrivHelper(pidlNew, pm, ppfs);
ILFree(pidlNew);
}
}
}
ASSERT_POINTER_MATCHES_HRESULT(*ppfs, hr);
return hr;
}
/*****************************************************************************\
FUNCTION: UpdateHiddenPassword
DESCRIPTION:
Since our IShellFolder::GetDisplayNameOf() will hide the password in some
cases, we need to 'patch' display names that come thru our
IShellFolder::GetDisplayName(). If a display name is coming in, we will
see if the CFtpSite has a m_pszRedirPassword. If it did, then the user entered
a password via the 'Login As...' dialog in place of the empty password,
which made it hidden. If this is the case, we then have IShellFolder::ParseDisplayName()
patch back in the password.
\*****************************************************************************/
HRESULT CFtpSite::UpdateHiddenPassword(LPITEMIDLIST pidl)
{
HRESULT hr = S_FALSE;
TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH];
TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH];
// Is it a candidate to a password to be inserted?
if (m_pszPassword &&
EVAL(SUCCEEDED(FtpPidl_GetUserName(pidl, szUserName, ARRAYSIZE(szUserName)))) &&
szUserName[0] &&
SUCCEEDED(FtpPidl_GetPassword(pidl, szPassword, ARRAYSIZE(szPassword), TRUE)) &&
!szPassword[0])
{
// Yes...
hr = FtpServerID_SetHiddenPassword(pidl, m_pszPassword);
}
return hr;
}
/*****************************************************************************\
CFtpSite::GetFtpDir
\*****************************************************************************/
HRESULT CFtpSite::GetFtpDir(LPCTSTR pszServer, LPCWSTR pszUrlPath, CFtpDir ** ppfd)
{
HRESULT hr = S_OK;
TCHAR szUrl[MAX_URL_STRING];
*ppfd = NULL;
hr = UrlCreate(pszServer, NULL, NULL, pszUrlPath, NULL, INTERNET_DEFAULT_FTP_PORT, NULL, szUrl, ARRAYSIZE(szUrl));
if (EVAL(SUCCEEDED(hr)))
{
LPITEMIDLIST pidl;
// We know this is a path.
hr = CreateFtpPidlFromUrlEx(szUrl, GetCWireEncoding(), NULL, &pidl, m_pm, FALSE, TRUE, TRUE);
if (EVAL(SUCCEEDED(hr)))
{
hr = GetFtpDir(pidl, ppfd);
ILFree(pidl);
}
}
return hr;
}
/*****************************************************************************\
FUNCTION: GetFtpDir
DESCRIPTION:
Obtain the FtpDir structure for an FTP site, creating one if
necessary. It is the caller's responsibility to Release the
FtpDir when finished.
\*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -