/*
 * Regster/Unregister servers. (for internal use)
 *
 * 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 "winerror.h"
#include "winreg.h"
#include "uuids.h"

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

#include "regsvr.h"

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

const WCHAR QUARTZ_wszREG_SZ[7] =
	{'R','E','G','_','S','Z',0};
const WCHAR QUARTZ_wszInprocServer32[] =
	{'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
const WCHAR QUARTZ_wszThreadingModel[] =
	{'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
const WCHAR QUARTZ_wszBoth[] =
	{'B','o','t','h',0};
const WCHAR QUARTZ_wszCLSID[] =
	{'C','L','S','I','D',0};
const WCHAR QUARTZ_wszFilterData[] =
	{'F','i','l','t','e','r','D','a','t','a',0};
const WCHAR QUARTZ_wszFriendlyName[] =
	{'F','r','i','e','n','d','l','y','N','a','m','e',0};
const WCHAR QUARTZ_wszInstance[] =
	{'I','n','s','t','a','n','c','e',0};
const WCHAR QUARTZ_wszMerit[] =
	{'M','e','r','i','t',0};
const WCHAR QUARTZ_wszMediaType[] =
	{'M','e','d','i','a',' ','T','y','p','e',0};
const WCHAR QUARTZ_wszSubType[] =
	{'S','u','b','T','y','p','e',0};
const WCHAR QUARTZ_wszExtensions[] =
	{'E','x','t','e','n','s','i','o','n','s',0};
const WCHAR QUARTZ_wszSourceFilter[] =
	{'S','o','u','r','c','e',' ','F','i','l','t','e','r',0};

void QUARTZ_CatPathSepW( WCHAR* pBuf )
{
	int	len = lstrlenW(pBuf);
	pBuf[len] = '\\';
	pBuf[len+1] = 0;
}

void QUARTZ_GUIDtoString( WCHAR* pBuf, const GUID* pguid )
{
	/* W"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}" */
	static const WCHAR wszFmt[] =
		{'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X',
		 '-','%','0','2','X','%','0','2','X','-','%','0','2','X','%',
		 '0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
		 '%','0','2','X','}',0};

	wsprintfW( pBuf, wszFmt,
		pguid->Data1, pguid->Data2, pguid->Data3,
		pguid->Data4[0], pguid->Data4[1],
		pguid->Data4[2], pguid->Data4[3],
		pguid->Data4[4], pguid->Data4[5],
		pguid->Data4[6], pguid->Data4[7] );
}

static
LONG QUARTZ_RegOpenKeyW(
	HKEY hkRoot, LPCWSTR lpszPath,
	REGSAM rsAccess, HKEY* phKey,
	BOOL fCreateKey )
{
	DWORD	dwDisp;
	WCHAR	wszREG_SZ[ NUMELEMS(QUARTZ_wszREG_SZ) ];

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

	if ( fCreateKey )
		return RegCreateKeyExW(
			hkRoot, lpszPath, 0, wszREG_SZ,
			REG_OPTION_NON_VOLATILE, rsAccess, NULL, phKey, &dwDisp );
	else
		return RegOpenKeyExW(
			hkRoot, lpszPath, 0, rsAccess, phKey );
}

static
LONG QUARTZ_RegSetValueString(
	HKEY hKey, LPCWSTR lpszName, LPCWSTR lpValue )
{
	return RegSetValueExW(
		hKey, lpszName, 0, REG_SZ,
		(const BYTE*)lpValue,
		sizeof(lpValue[0]) * (lstrlenW(lpValue)+1) );
}

static
LONG QUARTZ_RegSetValueDWord(
	HKEY hKey, LPCWSTR lpszName, DWORD dwValue )
{
	return RegSetValueExW(
		hKey, lpszName, 0, REG_DWORD,
		(const BYTE*)(&dwValue), sizeof(DWORD) );
}

static
LONG QUARTZ_RegSetValueBinary(
	HKEY hKey, LPCWSTR lpszName,
	const BYTE* pData, int iLenOfData )
{
	return RegSetValueExW(
		hKey, lpszName, 0, REG_BINARY, pData, iLenOfData );
}

