/*
 * Implementation of CLSID_SystemDeviceEnum.
 * Implements IMoniker for CLSID_CDeviceMoniker.
 * Implements IPropertyBag. (internal)
 *
 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
 *
 * 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
 */

#include "config.h"

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "objidl.h"
#include "oleidl.h"
#include "ocidl.h"
#include "oleauto.h"
#include "strmif.h"
#include "uuids.h"

#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);

#include "quartz_private.h"
#include "devenum.h"
#include "enumunk.h"
#include "complist.h"
#include "regsvr.h"

#ifndef NUMELEMS
#define NUMELEMS(elem)	(sizeof(elem)/sizeof(elem[0]))
#endif	/* NUMELEMS */

/***************************************************************************
 *
 *	new/delete for CLSID_SystemDeviceEnum
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry CSysDevEnum_IFEntries[] =
{
  { &IID_ICreateDevEnum, offsetof(CSysDevEnum,createdevenum)-offsetof(CSysDevEnum,unk) },
};


static void QUARTZ_DestroySystemDeviceEnum(IUnknown* punk)
{
	CSysDevEnum_THIS(punk,unk);

	CSysDevEnum_UninitICreateDevEnum( This );
}

HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj)
{
	CSysDevEnum*	psde;
	HRESULT	hr;

	TRACE("(%p,%p)\n",punkOuter,ppobj);

	psde = (CSysDevEnum*)QUARTZ_AllocObj( sizeof(CSysDevEnum) );
	if ( psde == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &psde->unk, punkOuter );

	hr = CSysDevEnum_InitICreateDevEnum( psde );
	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj( psde );
		return hr;
	}

	psde->unk.pEntries = CSysDevEnum_IFEntries;
	psde->unk.dwEntries = sizeof(CSysDevEnum_IFEntries)/sizeof(CSysDevEnum_IFEntries[0]);
	psde->unk.pOnFinalRelease = QUARTZ_DestroySystemDeviceEnum;

	*ppobj = (void*)(&psde->unk);

	return S_OK;
}


/***************************************************************************
 *
 *	CSysDevEnum::ICreateDevEnum
 *
 */


