mirror of https://github.com/lianthony/NT4.0
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.
156 lines
3.7 KiB
156 lines
3.7 KiB
#include "shellprv.h"
|
|
#pragma hdrstop
|
|
|
|
typedef struct _DefEnum // deunk
|
|
{
|
|
IEnumIDList eunk;
|
|
int cRef;
|
|
int iCur;
|
|
LPITEMIDLIST pidlReturn;
|
|
LPVOID lpData;
|
|
LPFNENUMCALLBACK lpfn;
|
|
} CDefEnum;
|
|
|
|
STDMETHODIMP CDefEnum_QueryInterface(LPENUMIDLIST peunk, REFIID riid, LPVOID * ppvObj);
|
|
STDMETHODIMP_(ULONG) CDefEnum_AddRef(LPENUMIDLIST peunk) ;
|
|
STDMETHODIMP_(ULONG) CDefEnum_Release(LPENUMIDLIST peunk);
|
|
STDMETHODIMP CDefEnum_Next(LPENUMIDLIST peunk, ULONG celt, LPITEMIDLIST * rgelt, ULONG * pceltFetched);
|
|
STDMETHODIMP CDefEnum_Skip(LPENUMIDLIST peunk, ULONG celt);
|
|
STDMETHODIMP CDefEnum_Reset(LPENUMIDLIST peunk);
|
|
STDMETHODIMP CDefEnum_Clone(LPENUMIDLIST peunk, LPENUMIDLIST * ppenm);
|
|
|
|
// Vtable
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
IEnumIDListVtbl c_DefEnumVtbl =
|
|
{
|
|
CDefEnum_QueryInterface,
|
|
CDefEnum_AddRef,
|
|
CDefEnum_Release,
|
|
CDefEnum_Next,
|
|
CDefEnum_Skip,
|
|
CDefEnum_Reset,
|
|
CDefEnum_Clone
|
|
};
|
|
#pragma data_seg()
|
|
|
|
HRESULT WINAPI SHCreateEnumObjects(HWND hwndOwner, LPVOID lpData, LPFNENUMCALLBACK lpfn, LPENUMIDLIST *ppeunk)
|
|
{
|
|
HRESULT hres = ResultFromScode(E_OUTOFMEMORY);
|
|
CDefEnum * pdeunk = (CDefEnum *)LocalAlloc( LPTR, SIZEOF(CDefEnum));
|
|
if (pdeunk)
|
|
{
|
|
pdeunk->eunk.lpVtbl = &c_DefEnumVtbl;
|
|
pdeunk->cRef = 1;
|
|
|
|
pdeunk->lpData = lpData;
|
|
pdeunk->lpfn = lpfn;
|
|
|
|
Assert(pdeunk->iCur == 0);
|
|
Assert(pdeunk->pidlReturn == NULL);
|
|
|
|
*ppeunk = &pdeunk->eunk;
|
|
|
|
hres = NOERROR;
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
|
|
void CDefEnum_SetReturn(LPARAM lParam, LPITEMIDLIST pidl)
|
|
{
|
|
CDefEnum * pdeunk = (CDefEnum *)lParam;
|
|
|
|
pdeunk->pidlReturn = pidl;
|
|
}
|
|
|
|
STDMETHODIMP CDefEnum_QueryInterface(LPENUMIDLIST peunk, REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
CDefEnum * this = IToClass(CDefEnum, eunk, peunk);
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumIDList))
|
|
{
|
|
*ppvObj = &this->eunk;
|
|
InterlockedIncrement(&this->cRef);
|
|
return NOERROR;
|
|
}
|
|
*ppvObj = NULL;
|
|
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDefEnum_AddRef(LPENUMIDLIST peunk)
|
|
{
|
|
CDefEnum * this = IToClass(CDefEnum, eunk, peunk);
|
|
InterlockedIncrement(&this->cRef);
|
|
return this->cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDefEnum_Release(LPENUMIDLIST peunk)
|
|
{
|
|
CDefEnum * this = IToClass(CDefEnum, eunk, peunk);
|
|
|
|
ULONG ulTmp = this->cRef;
|
|
|
|
if (InterlockedDecrement(&this->cRef) != 0)
|
|
return ulTmp - 1;
|
|
|
|
this->lpfn((LPARAM)this, this->lpData, ECID_RELEASE, 0);
|
|
|
|
LocalFree((HLOCAL)this);
|
|
|
|
return 0;
|
|
}
|
|
|
|
STDMETHODIMP CDefEnum_Next(LPENUMIDLIST peunk, ULONG celt, LPITEMIDLIST *ppidlOut, ULONG *pceltFetched)
|
|
{
|
|
CDefEnum * this = IToClass(CDefEnum, eunk, peunk);
|
|
HRESULT hres;
|
|
|
|
this->pidlReturn = NULL;
|
|
|
|
hres = this->lpfn((LPARAM)this, this->lpData, ECID_SETNEXTID, this->iCur);
|
|
if (hres == NOERROR)
|
|
{
|
|
this->iCur++;
|
|
|
|
Assert(this->pidlReturn);
|
|
|
|
*ppidlOut = this->pidlReturn;
|
|
|
|
if (pceltFetched)
|
|
*pceltFetched = 1;
|
|
}
|
|
else
|
|
{
|
|
Assert(this->pidlReturn == NULL);
|
|
|
|
*ppidlOut = NULL;
|
|
if (pceltFetched)
|
|
*pceltFetched = 0;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
|
|
|
|
|
|
///// These will be used by all enums that aren't yet implemented
|
|
|
|
STDMETHODIMP CDefEnum_Skip(LPENUMIDLIST peunk, ULONG celt)
|
|
{
|
|
// REVIEW: Implement it later.
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP CDefEnum_Reset(LPENUMIDLIST peunk)
|
|
{
|
|
// REVIEW: Implement it later.
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP CDefEnum_Clone(LPENUMIDLIST peunk, LPENUMIDLIST * ppenm)
|
|
{
|
|
// We'll never support this function.
|
|
return ResultFromScode(E_FAIL);
|
|
}
|