mirror of
https://github.com/reactos/reactos.git
synced 2024-11-11 01:04:11 +00:00
c2d0d784c7
- Create a branch to do a proper merge of USB work from a trunk base instead of from cmake-bringup - In the future, DO NOT under any circumstances branch another branch. This leads to merge problems! svn path=/branches/usb-bringup-trunk/; revision=55018
343 lines
6.2 KiB
C
343 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;
|
|
}
|