You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
343 lines
9.5 KiB
343 lines
9.5 KiB
/****************************************************************************
|
|
SERVER.CPP : COM server functionality
|
|
|
|
History:
|
|
15-NOV-1999 CSLim Created
|
|
****************************************************************************/
|
|
|
|
#include "private.h"
|
|
#include "korimx.h"
|
|
#include "regsvr.h"
|
|
#include "regimx.h"
|
|
#include "init.h"
|
|
#include "gdata.h"
|
|
#include "catutil.h"
|
|
#include "insert.h"
|
|
#include "immxutil.h"
|
|
#include "hanja.h"
|
|
|
|
#if !defined(NOCLIB) && defined(_M_IX86)
|
|
extern "C" BOOL WINAPI _CRT_INIT(HINSTANCE, DWORD, LPVOID);
|
|
#endif
|
|
|
|
|
|
#ifdef DEBUG
|
|
DWORD g_dwThreadDllMain = 0;
|
|
#endif
|
|
|
|
void DllAddRef(void);
|
|
void DllRelease(void);
|
|
|
|
LONG g_cRefDll = 0;
|
|
|
|
//
|
|
// CClassFactory declaration with IClassFactory Interface
|
|
//
|
|
class CClassFactory : public IClassFactory
|
|
{
|
|
public:
|
|
// IUnknown methods
|
|
virtual STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
|
|
virtual STDMETHODIMP_(ULONG) AddRef(void);
|
|
virtual STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
// IClassFactory methods
|
|
virtual STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
|
|
virtual STDMETHODIMP LockServer(BOOL fLock);
|
|
|
|
// Constructor & Destructor
|
|
CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj));
|
|
~CClassFactory();
|
|
|
|
public:
|
|
REFCLSID _rclsid;
|
|
HRESULT (*_pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
|
|
};
|
|
|
|
CClassFactory::CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj))
|
|
: _rclsid( rclsid ), _pfnCreateInstance( pfnCreateInstance )
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("constructor of CClassFactory 0x%08x"), this);
|
|
}
|
|
|
|
CClassFactory::~CClassFactory()
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("destructor of CClassFactory 0x%08x"), this);
|
|
}
|
|
|
|
STDAPI CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("CClassFactory::QueryInterface called."));
|
|
if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
|
|
{
|
|
*ppvObj = SAFECAST(this, IClassFactory*);
|
|
DllAddRef();
|
|
return NOERROR;
|
|
}
|
|
*ppvObj = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDAPI_(ULONG) CClassFactory::AddRef()
|
|
{
|
|
DllAddRef();
|
|
DebugMsg(DM_TRACE, TEXT("CClassFactory::AddRef called. g_cRefDll=%d"), g_cRefDll);
|
|
return g_cRefDll;
|
|
}
|
|
|
|
STDAPI_(ULONG) CClassFactory::Release()
|
|
{
|
|
DllRelease();
|
|
DebugMsg(DM_TRACE, TEXT("CClassFactory::Release called. g_cRefDll=%d"), g_cRefDll);
|
|
return g_cRefDll;
|
|
}
|
|
|
|
STDAPI CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("CClassFactory::CreateInstance called."));
|
|
return this->_pfnCreateInstance(pUnkOuter, riid, ppvObj);
|
|
}
|
|
|
|
STDAPI CClassFactory::LockServer(BOOL fLock)
|
|
{
|
|
if (fLock)
|
|
DllAddRef();
|
|
else
|
|
DllRelease();
|
|
DebugMsg(DM_TRACE, TEXT("CClassFactory::LockServer(%s) to %d"), fLock ? TEXT("LOCK") : TEXT("UNLOCK"), g_cRefDll);
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// Build Global Objects
|
|
//
|
|
|
|
CClassFactory *g_ObjectInfo[1] = { NULL };
|
|
|
|
void BuildGlobalObjects(void)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("BuildGlobalObjects called."));
|
|
|
|
// Build CClassFactory Objects
|
|
g_ObjectInfo[0] = new CClassFactory(CLSID_KorIMX, CKorIMX::CreateInstance);
|
|
|
|
// You can add more object info here.
|
|
// Don't forget to increase number of item for g_ObjectInfo[],
|
|
// and add function prototype to private.h
|
|
}
|
|
|
|
void FreeGlobalObjects(void)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("FreeGlobalObjects called."));
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
DllMain
|
|
---------------------------------------------------------------------------*/
|
|
STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pvReserved)
|
|
{
|
|
WNDCLASSEX wndclass;
|
|
|
|
#if DEBUG
|
|
g_dwThreadDllMain = GetCurrentThreadId();
|
|
#endif
|
|
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
#if !defined(NOCLIB) && defined(_M_IX86)
|
|
_CRT_INIT(hInstance, dwReason, pvReserved);
|
|
#endif
|
|
CcshellGetDebugFlags();
|
|
Dbg_MemInit(TEXT("KORIMX"), NULL);
|
|
|
|
g_hInst = hInstance;
|
|
|
|
g_cs.Init();
|
|
|
|
ZeroMemory(&wndclass, sizeof(wndclass));
|
|
wndclass.cbSize = sizeof(wndclass);
|
|
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
|
|
wndclass.hInstance = hInstance;
|
|
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
wndclass.lpfnWndProc = CKorIMX::_OwnerWndProc;
|
|
wndclass.lpszClassName = c_szOwnerWndClass;
|
|
RegisterClassEx(&wndclass);
|
|
|
|
// Initialize Shared memory
|
|
CIMEData::InitSharedData();
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
UnregisterClass(c_szOwnerWndClass, g_hInst);
|
|
|
|
g_cs.Delete();
|
|
|
|
#if !defined(NOCLIB) && defined(_M_IX86)
|
|
_CRT_INIT(hInstance, dwReason, pvReserved);
|
|
#endif
|
|
// Close lex file if has opened ever.
|
|
CloseLex();
|
|
|
|
// Close shared memory
|
|
CIMEData::CloseSharedMemory();
|
|
|
|
// This should be last.
|
|
Dbg_MemUninit();
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
|
|
#if DEBUG
|
|
g_dwThreadDllMain = 0;
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
DllAddRef
|
|
---------------------------------------------------------------------------*/
|
|
void DllAddRef(void)
|
|
{
|
|
InterlockedIncrement(&g_cRefDll);
|
|
ASSERT(1000 > g_cRefDll); // reasonable upper limit
|
|
DllInit();
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
DllRelease
|
|
---------------------------------------------------------------------------*/
|
|
void DllRelease(void)
|
|
{
|
|
InterlockedDecrement(&g_cRefDll);
|
|
if (0 == g_cRefDll)
|
|
FreeGlobalObjects();
|
|
ASSERT(0 <= g_cRefDll); // don't underflow
|
|
DllUninit();
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
DllGetClassObject
|
|
---------------------------------------------------------------------------*/
|
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObj)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("DllGetClassObject called."));
|
|
if (0 == g_cRefDll)
|
|
BuildGlobalObjects();
|
|
|
|
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 (0 < g_cRefDll)
|
|
return S_FALSE;
|
|
DebugMsg(DM_TRACE, TEXT("DllCanUnloadNow returning S_OK"));
|
|
return S_OK;
|
|
}
|
|
|
|
// TIP Categories to be added
|
|
const REGISTERCAT c_rgRegCat[] =
|
|
{
|
|
{&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_KorIMX},
|
|
{&GUID_TFCAT_TIP_KEYBOARD, &CLSID_KorIMX},
|
|
{&GUID_TFCAT_PROPSTYLE_CUSTOM, &GUID_PROP_OVERTYPE},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
|
|
// TIP Profile name
|
|
const REGTIPLANGPROFILE c_rgProf[] =
|
|
{
|
|
{ MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), &GUID_Profile, SZ_TIPDISPNAME, SZ_TIPMODULENAME, (IDI_UNIKOR-IDI_ICONBASE), IDS_PROFILEDESC },
|
|
{0, &GUID_NULL, L"", L"", 0, 0}
|
|
};
|
|
|
|
BOOL FIsAvailable( REFCLSID refclsid, BOOL fLocalSvr );
|
|
|
|
/*---------------------------------------------------------------------------
|
|
DllRegisterServer
|
|
---------------------------------------------------------------------------*/
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
TCHAR achPath[MAX_PATH+1];
|
|
HRESULT hr = E_FAIL;
|
|
|
|
TFInitLib();
|
|
|
|
if (GetModuleFileName(g_hInst, achPath, ARRAYSIZE(achPath)) == 0)
|
|
goto Exit;
|
|
|
|
if (!RegisterServer(CLSID_KorIMX, SZ_TIPSERVERNAME, achPath, TEXT("Apartment"), NULL))
|
|
goto Exit;
|
|
|
|
if (!RegisterTIP(g_hInst, CLSID_KorIMX, SZ_TIPNAME, c_rgProf))
|
|
goto Exit;
|
|
|
|
if (FAILED(RegisterCategories(CLSID_KorIMX, c_rgRegCat)))
|
|
goto Exit;
|
|
|
|
hr = S_OK;
|
|
|
|
Exit:
|
|
TFUninitLib();
|
|
return hr;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
DllUnregisterServer
|
|
---------------------------------------------------------------------------*/
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
TFInitLib();
|
|
|
|
if (FAILED(hr = RegisterServer(CLSID_KorIMX, NULL, NULL, NULL, NULL) ? S_OK : E_FAIL))
|
|
goto Exit;
|
|
|
|
if (FAILED(UnregisterCategories(CLSID_KorIMX, c_rgRegCat)))
|
|
goto Exit;
|
|
|
|
if (!UnregisterTIP(CLSID_KorIMX))
|
|
goto Exit;
|
|
|
|
hr = S_OK;
|
|
|
|
Exit:
|
|
TFUninitLib();
|
|
return hr;
|
|
}
|