📄 ftpeidl.cpp
字号:
hr = S_OK;
}
else
IUnknown_Set(&m_pflHfpl, NULL);
}
}
return hr;
}
/*****************************************************************************
* CFtpEidl::_NextOne
*****************************************************************************/
LPITEMIDLIST CFtpEidl::_NextOne(DWORD * pdwIndex)
{
LPITEMIDLIST pidl = NULL;
LPITEMIDLIST pidlResult = NULL;
if (m_pflHfpl)
{
while ((*pdwIndex < (DWORD) m_pflHfpl->GetCount()) && (pidl = m_pflHfpl->GetPidl(*pdwIndex)))
{
ASSERT(IsValidPIDL(pidl));
(*pdwIndex)++;
if (_fFilter(m_shcontf, FtpPidl_GetAttributes(pidl)))
{
pidlResult = ILClone(pidl);
break; // We don't need to search any more.
}
}
}
return pidlResult;
}
//===========================
// *** IEnumIDList Interface ***
//===========================
/*****************************************************************************
*
* IEnumIDList::Next
*
* Creates a brand new enumerator based on an existing one.
*
*
* OLE random documentation of the day: IEnumXXX::Next.
*
* rgelt - Receives an array of size celt (or larger).
*
* "Receives an array"? No, it doesn't receive an array.
* It *is* an array. The array receives *elements*.
*
* "Or larger"? Does this mean I can return more than the caller
* asked for? No, of course not, because the caller didn't allocate
* enough memory to hold that many return values.
*
* No semantics are assigned to the possibility of celt = 0.
* Since I am a mathematician, I treat it as vacuous success.
*
* pcelt is documented as an INOUT parameter, but no semantics
* are assigned to its input value.
*
* The dox don't say that you are allowed to return *pcelt < celt
* for reasons other than "no more elements", but the shell does
* it everywhere, so maybe it's legal...
*
*****************************************************************************/
HRESULT CFtpEidl::Next(ULONG celt, LPITEMIDLIST * rgelt, ULONG *pceltFetched)
{
HRESULT hr = S_OK;
LPITEMIDLIST pidl = NULL;
DWORD dwIndex;
// The shell on pre-NT5 enums us w/o ole initialized which causes problems
// when we call CoCreateInstance(). This happens in the thunking code
// of encode.cpp when thunking strings.
HRESULT hrOleInit = SHOleInitialize(0);
if (m_fDead)
return E_FAIL;
if (!m_fInited)
{
hr = _Init();
if (FAILED(hr) && (HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr))
{
// Did we need to redirect because of a new password or username?
if (HRESULT_FROM_WIN32(ERROR_NETWORK_ACCESS_DENIED) == hr)
{
m_fDead = TRUE;
hr = E_FAIL;
}
else if (!m_fErrorDisplayed)
{
DisplayWininetError(m_hwndOwner, FALSE, HRESULT_CODE(hr), IDS_FTPERR_TITLE_ERROR, IDS_FTPERR_GETDIRLISTING, IDS_FTPERR_WININET, MB_OK, NULL);
m_fErrorDisplayed = TRUE;
}
}
}
if (S_OK == hr)
{
// Do they want more and do we have more to give?
for (dwIndex = 0; (dwIndex < celt) && (pidl = _NextOne(&m_nIndex)); dwIndex++)
rgelt[dwIndex] = pidl; // Yes, so give away...
if (pceltFetched)
*pceltFetched = dwIndex;
// Were we able to give any?
if (0 == dwIndex)
hr = S_FALSE;
}
SHOleUninitialize(hrOleInit);
return hr;
}
/*****************************************************************************
* IEnumIDList::Skip
*****************************************************************************/
HRESULT CFtpEidl::Skip(ULONG celt)
{
m_nIndex += celt;
return S_OK;
}
/*****************************************************************************
* IEnumIDList::Reset
*****************************************************************************/
HRESULT CFtpEidl::Reset(void)
{
m_fErrorDisplayed = FALSE;
if (!m_fInited)
_Init();
m_nIndex = 0;
return S_OK;
}
/*****************************************************************************\
* IEnumIDList::Clone
*
* Creates a brand new enumerator based on an existing one.
\*****************************************************************************/
HRESULT CFtpEidl::Clone(IEnumIDList **ppenum)
{
return CFtpEidl_Create(m_pfd, m_pff, m_hwndOwner, m_shcontf, m_nIndex, ppenum);
}
/*****************************************************************************\
* CFtpEidl_Create
*
* Creates a brand new enumerator based on an ftp site.
\*****************************************************************************/
HRESULT CFtpEidl_Create(CFtpDir * pfd, CFtpFolder * pff, HWND hwndOwner, DWORD shcontf, IEnumIDList ** ppenum)
{
CFtpEidl * pfe;
HRESULT hres = CFtpEidl_Create(pfd, pff, hwndOwner, shcontf, &pfe);
*ppenum = NULL;
if (EVAL(pfe))
{
hres = pfe->QueryInterface(IID_IEnumIDList, (LPVOID *) ppenum);
pfe->Release();
}
return hres;
}
/*****************************************************************************
*
* CFtpEidl_Create
*
* Creates a brand new enumerator based on an ftp site.
*
*****************************************************************************/
HRESULT CFtpEidl_Create(CFtpDir * pfd, CFtpFolder * pff, HWND hwndOwner, DWORD shcontf, CFtpEidl ** ppfe)
{
CFtpEidl * pfe = new CFtpEidl();
HRESULT hr = E_OUTOFMEMORY;
ASSERT(pfd && pff && ppfe);
*ppfe = pfe;
if (EVAL(pfe))
{
ATOMICRELEASE(pfe->m_pm);
pfe->m_pm = pff->GetIMalloc();
IUnknown_Set(&pfe->m_pff, pff);
IUnknown_Set(&pfe->m_pfd, pfd);
pfe->m_pflHfpl = pfd->GetHfpl();
pfe->m_shcontf = shcontf;
pfe->m_hwndOwner = hwndOwner;
}
return hr;
}
/*****************************************************************************\
* CFtpEidl_Create
*
* Creates a brand new enumerator based on an ftp site.
\*****************************************************************************/
HRESULT CFtpEidl_Create(CFtpDir * pfd, CFtpFolder * pff, HWND hwndOwner, DWORD shcontf, DWORD dwIndex, IEnumIDList ** ppenum)
{
CFtpEidl * pfe;
HRESULT hres = CFtpEidl_Create(pfd, pff, hwndOwner, shcontf, &pfe);
if (EVAL(SUCCEEDED(hres)))
{
pfe->m_nIndex = dwIndex;
hres = pfe->QueryInterface(IID_IEnumIDList, (LPVOID *) ppenum);
ASSERT(SUCCEEDED(hres));
pfe->Release();
}
return hres;
}
/****************************************************\
Constructor
\****************************************************/
CFtpEidl::CFtpEidl() : m_cRef(1)
{
DllAddRef();
// This needs to be allocated in Zero Inited Memory.
// Assert that all Member Variables are inited to Zero.
ASSERT(!m_fInited);
ASSERT(!m_nIndex);
ASSERT(!m_shcontf);
ASSERT(!m_pflHfpl);
ASSERT(!m_pfd);
ASSERT(!m_pm);
ASSERT(!m_hwndOwner);
ASSERT(!m_fInited);
ASSERT(!m_fDead);
m_hrOleInited = E_FAIL;
LEAK_ADDREF(LEAK_CFtpEidl);
}
/****************************************************\
Destructor
\****************************************************/
CFtpEidl::~CFtpEidl()
{
IUnknown_Set(&m_pflHfpl, NULL);
IUnknown_Set(&m_pm, NULL);
IUnknown_Set(&m_pfd, NULL);
IUnknown_Set(&m_pff, NULL);
DllRelease();
LEAK_DELREF(LEAK_CFtpEidl);
SHCoUninitialize(m_hrOleInited);
}
//===========================
// *** IUnknown Interface ***
//===========================
ULONG CFtpEidl::AddRef()
{
m_cRef++;
return m_cRef;
}
ULONG CFtpEidl::Release()
{
ASSERT(m_cRef > 0);
m_cRef--;
if (m_cRef > 0)
return m_cRef;
delete this;
return 0;
}
HRESULT CFtpEidl::QueryInterface(REFIID riid, void **ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumIDList))
{
*ppvObj = SAFECAST(this, IEnumIDList*);
}
else if (IsEqualIID(riid, IID_IObjectWithSite))
{
*ppvObj = SAFECAST(this, IObjectWithSite*);
}
else
{
TraceMsg(TF_FTPQI, "CFtpEidl::QueryInterface() failed.");
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -