Leaked source code of windows server 2003
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

/**************************************************************************
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;
}