You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
354 lines
7.3 KiB
354 lines
7.3 KiB
/**************************************************************************
|
|
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
PARTICULAR PURPOSE.
|
|
|
|
Copyright 1998 Microsoft Corporation. All Rights Reserved.
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
|
|
File: EnumIDL.cpp
|
|
|
|
Description: Implements IEnumIDList.
|
|
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
#include statements
|
|
**************************************************************************/
|
|
|
|
#include "EnumIDL.h"
|
|
#include "ShlFldr.h"
|
|
#include "mshtml.h"
|
|
#include "msxml.h"
|
|
#include "ParseXML.h"
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::CEnumIDList
|
|
|
|
**************************************************************************/
|
|
|
|
CEnumIDList::CEnumIDList(IXMLDocument *pXMLDoc, DWORD dwFlags)
|
|
{
|
|
g_DllRefCount++;
|
|
|
|
m_pFirst = m_pLast = m_pCurrent = NULL;
|
|
|
|
m_pXMLRoot = NULL;
|
|
m_dwFlags = dwFlags;
|
|
m_fFolder = FALSE;
|
|
m_pXMLDoc = pXMLDoc;
|
|
|
|
m_pPidlMgr = new CPidlMgr();
|
|
if(!m_pPidlMgr)
|
|
{
|
|
delete this;
|
|
return;
|
|
}
|
|
|
|
//get the shell's IMalloc pointer
|
|
//we'll keep this until we get destroyed
|
|
if(FAILED(SHGetMalloc(&m_pMalloc)))
|
|
{
|
|
delete this;
|
|
return;
|
|
}
|
|
|
|
if(!CreateEnumList())
|
|
{
|
|
delete this;
|
|
return;
|
|
}
|
|
|
|
m_ObjRefCount = 1;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::~CEnumIDList
|
|
|
|
**************************************************************************/
|
|
|
|
CEnumIDList::~CEnumIDList()
|
|
{
|
|
DeleteList();
|
|
|
|
if(m_pMalloc)
|
|
m_pMalloc->Release();
|
|
|
|
if(m_pPidlMgr)
|
|
delete m_pPidlMgr;
|
|
|
|
g_DllRefCount--;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::QueryInterface
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CEnumIDList::QueryInterface(REFIID riid, LPVOID *ppReturn)
|
|
{
|
|
*ppReturn = NULL;
|
|
|
|
//IUnknown
|
|
if(IsEqualIID(riid, IID_IUnknown))
|
|
{
|
|
*ppReturn = this;
|
|
}
|
|
|
|
//IEnumIDList
|
|
else if(IsEqualIID(riid, IID_IEnumIDList))
|
|
{
|
|
*ppReturn = (IEnumIDList*)this;
|
|
}
|
|
|
|
if(*ppReturn)
|
|
{
|
|
(*(LPUNKNOWN*)ppReturn)->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::AddRef
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP_(DWORD) CEnumIDList::AddRef()
|
|
{
|
|
return ++m_ObjRefCount;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::Release
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP_(DWORD) CEnumIDList::Release()
|
|
{
|
|
if(--m_ObjRefCount == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
return m_ObjRefCount;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::Next()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CEnumIDList::Next(DWORD dwElements, LPITEMIDLIST apidl[], LPDWORD pdwFetched)
|
|
{
|
|
DWORD dwIndex;
|
|
HRESULT hr = S_OK;
|
|
|
|
if(dwElements > 1 && !pdwFetched)
|
|
return E_INVALIDARG;
|
|
|
|
for(dwIndex = 0; dwIndex < dwElements; dwIndex++)
|
|
{
|
|
//is this the last item in the list?
|
|
if(!m_pCurrent)
|
|
{
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
apidl[dwIndex] = m_pPidlMgr->Copy(m_pCurrent->pidl);
|
|
|
|
m_pCurrent = m_pCurrent->pNext;
|
|
}
|
|
|
|
if(pdwFetched)
|
|
*pdwFetched = dwIndex;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::Skip()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CEnumIDList::Skip(DWORD dwSkip)
|
|
{
|
|
DWORD dwIndex;
|
|
HRESULT hr = S_OK;
|
|
|
|
for(dwIndex = 0; dwIndex < dwSkip; dwIndex++)
|
|
{
|
|
//is this the last item in the list?
|
|
if(!m_pCurrent)
|
|
{
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
m_pCurrent = m_pCurrent->pNext;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::Reset()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CEnumIDList::Reset(VOID)
|
|
{
|
|
m_pCurrent = m_pFirst;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::Clone()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CEnumIDList::Clone(LPENUMIDLIST *ppEnum)
|
|
{
|
|
HRESULT hr = E_OUTOFMEMORY;
|
|
|
|
*ppEnum = new CEnumIDList(m_pXMLDoc, m_dwFlags);
|
|
|
|
if(*ppEnum)
|
|
{
|
|
LPENUMLIST pTemp;
|
|
|
|
//synchronize the current pointer
|
|
for(pTemp = m_pFirst; pTemp != m_pCurrent; pTemp = pTemp->pNext)
|
|
{
|
|
(*ppEnum)->Skip(1);
|
|
}
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::CreateEnumList()
|
|
|
|
**************************************************************************/
|
|
|
|
BOOL CEnumIDList::CreateEnumList(VOID)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Get the sourse XML
|
|
if (m_pXMLDoc == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_pXMLRoot == NULL)
|
|
{
|
|
hr = m_pXMLDoc->get_root(&m_pXMLRoot);
|
|
if (!SUCCEEDED(hr) || !m_pXMLRoot)
|
|
{
|
|
SAFERELEASE(m_pXMLRoot);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//enumerate the folders
|
|
//
|
|
// Now walk the OM
|
|
//
|
|
// Dump the top level meta nodes of the document.
|
|
//
|
|
DumpElement(NULL, m_pPidlMgr, this, m_pXMLRoot, T_ROOT);
|
|
|
|
// Done
|
|
SAFERELEASE(m_pXMLRoot);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::AddToEnumList()
|
|
|
|
**************************************************************************/
|
|
|
|
BOOL CEnumIDList::AddToEnumList(LPITEMIDLIST pidl)
|
|
{
|
|
LPENUMLIST pNew;
|
|
|
|
pNew = (LPENUMLIST)m_pMalloc->Alloc(sizeof(ENUMLIST));
|
|
|
|
if(pNew)
|
|
{
|
|
//set the next pointer
|
|
pNew->pNext = NULL;
|
|
pNew->pidl = pidl;
|
|
|
|
//is this the first item in the list?
|
|
if(!m_pFirst)
|
|
{
|
|
m_pFirst = pNew;
|
|
m_pCurrent = m_pFirst;
|
|
}
|
|
|
|
if(m_pLast)
|
|
{
|
|
//add the new item to the end of the list
|
|
m_pLast->pNext = pNew;
|
|
}
|
|
|
|
//update the last item pointer
|
|
m_pLast = pNew;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CEnumIDList::DeleteList()
|
|
|
|
**************************************************************************/
|
|
|
|
BOOL CEnumIDList::DeleteList(VOID)
|
|
{
|
|
LPENUMLIST pDelete;
|
|
|
|
while(m_pFirst)
|
|
{
|
|
pDelete = m_pFirst;
|
|
m_pFirst = pDelete->pNext;
|
|
|
|
//free the pidl
|
|
m_pPidlMgr->Delete(pDelete->pidl);
|
|
|
|
//free the list item
|
|
m_pMalloc->Free(pDelete);
|
|
}
|
|
|
|
m_pFirst = m_pLast = m_pCurrent = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
|