static HRESULT WINAPI
ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj)
{
	CSysDevEnum_THIS(iface,createdevenum);

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

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
ICreateDevEnum_fnAddRef(ICreateDevEnum* iface)
{
	CSysDevEnum_THIS(iface,createdevenum);

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

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
ICreateDevEnum_fnRelease(ICreateDevEnum* iface)
{
	CSysDevEnum_THIS(iface,createdevenum);

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

	return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags)
{
	CSysDevEnum_THIS(iface,createdevenum);
	HRESULT	hr;
	HKEY	hKey;
	QUARTZ_CompList*	pMonList;
	IMoniker*	pMon;
	DWORD	dwIndex;
	LONG	lr;
	WCHAR	wszPath[ 1024 ];
	DWORD	dwLen;
	DWORD	dwNameMax;
	DWORD	cbName;
	FILETIME	ftLastWrite;

	TRACE("(%p)->(%s,%p,%08lx)\n",This,
		debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
	if ( dwFlags != 0 )
	{
		FIXME("unknown flags %08lx\n",dwFlags);
		return E_NOTIMPL;
	}

	if ( ppobj == NULL )
		return E_POINTER;
	*ppobj = NULL;

	hr = QUARTZ_CreateCLSIDPath(
		wszPath, sizeof(wszPath)/sizeof(wszPath[0]) - 16,
		rclsidDeviceClass, QUARTZ_wszInstance );
	if ( FAILED(hr) )
		return hr;

	lr = RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
		0, KEY_READ, &hKey );
	if ( lr != ERROR_SUCCESS )
	{
		TRACE("cannot open %s\n",debugstr_w(wszPath));
		if ( lr == ERROR_FILE_NOT_FOUND ||
			 lr == ERROR_PATH_NOT_FOUND )
			return S_FALSE;
		return E_FAIL;
	}

	dwLen = lstrlenW(wszPath);
	wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
	dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;

	pMonList = QUARTZ_CompList_Alloc();
	if ( pMonList == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}

	/* enumerate all subkeys. */
	dwIndex = 0;
	while ( 1 )
	{
		cbName = dwNameMax;
		lr = RegEnumKeyExW(
			hKey, dwIndex, &wszPath[dwLen], &cbName,
			NULL, NULL, NULL, &ftLastWrite );
		if ( lr == ERROR_NO_MORE_ITEMS )
			break;
		if ( lr != ERROR_SUCCESS )
		{
			TRACE("RegEnumKeyEx returns %08lx\n",lr);
			hr = E_FAIL;
			goto err;
		}

		hr = QUARTZ_CreateDeviceMoniker(
			HKEY_CLASSES_ROOT, wszPath, &pMon );
		if ( FAILED(hr) )
			goto err;

		hr = QUARTZ_CompList_AddComp(
			pMonList, (IUnknown*)pMon, NULL, 0 );
		IMoniker_Release( pMon );

		if ( FAILED(hr) )
			goto err;

		dwIndex ++;
	}

	/* create an enumerator. */
	hr = QUARTZ_CreateEnumUnknown(
		&IID_IEnumMoniker, (void**)ppobj, pMonList );
	if ( FAILED(hr) )
		goto err;

	hr = S_OK;
err:
	if ( pMonList != NULL )
		QUARTZ_CompList_Free( pMonList );
	RegCloseKey( hKey );

	return hr;
}

static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	ICreateDevEnum_fnQueryInterface,
	ICreateDevEnum_fnAddRef,
	ICreateDevEnum_fnRelease,
	/* ICreateDevEnum fields */
	ICreateDevEnum_fnCreateClassEnumerator,
};

HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
{
	TRACE("(%p)\n",psde);
	ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;

	return NOERROR;
}

void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
{
	TRACE("(%p)\n",psde);
}


/***************************************************************************
 *
 *	CDeviceMoniker::IMoniker
 *
 */

static HRESULT WINAPI
IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj)
{
	CDeviceMoniker_THIS(iface,moniker);

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

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IMoniker_fnAddRef(IMoniker* iface)
{
	CDeviceMoniker_THIS(iface,moniker);

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

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IMoniker_fnRelease(IMoniker* iface)
{
	CDeviceMoniker_THIS(iface,moniker);

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

	return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI IMoniker_fnGetClassID(IMoniker* iface, CLSID *pClassID)
{
	CDeviceMoniker_THIS(iface,moniker);

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

	if ( pClassID == NULL )
		return E_POINTER;
	memcpy( pClassID, &CLSID_CDeviceMoniker, sizeof(CLSID) );

	return NOERROR;
}

static HRESULT WINAPI IMoniker_fnIsDirty(IMoniker* iface)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnLoad(IMoniker* iface, IStream* pStm)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnSave(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnGetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnBindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
{
	CDeviceMoniker_THIS(iface,moniker);
	HRESULT	hr;
	IPropertyBag*	pPropBag;
	IPersistPropertyBag*	pPersistPropBag;
	VARIANT	vClsid;
	CLSID	clsid;

	TRACE("(%p)->(%p,%p,%s,%p)\n",This,
		pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
	if ( pbc != NULL )
	{
		FIXME("IBindCtx* pbc != NULL not implemented.\n");
		return E_FAIL;
	}
	if ( pmkToLeft != NULL )
	{
		FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
		return E_FAIL;
	}
	if ( ppvResult == NULL )
		return E_POINTER;

	hr = QUARTZ_CreateRegPropertyBag(
			This->m_hkRoot, This->m_pwszPath, &pPropBag );
	if ( FAILED(hr) )
		return hr;

	vClsid.n1.n2.vt = VT_BSTR;
	hr = IPropertyBag_Read(
			pPropBag, QUARTZ_wszCLSID, &vClsid, NULL );
	IPropertyBag_Release( pPropBag );
	if ( FAILED(hr) )
		return hr;

	hr = CLSIDFromString( vClsid.n1.n2.n3.bstrVal, &clsid );
	SysFreeString(vClsid.n1.n2.n3.bstrVal);
	if ( FAILED(hr) )
		return hr;

	hr = CoCreateInstance(
		&clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult );
	if ( FAILED(hr) )
		return hr;

	hr = IUnknown_QueryInterface((IUnknown*)*ppvResult,&IID_IPersistPropertyBag,(void**)&pPersistPropBag);
	if ( hr == E_NOINTERFACE )
	{
		hr = S_OK;
	}
	else
	if ( SUCCEEDED(hr) )
	{
		hr = QUARTZ_CreateRegPropertyBag(
				This->m_hkRoot, This->m_pwszPath, &pPropBag );
		if ( SUCCEEDED(hr) )
		{
			hr = IPersistPropertyBag_Load(pPersistPropBag,pPropBag,NULL);
			IPropertyBag_Release( pPropBag );
		}
		IPersistPropertyBag_Release(pPersistPropBag);
	}

	if ( FAILED(hr) )
	{
		IUnknown_Release((IUnknown*)*ppvResult);
		*ppvResult = NULL;
	}

	TRACE( "hr = %08lx\n", hr );

	return hr;
}

static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
{
	CDeviceMoniker_THIS(iface,moniker);
	HRESULT	hr;

	TRACE("(%p)->(%p,%p,%s,%p)\n",This,
		pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
	if ( pbc != NULL )
	{
		FIXME("IBindCtx* pbc != NULL not implemented.\n");
		return E_FAIL;
	}
	if ( pmkToLeft != NULL )
	{
		FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
		return E_FAIL;
	}
	if ( ppvResult == NULL )
		return E_POINTER;

	hr = E_NOINTERFACE;
	if ( IsEqualGUID(riid,&IID_IUnknown) ||
		 IsEqualGUID(riid,&IID_IPropertyBag) )
	{
		hr = QUARTZ_CreateRegPropertyBag(
			This->m_hkRoot, This->m_pwszPath,
			(IPropertyBag**)ppvResult );
	}

	return hr;
}

static HRESULT WINAPI IMoniker_fnReduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
	CDeviceMoniker_THIS(iface,moniker);

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

	if ( ppmkReduced == NULL )
		return E_POINTER;

	*ppmkReduced = iface; IMoniker_AddRef(iface);

	return MK_S_REDUCED_TO_SELF;
}

static HRESULT WINAPI IMoniker_fnComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnEnum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
	CDeviceMoniker_THIS(iface,moniker);

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

	if ( ppenumMoniker == NULL )
		return E_POINTER;

	*ppenumMoniker = NULL;
	return NOERROR;
}

static HRESULT WINAPI IMoniker_fnIsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnHash(IMoniker* iface,DWORD* pdwHash)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnIsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnGetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnInverse(IMoniker* iface,IMoniker** ppmk)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnCommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnRelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnGetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
{
	CDeviceMoniker_THIS(iface,moniker);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IMoniker_fnIsSystemMoniker(IMoniker* iface,DWORD* pdwMksys)
{
	CDeviceMoniker_THIS(iface,moniker);

	TRACE("(%p)->()\n",This);
	if ( pdwMksys == NULL )
		return E_POINTER;

	*pdwMksys = MKSYS_NONE;
	return S_FALSE;
}


static ICOM_VTABLE(IMoniker) imoniker =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IMoniker_fnQueryInterface,
	IMoniker_fnAddRef,
	IMoniker_fnRelease,
	/* IPersist fields */
	IMoniker_fnGetClassID,
	/* IPersistStream fields */
	IMoniker_fnIsDirty,
	IMoniker_fnLoad,
	IMoniker_fnSave,
	IMoniker_fnGetSizeMax,
	/* IMoniker fields */
	IMoniker_fnBindToObject,
	IMoniker_fnBindToStorage,
	IMoniker_fnReduce,
	IMoniker_fnComposeWith,
	IMoniker_fnEnum,
	IMoniker_fnIsEqual,
	IMoniker_fnHash,
	IMoniker_fnIsRunning,
	IMoniker_fnGetTimeOfLastChange,
	IMoniker_fnInverse,
	IMoniker_fnCommonPrefixWith,
	IMoniker_fnRelativePathTo,
	IMoniker_fnGetDisplayName,
	IMoniker_fnParseDisplayName,
	IMoniker_fnIsSystemMoniker,
};


static HRESULT CDeviceMoniker_InitIMoniker(
	CDeviceMoniker* pdm, HKEY hkRoot, LPCWSTR lpKeyPath )
{
	DWORD	dwLen;

	ICOM_VTBL(&pdm->moniker) = &imoniker;
	pdm->m_hkRoot = hkRoot;
	pdm->m_pwszPath = NULL;

	dwLen = sizeof(WCHAR)*(lstrlenW(lpKeyPath)+1);
	pdm->m_pwszPath = (WCHAR*)QUARTZ_AllocMem( dwLen );
	if ( pdm->m_pwszPath == NULL )
		return E_OUTOFMEMORY;
	memcpy( pdm->m_pwszPath, lpKeyPath, dwLen );

	return NOERROR;
}

static void CDeviceMoniker_UninitIMoniker(
	CDeviceMoniker* pdm )
{
	if ( pdm->m_pwszPath != NULL )
		QUARTZ_FreeMem( pdm->m_pwszPath );
}

/***************************************************************************
 *
 *	new/delete for CDeviceMoniker
 *
 */

static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk)
{
	CDeviceMoniker_THIS(punk,unk);

	CDeviceMoniker_UninitIMoniker( This );
}

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry CDeviceMoniker_IFEntries[] =
{
  { &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
  { &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
  { &IID_IMoniker, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
};

HRESULT QUARTZ_CreateDeviceMoniker(
	HKEY hkRoot, LPCWSTR lpKeyPath,
	IMoniker** ppMoniker )
{
	CDeviceMoniker*	pdm;
	HRESULT	hr;

	TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppMoniker );

	pdm = (CDeviceMoniker*)QUARTZ_AllocObj( sizeof(CDeviceMoniker) );
	if ( pdm == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &pdm->unk, NULL );
	hr = CDeviceMoniker_InitIMoniker( pdm, hkRoot, lpKeyPath );
	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj( pdm );
		return hr;
	}

	pdm->unk.pEntries = CDeviceMoniker_IFEntries;
	pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]);
	pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker;

	*ppMoniker = (IMoniker*)(&pdm->moniker);

	return S_OK;
}


/***************************************************************************
 *
 *	CRegPropertyBag::IPropertyBag
 *
 */

static HRESULT WINAPI
IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj)
{
	CRegPropertyBag_THIS(iface,propbag);

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

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IPropertyBag_fnAddRef(IPropertyBag* iface)
{
	CRegPropertyBag_THIS(iface,propbag);

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

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IPropertyBag_fnRelease(IPropertyBag* iface)
{
	CRegPropertyBag_THIS(iface,propbag);

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

	return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog)
{
	CRegPropertyBag_THIS(iface,propbag);
	HRESULT hr;
	LONG	lr;
	DWORD	dwSize;
	DWORD	dwValueType;
	DWORD	dwDWordValue;
	SAFEARRAYBOUND	sab;
	SAFEARRAY*	pArray;

	TRACE("(%p)->(%s,%p,%p)\n",This,
		debugstr_w(lpszPropName),pVar,pLog);

	if ( lpszPropName == NULL || pVar == NULL )
		return E_POINTER;

	dwSize = 0;
	lr = RegQueryValueExW(
		This->m_hKey, lpszPropName, NULL,
		&dwValueType, NULL, &dwSize );
	if ( lr != ERROR_SUCCESS )
	{
		WARN( "RegQueryValueExW failed.\n" );
		return E_INVALIDARG;
	}

	switch ( dwValueType )
	{
	case REG_SZ:
		TRACE( "REG_SZ / length = %lu\n", dwSize );
		if ( pVar->n1.n2.vt == VT_EMPTY )
			pVar->n1.n2.vt = VT_BSTR;
		if ( pVar->n1.n2.vt != VT_BSTR )
		{
			FIXME( "type of VARIANT is not BSTR.\n" );
			return E_FAIL;
		}

		pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen(
			NULL, dwSize );
		if ( pVar->n1.n2.n3.bstrVal == NULL )
		{
			WARN( "out of memory.\n" );
			return E_OUTOFMEMORY;
		}
		lr = RegQueryValueExW(
			This->m_hKey, lpszPropName, NULL,
			&dwValueType,
			(BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize );
		if ( lr != ERROR_SUCCESS )
		{
			WARN( "failed to query value\n" );
			SysFreeString(pVar->n1.n2.n3.bstrVal);
			return E_FAIL;
		}
		TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) );
		break;
	case REG_BINARY:
		TRACE( "REG_BINARY / length = %lu\n", dwSize );
		if ( pVar->n1.n2.vt == VT_EMPTY )
			pVar->n1.n2.vt = VT_ARRAY|VT_UI1;
		if ( pVar->n1.n2.vt != (VT_ARRAY|VT_UI1) )
		{
			FIXME( "type of VARIANT is not VT_ARRAY|VT_UI1.\n" );
			return E_FAIL;
		}
		sab.lLbound = 0;
		sab.cElements = dwSize;
		pArray = SafeArrayCreate( VT_UI1, 1, &sab );
		if ( pArray == NULL )
			return E_OUTOFMEMORY;
		hr = SafeArrayLock( pArray );
		if ( FAILED(hr) )
		{
			WARN( "safe array can't be locked\n" );
			SafeArrayDestroy( pArray );
			return hr;
		}
		lr = RegQueryValueExW(
			This->m_hKey, lpszPropName, NULL,
			&dwValueType,
			(BYTE*)pArray->pvData, &dwSize );
		SafeArrayUnlock( pArray );
		if ( lr != ERROR_SUCCESS )
		{
			WARN( "failed to query value\n" );
			SafeArrayDestroy( pArray );
			return E_FAIL;
		}
		pVar->n1.n2.n3.parray = pArray;
		TRACE( "value is SAFEARRAY - array of BYTE; \n" );
		break;
	case REG_DWORD:
		TRACE( "REG_DWORD / length = %lu\n", dwSize );
		if ( dwSize != sizeof(DWORD) )
		{
			WARN( "The length of REG_DWORD value is not sizeof(DWORD).\n" );
			return E_FAIL;
		}
		if ( pVar->n1.n2.vt == VT_EMPTY )
			pVar->n1.n2.vt = VT_I4;
		if ( pVar->n1.n2.vt != VT_I4 )
		{
			FIXME( "type of VARIANT is not VT_I4.\n" );
			return E_FAIL;
		}
		lr = RegQueryValueExW(
			This->m_hKey, lpszPropName, NULL,
			&dwValueType,
			(BYTE*)(&dwDWordValue), &dwSize );
		if ( lr != ERROR_SUCCESS )
		{
			WARN( "failed to query value\n" );
			return E_FAIL;
		}
		pVar->n1.n2.n3.lVal = dwDWordValue;
		TRACE( "value is DWORD; %08lx\n", dwDWordValue );
		break;
	default:
		FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This,
			debugstr_w(lpszPropName),pVar,pLog);
		return E_FAIL;
	}

	TRACE( "returned successfully.\n" );
	return NOERROR;
}

static HRESULT WINAPI
IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar)
{
	CRegPropertyBag_THIS(iface,propbag);
	HRESULT hr;
	LONG	lr;
	DWORD	dwDWordValue;
	SAFEARRAY*	pArray;

	TRACE("(%p)->(%s,%p)\n",This,
		debugstr_w(lpszPropName),pVar);

	if ( lpszPropName == NULL || pVar == NULL )
		return E_POINTER;

	switch ( pVar->n1.n2.vt )
	{
	case VT_I4: /* REG_DWORD */
		dwDWordValue = pVar->n1.n2.n3.lVal;
		lr = RegSetValueExW(
			This->m_hKey, lpszPropName, 0,
			REG_DWORD,
			(const BYTE*)(&dwDWordValue), sizeof(DWORD) );
		if ( lr != ERROR_SUCCESS )
		{
			WARN( "failed to set value\n" );
			return E_FAIL;
		}
		break;
	case VT_BSTR: /* REG_SZ */
		lr = RegSetValueExW(
			This->m_hKey, lpszPropName, 0,
			REG_SZ,
			(const BYTE*)(pVar->n1.n2.n3.bstrVal),
			SysStringByteLen( pVar->n1.n2.n3.bstrVal ) );
		if ( lr != ERROR_SUCCESS )
		{
			WARN( "failed to set value\n" );
			return E_FAIL;
		}
		break;
	case (VT_ARRAY|VT_UI1): /* REG_BINARY */
		pArray = pVar->n1.n2.n3.parray;
		if ( pArray->cDims != 1 || pArray->cbElements != 1 ||
			 pArray->rgsabound[0].lLbound != 0 )
		{
			WARN( "invalid array\n" );
			return E_INVALIDARG;
		}
		hr = SafeArrayLock( pArray );
		if ( FAILED(hr) )
		{
			WARN( "safe array can't be locked\n" );
			return hr;
		}
		lr = RegSetValueExW(
			This->m_hKey, lpszPropName, 0,
			REG_BINARY,
			(const BYTE*)pArray->pvData,
			pArray->rgsabound[0].cElements );
		SafeArrayUnlock( pArray );
		if ( lr != ERROR_SUCCESS )
		{
			WARN( "failed to set value\n" );
			return E_FAIL;
		}
		break;
	default:
		FIXME("(%p)->(%s,%p) invalid/unsupported VARIANT type %04x\n",This,
			debugstr_w(lpszPropName),pVar,pVar->n1.n2.vt);
		return E_INVALIDARG;
	}

	TRACE( "returned successfully.\n" );
	return NOERROR;
}




