mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-30 04:07:42 +00:00
* moved ConvertUTF.h -> common/windows/cpp/include * moved crc32.h -> common/windows/cpp/include * moved keymansentry.h -> common/windows/cpp/include * moved registry.h -> common/windows/cpp/include * moved unicode.h -> common/windows/cpp/include * moved xstring.h -> common/windows/cpp/include and updated corresponding references. Deleted a bunch of old references to missing headers from .vcxproj files. Updated vkeys.h and vkeys.cpp references in .vcxproj to use $(KEYMAN_ROOT) instead of relative paths.
299 lines
7.7 KiB
C++
299 lines
7.7 KiB
C++
/*
|
|
Name: server
|
|
Copyright: Copyright (C) SIL International.
|
|
Documentation:
|
|
Description:
|
|
Create Date: 6 Nov 2007
|
|
|
|
Modified Date: 7 Nov 2013
|
|
Authors: mcdurdin
|
|
Related Files:
|
|
Dependencies:
|
|
|
|
Bugs:
|
|
Todo:
|
|
Notes:
|
|
History: 06 Nov 2007 - mcdurdin - I1140 - Add KeymanAddinConfigure function to reconfigure the user's TSF linked keyboards
|
|
22 Mar 2010 - mcdurdin - Compiler fixup - x64 support
|
|
18 Mar 2011 - mcdurdin - I2807 - Enable/disable addins
|
|
24 Oct 2012 - mcdurdin - I3481 - V9.0 - Eliminate unsafe calls in C++
|
|
07 Nov 2012 - mcdurdin - I3549 - V9.0 - x64 version of kmtip addin
|
|
07 Nov 2012 - mcdurdin - I3550 - V9.0 - TSF Addin should be always enabled in 9.0
|
|
07 Nov 2013 - mcdurdin - I3944 - x64 kmtip has duplicated exports
|
|
*/
|
|
//
|
|
// server.cpp
|
|
//
|
|
// COM server exports.
|
|
//
|
|
|
|
#include "pch.h"
|
|
#include "kmtip.h"
|
|
#include "../../../../common/windows/cpp/include/registry.h"
|
|
|
|
void FreeGlobalObjects(void);
|
|
|
|
class CClassFactory;
|
|
static CClassFactory *g_ObjectInfo[1] = { NULL };
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DllAddRef
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void DllAddRef(void)
|
|
{
|
|
InterlockedIncrement(&g_cRefDll);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DllRelease
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void DllRelease(void)
|
|
{
|
|
if (InterlockedDecrement(&g_cRefDll) < 0) // g_cRefDll == -1 with zero refs
|
|
{
|
|
EnterCriticalSection(&g_cs);
|
|
|
|
// need to check ref again after grabbing mutex
|
|
if (g_ObjectInfo[0] != NULL)
|
|
{
|
|
FreeGlobalObjects();
|
|
}
|
|
assert(g_cRefDll == -1);
|
|
|
|
LeaveCriticalSection(&g_cs);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CClassFactory declaration with IClassFactory Interface
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CClassFactory : public IClassFactory
|
|
{
|
|
public:
|
|
// IUnknown methods
|
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
// IClassFactory methods
|
|
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
|
|
STDMETHODIMP LockServer(BOOL fLock);
|
|
|
|
// Constructor
|
|
CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj))
|
|
: _rclsid(rclsid)
|
|
{
|
|
_pfnCreateInstance = pfnCreateInstance;
|
|
}
|
|
|
|
public:
|
|
REFCLSID _rclsid;
|
|
HRESULT (*_pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CClassFactory::QueryInterface
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
|
|
{
|
|
if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
|
|
{
|
|
*ppvObj = this;
|
|
DllAddRef();
|
|
return NOERROR;
|
|
}
|
|
*ppvObj = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CClassFactory::AddRef
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI_(ULONG) CClassFactory::AddRef()
|
|
{
|
|
DllAddRef();
|
|
return g_cRefDll+1; // -1 w/ no refs
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CClassFactory::Release
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI_(ULONG) CClassFactory::Release()
|
|
{
|
|
DllRelease();
|
|
return g_cRefDll+1; // -1 w/ no refs
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CClassFactory::CreateInstance
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
|
|
{
|
|
return _pfnCreateInstance(pUnkOuter, riid, ppvObj);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CClassFactory::LockServer
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CClassFactory::LockServer(BOOL fLock)
|
|
{
|
|
if (fLock)
|
|
{
|
|
DllAddRef();
|
|
}
|
|
else
|
|
{
|
|
DllRelease();
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// BuildGlobalObjects
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void BuildGlobalObjects(void)
|
|
{
|
|
// Build CClassFactory Objects
|
|
|
|
g_ObjectInfo[0] = new CClassFactory(c_clsidKMTipTextService, CKMTipTextService::CreateInstance);
|
|
|
|
// You can add more object info here.
|
|
// Don't forget to increase number of item for g_ObjectInfo[],
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// FreeGlobalObjects
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void FreeGlobalObjects(void)
|
|
{
|
|
// Free CClassFactory Objects
|
|
for (int i = 0; i < ARRAYSIZE(g_ObjectInfo); i++)
|
|
{
|
|
if (NULL != g_ObjectInfo[i])
|
|
{
|
|
delete g_ObjectInfo[i];
|
|
g_ObjectInfo[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DllGetClassObject
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObj)
|
|
{
|
|
if (g_ObjectInfo[0] == NULL)
|
|
{
|
|
EnterCriticalSection(&g_cs);
|
|
|
|
// need to check ref again after grabbing mutex
|
|
if (g_ObjectInfo[0] == NULL)
|
|
{
|
|
BuildGlobalObjects();
|
|
}
|
|
|
|
LeaveCriticalSection(&g_cs);
|
|
}
|
|
|
|
if (IsEqualIID(riid, IID_IClassFactory) ||
|
|
IsEqualIID(riid, IID_IUnknown))
|
|
{
|
|
for (int i = 0; i < ARRAYSIZE(g_ObjectInfo); i++)
|
|
{
|
|
if (NULL != g_ObjectInfo[i] &&
|
|
IsEqualGUID(rclsid, g_ObjectInfo[i]->_rclsid))
|
|
{
|
|
*ppvObj = (void *)g_ObjectInfo[i];
|
|
DllAddRef(); // class factory holds DLL ref count
|
|
return NOERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
*ppvObj = NULL;
|
|
|
|
return CLASS_E_CLASSNOTAVAILABLE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DllCanUnloadNow
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
if (g_cRefDll >= 0) // -1 with no refs
|
|
return S_FALSE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DllUnregisterServer
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
CKMTipTextService::RegisterCategories(FALSE);
|
|
CKMTipTextService::UnregisterProfiles();
|
|
CKMTipTextService::UnregisterServer();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DllRegisterServer
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
// register this service's profile with the tsf
|
|
if (!CKMTipTextService::RegisterServer() ||
|
|
!CKMTipTextService::RegisterProfiles() ||
|
|
!CKMTipTextService::RegisterCategories(TRUE))
|
|
{
|
|
DllUnregisterServer(); // cleanup any loose ends
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|