reactos/dll/win32/netshell/enumlist.c
2011-05-24 18:40:34 +00:00

344 lines
6.2 KiB
C

#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef struct tagGUIDStruct
{
BYTE dummy; /* offset 01 is unknown */
GUID guid; /* offset 02 */
} GUIDStruct;
#define PT_GUID 0x1F
typedef struct tagPIDLDATA
{
BYTE type; /*00*/
union
{
struct tagGUIDStruct guid;
struct tagVALUEStruct value;
}u;
} PIDLDATA, *LPPIDLDATA;
typedef struct tagENUMLIST
{
struct tagENUMLIST *pNext;
LPITEMIDLIST pidl;
}ENUMLIST, *LPENUMLIST;
typedef struct
{
const IEnumIDListVtbl *lpVtbl;
LONG ref;
LPENUMLIST mpFirst;
LPENUMLIST mpLast;
LPENUMLIST mpCurrent;
} IEnumIDListImpl;
/**************************************************************************
* AddToEnumList()
*/
BOOL
AddToEnumList(
IEnumIDList * iface,
LPITEMIDLIST pidl)
{
LPENUMLIST pNew;
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
if (!iface || !pidl)
return FALSE;
pNew = (LPENUMLIST)SHAlloc(sizeof(ENUMLIST));
if(pNew)
{
pNew->pNext = NULL;
pNew->pidl = pidl;
if(!This->mpFirst)
{
This->mpFirst = pNew;
This->mpCurrent = pNew;
}
if(This->mpLast)
{
/*add the new item to the end of the list */
This->mpLast->pNext = pNew;
}
/*update the last item pointer */
This->mpLast = pNew;
return TRUE;
}
return FALSE;
}
static
HRESULT
WINAPI
IEnumIDList_fnQueryInterface(
IEnumIDList * iface,
REFIID riid,
LPVOID *ppvObj)
{
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
*ppvObj = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumIDList))
{
*ppvObj = This;
IEnumIDList_AddRef((IEnumIDList*)*ppvObj);
return S_OK;
}
return E_NOINTERFACE;
}
static
ULONG
WINAPI
IEnumIDList_fnAddRef(
IEnumIDList * iface)
{
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
return refCount;
}
static
ULONG
WINAPI IEnumIDList_fnRelease(
IEnumIDList * iface)
{
LPENUMLIST pDelete;
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
if (!refCount)
{
while(This->mpFirst)
{
pDelete = This->mpFirst;
This->mpFirst = pDelete->pNext;
SHFree(pDelete->pidl);
SHFree(pDelete);
}
CoTaskMemFree(This);
}
return refCount;
}
static
HRESULT
WINAPI
IEnumIDList_fnNext(
IEnumIDList * iface,
ULONG celt,
LPITEMIDLIST * rgelt,
ULONG *pceltFetched)
{
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
ULONG i;
HRESULT hr = S_OK;
LPITEMIDLIST temp;
if(pceltFetched)
*pceltFetched = 0;
*rgelt=0;
if(celt > 1 && !pceltFetched)
{
return E_INVALIDARG;
}
if(celt > 0 && !This->mpCurrent)
{
return S_FALSE;
}
for(i = 0; i < celt; i++)
{
if(!(This->mpCurrent))
break;
temp = ILClone(This->mpCurrent->pidl);
rgelt[i] = temp;
This->mpCurrent = This->mpCurrent->pNext;
}
if(pceltFetched)
{
*pceltFetched = i;
}
return hr;
}
static
HRESULT
WINAPI
IEnumIDList_fnSkip(
IEnumIDList * iface,ULONG celt)
{
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
DWORD dwIndex;
HRESULT hr = S_OK;
for(dwIndex = 0; dwIndex < celt; dwIndex++)
{
if(!This->mpCurrent)
{
hr = S_FALSE;
break;
}
This->mpCurrent = This->mpCurrent->pNext;
}
return hr;
}
static
HRESULT
WINAPI
IEnumIDList_fnReset(
IEnumIDList * iface)
{
IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
This->mpCurrent = This->mpFirst;
return S_OK;
}
static
HRESULT
WINAPI
IEnumIDList_fnClone(
IEnumIDList * iface,
LPENUMIDLIST * ppenum)
{
//IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
return E_NOTIMPL;
}
static const IEnumIDListVtbl eidlvt =
{
IEnumIDList_fnQueryInterface,
IEnumIDList_fnAddRef,
IEnumIDList_fnRelease,
IEnumIDList_fnNext,
IEnumIDList_fnSkip,
IEnumIDList_fnReset,
IEnumIDList_fnClone,
};
IEnumIDList * IEnumIDList_Constructor(void)
{
IEnumIDListImpl *lpeidl = CoTaskMemAlloc(sizeof(IEnumIDListImpl));
if (lpeidl)
{
lpeidl->ref = 1;
lpeidl->lpVtbl = &eidlvt;
lpeidl->mpCurrent = NULL;
lpeidl->mpLast = NULL;
lpeidl->mpFirst = NULL;
}
return (IEnumIDList*)lpeidl;
}
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 = 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)
{
REFIID iid = _ILGetGUIDPointer(pidl);
if (iid)
return IsEqualIID(iid, &CLSID_NetworkConnections);
return FALSE;
}
LPITEMIDLIST ILCreateNetConnectItem(INetConnection * pItem)
{
LPITEMIDLIST pidl;
LPPIDLDATA pdata;
pidl = _ILAlloc(0x99, sizeof(PIDLDATA));
pdata = _ILGetDataPointer(pidl);
pdata->u.value.pItem = (PVOID)pItem;
return pidl;
}
VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata = _ILGetDataPointer(pidl);
if (pdata && pdata->type==0x99)
return (VALUEStruct*)&(pdata->u.value);
return NULL;
}