Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

277 lines
6.1 KiB

#include "shellprv.h"
#pragma hdrstop
#pragma warning(disable: 4200) // zero-sized array in struct
//
// Member: WCommonUnknown::QueryInterface
//
HRESULT STDMETHODCALLTYPE WCommonUnknown_QueryInterface(void * punk, REFIID riid, LPVOID * ppvObj)
{
PWCommonUnknown this = IToClassN(WCommonUnknown, unk, punk);
if (IsEqualIID(riid, this->riid) || IsEqualIID(riid, &IID_IUnknown))
{
*ppvObj = &(this->ck.unk);
this->ck.punkOuter->lpVtbl->AddRef(this->ck.punkOuter);
return NOERROR;
}
*ppvObj = NULL;
return(ResultFromScode(E_NOINTERFACE));
}
//
// Member: WCommonUnknown::AddRef
//
ULONG STDMETHODCALLTYPE WCommonUnknown_AddRef(void * punk)
{
PWCommonUnknown this = IToClassN(WCommonUnknown, unk, punk);
this->cRef++;
return(this->cRef);
}
//
// Thunk: WCommonKnown::QueryInterface
//
HRESULT STDMETHODCALLTYPE WCommonKnown_QueryInterface(void * punk, REFIID riid, LPVOID * ppvObj)
{
PWCommonKnown this = IToClassN(WCommonKnown, unk, punk);
return(this->punkOuter->lpVtbl->QueryInterface(this->punkOuter, riid, ppvObj));
}
//
// Thunk: WCommonKnown::AddRef
//
ULONG STDMETHODCALLTYPE WCommonKnown_AddRef(void * punk)
{
PWCommonKnown this = IToClassN(WCommonKnown, unk, punk);
return(this->punkOuter->lpVtbl->AddRef(this->punkOuter));
}
//
// Thunk: WCommonKnown::Release
//
ULONG STDMETHODCALLTYPE WCommonKnown_Release(void * punk)
{
PWCommonKnown this = IToClassN(WCommonKnown, unk, punk);
return(this->punkOuter->lpVtbl->Release(this->punkOuter));
}
typedef struct _COMMOBJ_OBJ
{
COMMOBJ_OBJDESC sDesc;
IUnknown *punkAgg;
} COMMOBJ_OBJ;
typedef struct _CommObj
{
IUnknown unk;
UINT cRef;
COMMOBJ_DESTROYOBJECT lpfnDestroy;
COMMINFO cinfo;
int nObjs;
COMMOBJ_OBJ sObjs[];
} CommObj, *PCommObj;
ULONG STDMETHODCALLTYPE CommObj_AddRef(void * punk);
//
// Thunk: CommObj::QueryInterface
//
HRESULT STDMETHODCALLTYPE CommObj_QueryInterface(void * punk, REFIID riid, LPVOID *ppv)
{
PCommObj this = IToClassN(CommObj, unk, punk);
COMMOBJ_OBJ *pObj;
HRESULT hres;
int nObjs;
*ppv = NULL; // assume error
for (nObjs=this->nObjs-1, pObj=&this->sObjs[0]; ; --nObjs, ++pObj)
{
if (nObjs < 0)
{
if (IsEqualIID(riid, &IID_IUnknown))
{
CommObj_AddRef(punk);
*ppv = punk;
return(NOERROR);
}
else
{
return(ResultFromScode(E_NOINTERFACE));
}
}
if (IsEqualIID(riid, pObj->sDesc.riid))
{
break;
}
}
if (!pObj->punkAgg)
{
hres = pObj->sDesc.lpfnCreate(&(this->unk), &this->cinfo, riid, &pObj->punkAgg);
if (!SUCCEEDED(hres))
{
pObj->punkAgg = NULL;
return(hres);
}
}
// Note that this should inc our ref count
return(pObj->punkAgg->lpVtbl->QueryInterface(pObj->punkAgg, riid, ppv));
}
//
// Thunk: CommObj::AddRef
//
ULONG STDMETHODCALLTYPE CommObj_AddRef(void * punk)
{
PCommObj this = IToClassN(CommObj, unk, punk);
++this->cRef;
return(this->cRef);
}
//
// Thunk: CommObj::Release
//
ULONG STDMETHODCALLTYPE CommObj_Release(void * punk)
{
PCommObj this = IToClassN(CommObj, unk, punk);
int nObjs;
COMMOBJ_OBJ *pObj;
--this->cRef;
if (this->cRef > 0)
{
return(this->cRef);
}
for (nObjs=this->nObjs, pObj=&this->sObjs[0]; nObjs>0; --nObjs, ++pObj)
{
if (pObj->punkAgg)
{
pObj->punkAgg->lpVtbl->Release(pObj->punkAgg);
}
}
//
// These castings are OK, because we are initializing them.
//
Str_SetPtr(&(LPTSTR)this->cinfo.pszSubObject, NULL);
Str_SetPtr(&(LPTSTR)this->cinfo.pszContainer, NULL);
if (this->cinfo.pidl) {
ILFree((LPITEMIDLIST)this->cinfo.pidl);
}
if (this->lpfnDestroy)
{
this->lpfnDestroy(&this->cinfo);
}
LocalFree(this);
return 0;
}
#pragma data_seg(".text", "CODE")
IUnknownVtbl s_CommObjVtbl =
{
CommObj_QueryInterface,
CommObj_AddRef,
CommObj_Release,
};
#pragma data_seg()
//
// Create a generic aggregate object
//
HRESULT Common_CreateObject(LPCOMMINFO lpcinfo,
COMMOBJ_DESTROYOBJECT lpfnDestroy,
const COMMOBJ_OBJDESC *lpObjDescs, UINT nObjs, REFIID riid, LPVOID *ppv)
{
PCommObj this;
HRESULT hres;
COMMOBJ_OBJ *pObj;
this = (PCommObj)LocalAlloc(LPTR, SIZEOF(CommObj) + nObjs*SIZEOF(COMMOBJ_OBJ));
if (!this)
{
goto Error1;
}
//
// There castings are OK, because we are initializing them.
//
if (!Str_SetPtr(&(LPTSTR)this->cinfo.pszContainer, lpcinfo->pszContainer))
{
goto Error2;
}
if (!Str_SetPtr(&(LPTSTR)this->cinfo.pszSubObject, lpcinfo->pszSubObject))
{
goto Error3;
}
this->cRef = 1;
this->unk.lpVtbl = (IUnknownVtbl *) &s_CommObjVtbl;
this->nObjs = nObjs;
for (pObj=&this->sObjs[0]; nObjs>0; --nObjs, ++pObj, ++lpObjDescs)
{
pObj->sDesc = *lpObjDescs;
}
this->lpfnDestroy = lpfnDestroy;
this->cinfo.lpData = lpcinfo->lpData;
this->cinfo.rclsid = lpcinfo->rclsid;
this->cinfo.hwndOwner = lpcinfo->hwndOwner;
hres = CommObj_QueryInterface(&(this->unk), riid, ppv);
CommObj_Release(&(this->unk));
return(hres);
Error3:
Str_SetPtr(&(LPTSTR)this->cinfo.pszContainer, NULL);
Error2:
LocalFree(this);
Error1:
// Make sure this always gets called exactly once per call to this fn;
// either here or in the final release
lpfnDestroy(lpcinfo);
return(ResultFromScode(E_OUTOFMEMORY));
}
//
// Member: WCommonUnknown::QueryInterface
//
HRESULT STDMETHODCALLTYPE Common_ESF_QueryInterface(void * punk, REFIID riid, LPVOID * ppvObj)
{
PWCommonUnknown this = IToClassN(WCommonUnknown, unk, punk);
if (IsEqualIID(riid, this->riid)
|| IsEqualIID(riid, &IID_IDelayedRelease)
|| IsEqualIID(riid, &IID_IUnknown))
{
*ppvObj = &(this->unk);
this->unk.lpVtbl->AddRef(&(this->unk));
return NOERROR;
}
*ppvObj = NULL;
return(ResultFromScode(E_NOINTERFACE));
}