#define UNICODE #define _WIN32_DCOM
#include <assert.h>
#include <stdio.h>
#include <windows.h>
#include <initguid.h>
#include "..\..\..\idl\ocr.h" #include "..\idl\contain.h"
HANDLE g_hExitEvent;
inline ULONG ComponentAddRef()
{
ULONG ul = CoAddRefServerProcess();
wprintf(TEXT("ComponentAddRef(%ld)\n"), ul);
return ul ;
}
inline ULONG ComponentRelease()
{
ULONG ul = CoReleaseServerProcess();
wprintf(TEXT("ComponentRelease(%ld)\n"), ul);
if (ul==0) {
SetEvent(g_hExitEvent);
}
return ul ;
}
void DisplayStatus(wchar_t *pwszMsg, HRESULT hr)
{
if (hr == S_OK) {
wprintf(TEXT("%s\n"), pwszMsg);
return;
}
if (HRESULT_FACILITY(hr) == FACILITY_WINDOWS) {
hr = HRESULT_CODE(hr);
}
wchar_t *pwszStatus;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&pwszStatus,
0,
NULL );
wprintf(TEXT("%s: %s (ECode: %lx)\n"), pwszMsg, pwszStatus, hr);
LocalFree(pwszStatus);
}
inline long ByteLen(wchar_t *pwsz)
{
return (sizeof(wchar_t)*(wcslen(pwsz)+1));
}
void RegisterComponent()
{
wchar_t wszKey[MAX_PATH];
wchar_t wszValue[MAX_PATH];
HKEY hKey = 0;
wcscpy(wszKey, TEXT("CLSID\\{80DA2D21-C466-11d1-83B4-006008CDD9AE}"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
wcscpy(wszValue, TEXT("Dictionary"));
RegSetValueEx(hKey, 0, 0, REG_SZ, (BYTE*)wszValue, ByteLen(wszValue));
wcscpy(wszValue, TEXT("{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
RegSetValueEx(hKey, TEXT("AppID"), 0, REG_SZ,
(BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
wcscpy(wszKey, TEXT("CLSID\\{80DA2D21-C466-11d1-83B4-006008CDD9AE}\\")
TEXT("LocalServer32"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
GetModuleFileName(0, wszValue, MAX_PATH);
RegSetValueEx(hKey, 0, 0, REG_SZ, (BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
wcscpy(wszKey, TEXT("AppID\\contain.exe"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
wcscpy(wszValue, TEXT("{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
RegSetValueEx(hKey, TEXT("AppID"), 0, REG_SZ,
(BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
wcscpy(wszKey, TEXT("AppID\\{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
wcscpy(wszValue, TEXT("Dictionary"));
RegSetValueEx(hKey, 0, 0, REG_SZ,
(BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
}
void UnregisterComponent()
{
long lRc = 0 ;
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("CLSID\\")
TEXT("{80DA2D21-C466-11d1-83B4-006008CDD9AE}\\")
TEXT("LocalServer32"));
DisplayStatus(TEXT("Unregistered LocalServer32"), lRc);
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("CLSID\\")
TEXT("{80DA2D21-C466-11d1-83B4-006008CDD9AE}"));
DisplayStatus(TEXT("Unregistered CLSID"), lRc);
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("AppID\\")
TEXT("{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
DisplayStatus(TEXT("Unregistered AppID"), lRc);
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("AppID\\contain.exe"));
DisplayStatus(TEXT("Unregistered contain.exe"), lRc);
}
class CoDictionary : public IDictionary, public ISpell {
public:
CoDictionary() : m_lRefCount(0), m_pISpell(0)
{
ComponentAddRef();
CreateInnerObject();
}
~CoDictionary()
{
if (m_pISpell) { m_pISpell->Release(); }
ComponentRelease();
}
static HRESULT CreateObject(LPUNKNOWN pUnkOuter, REFIID riid,
void** ppv);
public:
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void)
{ return InterlockedIncrement(&m_lRefCount); }
STDMETHODIMP_(ULONG) Release(void)
{
long lCount = InterlockedDecrement(&m_lRefCount);
if (lCount == 0) { delete this; }
return lCount;
}
STDMETHODIMP LookUp()
{ wprintf(TEXT("Lookup success...\n")); return S_OK; }
STDMETHODIMP Check(wchar_t *pszWord, PossibleWords *pWords)
{ return m_pISpell->Check(pszWord, pWords); }
private:
void CreateInnerObject();
private:
LONG m_lRefCount;
ISpell *m_pISpell ;
};
void CoDictionary::CreateInnerObject()
{
MULTI_QI mqi[] = { {&IID_ISpell, NULL, S_OK} };
HRESULT hr = CoCreateInstanceEx(CLSID_OcrEngine,
NULL, CLSCTX_SERVER,
NULL,
sizeof(mqi)/sizeof(mqi[0]),
mqi);
if (SUCCEEDED(hr) && SUCCEEDED(mqi[0].hr)) {
m_pISpell = reinterpret_cast<ISpell *>(mqi[0].pItf);
} else {
DisplayStatus(TEXT("Failed to create inner object..."), S_OK);
assert(false);
}
}
HRESULT CoDictionary::CreateObject(LPUNKNOWN pUnkOuter,
REFIID riid,
void** ppv)
{
*ppv = NULL;
if (pUnkOuter != NULL) { return CLASS_E_NOAGGREGATION; }
CoDictionary * pDictionary = new CoDictionary;
if (pDictionary == NULL) { return E_OUTOFMEMORY; }
HRESULT hr = pDictionary->QueryInterface(riid, ppv);
if (FAILED(hr)) { delete pDictionary; }
return hr;
}
STDMETHODIMP
CoDictionary::QueryInterface(REFIID riid, void** ppv)
{
if (ppv==NULL) { return E_INVALIDARG; }
if (riid==IID_IUnknown) {
*ppv= static_cast<IDictionary *>(this);
} else if (riid==IID_IDictionary) {
*ppv= static_cast<IDictionary *>(this);
} else if (riid==IID_ISpell) {
*ppv= static_cast<ISpell *>(this);
} else {
*ppv=NULL; return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
class CoDictionaryFactory : public IClassFactory
{
public:
STDMETHODIMP QueryInterface (REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef(void)
{ return 1; }
STDMETHODIMP_(ULONG) Release(void)
{ return 1; }
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
void **ppv)
{
return CoDictionary::CreateObject(pUnkOuter, riid, ppv);
}
STDMETHODIMP LockServer(BOOL fLock)
{
if (fLock) {
ComponentAddRef();
} else {
ComponentRelease();
}
return S_OK;
}
};
CoDictionaryFactory g_DictionaryClassFactory;
STDMETHODIMP
CoDictionaryFactory::QueryInterface(REFIID riid, void** ppv)
{
if (ppv==NULL) { return E_INVALIDARG; }
if (riid==IID_IUnknown) {
*ppv= static_cast<IClassFactory *>(this);
} else if (riid==IID_IClassFactory) {
*ppv= static_cast<IClassFactory *>(this);
} else {
*ppv=NULL; return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
void main(int argc, char **argv)
{
DisplayStatus(TEXT("Server: Started"), S_OK);
g_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
assert(g_hExitEvent);
if (argc > 1) {
if (_stricmp(argv[1], "-RegServer")==0){
RegisterComponent();
DisplayStatus(TEXT("Registered..."), S_OK);
return ;
}
if (_stricmp(argv[1], "-UnRegServer")==0){
UnregisterComponent();
DisplayStatus(TEXT("Unregistered..."), S_OK);
return ;
}
}
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
assert(SUCCEEDED(hr));
DWORD dwRegister;
hr = CoRegisterClassObject(CLSID_Dictionary,
&g_DictionaryClassFactory,
CLSCTX_SERVER,
REGCLS_MULTIPLEUSE,
&dwRegister);
assert(SUCCEEDED(hr));
g_DictionaryClassFactory.Release();
WaitForSingleObject(g_hExitEvent, INFINITE);
CoRevokeClassObject(dwRegister);
CoUninitialize();
DisplayStatus(TEXT("Server shutting down in 5 seconds..."), S_OK);
Sleep(5000);
}