/*
 *	SHRegOpenStream
 */
#include <string.h>

#include "wine/obj_storage.h"

#include "debug.h"
#include "heap.h"
#include "winerror.h"
#include "winreg.h"

#include "shell.h"
#include "pidl.h"
#include "shell32_main.h"

typedef struct 
{	ICOM_VTABLE(IStream)* lpvtbl;
	DWORD		ref;
	HKEY		hKey;
	LPSTR		pszSubKey;
	LPSTR		pszValue;
	LPBYTE		pbBuffer;
	DWORD		dwLength;
	DWORD		dwPos;
} ISHRegStream;

static struct ICOM_VTABLE(IStream) rstvt;

/**************************************************************************
*   IStream_Constructor()
*/
IStream *IStream_Constructor(HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, DWORD grfMode)
{	ISHRegStream*	rstr;
	DWORD		dwType;
	
	rstr = (ISHRegStream*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ISHRegStream));
	rstr->lpvtbl=&rstvt;
	rstr->ref = 1;

	if ( ERROR_SUCCESS == RegOpenKeyExA (hKey, pszSubKey, 0, KEY_READ, &(rstr->hKey)))
	{ if ( ERROR_SUCCESS == RegQueryValueExA(rstr->hKey, (LPSTR)pszValue,0,0,0,&(rstr->dwLength)))
	  { 
	    /* read the binary data into the buffer */
	    rstr->pbBuffer = HeapAlloc(GetProcessHeap(),0,rstr->dwLength);
	    if (rstr->pbBuffer)
	    { if ( ERROR_SUCCESS == RegQueryValueExA(rstr->hKey, (LPSTR)pszValue,0,&dwType,rstr->pbBuffer,&(rstr->dwLength)))
	      { if (dwType == REG_BINARY )
	        { rstr->pszSubKey = HEAP_strdupA (GetProcessHeap(),0, pszSubKey);
	          rstr->pszValue = HEAP_strdupA (GetProcessHeap(),0, pszValue);		
	          TRACE(shell,"(%p)->0x%08x,%s,%s,0x%08lx\n", rstr, hKey, pszSubKey, pszValue, grfMode);
	          shell32_ObjCount++;
	          return (IStream*)rstr;
	        }
	      }
	      HeapFree (GetProcessHeap(),0,rstr->pbBuffer);
	    }
	  }
	  RegCloseKey(rstr->hKey);

	}
	HeapFree (GetProcessHeap(),0,rstr);
	return NULL;
}

/**************************************************************************
*  IStream_fnQueryInterface
*/
static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
{
	ICOM_THIS(ISHRegStream, iface);

	char    xriid[50];
	WINE_StringFromCLSID((LPCLSID)riid,xriid);

	TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);

	*ppvObj = NULL;

	if(IsEqualIID(riid, &IID_IUnknown))	/*IUnknown*/
	{ *ppvObj = This; 
	}
	else if(IsEqualIID(riid, &IID_IStream))	/*IStream*/
	{ *ppvObj = This;
	}   

	if(*ppvObj)
	{ 
	  IStream_AddRef((IStream*)*ppvObj);      
	  TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
	  return S_OK;
	}
	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;
}

/**************************************************************************
*  IStream_fnAddRef
*/
static ULONG WINAPI IStream_fnAddRef(IStream *iface)
{
	ICOM_THIS(ISHRegStream, iface);

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

	shell32_ObjCount++;
	return ++(This->ref);
}

/**************************************************************************
*  IStream_fnRelease
*/
static ULONG WINAPI IStream_fnRelease(IStream *iface)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)->()\n",This);

	shell32_ObjCount--;

	if (!--(This->ref)) 
	{ TRACE(shell," destroying SHReg IStream (%p)\n",This);

	  if (This->pszSubKey)
	    HeapFree(GetProcessHeap(),0,This->pszSubKey);

	  if (This->pszValue)
	    HeapFree(GetProcessHeap(),0,This->pszValue);

	  if (This->pbBuffer)
	    HeapFree(GetProcessHeap(),0,This->pbBuffer);

	  if (This->hKey)
	    RegCloseKey(This->hKey);

	  HeapFree(GetProcessHeap(),0,This);
	  return 0;
	}
	return This->ref;
}

HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead)
{
	ICOM_THIS(ISHRegStream, iface);

	DWORD dwBytesToRead, dwBytesLeft;
	
	TRACE(shell,"(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
	
	if ( !pv )
	  return STG_E_INVALIDPOINTER;
	  
	dwBytesLeft = This->dwLength - This->dwPos;

	if ( 0 >= dwBytesLeft )						/* end of buffer */
	  return S_FALSE;
	
	dwBytesToRead = ( cb > dwBytesLeft) ? dwBytesLeft : cb;

	memmove ( pv, (This->pbBuffer) + (This->dwPos), dwBytesToRead);
	
	This->dwPos += dwBytesToRead;					/* adjust pointer */

	if (pcbRead)
	  *pcbRead = dwBytesToRead;

	return S_OK;
}
HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnRevert (IStream * iface)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnLockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG*   pstatstg, DWORD grfStatFlag)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}
HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm)
{
	ICOM_THIS(ISHRegStream, iface);

	TRACE(shell,"(%p)\n",This);

	return E_NOTIMPL;
}

static struct ICOM_VTABLE(IStream) rstvt = 
{	
	IStream_fnQueryInterface,
	IStream_fnAddRef,
	IStream_fnRelease,
	IStream_fnRead,
	IStream_fnWrite,
	IStream_fnSeek,
	IStream_fnSetSize,
	IStream_fnCopyTo,
	IStream_fnCommit,
	IStream_fnRevert,
	IStream_fnLockRegion,
	IStream_fnUnlockRegion,
	IStream_fnStat,
	IStream_fnClone
	
};

/*************************************************************************
 * OpenRegStream				[SHELL32.85]
 *
 * NOTES
 *     exported by ordinal
 */
IStream * WINAPI OpenRegStream(HKEY hkey, LPCSTR pszSubkey, LPCSTR pszValue, DWORD grfMode)
{
	TRACE(shell,"(0x%08x,%s,%s,0x%08lx)\n",hkey, pszSubkey, pszValue, grfMode);
	return IStream_Constructor(hkey, pszSubkey, pszValue, grfMode);
}
