/*
 *	basic interfaces
 *
 *	Copyright 1997	Marcus Meissner
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "winerror.h"
#include "ole.h"
#include "ole2.h"
#include "ldt.h"
#include "heap.h"
#include "compobj.h"
#include "interfaces.h"
#include "shlobj.h"
#include "local.h"
#include "module.h"
#include "debug.h"

/****************************************************************************
 * IUnknown
 */
static ULONG WINAPI IUnknown_AddRef(LPUNKNOWN this) { 
	TRACE(relay,"(%p)->AddRef()\n",this);
	return ++(this->ref);
}
static ULONG WINAPI IUnknown_Release(LPUNKNOWN this) {
	TRACE(relay,"(%p)->Release()\n",this);
	if (!--(this->ref)) {
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}

static HRESULT WINAPI IUnknown_QueryInterface(LPUNKNOWN this,REFIID refiid,LPVOID *obj) {
	char	xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);

	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
		*obj = this;
		return 0; 
	}
	return OLE_E_ENUM_NOMORE; 
}

static IUnknown_VTable uvt = {
	IUnknown_QueryInterface,
	IUnknown_AddRef,
	IUnknown_Release
};


LPUNKNOWN
IUnknown_Constructor() {
	LPUNKNOWN	unk;

	unk = (LPUNKNOWN)HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown));
	unk->lpvtbl	= &uvt;
	unk->ref	= 1;
	return unk;
}

/****************************************************************************
 * IMalloc16
 */
ULONG WINAPI IMalloc16_AddRef(LPMALLOC16 this) {
	TRACE(relay,"(%p)->AddRef()\n",this);
	return 1; /* cannot be freed */
}

ULONG WINAPI IMalloc16_Release(LPMALLOC16 this) {
	TRACE(relay,"(%p)->Release()\n",this);
	return 1; /* cannot be freed */
}

HRESULT WINAPI IMalloc16_QueryInterface(LPMALLOC16 this,REFIID refiid,LPVOID *obj) {
	char	xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
		!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
	) {
		*obj = this;
		return 0;
	}
	return OLE_E_ENUM_NOMORE; 
}

LPVOID WINAPI IMalloc16_Alloc(LPMALLOC16 this,DWORD cb) {
	TRACE(relay,"(%p)->Alloc(%ld)\n",this,cb);
	return (LPVOID)PTR_SEG_OFF_TO_SEGPTR(this->heap,LOCAL_Alloc(this->heap,0,cb));
}

LPVOID WINAPI IMalloc16_Realloc(LPMALLOC16 this,LPVOID pv,DWORD cb) {
	TRACE(relay,"(%p)->Realloc(%p,%ld)\n",this,pv,cb);
	return (LPVOID)PTR_SEG_OFF_TO_SEGPTR(this->heap,LOCAL_ReAlloc(this->heap,0,LOWORD(pv),cb));
}
VOID WINAPI IMalloc16_Free(LPMALLOC16 this,LPVOID pv) {
	TRACE(relay,"(%p)->Free(%p)\n",this,pv);
	LOCAL_Free(this->heap,LOWORD(pv));
}

DWORD WINAPI IMalloc16_GetSize(LPMALLOC16 this,LPVOID pv) {
	TRACE(relay,"(%p)->GetSize(%p)\n",this,pv);
	return LOCAL_Size(this->heap,LOWORD(pv));
}

INT16 WINAPI IMalloc16_DidAlloc(LPMALLOC16 this,LPVOID pv) {
	TRACE(relay,"(%p)->DidAlloc(%p)\n",this,pv);
	return (INT16)-1;
}
LPVOID WINAPI IMalloc16_HeapMinimize(LPMALLOC16 this) {
	TRACE(relay,"(%p)->HeapMinimize()\n",this);
	return NULL;
}

static IMalloc16_VTable mvt16 = {
	IMalloc16_QueryInterface,
	IMalloc16_AddRef,
	IMalloc16_Release,
	IMalloc16_Alloc,
	IMalloc16_Realloc,
	IMalloc16_Free,
	IMalloc16_GetSize,
	IMalloc16_DidAlloc,
	IMalloc16_HeapMinimize,
};
static IMalloc16_VTable *msegvt16 = NULL;

