// githelp.h ///////////////////////////////////////////////////////////////////////////// // Copyright (c) 1998, Chris Sells // All rights reserved. // 3/17/98: 1st release. // // NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK. // // To contact the author with suggestions or comments, use csells@sellsbrothers.com. ///////////////////////////////////////////////////////////////////////////// // This file global wrapper functions around each of the IGlobalInterfaceTable // methods. It uses a static variable held the global function CoGetGit. Since // CoGetGit should have exactly one implementation, the githelp.cpp file must // be included in exactly one place, e.g. in stdafx.cpp. // // HRESULT CoGetGit(IGlobalInterfaceTable** ppgit); // Accesses the single instance of the GIT. // // HRESULT CoRegisterInterfaceInGlobal(IUnknown* punk, REFIID riid, DWORD* pdwCookie); // Global wrapper for IGlobalInterfaceTable::RegisterInterfaceInGlobal. // // HRESULT CoRevokeInterfaceFromGlobal(DWORD dwCookie); // Global wrapper for IGlobalInterfaceTable::RevokeInterfaceFromGlobal. // // HRESULT CoGetInterfaceFromGlobal(DWORD dwCookie, REFIID riid, void** ppv); // Global wrapper for IGlobalInterfaceTable::GetInterfaceFromGlobal. // // HRESULT CoMarshalInterThreadInterfaceInGIT(REFIID riid, IUnknown* punk, DWORD* pdwCookie); // Marshals an interface into the GIT ala CoMarshalInterThreadInterfaceInStream. // // HRESULT CoGetInterfaceAndRevokeFromGIT(DWORD dwCookie, REFIID riid, void** ppv); // Unmarshals interface from the GIT and removes it ala CoGetInterfaceAndReleaseStream. // // Usage: /* HRESULT SpawnThread() { IMouse* pm = 0; HRESULT hr = CoCreateInstance(CLSID_Mouse, 0, CLSCTX_INPROC_SERVER, IID_IMouse, (void**)&pm); if( SUCCEEDED(hr) ) { // DONE: Marshalled itf into GIT DWORD dwCookie; hr = CoMarshalInterThreadInterfaceInGIT(IID_IMouse, pm, &dwCookie); if( SUCCEEDED(hr) ) { DWORD tid; HANDLE hThread = CreateThread(0, 0, ThreadProc, (void*)dwCookie, 0, &tid); if( hThread ) CloseHandle(hThread); // DONE: If thread doesn't start, remove itf from GIT else hr = CoRevokeInterfaceFromGlobal(dwCookie); } pm->Release(); } return hr; } DWORD WINAPI ThreadProc(void* pv) { CoInitialize(0); // DONE: Pull pointer out of GIT DWORD dwCookie = (DWORD)pv; IMouse* pm = 0; HRESULT hr = CoGetInterfaceAndRevokeFromGIT(dwCookie, IID_IMouse, (void**)&pm); if( SUCCEEDED(hr) ) { // Use pm pm->Release(); } CoUninitialize(); return hr; } */ #pragma once // IGlobalInterfaceTable wrappers HRESULT CoGetGit(IGlobalInterfaceTable** ppgit); HRESULT CoRegisterInterfaceInGlobal(IUnknown* punk, REFIID riid, DWORD* pdwCookie); HRESULT CoRevokeInterfaceFromGlobal(DWORD dwCookie); HRESULT CoGetInterfaceFromGlobal(DWORD dwCookie, REFIID riid, void** ppv); // Single marshal helpers HRESULT CoMarshalInterThreadInterfaceInGIT(REFIID riid, IUnknown* punk, DWORD* pdwCookie); HRESULT CoGetInterfaceAndRevokeFromGIT(DWORD dwCookie, REFIID riid, void** ppv); // Inline implementations inline HRESULT CoRegisterInterfaceInGlobal(IUnknown* punk, REFIID riid, DWORD* pdwCookie) { *pdwCookie = 0; IGlobalInterfaceTable* pgit = 0; HRESULT hr = CoGetGit(&pgit); if( SUCCEEDED(hr) ) { hr = pgit->RegisterInterfaceInGlobal(punk, riid, pdwCookie); pgit->Release(); } return hr; } inline HRESULT CoRevokeInterfaceFromGlobal(DWORD dwCookie) { IGlobalInterfaceTable* pgit = 0; HRESULT hr = CoGetGit(&pgit); if( SUCCEEDED(hr) ) { hr = pgit->RevokeInterfaceFromGlobal(dwCookie); pgit->Release(); } return hr; } inline HRESULT CoGetInterfaceFromGlobal(DWORD dwCookie, REFIID riid, void** ppv) { IGlobalInterfaceTable* pgit = 0; HRESULT hr = CoGetGit(&pgit); if( SUCCEEDED(hr) ) { hr = pgit->GetInterfaceFromGlobal(dwCookie, riid, ppv); pgit->Release(); } return hr; } inline HRESULT CoMarshalInterThreadInterfaceInGIT(REFIID riid, IUnknown* punk, DWORD* pdwCookie) { return CoRegisterInterfaceInGlobal(punk, riid, pdwCookie); } inline HRESULT CoGetInterfaceAndRevokeFromGIT(DWORD dwCookie, REFIID riid, void** ppv) { HRESULT hr = CoGetInterfaceFromGlobal(dwCookie, riid, ppv); if( SUCCEEDED(hr) ) { hr = CoRevokeInterfaceFromGlobal(dwCookie); if( FAILED(hr) ) { char sz[32]; wsprintf(sz, "Revoking itf failed: 0x%x.\n", hr); OutputDebugString(sz); // Coerce hr to success hr = S_OK; } } return hr; }