20141121调研
20141121调研
1、在系统服务里调用进程外COM的接口,接口中会启动第三个进程,此时创建出来的进程外COM所在的进程和第三个进程,都是SYSTEM权限启动的。
另外,如果之前进程外COM已启动了一个进程,但不是SYSTEM权限的,那个系统服务调时,还会再创建一个新的COM进程
2、
一种调COM示例,使用了别人封的CDispatch类,可调进程内、外COM,前提是注册过,在注册表中有信息
::CoInitialize(NULL); CDispatch obj; IID _iid; //CLSIDFromString(L"{42637A0F-E8B8-4737-ABF4-F8B929E32651}", &_iid); CLSIDFromProgID(L"aaaaa.bbbb", &_iid); HRESULT hr = E_FAIL; CComPtr<IClassFactory> cf; //hr = CoGetClassObject(_iid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (LPVOID*)&cf);//进程内 hr = CoGetClassObject(_iid, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (LPVOID*)&cf);//进程外 if (cf) { hr = cf->CreateInstance(NULL, IID_IDispatch, (void**)&obj); } if (obj) { obj.Invoke(L"methodname", "参数"); } obj = NULL; cf = NULL; ::CoUninitialize();
如果没注册过的进程内COM,可以如下调,查找函数入口,取得类厂,创建对象再调
//定义函数指针 typedef HRESULT (_stdcall *Func) (REFCLSID , REFIID , LPVOID*); Func g_DllGetClassObject=NULL; test() { //加载dll,找入口,得到类厂,得到对象,调用 ::CoInitialize(NULL); CString sPath = _T("C:\\test.dll"); HMODULE mod = LoadLibrary(sPath); if (mod) { g_DllGetClassObject = (Func)GetProcAddress(mod, "DllGetClassObject"); if (g_DllGetClassObject) { CDispatch obj; IID _iid; CLSIDFromString(L"{D6C9D706-8DE1-4DAF-B1E8-CDF2A9280BFC}", &_iid); //CLSIDFromProgID(L"aaaaa.bbbbb", &_iid); HRESULT hr = E_FAIL; CComPtr<IClassFactory> cf; hr = CoGetClassObject(_iid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (LPVOID*)&cf); if (cf) { hr = cf->CreateInstance(NULL, IID_IDispatch, (void**)&obj); } if (obj) { CComVariant vResult = obj.Invoke(L"InvokeMethod", "SelectFile", "{}"); vResult.ChangeType(VT_BSTR); CString s = vResult.bstrVal; } obj = NULL; cf = NULL; ::CoUninitialize(); } } }
3、
CDispatch实现如下
disputil.h
源码来自http://download.csdn.net/detail/redui/3756638
redui的Raptor实现中的一个文件Raptor
#pragma once #include <atlcomcli.h> #include <atlexcept.h> #include <dispex.h> #pragma warning( disable : 4290 )
class CDispatch : public CComDispatchDriver { HRESULT m_hr; public: static CComVariant& vOptional() { static CComVariant vOpt; return vOpt; } CDispatch() : m_hr(S_OK) {} CDispatch(IDispatch* lp) : CComDispatchDriver(lp), m_hr(S_OK) {} CDispatch(const CDispatch& lp) : CComDispatchDriver(lp.p), m_hr(S_OK) {} CDispatch(const CComVariant& v) : m_hr(E_UNEXPECTED) { if (v.vt == VT_DISPATCH && v.pdispVal) m_hr = v.pdispVal->QueryInterface(IID_IDispatch, (void**)&p); else if (v.vt == VT_UNKNOWN && v.punkVal) m_hr = v.punkVal->QueryInterface(IID_IDispatch, (void**)&p); } HRESULT GetLastHResult() { return m_hr; } bool Has(LPCOLESTR lpsz) { DISPID dispid; m_hr=GetIDOfName(lpsz, &dispid); #ifdef __dispex_h__ if (FAILED(m_hr)) { CComQIPtr<IDispatchEx> dispex(p); if (dispex.p) { DISPID did = DISPID_UNKNOWN; m_hr = dispex.p->GetDispID((BSTR)lpsz, fdexNameCaseSensitive, &did); } } #endif // __dispex_h__ return SUCCEEDED(m_hr); } CComVariant Get(LPCOLESTR lpsz) { CComVariant v; ATLASSERT(p); if (p==NULL) return v; m_hr = GetPropertyByName(lpsz, &v); #ifdef __dispex_h__ if (FAILED(m_hr)) { CComQIPtr<IDispatchEx> dispex(p); if (dispex.p) { DISPID did = DISPID_UNKNOWN; m_hr = dispex.p->GetDispID((BSTR)lpsz, fdexNameCaseSensitive, &did); if (SUCCEEDED(m_hr) && did!=DISPID_UNKNOWN) m_hr = GetProperty(did, &v); } } #endif // __dispex_h__ ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); return v; } CComVariant Get(DISPID dispid) { CComVariant v; ATLASSERT(p); if (p==NULL) return v; m_hr = GetProperty(dispid, &v); ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); return v; } CDispatch GetPtr(LPCOLESTR lpsz) { return Get(lpsz); } CDispatch GetPtr(DISPID dispid) { return Get(dispid); } #ifdef __dispex_h__ CComVariant GetEx(LPCOLESTR lpsz) { ATLASSERT(p); if (p==NULL) return CComVariant(); CComVariant v; m_hr = GetPropertyByName(lpsz, &v); if (SUCCEEDED(m_hr)) return v; CComQIPtr<IDispatchEx> dispex(p); if (dispex.p) { DISPID did = DISPID_UNKNOWN; m_hr = dispex.p->GetDispID((BSTR)lpsz, fdexNameCaseSensitive|fdexNameEnsure, &did); } ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); return CComVariant(); } CDispatch GetExPtr(LPCOLESTR lpsz) { return Get(lpsz); } #endif // __dispex_h__ void Put(LPCOLESTR lpsz, CComVariant v) { ATLASSERT(p); if (p==NULL) return; m_hr = PutPropertyByName(lpsz, &v); #ifdef __dispex_h__ if (FAILED(m_hr)) { CComQIPtr<IDispatchEx> dispex(p); if (dispex.p) { DISPID did = DISPID_UNKNOWN; m_hr = dispex.p->GetDispID((BSTR)lpsz, fdexNameCaseSensitive|fdexNameEnsure, &did); if (SUCCEEDED(m_hr) && did!=DISPID_UNKNOWN) m_hr = PutProperty(did, &v); } } #endif // __dispex_h__ ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); } void Put(DISPID dispid, CComVariant v) { ATLASSERT(p); if (p==NULL) return; m_hr = PutProperty(dispid, &v); ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); } CComVariant Invoke(LPCOLESTR lpsz, CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { CComVariant v; ATLASSERT(p); if (p==NULL) return v; CComVariant pm[6] = {param6, param5, param4, param3, param2, param1}; int nOptCnt = 0; if (param6.vt == VT_EMPTY) nOptCnt++; if (param5.vt == VT_EMPTY) nOptCnt++; if (param4.vt == VT_EMPTY) nOptCnt++; if (param3.vt == VT_EMPTY) nOptCnt++; if (param2.vt == VT_EMPTY) nOptCnt++; if (param1.vt == VT_EMPTY) nOptCnt++; m_hr = __super::InvokeN(lpsz, nOptCnt==6?NULL:&pm[nOptCnt], 6-nOptCnt, &v); ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); return v; } CComVariant Invoke(DISPID dispid, CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { CComVariant v; ATLASSERT(p); if (p==NULL) return v; CComVariant pm[6] = {param6, param5, param4, param3, param2, param1}; int nOptCnt = 0; if (param6.vt == VT_EMPTY) nOptCnt++; if (param5.vt == VT_EMPTY) nOptCnt++; if (param4.vt == VT_EMPTY) nOptCnt++; if (param3.vt == VT_EMPTY) nOptCnt++; if (param2.vt == VT_EMPTY) nOptCnt++; if (param1.vt == VT_EMPTY) nOptCnt++; m_hr = __super::InvokeN(dispid, nOptCnt==6?NULL:&pm[nOptCnt], 6-nOptCnt, &v); ATLASSERT(SUCCEEDED(m_hr)); //if (FAILED(hr)) AtlThrow(hr); return v; } CDispatch InvokePtr(LPCOLESTR lpsz, CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { return Invoke(lpsz, param1, param2, param3, param4, param5, param6); } CDispatch InvokePtr(DISPID dispid, CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { return Invoke(dispid, param1, param2, param3, param4, param5, param6); } CComVariant InvokeCallback(CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { return Invoke((DISPID)DISPID_VALUE, param1, param2, param3, param4, param5, param6); } CDispatch InvokeCallbackPtr(CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { return InvokeCallback(param1, param2, param3, param4, param5, param6); } CDispatch Construct(DISPID dispid, CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { CComVariant v; ATLASSERT(p); if (p==NULL) return v; CComVariant pm[6] = {param6, param5, param4, param3, param2, param1}; int nOptCnt = 0; if (param6.vt == VT_EMPTY) nOptCnt++; if (param5.vt == VT_EMPTY) nOptCnt++; if (param4.vt == VT_EMPTY) nOptCnt++; if (param3.vt == VT_EMPTY) nOptCnt++; if (param2.vt == VT_EMPTY) nOptCnt++; if (param1.vt == VT_EMPTY) nOptCnt++; DISPPARAMS dispparams = { nOptCnt==6?NULL:&pm[nOptCnt], NULL, 6-nOptCnt, 0}; m_hr = p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_CONSTRUCT, &dispparams, &v, NULL, NULL); ATLASSERT(SUCCEEDED(m_hr)); return v; } CDispatch Construct(LPCOLESTR lpsz, CComVariant param1=vOptional(), CComVariant param2=vOptional(), CComVariant param3=vOptional(), CComVariant param4=vOptional(), CComVariant param5=vOptional(), CComVariant param6=vOptional()) { CComVariant v; ATLASSERT(p); if (p==NULL) return v; DISPID dispid; if (SUCCEEDED(m_hr=GetIDOfName(lpsz, &dispid))) return Construct(dispid, param1, param2, param3, param4, param5, param6); return v; } };