static ICOM_VTABLE(IPropertyBag) ipropbag =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IPropertyBag_fnQueryInterface,
	IPropertyBag_fnAddRef,
	IPropertyBag_fnRelease,
	/* IPropertyBag fields */
	IPropertyBag_fnRead,
	IPropertyBag_fnWrite,
};

static HRESULT CRegPropertyBag_InitIPropertyBag(
	CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath )
{
	WCHAR	wszREG_SZ[ NUMELEMS(QUARTZ_wszREG_SZ) ];
	DWORD	dwDisp;

	ICOM_VTBL(&prpb->propbag) = &ipropbag;

	memcpy(wszREG_SZ,QUARTZ_wszREG_SZ,sizeof(QUARTZ_wszREG_SZ) );

	if ( RegCreateKeyExW(
			hkRoot, lpKeyPath, 0, wszREG_SZ,
			REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
			&prpb->m_hKey, &dwDisp ) != ERROR_SUCCESS )
		return E_FAIL;

	return NOERROR;
}

static void CRegPropertyBag_UninitIPropertyBag(
	CRegPropertyBag* prpb )
{
	RegCloseKey( prpb->m_hKey );
}


/***************************************************************************
 *
 *	new/delete for CRegPropertyBag
 *
 */

static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk)
{
	CRegPropertyBag_THIS(punk,unk);

	CRegPropertyBag_UninitIPropertyBag(This);
}