LPMALLOC16
IMalloc16_Constructor() {
	LPMALLOC16	this;

	this = (LPMALLOC16)SEGPTR_NEW(IMalloc16);
	if (__winelib) {
		this->lpvtbl = &mvt16;
	} else {
		HMODULE16	hcomp = GetModuleHandle16("COMPOBJ");
		if (!msegvt16) {
			this->lpvtbl = msegvt16 = SEGPTR_NEW(IMalloc16_VTable);

#define FN(x) this->lpvtbl->fn##x = (void*)WIN32_GetProcAddress16(hcomp,"IMalloc16_"#x);assert(this->lpvtbl->fn##x);
			FN(QueryInterface)
			FN(AddRef)
			FN(Release)
			FN(Alloc)
			FN(Realloc)
			FN(Free)
			FN(GetSize)
			FN(DidAlloc)
			FN(HeapMinimize)
			msegvt16 = (LPMALLOC16_VTABLE)SEGPTR_GET(msegvt16);
#undef FN
		}
		this->lpvtbl = msegvt16;
	}
	this->ref = 1;
	/* FIXME: implement multiple heaps */
	this->heap = GlobalAlloc16(GMEM_MOVEABLE,64000);
	LocalInit(this->heap,0,64000);
	return (LPMALLOC16)SEGPTR_GET(this);
}

/****************************************************************************
 * IMalloc32
 */
static ULONG WINAPI IMalloc32_AddRef(LPMALLOC32 this) {
	TRACE(relay,"(%p)->AddRef()\n",this);
	return 1; /* cannot be freed */
}

static ULONG WINAPI IMalloc32_Release(LPMALLOC32 this) {
	TRACE(relay,"(%p)->Release()\n",this);
	return 1; /* cannot be freed */
}

static HRESULT WINAPI IMalloc32_QueryInterface(LPMALLOC32 this,REFIID refiid,LPVOID *obj) {
	char	xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
		!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
	) {
		*obj = this;
		return 0;
	}
	return OLE_E_ENUM_NOMORE; 
}

static LPVOID WINAPI IMalloc32_Alloc(LPMALLOC32 this,DWORD cb) {
	TRACE(relay,"(%p)->Alloc(%ld)\n",this,cb);
	return HeapAlloc(GetProcessHeap(),0,cb);
}

static LPVOID WINAPI IMalloc32_Realloc(LPMALLOC32 this,LPVOID pv,DWORD cb) {
	TRACE(relay,"(%p)->Realloc(%p,%ld)\n",this,pv,cb);
	return HeapReAlloc(GetProcessHeap(),0,pv,cb);
}
static VOID WINAPI IMalloc32_Free(LPMALLOC32 this,LPVOID pv) {
	TRACE(relay,"(%p)->Free(%p)\n",this,pv);
	HeapFree(GetProcessHeap(),0,pv);
}

static DWORD WINAPI IMalloc32_GetSize(LPMALLOC32 this,LPVOID pv) {
	TRACE(relay,"(%p)->GetSize(%p)\n",this,pv);
	return HeapSize(GetProcessHeap(),0,pv);
}

static INT32 WINAPI IMalloc32_DidAlloc(LPMALLOC32 this,LPVOID pv) {
	TRACE(relay,"(%p)->DidAlloc(%p)\n",this,pv);
	return -1;
}
static LPVOID WINAPI IMalloc32_HeapMinimize(LPMALLOC32 this) {
	TRACE(relay,"(%p)->HeapMinimize()\n",this);
	return NULL;
}

static IMalloc32_VTable VT_IMalloc32 = {
	IMalloc32_QueryInterface,
	IMalloc32_AddRef,
	IMalloc32_Release,
	IMalloc32_Alloc,
	IMalloc32_Realloc,
	IMalloc32_Free,
	IMalloc32_GetSize,
	IMalloc32_DidAlloc,
	IMalloc32_HeapMinimize,
};

LPMALLOC32
IMalloc32_Constructor() {
	LPMALLOC32	this;

	this = (LPMALLOC32)HeapAlloc(GetProcessHeap(),0,sizeof(IMalloc32));
	this->lpvtbl = &VT_IMalloc32;
	this->ref = 1;
	return this;
}
/****************************************************************************
 * API Functions
 */
/****************************************************************************
 * 		IsValidInterface		(OLE32.78)
 * RETURNS
 *  True, if the passed pointer is a valid interface
 */
BOOL32 WINAPI IsValidInterface32(
	LPUNKNOWN punk	/* [in] interface to be tested */
) {
	return !(
		IsBadReadPtr32(punk,4)					||
		IsBadReadPtr32(punk->lpvtbl,4)				||
		IsBadReadPtr32(punk->lpvtbl->fnQueryInterface,9)	||
		IsBadCodePtr32(punk->lpvtbl->fnQueryInterface)
	);
}
