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

Windows编程

开发平台:

Visual C++

  1. // local.cpp
  2. #define _WIN32_DCOM
  3. #include <iostream.h>
  4. #include <stdio.h>
  5. #include "Componentcomponent.h"
  6. #include "registry.h"
  7. HANDLE g_hEvent;
  8. class CInsideCOM : public ISum
  9. {
  10. public:
  11. // IUnknown
  12. ULONG __stdcall AddRef();
  13. ULONG __stdcall Release();
  14. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  15. // ISum
  16. HRESULT __stdcall Sum(int x, int y, int *retval);
  17. HRESULT __stdcall Sum2(myDataType test, int *retval);
  18. CInsideCOM();
  19. ~CInsideCOM();
  20. private:
  21. long m_cRef;
  22. };
  23. CInsideCOM::CInsideCOM() : m_cRef(1)
  24. {
  25. CoAddRefServerProcess();
  26. }
  27. CInsideCOM::~CInsideCOM()
  28. {
  29. cout << "Component: CInsideCOM::~CInsideCOM()" << endl;
  30. if(CoReleaseServerProcess() == 0)
  31. SetEvent(g_hEvent);
  32. }
  33. ULONG CInsideCOM::AddRef()
  34. {
  35. cout << "Component: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  36. return InterlockedIncrement(&m_cRef);
  37. }
  38. ULONG CInsideCOM::Release()
  39. {
  40. cout << "Component: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  41. unsigned cRef = InterlockedDecrement(&m_cRef);
  42. if(cRef != 0)
  43. return cRef;
  44. delete this;
  45. return 0;
  46. }
  47. HRESULT CInsideCOM::QueryInterface(REFIID iid, void **ppv)
  48. {
  49. if(iid == IID_IUnknown)
  50. {
  51. cout << "Component: CInsideCOM::QueryInterface() for IUnknown" << endl;
  52. *ppv = (IUnknown*)this;
  53. }
  54. else if(iid == IID_ISum)
  55. {
  56. cout << "Component: CInsideCOM::QueryInterface() for ISum" << endl;
  57. *ppv = (ISum*)this;
  58. }
  59. else
  60. {
  61. *ppv = NULL;
  62. return E_NOINTERFACE;
  63. }
  64. AddRef();
  65. return S_OK;
  66. }
  67. HRESULT CInsideCOM::Sum(int x, int y, int *retval)
  68. {
  69. *retval = x + y;
  70. return S_OK;
  71. }
  72. HRESULT CInsideCOM::Sum2(myDataType test, int *retval)
  73. {
  74. *retval = test.x + test.y;
  75. return S_OK;
  76. }
  77. class CFactory : public IClassFactory
  78. {
  79. public:
  80. // IUnknown
  81. ULONG __stdcall AddRef();
  82. ULONG __stdcall Release();
  83. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  84. // IClassFactory
  85. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
  86. HRESULT __stdcall LockServer(BOOL bLock);
  87. CFactory() : m_cRef(1) { }
  88. ~CFactory() { cout << "Component: CFactory::~CFactory()" << endl; }
  89. private:
  90. long m_cRef;
  91. };
  92. ULONG CFactory::AddRef()
  93. {
  94. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  95. return InterlockedIncrement(&m_cRef);
  96. }
  97. ULONG CFactory::Release()
  98. {
  99. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  100. unsigned cRef = InterlockedDecrement(&m_cRef);
  101. if(cRef != 0)
  102. return cRef;
  103. delete this;
  104. return 0;
  105. }
  106. HRESULT CFactory::QueryInterface(REFIID iid, void** ppv)
  107. {
  108. if((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  109. {
  110. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  111. *ppv = (IClassFactory *)this;
  112. }
  113. else 
  114. {
  115. *ppv = NULL;
  116. return E_NOINTERFACE;
  117. }
  118. AddRef();
  119. return S_OK;
  120. }
  121. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void **ppv)
  122. {
  123. if(pUnknownOuter != NULL)
  124. return CLASS_E_NOAGGREGATION;
  125. CInsideCOM *pInsideCOM = new CInsideCOM;
  126. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  127. if(pInsideCOM == NULL)
  128. return E_OUTOFMEMORY;
  129. HRESULT hr = pInsideCOM->QueryInterface(iid, ppv);
  130. pInsideCOM->Release();
  131. return hr;
  132. }
  133. HRESULT CFactory::LockServer(BOOL bLock)
  134. {
  135. if(bLock)
  136. CoAddRefServerProcess();
  137. else
  138. if(CoReleaseServerProcess() == 0)
  139. SetEvent(g_hEvent);
  140. return S_OK;
  141. }
  142. void RegisterComponent()
  143. {
  144. ITypeLib* pTypeLib = 0;
  145. HRESULT hr = LoadTypeLibEx(L"component.exe", REGKIND_DEFAULT, &pTypeLib);
  146. if(FAILED(hr))
  147. cout << "LoadTypeLibEx failed" << endl;
  148. ITypeInfo* pTypeInfo = 0;
  149. const GUID GUID_myDataType = {0x10000099,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
  150. hr = pTypeLib->GetTypeInfoOfGuid(GUID_myDataType, &pTypeInfo);
  151. if(FAILED(hr))
  152. cout << "GetTypeInfoOfGuid failed" << endl;
  153. pTypeLib->Release();
  154. IRecordInfo* pRecordInfo = 0;
  155. hr = GetRecordInfoFromTypeInfo(pTypeInfo, &pRecordInfo);
  156. if(FAILED(hr))
  157. cout << "GetRecordInfoFromTypeInfo failed" << endl;
  158. pTypeInfo->Release();
  159. BSTR string = 0;
  160. hr = pRecordInfo->GetName(&string);
  161. ULONG size;
  162. hr = pRecordInfo->GetSize(&size);
  163. if(FAILED(hr))
  164. cout << "GetName failed" << endl;
  165. wprintf(L"name is %s, size is %d bytesn", string, size);
  166. Sleep(2000);
  167. pRecordInfo->Release();
  168. SysFreeString(string);
  169. RegisterServer("component.exe", CLSID_InsideCOM, "Inside COM Sample", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  170. }
  171. void CommandLineParameters(int argc, char** argv)
  172. {
  173. RegisterComponent();
  174. if(argc < 2)
  175. {
  176. cout << "No parameter, but registered anyway..." << endl;
  177. exit(false);
  178. }
  179. char* szToken = strtok(argv[1], "-/"); 
  180. if(_stricmp(szToken, "RegServer") == 0)
  181. {
  182. RegisterComponent();
  183. cout << "RegServer" << endl;
  184. exit(true);
  185. }
  186. if(_stricmp(szToken, "UnregServer") == 0)
  187. {
  188. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  189. UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  190. cout << "UnregServer" << endl;
  191. exit(true);
  192. }
  193. if(_stricmp(szToken, "Embedding") != 0)
  194. {
  195. cout << "Invalid parameter" << endl;
  196. exit(false);
  197. }
  198. }
  199. void main(int argc, char** argv)
  200. {
  201. CommandLineParameters(argc, argv);
  202. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  203. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  204. DWORD dwRegister;
  205. IClassFactory *pIFactory = new CFactory();
  206. CoRegisterClassObject(CLSID_InsideCOM, pIFactory, CLSCTX_LOCAL_SERVER, REGCLS_SUSPENDED|REGCLS_MULTIPLEUSE, &dwRegister);
  207. CoResumeClassObjects();
  208. WaitForSingleObject(g_hEvent, INFINITE);
  209. CloseHandle(g_hEvent);
  210. CoRevokeClassObject(dwRegister);
  211. pIFactory->Release();
  212. CoUninitialize();
  213. }