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. HRESULT 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. HRESULT CPrimeCall::Init()
  58. {
  59. if(m_pCtrlUnk)
  60. return m_pCtrlUnk->QueryInterface(IID_ISynchronize, (void**)&m_pSynchronize);
  61. return E_UNEXPECTED;
  62. }
  63. CPrimeCall::CPrimeCall(IUnknown* pCtrlUnk) : m_cRef(1)
  64. {
  65. g_cLocks++;
  66. m_pCtrlUnk = pCtrlUnk;
  67. }
  68. CPrimeCall::~CPrimeCall()
  69. {
  70. g_cLocks--;
  71. m_pSynchronize->Release();
  72. }
  73. HRESULT CPrimeCall::QueryInterface_NoAggregation(REFIID riid, void** ppv)
  74. {
  75. if(riid == IID_IUnknown)
  76. *ppv = (INoAggregationUnknown*)this;
  77. else if(riid == IID_AsyncIPrime)
  78. *ppv = (AsyncIPrime*)this;
  79. else 
  80. {
  81. *ppv = NULL;
  82. return E_NOINTERFACE;
  83. }
  84. ((IUnknown*)(*ppv))->AddRef();
  85. return S_OK;
  86. }
  87. ULONG CPrimeCall::AddRef_NoAggregation()
  88. {
  89. return ++m_cRef;
  90. }
  91. ULONG CPrimeCall::Release_NoAggregation()
  92. {
  93. if(--m_cRef != 0)
  94. return m_cRef;
  95. delete this;
  96. return 0;
  97. }
  98. ULONG CPrimeCall::AddRef()
  99. {
  100. return m_pCtrlUnk->AddRef();
  101. }
  102. ULONG CPrimeCall::Release()
  103. {
  104. return m_pCtrlUnk->Release();
  105. }
  106. HRESULT CPrimeCall::QueryInterface(REFIID riid, void** ppv)
  107. {
  108. return m_pCtrlUnk->QueryInterface(riid, ppv);
  109. }
  110. class CInsideCOM : public IPrime, public ICallFactory
  111. {
  112. public:
  113. // IUnknown
  114. ULONG __stdcall AddRef();
  115. ULONG __stdcall Release();
  116. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  117. // IPrime
  118. HRESULT __stdcall IsPrime(int testnumber, int* retval);
  119. // ICallFactory
  120.     HRESULT __stdcall CreateCall(REFIID riid, IUnknown* pCtrlUnk, REFIID riid2, IUnknown** ppv);
  121. CInsideCOM() : m_cRef(1) { g_cLocks++; }
  122. ~CInsideCOM()
  123. {
  124. g_cLocks--;
  125. }
  126. private:
  127. ULONG m_cRef;
  128. };
  129. HRESULT CInsideCOM::CreateCall(REFIID riid, IUnknown* pCtrlUnk, REFIID riid2, IUnknown** ppv)
  130. {
  131. if(riid != IID_AsyncIPrime)
  132. return E_INVALIDARG;
  133. CPrimeCall* pPrimeCall = new CPrimeCall(pCtrlUnk);
  134. HRESULT hr = pPrimeCall->Init();
  135. hr = pPrimeCall->QueryInterface_NoAggregation(riid2, (void**)ppv);
  136. pPrimeCall->Release_NoAggregation();
  137. return hr;
  138. }
  139. HRESULT CPrimeCall::Begin_IsPrime(int testnumber)
  140. {
  141. unsigned long count;
  142. unsigned long halfnumber = testnumber / 2 + 1;
  143. HRESULT hr = 0;
  144. for(count = 2; count < halfnumber; count++)
  145. {
  146. ICancelMethodCalls* pCancelMethodCalls = 0;
  147. CoGetCallContext(IID_ICancelMethodCalls, (void**)&pCancelMethodCalls);
  148. hr = pCancelMethodCalls->TestCancel();
  149. pCancelMethodCalls->Release();
  150. // hr = CoTestCancel();
  151. if(hr == RPC_E_CALL_CANCELED)
  152. {
  153. char buffer[255];
  154. wsprintf(buffer, "Begin_IsPrime(%d) canceled", testnumber);
  155. MessageBox(0, buffer, "HER THERE", MB_OK);
  156. return RPC_E_CALL_CANCELED;
  157. }
  158. if(testnumber % count == 0)
  159. {
  160. m_retval = false;
  161. m_pSynchronize->Signal();
  162. return S_OK;
  163. }
  164. }
  165. m_retval = true;
  166.     m_pSynchronize->Signal();
  167. return S_OK;
  168. }
  169. HRESULT CPrimeCall::Finish_IsPrime(int* retval)
  170. {
  171. *retval = m_retval;
  172. return S_OK;
  173. }
  174. HRESULT CInsideCOM::IsPrime(int testnumber, int* retval)
  175. {
  176. unsigned long count;
  177. unsigned long HalfNumber = testnumber / 2 + 1;
  178. for(count = 2; count < HalfNumber; count++)
  179. {
  180. if(testnumber % count == 0)
  181. {
  182. *retval = false;
  183. return S_OK;
  184. }
  185. }
  186. *retval = true;
  187. return S_OK;
  188. }
  189. ULONG CInsideCOM::AddRef()
  190. {
  191. return ++m_cRef;
  192. }
  193. ULONG CInsideCOM::Release()
  194. {
  195. if(--m_cRef != 0)
  196. return m_cRef;
  197. delete this;
  198. return 0;
  199. }
  200. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  201. {
  202. if(riid == IID_IUnknown)
  203. *ppv = (IPrime*)this;
  204. else if(riid == IID_ICallFactory)
  205. *ppv = (ICallFactory*)this;
  206. else if(riid == IID_IPrime)
  207. *ppv = (IPrime*)this;
  208. else
  209. {
  210. *ppv = NULL;
  211. return E_NOINTERFACE;
  212. }
  213. AddRef();
  214. return S_OK;
  215. }
  216. class CFactory : public IClassFactory
  217. {
  218. public:
  219. // IUnknown
  220. ULONG __stdcall AddRef();
  221. ULONG __stdcall Release();
  222. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  223. // IClassFactory
  224. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  225. HRESULT __stdcall LockServer(BOOL bLock);
  226. CFactory() : m_cRef(1) { g_cLocks++; }
  227. ~CFactory() { g_cLocks--; }
  228. private:
  229. ULONG m_cRef;
  230. };
  231. ULONG CFactory::AddRef()
  232. {
  233. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  234. return ++m_cRef;
  235. }
  236. ULONG CFactory::Release()
  237. {
  238. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  239. if(--m_cRef != 0)
  240. return m_cRef;
  241. delete this;
  242. return 0;
  243. }
  244. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  245. {
  246. if(riid == IID_IUnknown || riid == IID_IClassFactory)
  247. *ppv = (IClassFactory*)this;
  248. else
  249. {
  250. *ppv = NULL;
  251. return E_NOINTERFACE;
  252. }
  253. AddRef();
  254. return S_OK;
  255. }
  256. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  257. {
  258. if(pUnknownOuter != NULL)
  259. return CLASS_E_NOAGGREGATION;
  260. CInsideCOM *pInsideCOM = new CInsideCOM;
  261. if(pInsideCOM == NULL)
  262. return E_OUTOFMEMORY;
  263. HRESULT hr = pInsideCOM->QueryInterface(riid, ppv);
  264. pInsideCOM->Release();
  265. return hr;
  266. }
  267. HRESULT CFactory::LockServer(BOOL bLock)
  268. {
  269. if(bLock)
  270. g_cLocks++;
  271. else
  272. g_cLocks--;
  273. return S_OK;
  274. }
  275. HRESULT __stdcall DllCanUnloadNow()
  276. {
  277. if(g_cLocks == 0)
  278. {
  279. MessageBox(0, "DllCanUnloadNow() ", "YES", MB_OK);
  280. return S_OK;
  281. }
  282. else
  283. {
  284. MessageBox(0, "DllCanUnloadNow() ", "No", MB_OK);
  285.     return S_FALSE;
  286. }
  287. }
  288. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  289. {
  290. if(clsid != CLSID_InsideCOM)
  291. return CLASS_E_CLASSNOTAVAILABLE;
  292. CFactory* pFactory = new CFactory;
  293. if(pFactory == NULL)
  294. return E_OUTOFMEMORY;
  295. HRESULT hr = pFactory->QueryInterface(riid, ppv);
  296. pFactory->Release();
  297. return hr;
  298. }
  299. HRESULT __stdcall DllRegisterServer()
  300. {
  301. char DllPath[MAX_PATH];
  302. GetModuleFileName(g_hInstance, DllPath, sizeof(DllPath));
  303. OLECHAR wDllPath[MAX_PATH];
  304. mbstowcs(wDllPath, DllPath, sizeof(wDllPath));
  305. ITypeLib* pTypeLib;
  306. HRESULT hr = LoadTypeLibEx(wDllPath, REGKIND_REGISTER, &pTypeLib);
  307. if(FAILED(hr))
  308. return hr;
  309. pTypeLib->Release();
  310. return RegisterServerEx(g_regData, DllPath);
  311. }
  312. HRESULT __stdcall DllUnregisterServer()
  313. {
  314. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  315. return UnregisterServerEx(g_regData);
  316. }
  317. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  318. {
  319. g_hInstance = hInstance;
  320. return TRUE;
  321. }