/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry CRegPropertyBag_IFEntries[] =
{
  { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) },
};

HRESULT QUARTZ_CreateRegPropertyBag(
	HKEY hkRoot, LPCWSTR lpKeyPath,
	IPropertyBag** ppPropBag )
{
	CRegPropertyBag*	prpb;
	HRESULT	hr;

	TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag );

	prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) );
	if ( prpb == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &prpb->unk, NULL );
	hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath );
	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj( prpb );
		return hr;
	}

	prpb->unk.pEntries = CRegPropertyBag_IFEntries;
	prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]);
	prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag;

	*ppPropBag = (IPropertyBag*)(&prpb->propbag);

	return S_OK;
}

/***************************************************************************
 *
 *	Helper for registering filters.
 *
 */

HRESULT QUARTZ_GetFilterRegPath(
	WCHAR** ppwszPath,	/* [OUT] path from HKEY_CLASSES_ROOT */
	const CLSID* pguidFilterCategory,	/* [IN] Category */
	const CLSID* pclsid,	/* [IN] CLSID of this filter */
	LPCWSTR lpInstance )	/* [IN] instance */
{
	HRESULT	hr;
	WCHAR	szKey[ 1024 ];
	WCHAR	szFilterPath[ 512 ];
	WCHAR	szCLSID[ 256 ];
	int	buflen;

	TRACE("(%p,%s,%s,%s)\n",ppwszPath,debugstr_guid(pguidFilterCategory),debugstr_guid(pclsid),debugstr_w(lpInstance) );

	*ppwszPath = NULL;

	QUARTZ_GUIDtoString( szCLSID, pclsid );
	lstrcpyW( szFilterPath, QUARTZ_wszInstance );
	QUARTZ_CatPathSepW( szFilterPath );
	if ( lpInstance != NULL )
	{
		if ( lstrlenW(lpInstance) >= 256 )
			return E_INVALIDARG;
		lstrcatW( szFilterPath, lpInstance );
	}
	else
	{
		lstrcatW( szFilterPath, szCLSID );
	}

	hr = QUARTZ_CreateCLSIDPath(
		szKey, NUMELEMS(szKey),
		pguidFilterCategory, szFilterPath );
	if ( FAILED(hr) )
		return hr;

	buflen = sizeof(WCHAR)*(lstrlenW(szKey)+1);
	*ppwszPath = QUARTZ_AllocMem( buflen );
	if ( *ppwszPath == NULL )
		return E_OUTOFMEMORY;
	memcpy( *ppwszPath, szKey, buflen );
	return S_OK;
}

