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

Windows编程

开发平台:

Visual C++

  1. // component.cpp
  2. #define _WIN32_DCOM
  3. #include <windows.h>
  4. #include <ocidl.h>
  5. #include <iostream.h>
  6. #include <stdio.h>
  7. #include <conio.h>
  8. #include "Componentcomponent.h" // Generated by MIDL
  9. #include "registry.h"
  10. const REG_DATA g_regData[] = {
  11.     { "CLSID\{10000002-0000-0000-0000-000000000001}", 0, "Inside COM+: In Process Component" },
  12.     { "CLSID\{10000002-0000-0000-0000-000000000001}", "AppID", "{10000002-0000-0000-0000-000000000001}" },
  13. { "CLSID\{10000002-0000-0000-0000-000000000001}\InprocServer32", 0, (const char*)-1 }, 
  14. { "CLSID\{10000002-0000-0000-0000-000000000001}\InprocServer32", "ThreadingModel", "Both" }, 
  15. { "CLSID\{10000002-0000-0000-0000-000000000001}\ProgID", 0, "Component.InsideCOM.1" },
  16. { "CLSID\{10000002-0000-0000-0000-000000000001}\VersionIndependentProgID", 0, "Component.InsideCOM" },
  17. { "AppID\{10000002-0000-0000-0000-000000000001}", 0, "Inside COM+: In Process Component" },
  18. { "AppID\{10000002-0000-0000-0000-000000000001}", "DllSurrogate", "" },
  19. { "Component.InsideCOM", 0, "Inside COM+: In Process Component" },
  20. { "Component.InsideCOM\CLSID", 0, "{10000002-0000-0000-0000-000000000001}" },
  21. { "Component.InsideCOM\CurVer", 0, "Component.InsideCOM.1" },
  22. { "Component.InsideCOM.1", 0, "Inside COM+: In Process Component" },
  23. { "Component.InsideCOM.1\CLSID", 0, "{10000002-0000-0000-0000-000000000001}" },
  24. { 0, 0, 0 }
  25. };
  26. HINSTANCE g_hInstance;
  27. long g_cLocks = 0;
  28. interface INoAggregationUnknown
  29. {
  30. virtual HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv)=0;
  31. virtual ULONG __stdcall AddRef_NoAggregation()=0;
  32. virtual ULONG __stdcall Release_NoAggregation()=0;
  33. };
  34. class CPrimeCall : public AsyncIPrime, public INoAggregationUnknown
  35. {
  36. public:
  37. // IUnknown
  38. ULONG __stdcall AddRef();
  39. ULONG __stdcall Release();
  40. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  41. // INoAggregationUnknown
  42. ULONG __stdcall AddRef_NoAggregation();
  43. ULONG __stdcall Release_NoAggregation();
  44. HRESULT __stdcall QueryInterface_NoAggregation(REFIID riid, void** ppv);
  45. // AsyncIPrime
  46.     HRESULT __stdcall Begin_IsPrime(int testnumber);
  47. HRESULT __stdcall Finish_IsPrime(int* retval);
  48. void Init();
  49. CPrimeCall(IUnknown* pCtrlUnk);
  50. ~CPrimeCall();
  51. private:
  52. ISynchronize* m_pSynchronize;
  53. IUnknown* m_pCtrlUnk;
  54. unsigned char m_retval;
  55. ULONG m_cRef;
  56. };
  57. void CPrimeCall::Init()
  58. {
  59. HRESULT hr = 0;
  60. if(m_pCtrlUnk)
  61. {
  62. hr = m_pCtrlUnk->QueryInterface(IID_ISynchronize, (void**)&m_pSynchronize);
  63. if(FAILED(hr))
  64. MessageBox(0, "QI FAILED", "for ISynch", MB_OK);
  65. }
  66. }
  67. CPrimeCall::CPrimeCall(IUnknown* pCtrlUnk) : m_cRef(1)
  68. {
  69. g_cLocks++;
  70. m_pCtrlUnk = pCtrlUnk;
  71. m_pSynchronize = 0;
  72. }
  73. CPrimeCall::~CPrimeCall()
  74. {
  75. g_cLocks--;
  76. m_pSynchronize->Release();
  77. }
  78. HRESULT CPrimeCall::QueryInterface_NoAggregation(REFIID riid, void** ppv)
  79. {
  80. if(riid == IID_IUnknown)
  81. *ppv = (INoAggregationUnknown*)this;
  82. else if(riid == IID_AsyncIPrime)
  83. *ppv = (AsyncIPrime*)this;
  84. else 
  85. {
  86. *ppv = NULL;
  87. return E_NOINTERFACE;
  88. }
  89. ((IUnknown*)(*ppv))->AddRef();
  90. return S_OK;
  91. }
  92. ULONG CPrimeCall::AddRef_NoAggregation()
  93. {
  94. return ++m_cRef;
  95. }
  96. ULONG CPrimeCall::Release_NoAggregation()
  97. {
  98. if(--m_cRef != 0)
  99. return m_cRef;
  100. delete this;
  101. return 0;
  102. }
  103. ULONG CPrimeCall::AddRef()
  104. {
  105. return m_pCtrlUnk->AddRef();
  106. }
  107. ULONG CPrimeCall::Release()
  108. {
  109. return m_pCtrlUnk->Release();
  110. }
  111. HRESULT CPrimeCall::QueryInterface(REFIID riid, void** ppv)
  112. {
  113. return m_pCtrlUnk->QueryInterface(riid, ppv);
  114. }
  115. class CInsideCOM : public IPrime, public ICallFactory
  116. {
  117. public:
  118. // IUnknown
  119. ULONG __stdcall AddRef();
  120. ULONG __stdcall Release();
  121. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  122. // IPrime
  123. HRESULT __stdcall IsPrime(int testnumber, int* retval);
  124. // ICallFactory
  125.     HRESULT __stdcall CreateCall(REFIID riid, IUnknown* pCtrlUnk, REFIID riid2, IUnknown** ppv);
  126. CInsideCOM() : m_cRef(1) { g_cLocks++; }
  127. ~CInsideCOM()
  128. {
  129. cout << "Component: CInsideCOM::~CInsideCOM()" << endl;
  130. g_cLocks--;
  131. }
  132. private:
  133. ULONG m_cRef;
  134. };
  135. HRESULT CInsideCOM::CreateCall(REFIID riid, IUnknown* pCtrlUnk, REFIID riid2, IUnknown** ppv)
  136. {
  137. if(riid != IID_AsyncIPrime)
  138. return E_INVALIDARG;
  139. CPrimeCall* pPrimeCall = new CPrimeCall(pCtrlUnk);
  140. pPrimeCall->Init();
  141. HRESULT hr = pPrimeCall->QueryInterface_NoAggregation(riid2, (void**)ppv);
  142. pPrimeCall->Release_NoAggregation();
  143. return hr;
  144. }
  145. HRESULT CPrimeCall::Begin_IsPrime(int testnumber)
  146. {
  147. unsigned long count;
  148. unsigned long HalfNumber = testnumber / 2 + 1;
  149. HRESULT hr = 0;
  150. for(count = 2; count < HalfNumber; count++)
  151. {
  152. if(CoTestCancel() == RPC_E_CALL_CANCELED)
  153. {
  154. char buffer[255];
  155. wsprintf(buffer, "Begin_IsPrime(%d) canceled", testnumber);
  156. MessageBox(0, buffer, "Call Canceled", MB_OK);
  157. return RPC_E_CALL_CANCELED;
  158. }
  159. if(testnumber % count == 0)
  160. {
  161. m_retval = false;
  162. m_pSynchronize->Signal();
  163. return S_OK;
  164. }
  165. }
  166. m_retval = true;
  167. m_pSynchronize->Signal();
  168. return S_OK;
  169. }
  170. HRESULT CPrimeCall::Finish_IsPrime(int* retval)
  171. {
  172. *retval = m_retval;
  173. return S_OK;
  174. }
  175. HRESULT CInsideCOM::IsPrime(int testnumber, int* retval)
  176. {
  177. unsigned long count;
  178. unsigned long HalfNumber = testnumber / 2 + 1;
  179. // MessageBox(0, "BEGIN", "ISPRIME", MB_OK);
  180. for(count = 2; count < HalfNumber; count++)
  181. {
  182. if(testnumber % count == 0)
  183. {
  184. *retval = false;
  185. return S_OK;
  186. }
  187. }
  188. *retval = true;
  189. return S_OK;
  190. }
  191. ULONG CInsideCOM::AddRef()
  192. {
  193. return ++m_cRef;
  194. }
  195. ULONG CInsideCOM::Release()
  196. {
  197. if(--m_cRef != 0)
  198. return m_cRef;
  199. delete this;
  200. return 0;
  201. }
  202. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  203. {
  204. if(riid == IID_IUnknown)
  205. *ppv = (IPrime*)this;
  206. else if(riid == IID_ICallFactory)
  207. *ppv = (ICallFactory*)this;
  208. else if(riid == IID_IPrime)
  209. *ppv = (IPrime*)this;
  210. else
  211. {
  212. *ppv = NULL;
  213. return E_NOINTERFACE;
  214. }
  215. ((IUnknown*)(*ppv))->AddRef();
  216. return S_OK;
  217. }
  218. class CFactory : public IClassFactory
  219. {
  220. public:
  221. // IUnknown
  222. ULONG __stdcall AddRef();
  223. ULONG __stdcall Release();
  224. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  225. // IClassFactory
  226. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  227. HRESULT __stdcall LockServer(BOOL bLock);
  228. CFactory() : m_cRef(1) { g_cLocks++; }
  229. ~CFactory() { g_cLocks--; }
  230. private:
  231. ULONG m_cRef;
  232. };
  233. ULONG CFactory::AddRef()
  234. {
  235. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  236. return ++m_cRef;
  237. }
  238. ULONG CFactory::Release()
  239. {
  240. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  241. if(--m_cRef != 0)
  242. return m_cRef;
  243. delete this;
  244. return 0;
  245. }
  246. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  247. {
  248. if(riid == IID_IUnknown || riid == IID_IClassFactory)
  249. *ppv = (IClassFactory*)this;
  250. else
  251. {
  252. *ppv = NULL;
  253. return E_NOINTERFACE;
  254. }
  255. AddRef();
  256. return S_OK;
  257. }
  258. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  259. {
  260. if(pUnknownOuter != NULL)
  261. return CLASS_E_NOAGGREGATION;
  262. CInsideCOM *pInsideCOM = new CInsideCOM;
  263. if(pInsideCOM == NULL)
  264. return E_OUTOFMEMORY;
  265. HRESULT hr = pInsideCOM->QueryInterface(riid, ppv);
  266. pInsideCOM->Release();
  267. return hr;
  268. }
  269. HRESULT CFactory::LockServer(BOOL bLock)
  270. {
  271. if(bLock)
  272. g_cLocks++;
  273. else
  274. g_cLocks--;
  275. return S_OK;
  276. }
  277. HRESULT __stdcall DllCanUnloadNow()
  278. {
  279. cout << "Component: DllCanUnloadNow() " << (g_cLocks == 0 ? "Yes" : "No") << endl;
  280. if(g_cLocks == 0)
  281. return S_OK;
  282. else
  283.     return S_FALSE;
  284. }
  285. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  286. {
  287. if(clsid != CLSID_InsideCOM)
  288. return CLASS_E_CLASSNOTAVAILABLE;
  289. CFactory* pFactory = new CFactory;
  290. if(pFactory == NULL)
  291. return E_OUTOFMEMORY;
  292. HRESULT hr = pFactory->QueryInterface(riid, ppv);
  293. pFactory->Release();
  294. return hr;
  295. }
  296. HRESULT __stdcall DllRegisterServer()
  297. {
  298. char DllPath[MAX_PATH];
  299. GetModuleFileName(g_hInstance, DllPath, sizeof(DllPath));
  300. OLECHAR wDllPath[MAX_PATH];
  301. mbstowcs(wDllPath, DllPath, sizeof(wDllPath));
  302. ITypeLib* pTypeLib;
  303. HRESULT hr = LoadTypeLibEx(wDllPath, REGKIND_REGISTER, &pTypeLib);
  304. if(FAILED(hr))
  305. return hr;
  306. pTypeLib->Release();
  307. return RegisterServerEx(g_regData, DllPath);
  308. }
  309. HRESULT __stdcall DllUnregisterServer()
  310. {
  311. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  312. return UnregisterServerEx(g_regData);
  313. }
  314. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  315. {
  316. g_hInstance = hInstance;
  317. return TRUE;
  318. }