component with GIT.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // component.cpp
  2. // This in-process component can be installed with the ThreadingModel value
  3. // set to Apartment, Free, or Both. This can be adjusted in the last parameter
  4. // of the RegisterServer function.
  5. #define _WIN32_DCOM
  6. #include <iostream.h>  // For cout
  7. #include "Component with GITcomponent.h" // Generated by MIDL
  8. #include "registry.h"  // For registry functions
  9. HINSTANCE g_hInstance;
  10. long g_cComponents = 0;
  11. long g_cServerLocks = 0;
  12. const CLSID CLSID_InsideCOM2 = {0x10000022,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}};
  13. class CInsideCOM : public ISum
  14. {
  15. public:
  16. // IUnknown
  17. ULONG __stdcall AddRef();
  18. ULONG __stdcall Release();
  19. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  20. // ISum
  21. HRESULT __stdcall Sum(int x, int y, int* retval);
  22. CInsideCOM();
  23. ~CInsideCOM();
  24. private:
  25. long m_cRef;
  26. IUnknown* m_pUnknownFTM;
  27. IGlobalInterfaceTable* m_pGIT;
  28. DWORD m_cookie;
  29. };
  30. CInsideCOM::CInsideCOM() : m_cRef(1)
  31. {
  32. InterlockedIncrement(&g_cComponents);
  33. CoCreateFreeThreadedMarshaler(this, &m_pUnknownFTM);
  34. ISum* pSum;
  35. HRESULT hr = CoCreateInstance(CLSID_InsideCOM2, NULL, CLSCTX_INPROC_SERVER, IID_ISum, (void**)&pSum);
  36. CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void**)&m_pGIT);
  37. m_pGIT->RegisterInterfaceInGlobal(pSum, IID_ISum, &m_cookie);
  38. pSum->Release();
  39. }
  40. CInsideCOM::~CInsideCOM()
  41. {
  42. InterlockedDecrement(&g_cComponents);
  43. m_pUnknownFTM->Release();
  44. m_pGIT->RevokeInterfaceFromGlobal(m_cookie);
  45. m_pGIT->Release();
  46. }
  47. ULONG CInsideCOM::AddRef()
  48. {
  49. cout << "Component: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  50. return InterlockedIncrement(&m_cRef);
  51. }
  52. ULONG CInsideCOM::Release()
  53. {
  54. cout << "Component: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  55. ULONG cRef = InterlockedDecrement(&m_cRef);
  56. if(cRef != 0)
  57. return cRef;
  58. delete this;
  59. return 0;
  60. }
  61. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  62. {
  63. if(riid == IID_IUnknown)
  64. {
  65. cout << "Component: CInsideCOM::QueryInterface() for IUnknown returning " << this << endl;
  66. *ppv = (IUnknown*)this;
  67. }
  68. else if(riid == IID_ISum)
  69. {
  70. cout << "Component: CInsideCOM::QueryInterface() for ISum returning " << this << endl;
  71. *ppv = (ISum*)this;
  72. }
  73. else if(riid == IID_IMarshal)
  74. {
  75. cout << "Component: CInsideCOM::QueryInterface() for IMarshal" << endl;
  76. return m_pUnknownFTM->QueryInterface(riid, ppv);
  77. }
  78. else 
  79. {
  80. *ppv = NULL;
  81. return E_NOINTERFACE;
  82. }
  83. AddRef();
  84. return S_OK;
  85. }
  86. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  87. {
  88. // Call into second component
  89. ISum* pSum;
  90. m_pGIT->GetInterfaceFromGlobal(m_cookie, IID_ISum, (void**)&pSum);
  91. HRESULT hr = pSum->Sum(x, y, retval);
  92. pSum->Release();
  93. return hr;
  94. }
  95. class CFactory : public IClassFactory
  96. {
  97. public:
  98. // IUnknown
  99. ULONG __stdcall AddRef();
  100. ULONG __stdcall Release();
  101. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  102. // IClassFactory
  103. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  104. HRESULT __stdcall LockServer(BOOL bLock);
  105. CFactory() : m_cRef(1) { }
  106. ~CFactory() { }
  107. private:
  108. long m_cRef;
  109. };
  110. ULONG CFactory::AddRef()
  111. {
  112. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  113. return InterlockedIncrement(&m_cRef);
  114. }
  115. ULONG CFactory::Release()
  116. {
  117. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  118. ULONG cRef = InterlockedDecrement(&m_cRef);
  119. if(cRef != 0)
  120. return cRef;
  121. delete this;
  122. return 0;
  123. }
  124. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  125. {
  126. if((riid == IID_IUnknown) || (riid == IID_IClassFactory))
  127. {
  128. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  129. *ppv = (IClassFactory *)this;
  130. }
  131. else
  132. {
  133. *ppv = NULL;
  134. return E_NOINTERFACE;
  135. }
  136. AddRef();
  137. return S_OK;
  138. }
  139. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  140. {
  141. if(pUnknownOuter != NULL)
  142. return CLASS_E_NOAGGREGATION;
  143. CInsideCOM *pInsideCOM = new CInsideCOM;
  144. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  145. if(pInsideCOM == NULL)
  146. return E_OUTOFMEMORY;
  147. // QueryInterface probably for IID_IUNKNOWN
  148. HRESULT hr = pInsideCOM->QueryInterface(riid, ppv);
  149. pInsideCOM->Release();
  150. return hr;
  151. }
  152. HRESULT CFactory::LockServer(BOOL bLock)
  153. {
  154. if(bLock)
  155. InterlockedIncrement(&g_cServerLocks);
  156. else
  157. InterlockedDecrement(&g_cServerLocks);
  158. return S_OK;
  159. }
  160. HRESULT __stdcall DllCanUnloadNow()
  161. {
  162. cout << "Component: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
  163. if(g_cServerLocks == 0 && g_cComponents == 0)
  164. return S_OK;
  165. else
  166. return S_FALSE;
  167. }
  168. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  169. {
  170. cout << "Component: DllGetClassObject" << endl;
  171. if(clsid != CLSID_InsideCOM)
  172. return CLASS_E_CLASSNOTAVAILABLE;
  173. CFactory* pFactory = new CFactory;
  174. if(pFactory == NULL)
  175. return E_OUTOFMEMORY;
  176. // QueryInterface probably for IClassFactory
  177. HRESULT hr = pFactory->QueryInterface(riid, ppv);
  178. pFactory->Release();
  179. return hr;
  180. }
  181. HRESULT __stdcall DllRegisterServer()
  182. {
  183. char DllPath[256];
  184. OLECHAR wDllPath[256];
  185. GetModuleFileName(g_hInstance, DllPath, 256);
  186. mbstowcs(wDllPath, DllPath, 256);
  187. ITypeLib* pTypeLib;
  188. HRESULT hr = LoadTypeLibEx(wDllPath, REGKIND_REGISTER, &pTypeLib);
  189. if(FAILED(hr))
  190. return hr;
  191. pTypeLib->Release();
  192. // Adjust the threading model here
  193. return RegisterServer("Component with GIT.dll", CLSID_InsideCOM, "Inside COM+ Sample", "Component.InsideCOM", "Component.InsideCOM.1", "Apartment");
  194. }
  195. HRESULT __stdcall DllUnregisterServer()
  196. {
  197. HRESULT hr = UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  198. if(FAILED(hr))
  199. return hr;
  200. return UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  201. }
  202. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  203. {
  204. g_hInstance = hInstance;
  205. return TRUE;
  206. }