私は次に(COMインターフェイスを純粋なC構造体+関数とDirect Xハックと解釈することから)見つけました。動作しますが何らかの理由で問題を解決しません。私のBEは...ワークブック、ワークシートのために同じことを行う必要があります
宣言:
typedef HRESULT STDMETHODCALLTYPE QueryInterfacePtr( REFIID, void **);
typedef ULONG STDMETHODCALLTYPE AddRefPtr();
typedef ULONG STDMETHODCALLTYPE ReleasePtr();
typedef ULONG STDMETHODCALLTYPE GetTypeInfoCountPtr(UINT *) ;
typedef ULONG STDMETHODCALLTYPE GetTypeInfoPtr (UINT, LCID, ITypeInfo **) ;
typedef ULONG STDMETHODCALLTYPE GetIDsOfNamesPtr (REFIID, LPOLESTR *,
UINT, LCID, DISPID *) ;
typedef ULONG STDMETHODCALLTYPE InvokePtr (DISPID, REFIID,
LCID, WORD, DISPPARAMS *,
VARIANT *, EXCEPINFO *, UINT *) ;
typedef struct {
// IUnknown functions
QueryInterfacePtr * QueryInterface;
AddRefPtr * AddRef;
ReleasePtr * Release;
// IDispatch functions
GetTypeInfoCountPtr* GetTypeInfoCount;
GetTypeInfoPtr* GetTypeInfo;
GetIDsOfNamesPtr* GetIDsOfNames;
InvokePtr* Invoke;
} IDispatchInterceptor;
typedef ULONG __stdcall releasePTR(IDispatch *self);
typedef ULONG __stdcall addrefPTR(IDispatch *self);
次は私がエクセルのために行われています:
static IDispatch * application = NULL;
static releasePTR* realRelease = NULL;
static addrefPTR* realAddRef = NULL;
static ULONG wasAdd = 0;
static ULONG oldCount = 0;
HRESULT STDMETHODCALLTYPE QueryInterfaceNativeOutOfProcSrv(REFIID riid, void **ppv){ return application->QueryInterface(riid,ppv);
}
ULONG STDMETHODCALLTYPE AddRefNativeOutOfProcSrv(){ return application->AddRef(); }
ULONG STDMETHODCALLTYPE ReleaseNativeOutOfProcSrv(){ return application->Release(); }
ULONG STDMETHODCALLTYPE GetTypeInfoCountSrv(UINT * count) { return application->GetTypeInfoCount(count); } ULONG STDMETHODCALLTYPE GetTypeInfoSrv (UINT n, LCID id, ITypeInfo ** inf) { return application->GetTypeInfo(n,id,inf); } ULONG STDMETHODCALLTYPE GetIDsOfNamesSrv (REFIID a, LPOLESTR * b, UINT c, LCID d, DISPID * e) { return application->GetIDsOfNames(a,b,c,d,e); } ULONG STDMETHODCALLTYPE InvokeSrv (DISPID a, REFIID b, LCID c, WORD d, DISPPARAMS * e, VARIANT * i, EXCEPINFO * j, UINT *k) { return application->Invoke(a,b,c,d,e,i,j,k); }
static IDispatchInterceptor interceptor = {QueryInterfaceNativeOutOfProcSrv,AddRefNativeOutOfProcSrv,ReleaseNativeOutOfProcSrv, GetTypeInfoCountSrv,GetTypeInfoSrv,GetIDsOfNamesSrv,InvokeSrv };
ULONG __stdcall release(IDispatch *self) {
ULONG c = realRelease(self);
Log->logWrite("release %d",c);
if ( c == 1)
{
if (instance != NULL)
{
instance->OnBeginShutdown(NULL);
Log->logWrite("OnBeginShutdown %d",c);
instance->OnEmbeddedDisconnection();
Log->logWrite("OnEmbeddedDisconnection %d",c);
instance = NULL;
}
}
//if (c == 2) {
// c = realRelease(self);
// c = realRelease(self);
//}
return c;
}
ULONG __stdcall addref(IDispatch *self) {
ULONG c = oldCount; if (wasAdd == 0) { c = realAddRef(self); oldCount = c; wasAdd++; } else if (wasAdd == 1) { Log->logWrite("ADDREF FAKE %d",c); wasAdd++; } else if (wasAdd == 2) { Log->logWrite("ADDREF FAKE %d",c); wasAdd++; } else { c = realAddRef(self); }
Log->logWrite("ADDREF %d",c); return c; }
void InterceptRelease( IDispatch obj){ void iunknown_vtable= (void*)((unsigned int)obj); void* idispatch_vtable = (void*)(((unsigned int)iunknown_vtable)+8); unsigned int* v1 = (unsigned int*)idispatch_vtable; realRelease = (releasePTR*)*v1; DWORD old; VirtualProtect(v1,4,PAGE_EXECUTE_READWRITE,&old);
*v1 = (unsigned int) release;
//while(obj->Release() > 0){};
}
void InterceptAddRef( IDispatch obj){ void iunknown_vtable= (void*)((unsigned int)obj); void* idispatch_vtable = (void*)(((unsigned int)iunknown_vtable)+4); unsigned int* v1 = (unsigned int*)idispatch_vtable; realAddRef = (addrefPTR*)*v1; DWORD old; VirtualProtect(v1,4,PAGE_EXECUTE_READWRITE,&old); *v1 = (unsigned int) addref; }
が適用されます。
IDispatch * app = Application;
InterceptRelease(app);
InterceptAddRef(app);
は良い仕組みがありません予期しないプロセスの終了に対処するためにout-of-proc COMで実行します。ハードクラッシュが捕捉され、RPC_E_SERVERFAULTエラーコードを使用してクライアントに報告されます。サーバーは稼動し続けます。あなたが頭の中でそれを撃つならば、混乱を取り除くのはあなたの仕事です。 –
"正当な理由でこのメッセージを傍受しようとしています。"これを行うには理由がありません。あなたは何を***実際にしようとしていますか? – Ben
私の問題を説明するUPDATE2を追加しました。 –