で説明したサンプルプログラムです。
コード全体をコピーしたい場合は、著作権表示といちごパックへのリンクを残した形でコピーしてください。
サンプルコードとしてその一部を利用、参照いただくぶんには問題ありません。
//
// Copyright (c) 2016 The Ichigopack Project (http://ichigopack.net/).
//
#include "ichigocomhelper.h"
#include <olectl.h>
#include <sstream>
#include <iomanip>
#include <string.h>
#include <new>
#include <exception>
#define LOGFILENAME L"c:\\tmp\\ichigo2.txt"
// {425C76F4-E126-456C-837D-1EE96DB89126}
static const GUID CLSID_Ichigo2 =
{ 0x425c76f4, 0xe126, 0x456c, { 0x83, 0x7d, 0x1e, 0xe9, 0x6d, 0xb8, 0x91, 0x26 } };
class CIchigo2Factory : public IClassFactory
{
public:
CIchigo2Factory();
~CIchigo2Factory();
// IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID* ppv );
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
// IClassFactory
HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown* pUnkOuter,
REFIID riid, LPVOID* ppv );
HRESULT STDMETHODCALLTYPE LockServer( BOOL fLock );
};
class CIchigo2 : public ISequentialStream
{
public:
CIchigo2();
~CIchigo2();
// IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID* ppv );
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
// ISequentialStream
HRESULT STDMETHODCALLTYPE Read( void* pv, ULONG cb, ULONG* pcbRead);
HRESULT STDMETHODCALLTYPE Write( const void* pv, ULONG cb,
ULONG* pcbWritten);
private:
LONG m_nRef;
};
/***********************************************************************/
HRESULT RunRegisterServer( HINSTANCE hinstEXE,
bool per_user_flag ) throw()
{
try {
std::wstring wstrName = suppGetModuleFileName( hinstEXE );
HKEY hkeyRoot;
std::wstring wstrSubkey = suppGetRegKeyCLSID( &hkeyRoot, per_user_flag,
CLSID_Ichigo2, L"LocalServer32" );
LONG regerr;
if ( wstrSubkey.empty() || wstrName.empty() ) {
return E_FAIL;
}
regerr = suppRegSetStringW(hkeyRoot, wstrSubkey.c_str(), NULL,
wstrName.c_str() );
if ( regerr != ERROR_SUCCESS ) {
return SELFREG_E_CLASS;
}
} catch ( const std::exception& ) {
return E_FAIL;
}
return S_OK;
}
HRESULT RunUnregisterServer( bool per_user_flag ) throw()
{
try {
HKEY hkeyRoot;
std::wstring wstrSubkey = suppGetRegKeyCLSID( &hkeyRoot, per_user_flag,
CLSID_Ichigo2, NULL );
LONG regerr;
if ( wstrSubkey.empty() ) {
return E_FAIL;
}
regerr = suppRegRemoveKeyW(hkeyRoot, wstrSubkey.c_str());
if ( regerr != ERROR_SUCCESS ) {
return SELFREG_E_CLASS;
}
} catch ( const std::exception& ) {
return E_FAIL;
}
return S_OK;
}
/***********************************************************************/
void LockServerProcess()
{
CoAddRefServerProcess();
}
void UnlockServerProcess()
{
if ( CoReleaseServerProcess() == 0 ) {
PostQuitMessage(0);
}
}
HRESULT RunEmbedding( HINSTANCE hinstEXE )
{
CIchigo2Factory factory;
HRESULT hr;
DWORD dwRegister = 0;
hr = CoRegisterClassObject(
CLSID_Ichigo2, static_cast<IClassFactory*>(&factory),
CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &dwRegister);
if ( FAILED(hr) ) {
return hr;
}
hr = CoResumeClassObjects();
if ( SUCCEEDED(hr) ) {
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CoRevokeClassObject(dwRegister);
return hr;
}
EXTERN_C int APIENTRY WinMain( HINSTANCE hinstEXE, HINSTANCE hinstNull,
LPSTR lpCmdLine, int nCmdShow )
{
HRESULT hr;
hr = CoInitialize(NULL);
if ( FAILED(hr) ) {
MessageBoxW( NULL, L"CoInitialize()", L"IchigoCom2", MB_OK );
return 1;
}
const char* pcommand;
bool invalid_command = false;
pcommand = strchr(lpCmdLine, '/');
if ( pcommand == NULL ) {
pcommand = strchr(lpCmdLine, '-');
}
if ( pcommand == NULL ) {
invalid_command = true;
}
if ( pcommand != NULL ) {
char* ptoken = _strdup(pcommand + 1);
if ( ptoken == NULL ) {
hr = E_OUTOFMEMORY;
} else {
strtok( ptoken, " \t\r\n" );
if ( _stricmp(ptoken, "embedding") == 0 ) {
hr = RunEmbedding( hinstEXE );
} else if ( _stricmp(ptoken, "regserver") == 0 ) {
hr = RunRegisterServer( hinstEXE, false );
} else if ( _stricmp(ptoken, "regserverperuser") == 0 ) {
hr = RunRegisterServer( hinstEXE, true );
} else if ( _stricmp(ptoken, "unregserver") == 0 ) {
hr = RunUnregisterServer( false );
} else if ( _stricmp(ptoken, "unregserverperuser") == 0 ) {
hr = RunUnregisterServer( true );
} else {
invalid_command = true;
}
free(ptoken);
}
}
CoUninitialize();
if ( invalid_command ) {
MessageBoxW( NULL, L"ichigocom2 /regserver|/unregserver", L"IchigoCom2",
MB_OK );
return 1;
}
if ( FAILED(hr) ) {
std::wostringstream wos;
wos << L"error " << std::hex << std::setfill(L'0') << std::setw(8) << hr;
MessageBoxW( NULL, wos.str().c_str(), L"IchigoCom2", MB_OK );
return 1;
}
return 0;
}
/***********************************************************************/
CIchigo2Factory::CIchigo2Factory()
{
}
CIchigo2Factory::~CIchigo2Factory()
{
}
HRESULT STDMETHODCALLTYPE CIchigo2Factory::QueryInterface( REFIID riid,
LPVOID* ppv )
{
*ppv = NULL;
if ( riid == IID_IUnknown || riid == IID_IClassFactory ) {
*ppv = static_cast<IClassFactory*>( this );
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE CIchigo2Factory::AddRef()
{
return 1;
}
ULONG STDMETHODCALLTYPE CIchigo2Factory::Release()
{
return 1;
}
HRESULT STDMETHODCALLTYPE CIchigo2Factory::CreateInstance(
IUnknown* pUnkOuter, REFIID riid, LPVOID* ppv )
{
*ppv = NULL;
if ( pUnkOuter != NULL ) {
return CLASS_E_NOAGGREGATION;
}
CIchigo2* pObj = new (std::nothrow) CIchigo2();
if ( pObj == NULL ) {
return E_OUTOFMEMORY;
}
HRESULT hr = pObj->QueryInterface( riid, ppv );
pObj->Release();
return hr;
}
HRESULT STDMETHODCALLTYPE CIchigo2Factory::LockServer( BOOL fLock )
{
if ( fLock ) {
LockServerProcess();
} else {
UnlockServerProcess();
}
return S_OK;
}
/***********************************************************************/
CIchigo2::CIchigo2() : m_nRef(1)
{
LockServerProcess();
}
CIchigo2::~CIchigo2()
{
UnlockServerProcess();
}
HRESULT STDMETHODCALLTYPE CIchigo2::QueryInterface( REFIID riid,
LPVOID* ppv )
{
*ppv = NULL;
if ( riid == IID_IUnknown || riid == IID_ISequentialStream ) {
*ppv = static_cast<ISequentialStream*>( this );
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE CIchigo2::AddRef()
{
return ++m_nRef;
}
ULONG STDMETHODCALLTYPE CIchigo2::Release()
{
if ( --m_nRef == 0 ) {
delete this;
return 0;
}
return m_nRef;
}
HRESULT STDMETHODCALLTYPE CIchigo2::Read( void* pv, ULONG cb,
ULONG* pcbRead)
{
*pcbRead = 0;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CIchigo2::Write( const void* pv, ULONG cb,
ULONG* pcbWritten)
{
return suppLogFileAppendW( LOGFILENAME, pv, cb, pcbWritten );
}