HRESULT QUARTZ_RegisterFilterToMoniker(
	IMoniker* pMoniker,	/* [IN] Moniker */
	const CLSID* pclsid,	/* [IN] CLSID of this filter */
	LPCWSTR lpFriendlyName,	/* [IN] friendly name */
	const BYTE* pbFilterData,	/* [IN] filter data */
	DWORD cbFilterData )	/* [IN] size of the filter data */
{
	IPropertyBag*	pPropBag = NULL;
	WCHAR	wszClsid[128];
	VARIANT var;
	HRESULT hr;
	SAFEARRAYBOUND	sab;
	SAFEARRAY*	pArray = NULL;

	TRACE("(%p,%s,%s,%p,%08lu)\n",pMoniker,debugstr_guid(pclsid),debugstr_w(lpFriendlyName),pbFilterData,cbFilterData);

	hr = IMoniker_BindToStorage(pMoniker,NULL,NULL,&IID_IPropertyBag,(void**)&pPropBag);
	if ( FAILED(hr) )
		goto err;
	QUARTZ_GUIDtoString( wszClsid, pclsid );
	var.n1.n2.vt = VT_BSTR;
	var.n1.n2.n3.bstrVal = SysAllocString(wszClsid);
	if ( var.n1.n2.n3.bstrVal == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}
	hr = IPropertyBag_Write(pPropBag,QUARTZ_wszCLSID,&var);
	SysFreeString(var.n1.n2.n3.bstrVal);
	if ( FAILED(hr) )
		goto err;

	var.n1.n2.vt = VT_BSTR;
	var.n1.n2.n3.bstrVal = SysAllocString(lpFriendlyName);
	if ( var.n1.n2.n3.bstrVal == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}
	hr = IPropertyBag_Write(pPropBag,QUARTZ_wszFriendlyName,&var);
	SysFreeString(var.n1.n2.n3.bstrVal);
	if ( FAILED(hr) )
		goto err;

	if ( pbFilterData != NULL )
	{
		var.n1.n2.vt = VT_ARRAY|VT_UI1;
		sab.lLbound = 0;
		sab.cElements = cbFilterData;
		pArray = SafeArrayCreate( VT_UI1, 1, &sab );
		if ( pArray == NULL )
		{
			hr = E_OUTOFMEMORY;
			goto err;
		}
		hr = SafeArrayLock( pArray );
		if ( FAILED(hr) )
			goto err;
		var.n1.n2.n3.parray = pArray;
		memcpy( pArray->pvData, pbFilterData, cbFilterData );
		hr = IPropertyBag_Write(pPropBag,QUARTZ_wszFilterData,&var);
		SafeArrayUnlock( pArray );
		if ( FAILED(hr) )
			goto err;
	}

	hr = NOERROR;
err:
	if ( pArray != NULL )
		SafeArrayDestroy( pArray );
	if ( pPropBag != NULL )
		IPropertyBag_Release(pPropBag);

	return hr;
}

