/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/


#include "stdafx.h"

#include "XMergeFilter.h"
#include "XMergeFactory.h"


CXMergeSyncModule _Module;


//////////////////////////////////////////////////////////////////////
// DLL Functions
//////////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain(HANDLE hInst, ULONG ulReason, LPVOID lpReserved)
{
	switch (ulReason)
	{
		case DLL_PROCESS_ATTACH:
			_Module.m_hInst = reinterpret_cast<HINSTANCE>(hInst);
			break;

		case DLL_PROCESS_DETACH:
			_Module.m_hInst = NULL;
			break;

		case DLL_THREAD_ATTACH:
			break;

		case DLL_THREAD_DETACH:
			break;
	}

	return TRUE;
}


STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
	// Create the factory object
	CXMergeFactory *pFactory = new CXMergeFactory();
	if (pFactory == NULL)
	{
		*ppv = NULL;
		return E_OUTOFMEMORY;
	}

	HRESULT hr = pFactory->QueryInterface(riid, ppv);
	pFactory->Release();

	return hr;
}


STDAPI DllCanUnloadNow()
{
	if (_Module.GetLockCount() == 0)
		return S_OK;

	return S_FALSE;
}


// Utility function to close open keys during registration
static _signalRegError(long lRet, HKEY hKey, HKEY hDataKey)
{
	if (hKey)
		::RegCloseKey(hKey);


	if (hDataKey)
		::RegCloseKey(hDataKey);

	return HRESULT_FROM_WIN32(lRet);
}


