reactos/dll/win32/netshell/enumlist.cpp
Amine Khaldi 527f2f9057 [SHELL/EXPERIMENTS]
* Create a branch for some evul shell experiments.

svn path=/branches/shell-experiments/; revision=61927
2014-02-02 19:37:27 +00:00

260 lines
4.4 KiB
C++

#include "precomp.h"
/**************************************************************************
* AddToEnumList()
*/
BOOL
CEnumIDList::AddToEnumList(LPITEMIDLIST pidl)
{
LPENUMLIST pNew;
if (!pidl)
return FALSE;
pNew = (LPENUMLIST)SHAlloc(sizeof(ENUMLIST));
if(pNew)
{
pNew->pNext = NULL;
pNew->pidl = pidl;
if(!mpFirst)
{
mpFirst = pNew;
mpCurrent = pNew;
}
if(mpLast)
{
/*add the new item to the end of the list */
mpLast->pNext = pNew;
}
/*update the last item pointer */
mpLast = pNew;
return TRUE;
}
return FALSE;
}
CEnumIDList::CEnumIDList()
{
ref = 0;
mpCurrent = NULL;
mpLast = NULL;
mpFirst = NULL;
}
HRESULT
WINAPI
CEnumIDList::QueryInterface(
REFIID riid,
LPVOID *ppvObj)
{
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumIDList))
{
*ppvObj = (IEnumIDList*)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG
WINAPI
CEnumIDList::AddRef()
{
ULONG refCount = InterlockedIncrement(&ref);
return refCount;
}
ULONG
WINAPI CEnumIDList::Release()
{
LPENUMLIST pDelete;
ULONG refCount = InterlockedDecrement(&ref);
if (!refCount)
{
while (mpFirst)
{
pDelete = mpFirst;
mpFirst = pDelete->pNext;
SHFree(pDelete->pidl);
SHFree(pDelete);
}
delete this;
}
return refCount;
}
HRESULT
WINAPI
CEnumIDList::Next(
ULONG celt,
LPITEMIDLIST * rgelt,
ULONG *pceltFetched)
{
ULONG i;
HRESULT hr = S_OK;
LPITEMIDLIST temp;
if(pceltFetched)
*pceltFetched = 0;
*rgelt=0;
if (celt > 1 && !pceltFetched)
{
return E_INVALIDARG;
}
if (celt > 0 && !mpCurrent)
{
return S_FALSE;
}
for (i = 0; i < celt; i++)
{
if (!mpCurrent)
break;
temp = ILClone(mpCurrent->pidl);
rgelt[i] = temp;
mpCurrent = mpCurrent->pNext;
}
if (pceltFetched)
*pceltFetched = i;
return hr;
}
HRESULT
WINAPI
CEnumIDList::Skip(ULONG celt)
{
DWORD dwIndex;
HRESULT hr = S_OK;
for (dwIndex = 0; dwIndex < celt; dwIndex++)
{
if (!mpCurrent)
{
hr = S_FALSE;
break;
}
mpCurrent = mpCurrent->pNext;
}
return hr;
}
HRESULT
WINAPI
CEnumIDList::Reset()
{
mpCurrent = mpFirst;
return S_OK;
}
HRESULT
WINAPI
CEnumIDList::Clone(
LPENUMIDLIST * ppenum)
{
//IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
return E_NOTIMPL;
}
LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
{
if(pidl && pidl->mkid.cb != 0x00)
return (LPPIDLDATA) &(pidl->mkid.abID);
return NULL;
}
LPITEMIDLIST _ILAlloc(BYTE type, unsigned int size)
{
LPITEMIDLIST pidlOut = NULL;
pidlOut = (LPITEMIDLIST)SHAlloc(size + 5);
if(pidlOut)
{
LPPIDLDATA pData;
ZeroMemory(pidlOut, size + 5);
pidlOut->mkid.cb = size + 3;
pData = _ILGetDataPointer(pidlOut);
if (pData)
pData->type = type;
}
return pidlOut;
}
LPITEMIDLIST _ILCreateNetConnect()
{
LPITEMIDLIST pidlOut;
pidlOut = _ILAlloc(PT_GUID, sizeof(PIDLDATA));
if (pidlOut)
{
LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
memcpy(&(pData->u.guid.guid), &CLSID_NetworkConnections, sizeof(GUID));
}
return pidlOut;
}
IID* _ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata =_ILGetDataPointer(pidl);
if (!pdata)
return NULL;
if (pdata->type != PT_GUID)
return NULL;
else
return &(pdata->u.guid.guid);
}
BOOL _ILIsNetConnect(LPCITEMIDLIST pidl)
{
IID *piid = _ILGetGUIDPointer(pidl);
if (piid)
return IsEqualIID(*piid, CLSID_NetworkConnections);
return FALSE;
}
LPITEMIDLIST ILCreateNetConnectItem(INetConnection * pItem)
{
LPITEMIDLIST pidl;
LPPIDLDATA pdata;
pidl = _ILAlloc(0x99, sizeof(PIDLDATA));
pdata = _ILGetDataPointer(pidl);
pdata->u.value.pItem = (INetConnection*)pItem;
return pidl;
}
VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata = _ILGetDataPointer(pidl);
if (pdata && pdata->type==0x99)
return (VALUEStruct*)&(pdata->u.value);
return NULL;
}