HRESULT QUARTZ_RegDeleteKey( HKEY hkRoot, LPCWSTR lpKeyPath )
{
	LONG	lr;
	HRESULT hr;
	HKEY	hKey;
	DWORD	dwIndex;
	DWORD	cbName;
	FILETIME	ftLastWrite;
	DWORD	dwType;
	WCHAR	wszPath[ 512 ];

	TRACE("(%08x,%s)\n",hkRoot,debugstr_w(lpKeyPath));

	lr = RegOpenKeyExW( hkRoot, lpKeyPath, 0, KEY_ALL_ACCESS, &hKey );
	if ( lr == ERROR_SUCCESS )
	{
		dwIndex = 0;
		while ( 1 )
		{
			cbName = NUMELEMS(wszPath);
			lr = RegEnumKeyExW(
				hKey, dwIndex, wszPath, &cbName,
				NULL, NULL, NULL, &ftLastWrite );
			if ( lr != ERROR_SUCCESS )
				break;
			hr = QUARTZ_RegDeleteKey( hKey, wszPath );
			if ( FAILED(hr) )
				return hr;
			if ( hr != S_OK )
				dwIndex ++;
		}
		while ( 1 )
		{
			cbName = NUMELEMS(wszPath);
			lr = RegEnumValueW(
				hKey, 0, wszPath, &cbName, 0,
				&dwType, NULL, 0 );
			if ( lr != ERROR_SUCCESS )
				break;
			lr = RegDeleteValueW( hKey, wszPath );
			if ( lr != ERROR_SUCCESS )
			{
				WARN("RegDeleteValueW - %08lx\n",lr);
				return E_FAIL;
			}
		}
	}
	RegCloseKey( hKey );

	lr = RegDeleteKeyW( hkRoot, lpKeyPath );
	WARN("RegDeleteKeyW - %08lx\n",lr);
	if ( lr != ERROR_SUCCESS && lr != ERROR_FILE_NOT_FOUND )
		return S_FALSE;
	return S_OK;
}