STDAPI DllRegisterServer()
{
	HKEY hKey = NULL;
	HKEY hDataKey = NULL;

	long lRet = 0;
	TCHAR sTemp[_MAX_PATH + 1] = "\0";


	/*
	 * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Writer export filter.
	 *
	 * Note that import are export are relative to the WinCE device, so files are
	 * exported to the desktop format.
	 */

	// Get a handle to the CLSID key
	lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Create the CLSID key for the XMergeFilter
	lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPSWExportCLSID, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWExportShortDesc,
				(::_tcslen(CXMergeFilter::m_pszPSWExportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
	lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
							(::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
							   * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);  hDataKey = NULL;

	// Create the InprocServer32 key
	lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Create the key for the DLL file.  First find the filename of the dll
	if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
	{
		lRet = ::GetLastError();
		if (lRet != ERROR_SUCCESS)
			return _signalRegError(lRet, hKey, hDataKey);
	}


	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
				(::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Setup the PegasusFilter key values
	lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWExportDesc,
				(::_tcslen(CXMergeFilter::m_pszPSWExportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("Export"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWExportExt,
				(::_tcslen(CXMergeFilter::m_pszPSWExportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;




	/*
	 * Following calls create the entries for the filter in
	 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
	 */

	lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
				0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	_snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPSWImportExt);
	lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
				0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPSWExportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;



	/*
	 * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Writer import filter.
	 *
	 * Note that import are export are relative to the WinCE device, so files are
	 * exported to the desktop format.
	 */
	// Get a handle to the CLSID key
	lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Create the CLSID key for the XMergeFilter
	lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPSWImportCLSID, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWImportShortDesc,
				(::_tcslen(CXMergeFilter::m_pszPSWImportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
	lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
							(::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
							   * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);  hDataKey = NULL;


	// Create the InprocServer32 key
	lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the key for the DLL file.  First find the filename of the dll
	if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
	{
		lRet = ::GetLastError();
		if (lRet != ERROR_SUCCESS)
			return _signalRegError(lRet, hKey, hDataKey);
	}


	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
				(::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Setup the PegasusFilter key values
	lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

		lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWImportDesc,
				(::_tcslen(CXMergeFilter::m_pszPSWImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("Import"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWImportExt,
				(::_tcslen(CXMergeFilter::m_pszPSWImportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	/*
	 * Following calls create the entries for the filter in
	 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
	 */
	lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
				0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Add in defaults for import and export
	_snprintf(sTemp, _MAX_PATH +1, "%c%s\0", '.', CXMergeFilter::m_pszPSWExportExt);
	lRet = ::RegCreateKeyEx(hKey, _T(sTemp), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ,
							(LPBYTE)CXMergeFilter::m_pszPSWImportCLSID,
							(::_tcslen(CXMergeFilter::m_pszPSWImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("DefaultExport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
							(::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hDataKey);

	// Update registered filters
	_snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPSWExportExt);
	lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
				0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPSWImportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;



	/*
	 * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Calc export filter.
	 *
	 * Note that import are export are relative to the WinCE device, so files are
	 * exported to the desktop format.
	 */

	// Get a handle to the CLSID key
	lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Create the CLSID key for the XMerge Filter
	lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPXLExportCLSID, 0, _T(""),
								0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLExportShortDesc,
				(::_tcslen(CXMergeFilter::m_pszPXLExportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
	lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
							(::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
							   * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);  hDataKey = NULL;


	// Create the InprocServer32 key
	lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the key for the DLL file.  First find the filename of the dll
	if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
	{
		lRet = ::GetLastError();
		if (lRet != ERROR_SUCCESS)
			return _signalRegError(lRet, hKey, hDataKey);
	}


	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
				(::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Setup the PegasusFilter key values
	lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

		lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLExportDesc,
				(::_tcslen(CXMergeFilter::m_pszPXLExportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("Export"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLExportExt,
				(::_tcslen(CXMergeFilter::m_pszPXLExportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;




	/*
	 * Following calls create the entries for the filter in
	 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
	 */

	lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
				0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	_snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPXLImportExt);
	lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
				0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPXLExportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;



	/*
	 * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Calc import filter.
	 *
	 * Note that import are export are relative to the WinCE device, so files are
	 * exported to the desktop format.
	 */
	// Get a handle to the CLSID key
	lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the CLSID key for the XMergeFilter
	lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPXLImportCLSID, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLImportShortDesc,
				(::_tcslen(CXMergeFilter::m_pszPXLImportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
	lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
							(::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
							   * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);  hDataKey = NULL;


	// Create the InprocServer32 key
	lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Create the key for the DLL file.  First find the filename of the dll
	if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
	{
		lRet = ::GetLastError();
		if (lRet != ERROR_SUCCESS)
			return _signalRegError(lRet, hKey, hDataKey);
	}


	lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
				(::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Setup the PegasusFilter key values
	lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

		lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLImportDesc,
				(::_tcslen(CXMergeFilter::m_pszPXLImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("Import"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLImportExt,
				(::_tcslen(CXMergeFilter::m_pszPXLImportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;



	/*
	 * Following calls create the entries for the filter in
	 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
	 */
	lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
				0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	// Add in defaults for import and export
	_snprintf(sTemp, _MAX_PATH +1, "%c%s\0", '.', CXMergeFilter::m_pszPXLExportExt);
	lRet = ::RegCreateKeyEx(hKey, _T(sTemp), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ,
							(LPBYTE)CXMergeFilter::m_pszPXLImportCLSID,
							(::_tcslen(CXMergeFilter::m_pszPSWImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	lRet = ::RegSetValueEx(hDataKey, _T("DefaultExport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
							(::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hDataKey);

	// Update registered filters


	_snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPXLExportExt);
	lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
				0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPXLImportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hKey);		hKey = NULL;
	::RegCloseKey(hDataKey);	hDataKey = NULL;



	return HRESULT_FROM_WIN32(lRet);
}


STDAPI DllUnregisterServer()
{
	long lRet = 0;
	HKEY hKey = NULL;
	HKEY hDataKey = NULL;

	TCHAR szClassName[_MAX_PATH] = "\0";
	TCHAR szKeyName[_MAX_PATH]   = "\0";
	DWORD dwClassName            = _MAX_PATH;
	DWORD dwKeyName              = _MAX_PATH;

	/*
	 * Remove HKEY_CLASS_ROOT\CLSID\{XXX} entry for the export and import filters
	 *
	 * Windows 95/98/Me allow one step deletion of a key and all subkeys.
	 * Windows NT/2000/XP do not so the subkeys must be deleted individually.
	 */
	lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// First up, the Writer export filter
	lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPSWExportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
				!= ERROR_NO_MORE_ITEMS)
	{
		lRet = ::RegDeleteKey(hDataKey, szKeyName);

		::lstrcpy(szKeyName, "\0");
		::lstrcpy(szClassName, "\0");

		dwClassName = _MAX_PATH;
		dwKeyName   = _MAX_PATH;
	}

	::RegCloseKey(hDataKey);  hDataKey = NULL;

	lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPSWExportCLSID);
	if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
		return _signalRegError(lRet, hKey, hDataKey);



	// Next, the Writer import filter
	lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPSWImportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
				!= ERROR_NO_MORE_ITEMS)
	{
		lRet = ::RegDeleteKey(hDataKey, szKeyName);

		::lstrcpy(szKeyName, "\0");
		::lstrcpy(szClassName, "\0");

		dwClassName = _MAX_PATH;
		dwKeyName   = _MAX_PATH;
	}

	::RegCloseKey(hDataKey);  hDataKey = NULL;

	lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPSWImportCLSID);
	if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
		return _signalRegError(lRet, hKey, hDataKey);


	// Next up, the Calc export filter
	lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPXLExportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
				!= ERROR_NO_MORE_ITEMS)
	{
		lRet = ::RegDeleteKey(hDataKey, szKeyName);

		::lstrcpy(szKeyName, "\0");
		::lstrcpy(szClassName, "\0");

		dwClassName = _MAX_PATH;
		dwKeyName   = _MAX_PATH;
	}

	::RegCloseKey(hDataKey);  hDataKey = NULL;

	lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPXLExportCLSID);
	if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
		return _signalRegError(lRet, hKey, hDataKey);


	// Next, the Calc import filter
	lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPXLImportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
				!= ERROR_NO_MORE_ITEMS)
	{
		lRet = ::RegDeleteKey(hDataKey, szKeyName);

		::lstrcpy(szKeyName, "\0");
		::lstrcpy(szClassName, "\0");

		dwClassName = _MAX_PATH;
		dwKeyName   = _MAX_PATH;
	}

	::RegCloseKey(hDataKey);  hDataKey = NULL;

	lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPXLImportCLSID);
	if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
		return _signalRegError(lRet, hKey, hDataKey);

	::RegCloseKey(hKey);  hKey = NULL;



	/*
	 * Remove the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
	 */
	lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
							0, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);


	// Remove the Writer export filter from the Writer import file extension subkey.
	_snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPSWImportExt);
	lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPSWExportCLSID);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::lstrcpyn(szKeyName, "\0", _MAX_PATH);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Remove the Writer import filter from the Writer export file extension subkey.
	_snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPSWExportExt);
	lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPSWImportCLSID);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::lstrcpyn(szKeyName, "\0", _MAX_PATH);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Make Binary Copy the default for Writer export file extension subkey DefaultImport
	_snprintf(szKeyName, _MAX_PATH, ".%s\0", CXMergeFilter::m_pszPSWExportExt);
	lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
							(::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::lstrcpyn(szKeyName, "\0", _MAX_PATH);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Remove the Calc export filter from the Calc import file extension subkey.
	_snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPXLImportExt);
	lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPXLExportCLSID);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::lstrcpyn(szKeyName, "\0", _MAX_PATH);
	::RegCloseKey(hDataKey);	hDataKey = NULL;

	// Remove the Calc import filter from the Calc export file extension subkey.
	_snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPXLExportExt);
	lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPXLImportCLSID);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::lstrcpyn(szKeyName, "\0", _MAX_PATH);
	::RegCloseKey(hDataKey);	hDataKey = NULL;


	// Make Binary Copy the default for Calc export file extension subkey DefaultImport
	_snprintf(szKeyName, _MAX_PATH, ".%s\0", CXMergeFilter::m_pszPXLExportExt);
	lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
							(::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
	if (lRet != ERROR_SUCCESS)
		return _signalRegError(lRet, hKey, hDataKey);

	::lstrcpyn(szKeyName, "\0", _MAX_PATH);
	::RegCloseKey(hDataKey);	hDataKey = NULL;



	::RegCloseKey(hKey);		hKey	 = NULL;

	return HRESULT_FROM_WIN32(lRet);
}


//////////////////////////////////////////////////////////////////////
// CXMergeSyncModule methods
//////////////////////////////////////////////////////////////////////
CXMergeSyncModule::CXMergeSyncModule ()
{
}

CXMergeSyncModule::~CXMergeSyncModule ()
{
}

long CXMergeSyncModule::LockServer(BOOL fLock)
{
	if(fLock)
		return ::InterlockedIncrement(&m_lLocks);
	else
		return ::InterlockedDecrement(&m_lLocks);
}

long CXMergeSyncModule::GetLockCount()
{
	return m_lLocks + m_lObjs;
}
