📄 ftpsite.cpp
字号:
HRESULT CFtpSite::GetFtpDir(LPCITEMIDLIST pidl, CFtpDir ** ppfd)
{
HRESULT hr = S_OK;
CFtpDir * pfd = NULL;
ENTERCRITICAL;
ASSERT(ppfd && m_FtpDirList);
pfd = (CFtpDir *) m_FtpDirList->Find(_CompareDirs, (LPVOID) pidl);
if (!pfd)
{
// We need to hold the critical section while setting up
// the new FtpDir structure, lest somebody else come in
// and try to create the same FtpDir while we are busy.
hr = CFtpDir_Create(this, pidl, &pfd);
if (EVAL(SUCCEEDED(hr)))
{
// NOTE: REF-COUNTING
// Note that CFtpDir has a pointer (m_pfs) to a CFtpSite.
// We just added a back pointer in CFtpSite's list of CFtpDir(s),
// so it's necessary for that back pointer to not have a ref.
// This will not be a problem because the back pointers will
// always be valid because: 1) CFtpDir's destructor removes the backpointer,
// and 2) CFtpDir holds a ref on CFtpSite, so it won't go away until
// all the CFtpDir(s) are good and ready. -BryanSt
hr = m_FtpDirList->AppendItem(pfd);
if (FAILED(hr))
IUnknown_Set(&pfd, NULL);
}
}
LEAVECRITICAL;
*ppfd = pfd;
if (pfd)
pfd->AddRef();
return hr;
}
/*****************************************************************************\
FUNCTION: FlushSubDirs
DESCRIPTION:
Every subdir of pidl is no longer valid so flush them. This is done
because the parent dir may have changed names so they are invalid.
PARAMETERS:
pidl: Path of ItemIDs (no-ServerID) that includes the full path w/o
the virtual root. This matches CFtpDir::m_pidlFtpDir
\*****************************************************************************/
HRESULT CFtpSite::FlushSubDirs(LPCITEMIDLIST pidl)
{
HRESULT hr = S_OK;
CFtpDir * pfd = NULL;
int nIndex;
ENTERCRITICAL;
// Count down so deleting items won't screw up the indicies.
for (nIndex = (m_FtpDirList->GetCount() - 1); nIndex >= 0; nIndex--)
{
pfd = (CFtpDir *) m_FtpDirList->GetItemPtr(nIndex);
if (pfd)
{
// Is this a child?
if (FtpItemID_IsParent(pidl, pfd->GetPathPidlReference()))
{
// Yes, pfd is a child of pidl so delete it.
m_FtpDirList->DeletePtrByIndex(nIndex);
pfd->Release();
}
}
}
LEAVECRITICAL;
return hr;
}
BOOL CFtpSite::IsSiteBlockedByRatings(HWND hwndDialogOwner)
{
if (!m_fRatingsChecked)
{
void * pvRatingDetails = NULL;
TCHAR szUrl[MAX_URL_STRING];
CHAR szUrlAnsi[MAX_URL_STRING];
HRESULT hr = S_OK; // Assume allowed (in case no ratings)
EVAL(SUCCEEDED(UrlCreateFromPidlW(m_pidl, SHGDN_FORPARSING, szUrl, ARRAYSIZE(szUrl), (ICU_ESCAPE | ICU_USERNAME), FALSE)));
SHTCharToAnsi(szUrl, szUrlAnsi, ARRAYSIZE(szUrlAnsi));
if (IS_RATINGS_ENABLED())
{
// S_OK - Allowed, S_FALSE - Not Allowed, FAILED() - not rated.
hr = RatingCheckUserAccess(NULL, szUrlAnsi, NULL, NULL, 0, &pvRatingDetails);
if (S_OK != hr) // Does user want to override with parent password in dialog?
hr = RatingAccessDeniedDialog2(hwndDialogOwner, NULL, pvRatingDetails);
if (pvRatingDetails)
RatingFreeDetails(pvRatingDetails);
}
if (S_OK == hr) // It's off by default.
m_fRatingsAllow = TRUE;
m_fRatingsChecked = TRUE;
}
return !m_fRatingsAllow;
}
/*****************************************************************************\
CFtpSite_Init
Initialize the global list of FTP sites.
Note that the DLL refcount is decremented after this is created,
so that this internal list doesn't prevent us from unloading.
\*****************************************************************************/
HRESULT CFtpSite_Init(void)
{
HRESULT hr = S_OK;
if (!g_FtpSiteCache)
hr = CFtpList_Create(10, NULL, 10, &g_FtpSiteCache);
return hr;
}
/*****************************************************************************\
FtpSitePurge_CallBack
Purge the global list of FTP sites.
\*****************************************************************************/
int FtpSitePurge_CallBack(LPVOID pvPunk, LPVOID pv)
{
IUnknown * punk = (IUnknown *) pvPunk;
if (punk)
punk->Release();
return 1;
}
/*****************************************************************************\
CFtpPunkList_Purge
Purge the global list of FTP sites.
\*****************************************************************************/
HRESULT CFtpPunkList_Purge(CFtpList ** pfl)
{
TraceMsg(TF_FTP_DLLLOADING, "CFtpPunkList_Purge() Purging our cache.");
if (*pfl)
{
(*pfl)->Enum(FtpSitePurge_CallBack, NULL);
IUnknown_Set(pfl, NULL);
}
return S_OK;
}
/*****************************************************************************\
CFtpSite_Create
Create a brand new CFtpSite given a name.
\*****************************************************************************/
HRESULT CFtpSite_Create(LPCITEMIDLIST pidl, LPCTSTR pszLookupStr, IMalloc * pm, CFtpSite ** ppfs)
{
CFtpSite * pfs = new CFtpSite();
HRESULT hr = E_OUTOFMEMORY;
ASSERT(pidl && pszLookupStr && ppfs);
*ppfs = NULL;
if (EVAL(pfs))
{
Str_SetPtr(&pfs->m_pszLookupStr, pszLookupStr);
IUnknown_Set((IUnknown **) &(pfs->m_pm), pm);
hr = CFtpList_Create(10, NULL, 10, &pfs->m_FtpDirList);
if (EVAL(SUCCEEDED(hr)))
{
// Did someone give us an empty URL?
if (EVAL(pidl) && EVAL(FtpPidl_IsValid(pidl)))
{
TCHAR szServer[INTERNET_MAX_HOST_NAME_LENGTH];
TCHAR szUser[INTERNET_MAX_USER_NAME_LENGTH];
TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH];
TCHAR szFragment[INTERNET_MAX_PASSWORD_LENGTH];
EVAL(SUCCEEDED(FtpPidl_GetServer(pidl, szServer, ARRAYSIZE(szServer))));
Str_SetPtr(&pfs->m_pszServer, szServer);
Pidl_Set(&pfs->m_pidl, pidl);
EVAL(SUCCEEDED(FtpPidl_GetUserName(pidl, szUser, ARRAYSIZE(szUser))));
Str_SetPtr(&pfs->m_pszUser, szUser);
if (FAILED(FtpPidl_GetPassword(pidl, szPassword, ARRAYSIZE(szPassword), TRUE)))
{
// Password expired
szPassword[0] = 0;
}
Str_SetPtr(&pfs->m_pszPassword, szPassword);
FtpPidl_GetFragment(pidl, szFragment, ARRAYSIZE(szFragment));
Str_SetPtr(&pfs->m_pszFragment, szFragment);
pfs->m_ipPortNum = FtpPidl_GetPortNum(pidl);
switch (FtpPidl_GetDownloadType(pidl))
{
case FTP_TRANSFER_TYPE_UNKNOWN:
pfs->m_fDLTypeSpecified = FALSE;
pfs->m_fASCIIDownload = FALSE;
break;
case FTP_TRANSFER_TYPE_ASCII:
pfs->m_fDLTypeSpecified = TRUE;
pfs->m_fASCIIDownload = TRUE;
break;
case FTP_TRANSFER_TYPE_BINARY:
pfs->m_fDLTypeSpecified = TRUE;
pfs->m_fASCIIDownload = FALSE;
break;
default:
ASSERT(0);
}
}
else
{
Str_SetPtr(&pfs->m_pszServer, NULL);
Str_SetPtr(&pfs->m_pszUser, NULL);
Str_SetPtr(&pfs->m_pszPassword, NULL);
Str_SetPtr(&pfs->m_pszFragment, NULL);
Pidl_Set(&pfs->m_pidl, NULL);
pfs->m_fDLTypeSpecified = FALSE;
}
*ppfs = pfs;
}
else
{
hr = E_FAIL;
pfs->Release();
}
}
return hr;
}
/****************************************************\
Constructor
\****************************************************/
CFtpSite::CFtpSite() : m_cRef(1)
{
DllAddRef();
// This needs to be allocated in Zero Inited Memory.
// Assert that all Member Variables are inited to Zero.
ASSERT(!m_pszServer);
ASSERT(!m_pidl);
ASSERT(!m_pszUser);
ASSERT(!m_pszPassword);
ASSERT(!m_pszFragment);
ASSERT(!m_pszLookupStr);
ASSERT(!m_pidlVirtualDir);
ASSERT(!m_fMotd);
ASSERT(!m_hint);
ASSERT(!m_hgti);
ASSERT(!m_FtpDirList);
ASSERT(!m_fRatingsChecked);
ASSERT(!m_fRatingsAllow);
LEAK_ADDREF(LEAK_CFtpSite);
}
/****************************************************\
Destructor
\****************************************************/
CFtpSite::~CFtpSite()
{
FlushHint(); // Frees m_hgti
Str_SetPtr(&m_pszServer, NULL);
Str_SetPtr(&m_pszUser, NULL);
Str_SetPtr(&m_pszPassword, NULL);
Str_SetPtr(&m_pszFragment, NULL);
Str_SetPtr(&m_pszLookupStr, NULL);
Str_SetPtr(&m_pszRedirPassword, NULL);
Pidl_Set(&m_pidlVirtualDir, NULL);
Pidl_Set(&m_pidl, NULL);
IUnknown_Set(&m_pfgMotd, NULL);
ASSERTCRITICAL;
CFtpPunkList_Purge(&m_FtpDirList);
TriggerDelayedAction(&m_hgti); // Out goes the cached handle
ASSERT(m_hint == 0); // Make sure he's gone
ATOMICRELEASE(m_pm);
DllRelease();
LEAK_DELREF(LEAK_CFtpSite);
}
//===========================
// *** IUnknown Interface ***
ULONG CFtpSite::AddRef()
{
m_cRef++;
return m_cRef;
}
ULONG CFtpSite::Release()
{
ASSERT(m_cRef > 0);
m_cRef--;
if (m_cRef > 0)
return m_cRef;
delete this;
return 0;
}
HRESULT CFtpSite::QueryInterface(REFIID riid, void **ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = SAFECAST(this, IUnknown*);
}
else
{
TraceMsg(TF_FTPQI, "CFtpSite::QueryInterface() failed.");
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -