/*
 * ErrorInfo API
 *
 * Copyright 2000 Patrik Stridvall, Juergen Schmied
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTES:
 *
 * The errorinfo is a per-thread object. The reference is stored in the
 * TEB at offset 0xf80.
 */

#include <stdarg.h>
#include <string.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "oleauto.h"
#include "winerror.h"

#include "wine/unicode.h"
#include "compobj_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/* this code is from SysAllocStringLen (ole2disp.c in oleaut32) */
static BSTR WINAPI ERRORINFO_SysAllocString(const OLECHAR* in)
{
    DWORD  bufferSize;
    DWORD* newBuffer;
    WCHAR* stringBuffer;
    DWORD len;

    if (in == NULL)
	return NULL;
    /*
     * Find the lenth of the buffer passed-in in bytes.
     */
    len = strlenW(in);
    bufferSize = len * sizeof (WCHAR);

    /*
     * Allocate a new buffer to hold the string.
     * don't forget to keep an empty spot at the beginning of the
     * buffer for the character count and an extra character at the
     * end for the '\0'.
     */
    newBuffer = HeapAlloc(GetProcessHeap(), 0,
                                 bufferSize + sizeof(WCHAR) + sizeof(DWORD));

    /*
     * If the memory allocation failed, return a null pointer.
     */
    if (newBuffer==0)
      return 0;

    /*
     * Copy the length of the string in the placeholder.
     */
    *newBuffer = bufferSize;

    /*
     * Skip the byte count.
     */
    newBuffer++;

    /*
     * Copy the information in the buffer.
     * Since it is valid to pass a NULL pointer here, we'll initialize the
     * buffer to nul if it is the case.
     */
    if (in != 0)
      memcpy(newBuffer, in, bufferSize);
    else
      memset(newBuffer, 0, bufferSize);

    /*
     * Make sure that there is a nul character at the end of the
     * string.
     */
    stringBuffer = (WCHAR*)newBuffer;
    stringBuffer[len] = 0;

    return (LPWSTR)stringBuffer;
}

/* this code is from SysFreeString (ole2disp.c in oleaut32)*/
static VOID WINAPI ERRORINFO_SysFreeString(BSTR in)
{
    DWORD* bufferPointer;

    /* NULL is a valid parameter */
    if(!in) return;

    /*
     * We have to be careful when we free a BSTR pointer, it points to
     * the beginning of the string but it skips the byte count contained
     * before the string.
     */
    bufferPointer = (DWORD*)in;

    bufferPointer--;

    /*
     * Free the memory from it's "real" origin.
     */
    HeapFree(GetProcessHeap(), 0, bufferPointer);
}


typedef struct ErrorInfoImpl
{
	const IErrorInfoVtbl           *lpvtei;
	const ICreateErrorInfoVtbl     *lpvtcei;
	const ISupportErrorInfoVtbl    *lpvtsei;
	LONG				ref;

	GUID m_Guid;
	BSTR bstrSource;
	BSTR bstrDescription;
	BSTR bstrHelpFile;
	DWORD m_dwHelpContext;
} ErrorInfoImpl;

static const IErrorInfoVtbl        IErrorInfoImpl_VTable;
static const ICreateErrorInfoVtbl  ICreateErrorInfoImpl_VTable;
static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable;

/*
 converts an object pointer to This
 */

static inline ErrorInfoImpl *impl_from_IErrorInfo( IErrorInfo *iface )
{
    return (ErrorInfoImpl *)((char*)iface - FIELD_OFFSET(ErrorInfoImpl, lpvtei));
}

static inline ErrorInfoImpl *impl_from_ICreateErrorInfo( ICreateErrorInfo *iface )
{
    return (ErrorInfoImpl *)((char*)iface - FIELD_OFFSET(ErrorInfoImpl, lpvtcei));
}

static inline ErrorInfoImpl *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface )
{
    return (ErrorInfoImpl *)((char*)iface - FIELD_OFFSET(ErrorInfoImpl, lpvtsei));
}


/*
 converts This to an object pointer
 */
#define _IErrorInfo_(This)		(IErrorInfo*)&(This->lpvtei)
#define _ICreateErrorInfo_(This)	(ICreateErrorInfo*)&(This->lpvtcei)
#define _ISupportErrorInfo_(This)	(ISupportErrorInfo*)&(This->lpvtsei)

IErrorInfo * IErrorInfoImpl_Constructor(void)
{
	ErrorInfoImpl * ei = HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl));
	if (ei)
	{
	  ei->lpvtei = &IErrorInfoImpl_VTable;
	  ei->lpvtcei = &ICreateErrorInfoImpl_VTable;
	  ei->lpvtsei = &ISupportErrorInfoImpl_VTable;
	  ei->ref = 1;
	  ei->bstrSource = NULL;
	  ei->bstrDescription = NULL;
	  ei->bstrHelpFile = NULL;
	  ei->m_dwHelpContext = 0;
	}
	return (IErrorInfo *)ei;
}


static HRESULT WINAPI IErrorInfoImpl_QueryInterface(
	IErrorInfo* iface,
	REFIID     riid,
	VOID**     ppvoid)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvoid);

	*ppvoid = NULL;

	if(IsEqualIID(riid, &IID_IErrorInfo))
	{
	  *ppvoid = _IErrorInfo_(This);
	}
	else if(IsEqualIID(riid, &IID_ICreateErrorInfo))
	{
	  *ppvoid = _ICreateErrorInfo_(This);
	}
	else if(IsEqualIID(riid, &IID_ISupportErrorInfo))
	{
	  *ppvoid = _ISupportErrorInfo_(This);
	}

	if(*ppvoid)
	{
	  IUnknown_AddRef( (IUnknown*)*ppvoid );
	  TRACE("-- Interface: (%p)->(%p)\n",ppvoid,*ppvoid);
	  return S_OK;
	}
	TRACE("-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;
}

static ULONG WINAPI IErrorInfoImpl_AddRef(
 	IErrorInfo* iface)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
	TRACE("(%p)->(count=%lu)\n",This,This->ref);
	return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IErrorInfoImpl_Release(
	IErrorInfo* iface)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
        ULONG ref = InterlockedDecrement(&This->ref);

	TRACE("(%p)->(count=%lu)\n",This,ref+1);

	if (!ref)
	{
	  TRACE("-- destroying IErrorInfo(%p)\n",This);
	  HeapFree(GetProcessHeap(),0,This);
	  return 0;
	}
	return ref;
}

static HRESULT WINAPI IErrorInfoImpl_GetGUID(
	IErrorInfo* iface,
	GUID * pGUID)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
	TRACE("(%p)->(count=%lu)\n",This,This->ref);
	if(!pGUID )return E_INVALIDARG;
	memcpy(pGUID, &This->m_Guid, sizeof(GUID));
	return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetSource(
	IErrorInfo* iface,
	BSTR *pBstrSource)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
	TRACE("(%p)->(pBstrSource=%p)\n",This,pBstrSource);
	if (pBstrSource == NULL)
	    return E_INVALIDARG;
	*pBstrSource = ERRORINFO_SysAllocString(This->bstrSource);
	return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetDescription(
	IErrorInfo* iface,
	BSTR *pBstrDescription)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

	TRACE("(%p)->(pBstrDescription=%p)\n",This,pBstrDescription);
	if (pBstrDescription == NULL)
	    return E_INVALIDARG;
	*pBstrDescription = ERRORINFO_SysAllocString(This->bstrDescription);

	return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetHelpFile(
	IErrorInfo* iface,
	BSTR *pBstrHelpFile)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

	TRACE("(%p)->(pBstrHelpFile=%p)\n",This, pBstrHelpFile);
	if (pBstrHelpFile == NULL)
	    return E_INVALIDARG;
	*pBstrHelpFile = ERRORINFO_SysAllocString(This->bstrHelpFile);

	return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetHelpContext(
	IErrorInfo* iface,
	DWORD *pdwHelpContext)
{
	ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
	TRACE("(%p)->(pdwHelpContext=%p)\n",This, pdwHelpContext);
	if (pdwHelpContext == NULL)
	    return E_INVALIDARG;
	*pdwHelpContext = This->m_dwHelpContext;

	return S_OK;
}

static const IErrorInfoVtbl IErrorInfoImpl_VTable =
{
  IErrorInfoImpl_QueryInterface,
  IErrorInfoImpl_AddRef,
  IErrorInfoImpl_Release,

  IErrorInfoImpl_GetGUID,
  IErrorInfoImpl_GetSource,
  IErrorInfoImpl_GetDescription,
  IErrorInfoImpl_GetHelpFile,
  IErrorInfoImpl_GetHelpContext
};


static HRESULT WINAPI ICreateErrorInfoImpl_QueryInterface(
	ICreateErrorInfo* iface,
	REFIID     riid,
	VOID**     ppvoid)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p)\n", This);
	return IErrorInfo_QueryInterface(_IErrorInfo_(This), riid, ppvoid);
}

static ULONG WINAPI ICreateErrorInfoImpl_AddRef(
 	ICreateErrorInfo* iface)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p)\n", This);
	return IErrorInfo_AddRef(_IErrorInfo_(This));
}

static ULONG WINAPI ICreateErrorInfoImpl_Release(
	ICreateErrorInfo* iface)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p)\n", This);
	return IErrorInfo_Release(_IErrorInfo_(This));
}


static HRESULT WINAPI ICreateErrorInfoImpl_SetGUID(
	ICreateErrorInfo* iface,
	REFGUID rguid)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p)->(%s)\n", This, debugstr_guid(rguid));
	memcpy(&This->m_Guid,  rguid, sizeof(GUID));
	return S_OK;
}

static HRESULT WINAPI ICreateErrorInfoImpl_SetSource(
	ICreateErrorInfo* iface,
	LPOLESTR szSource)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p): %s\n",This, debugstr_w(szSource));
	if (This->bstrSource != NULL)
	    ERRORINFO_SysFreeString(This->bstrSource);
	This->bstrSource = ERRORINFO_SysAllocString(szSource);

	return S_OK;
}

static HRESULT WINAPI ICreateErrorInfoImpl_SetDescription(
	ICreateErrorInfo* iface,
	LPOLESTR szDescription)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p): %s\n",This, debugstr_w(szDescription));
	if (This->bstrDescription != NULL)
	    ERRORINFO_SysFreeString(This->bstrDescription);
	This->bstrDescription = ERRORINFO_SysAllocString(szDescription);

	return S_OK;
}

static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpFile(
	ICreateErrorInfo* iface,
	LPOLESTR szHelpFile)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile));
	if (This->bstrHelpFile != NULL)
	    ERRORINFO_SysFreeString(This->bstrHelpFile);
	This->bstrHelpFile = ERRORINFO_SysAllocString(szHelpFile);
	return S_OK;
}

static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext(
	ICreateErrorInfo* iface,
 	DWORD dwHelpContext)
{
	ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
	TRACE("(%p,%ld)\n",This,dwHelpContext);
	This->m_dwHelpContext = dwHelpContext;
	return S_OK;
}

static const ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable =
{
  ICreateErrorInfoImpl_QueryInterface,
  ICreateErrorInfoImpl_AddRef,
  ICreateErrorInfoImpl_Release,

  ICreateErrorInfoImpl_SetGUID,
  ICreateErrorInfoImpl_SetSource,
  ICreateErrorInfoImpl_SetDescription,
  ICreateErrorInfoImpl_SetHelpFile,
  ICreateErrorInfoImpl_SetHelpContext
};

static HRESULT WINAPI ISupportErrorInfoImpl_QueryInterface(
	ISupportErrorInfo* iface,
	REFIID     riid,
	VOID**     ppvoid)
{
	ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface);
	TRACE("(%p)\n", This);

	return IErrorInfo_QueryInterface(_IErrorInfo_(This), riid, ppvoid);
}

static ULONG WINAPI ISupportErrorInfoImpl_AddRef(
 	ISupportErrorInfo* iface)
{
	ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface);
	TRACE("(%p)\n", This);
	return IErrorInfo_AddRef(_IErrorInfo_(This));
}

static ULONG WINAPI ISupportErrorInfoImpl_Release(
	ISupportErrorInfo* iface)
{
	ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface);
	TRACE("(%p)\n", This);
	return IErrorInfo_Release(_IErrorInfo_(This));
}


static HRESULT WINAPI ISupportErrorInfoImpl_InterfaceSupportsErrorInfo(
	ISupportErrorInfo* iface,
	REFIID riid)
{
	ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface);
	TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
	return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE;
}

static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable =
{
  ISupportErrorInfoImpl_QueryInterface,
  ISupportErrorInfoImpl_AddRef,
  ISupportErrorInfoImpl_Release,


  ISupportErrorInfoImpl_InterfaceSupportsErrorInfo
};
/***********************************************************************
 *		CreateErrorInfo (OLE32.@)
 */
HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
{
	IErrorInfo * pei;
	HRESULT res;
	TRACE("(%p)\n", pperrinfo);
	if(! pperrinfo ) return E_INVALIDARG;
	if(!(pei=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY;

	res = IErrorInfo_QueryInterface(pei, &IID_ICreateErrorInfo, (LPVOID*)pperrinfo);
	IErrorInfo_Release(pei);
	return res;
}

/***********************************************************************
 *		GetErrorInfo (OLE32.@)
 */
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
{
	TRACE("(%ld, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo);

	if(!pperrinfo) return E_INVALIDARG;
        
	if (!COM_CurrentInfo()->errorinfo)
	{
	   *pperrinfo = NULL;
	   return S_FALSE;
	}

	*pperrinfo = COM_CurrentInfo()->errorinfo;
        
	/* clear thread error state */
	COM_CurrentInfo()->errorinfo = NULL;
	return S_OK;
}

/***********************************************************************
 *		SetErrorInfo (OLE32.@)
 */
HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
{
	IErrorInfo * pei;

	TRACE("(%ld, %p)\n", dwReserved, perrinfo);
	
	/* release old errorinfo */
	pei = COM_CurrentInfo()->errorinfo;
	if (pei) IErrorInfo_Release(pei);

	/* set to new value */
	COM_CurrentInfo()->errorinfo = perrinfo;
	if (perrinfo) IErrorInfo_AddRef(perrinfo);
        
	return S_OK;
}