static
HRESULT QUARTZ_GetPropertyFromMoniker(
	IMoniker* pMoniker,	/* [IN] Moniker */
	LPCOLESTR lpszPropName,	/* [IN] Property */
	VARIANT* pVar )	/* [OUT] */
{
	IPropertyBag*	pPropBag = NULL;
	HRESULT hr;

	TRACE("(%p,%s,%p)\n",pMoniker,debugstr_w(lpszPropName),pVar);

	hr = IMoniker_BindToStorage(pMoniker,NULL,NULL,&IID_IPropertyBag,(void**)&pPropBag);
	if ( FAILED(hr) )
		return hr;
	hr = IPropertyBag_Read(pPropBag,lpszPropName,pVar,NULL);
	IPropertyBag_Release(pPropBag);

	return hr;
}

HRESULT QUARTZ_GetCLSIDFromMoniker(
	IMoniker* pMoniker,	/* [IN] Moniker */
	CLSID* pclsid )	/* [OUT] */
{
	VARIANT	var;
	HRESULT hr;

	var.n1.n2.vt = VT_BSTR;
	hr = QUARTZ_GetPropertyFromMoniker(
		pMoniker, QUARTZ_wszCLSID, &var );
	if ( hr == S_OK )
	{
		hr = CLSIDFromString(var.n1.n2.n3.bstrVal,pclsid);
		SysFreeString(var.n1.n2.n3.bstrVal);
	}

	return hr;
}