HRESULT QUARTZ_CreateCLSIDPath(
        WCHAR* pwszBuf, DWORD dwBufLen,
        const CLSID* pclsid,
        LPCWSTR lpszPathFromCLSID )
{
	int avail;

	lstrcpyW( pwszBuf, QUARTZ_wszCLSID );
	QUARTZ_CatPathSepW( pwszBuf+5 );
	QUARTZ_GUIDtoString( pwszBuf+6, pclsid );
	if ( lpszPathFromCLSID != NULL )
	{
		avail = (int)dwBufLen - lstrlenW(pwszBuf) - 8;
		if ( avail <= lstrlenW(lpszPathFromCLSID) )
			return E_FAIL;
		QUARTZ_CatPathSepW( pwszBuf );
		lstrcatW( pwszBuf, lpszPathFromCLSID );
	}

	return NOERROR;
}

HRESULT QUARTZ_OpenCLSIDKey(
	HKEY* phKey,	/* [OUT] hKey */
	REGSAM rsAccess,	/* [IN] access */
	BOOL fCreate,	/* TRUE = RegCreateKey, FALSE = RegOpenKey */
	const CLSID* pclsid,	/* CLSID */
	LPCWSTR lpszPathFromCLSID )	/* related path from CLSID */
{
	WCHAR	szKey[ 1024 ];
	HRESULT	hr;
	LONG	lr;

	hr = QUARTZ_CreateCLSIDPath(
		szKey, NUMELEMS(szKey),
		pclsid, lpszPathFromCLSID );
	if ( FAILED(hr) )
		return hr;

	lr = QUARTZ_RegOpenKeyW(
		HKEY_CLASSES_ROOT, szKey, rsAccess, phKey, fCreate );
	if ( lr != ERROR_SUCCESS )
		return E_FAIL;

	return S_OK;
}



HRESULT QUARTZ_RegisterAMovieDLLServer(
	const CLSID* pclsid,	/* [IN] CLSID */
	LPCWSTR lpFriendlyName,	/* [IN] Friendly name */
	LPCWSTR lpNameOfDLL,	/* [IN] name of the registered DLL */
	BOOL fRegister )	/* [IN] TRUE = register, FALSE = unregister */
{
	HRESULT	hr;
	HKEY	hKey;

	if ( fRegister )
	{
		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, TRUE,
			pclsid, NULL );
		if ( FAILED(hr) )
			return hr;

			if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString(
				hKey, NULL, lpFriendlyName ) != ERROR_SUCCESS )
				hr = E_FAIL;

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;

		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, TRUE,
			pclsid, QUARTZ_wszInprocServer32 );
		if ( FAILED(hr) )
			return hr;

			if ( QUARTZ_RegSetValueString(
				hKey, NULL, lpNameOfDLL ) != ERROR_SUCCESS )
				hr = E_FAIL;
			if ( QUARTZ_RegSetValueString(
				hKey, QUARTZ_wszThreadingModel,
				QUARTZ_wszBoth ) != ERROR_SUCCESS )
				hr = E_FAIL;

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;
	}
	else
	{
		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, FALSE,
			pclsid, NULL );
		if ( FAILED(hr) )
			return NOERROR;

			RegDeleteValueW( hKey, NULL );
			RegDeleteValueW( hKey, QUARTZ_wszThreadingModel );

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;

		/* I think key should be deleted only if no subkey exists. */
		FIXME( "unregister %s - key should be removed!\n",
				debugstr_guid(pclsid) );
	}

	return NOERROR;
}


HRESULT QUARTZ_RegisterCategory(
	const CLSID* pguidFilterCategory,	/* [IN] Category */
	LPCWSTR lpFriendlyName,	/* [IN] friendly name */
	DWORD dwMerit,	/* [IN] merit */
	BOOL fRegister )	/* [IN] TRUE = register, FALSE = unregister */
{
	HRESULT	hr;
	HKEY	hKey;
	WCHAR	szFilterPath[ 256 ];
	WCHAR	szCLSID[ 256 ];

	QUARTZ_GUIDtoString( szCLSID, pguidFilterCategory );
	lstrcpyW( szFilterPath, QUARTZ_wszInstance );
	QUARTZ_CatPathSepW( szFilterPath );
	lstrcatW( szFilterPath, szCLSID );

	if ( fRegister )
	{
		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, TRUE,
			&CLSID_ActiveMovieCategories, szFilterPath );
		if ( FAILED(hr) )
			return hr;

			if ( QUARTZ_RegSetValueString(
				hKey, QUARTZ_wszCLSID, szCLSID ) != ERROR_SUCCESS )
				hr = E_FAIL;
			if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString(
				hKey, QUARTZ_wszFriendlyName,
				lpFriendlyName ) != ERROR_SUCCESS )
				hr = E_FAIL;
			if ( dwMerit != 0 &&
				 QUARTZ_RegSetValueDWord(
				 	hKey, QUARTZ_wszMerit, dwMerit ) != ERROR_SUCCESS )
				hr = E_FAIL;

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;
	}
	else
	{
		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, FALSE,
			&CLSID_ActiveMovieCategories, szFilterPath );
		if ( FAILED(hr) )
			return NOERROR;

			RegDeleteValueW( hKey, QUARTZ_wszCLSID );
			RegDeleteValueW( hKey, QUARTZ_wszFriendlyName );
			RegDeleteValueW( hKey, QUARTZ_wszMerit );

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;

		/* I think key should be deleted only if no subkey exists. */
		FIXME( "unregister category %s - key should be removed!\n",
			debugstr_guid(pguidFilterCategory) );
	}

	return NOERROR;
}


HRESULT QUARTZ_RegisterAMovieFilter(
	const CLSID* pguidFilterCategory,	/* [IN] Category */
	const CLSID* pclsid,	/* [IN] CLSID of this filter */
	const BYTE* pbFilterData,	/* [IN] filter data(no spec) */
	DWORD cbFilterData,	/* [IN] size of the filter data */
	LPCWSTR lpFriendlyName,	/* [IN] friendly name */
	LPCWSTR lpInstance,	/* [IN] instance */
	BOOL fRegister )	/* [IN] TRUE = register, FALSE = unregister */
{
	HRESULT	hr;
	HKEY	hKey;
	WCHAR	szFilterPath[ 256 ];
	WCHAR	szCLSID[ 256 ];

	QUARTZ_GUIDtoString( szCLSID, pclsid );
	lstrcpyW( szFilterPath, QUARTZ_wszInstance );
	QUARTZ_CatPathSepW( szFilterPath );
	lstrcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID );

	if ( fRegister )
	{
		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, TRUE,
			pguidFilterCategory, szFilterPath );
		if ( FAILED(hr) )
			return hr;

			if ( QUARTZ_RegSetValueString(
				hKey, QUARTZ_wszCLSID, szCLSID ) != ERROR_SUCCESS )
				hr = E_FAIL;
			if ( pbFilterData != NULL && cbFilterData > 0 &&
				 QUARTZ_RegSetValueBinary(
				 	hKey, QUARTZ_wszFilterData,
				 	pbFilterData, cbFilterData ) != ERROR_SUCCESS )
				hr = E_FAIL;
			if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString(
				hKey, QUARTZ_wszFriendlyName,
				lpFriendlyName ) != ERROR_SUCCESS )
				hr = E_FAIL;

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;
	}
	else
	{
		hr = QUARTZ_OpenCLSIDKey(
			&hKey, KEY_ALL_ACCESS, FALSE,
			pguidFilterCategory, szFilterPath );
		if ( FAILED(hr) )
			return NOERROR;

			RegDeleteValueW( hKey, QUARTZ_wszCLSID );
			RegDeleteValueW( hKey, QUARTZ_wszFilterData );
			RegDeleteValueW( hKey, QUARTZ_wszFriendlyName );

		RegCloseKey( hKey );
		if ( FAILED(hr) )
			return hr;

		/* I think key should be deleted only if no subkey exists. */
		FIXME( "unregister category %s filter %s - key should be removed!\n",
			debugstr_guid(pguidFilterCategory),
			debugstr_guid(pclsid) );
	}

	return NOERROR;
}