HRESULT QUARTZ_GetMeritFromMoniker(
	IMoniker* pMoniker,	/* [IN] Moniker */
	DWORD* pdwMerit )	/* [OUT] */
{
	VARIANT	var;
	HRESULT hr;

	var.n1.n2.vt = VT_I4;
	hr = QUARTZ_GetPropertyFromMoniker(
		pMoniker, QUARTZ_wszMerit, &var );
	if ( hr == S_OK )
		*pdwMerit = var.n1.n2.n3.lVal;

	return hr;
}

HRESULT QUARTZ_GetFilterDataFromMoniker(
	IMoniker* pMoniker,	/* [IN] Moniker */
	BYTE** ppbFilterData,	/* [OUT] */
	DWORD* pcbFilterData )	/* [OUT] */
{
	VARIANT	var;
	HRESULT hr;
	SAFEARRAY*	pArray;

	var.n1.n2.vt = VT_ARRAY|VT_UI1;
	hr = QUARTZ_GetPropertyFromMoniker(
		pMoniker, QUARTZ_wszFilterData, &var );
	if ( hr == S_OK )
	{
		pArray = var.n1.n2.n3.parray;
		hr = SafeArrayLock( pArray );
		if ( SUCCEEDED(hr) )
		{
			*pcbFilterData = pArray->rgsabound[0].cElements - pArray->rgsabound[0].lLbound;
			*ppbFilterData = (BYTE*)QUARTZ_AllocMem( *pcbFilterData );
			if ( *ppbFilterData == NULL )
				hr = E_OUTOFMEMORY;
			else
				memcpy( *ppbFilterData, pArray->pvData, *pcbFilterData );

			SafeArrayUnlock( pArray );
		}
		SafeArrayDestroy( pArray );
	}

	return hr;
}

