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

Windows编程

开发平台:

Visual C++

  1. /*
  2.  Bug in MIDL: Comment out the three references to _maxcount_test in the component_p.c file
  3. */
  4. // local.cpp
  5. #define _WIN32_DCOM
  6. #include <windows.h>
  7. #include <iostream.h>  // For cout
  8. #include "registry.h"  // For registry functions
  9. #include "Componentcomponent.h" // Generated by MIDL
  10. #include <stdio.h>
  11. #include <conio.h>
  12. long g_cComponents = 0;
  13. long g_cServerLocks = 0;
  14. HANDLE g_hEvent;
  15. class CTestIDL : public ITest
  16. {
  17. public:
  18. // IUnknown
  19. ULONG __stdcall AddRef();
  20. ULONG __stdcall Release();
  21. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  22. // ITest
  23. HRESULT __stdcall SquareInteger(int myInteger, int* square);
  24. HRESULT __stdcall SumOfIntegers1(int myIntegers[5], int* sum);
  25. HRESULT __stdcall SumOfIntegers2(int cMax, int* myIntegers, int* sum);
  26. HRESULT __stdcall SumOfIntegers3(SUM_STRUCT* myIntegers, int* sum);
  27. HRESULT __stdcall SumOfIntegers4(int cFirst, int cActual, int* myIntegers[7], int* sum);
  28. HRESULT __stdcall ProduceIntegers1(int cMax, int* myIntegers);
  29. HRESULT __stdcall ProduceIntegers2(int* pcActual, int myIntegers[4096]);
  30. HRESULT __stdcall ProduceIntegers3(int cMax, int* pcActual, int* myIntegers);
  31. HRESULT __stdcall SendReceiveIntegers(int* pcActual, int myIntegers[4096]);
  32. HRESULT __stdcall SendString1(int cLength, wchar_t* myString);
  33. HRESULT __stdcall SendString2(wchar_t* myString);
  34. HRESULT __stdcall SendReceiveString1(wchar_t* myString);
  35. HRESULT __stdcall SendReceiveString2(int cMax, wchar_t* myString);
  36. HRESULT __stdcall SendReceiveString3(wchar_t** myString);
  37. HRESULT __stdcall SendInteger(int** test);
  38. HRESULT __stdcall SendIntegers1(int** test);
  39. HRESULT __stdcall SendIntegers2(int** test);
  40. HRESULT __stdcall SendIntegers3(int** test);
  41. CTestIDL() : m_cRef(1) { g_cComponents++; }
  42. ~CTestIDL() { cout << "Component: CTestIDL::~CTestIDL()" << endl, g_cComponents--; }
  43. private:
  44. ULONG m_cRef;
  45. };
  46. ULONG CTestIDL::AddRef()
  47. {
  48. cout << "Component: CTestIDL::AddRef() m_cRef = " << m_cRef + 1 << endl;
  49. return ++m_cRef;
  50. }
  51. ULONG CTestIDL::Release()
  52. {
  53. cout << "Component: CTestIDL::Release() m_cRef = " << m_cRef - 1 << endl;
  54. if(--m_cRef != 0)
  55. return m_cRef;
  56. SetEvent(g_hEvent); // ADD THIS!!!
  57. delete this;
  58. return 0;
  59. }
  60. HRESULT CTestIDL::QueryInterface(REFIID riid, void** ppv)
  61. {
  62. if(riid == IID_IUnknown)
  63. {
  64. cout << "Component: CTestIDL::QueryInterface() for IUnknown returning " << this << endl;
  65. *ppv = reinterpret_cast<IUnknown*>(this);
  66. }
  67. else if(riid == IID_ITest)
  68. {
  69. cout << "Component: CTestIDL::QueryInterface() for ITest returning " << this << endl;
  70. *ppv = (ITest*)this;
  71. }
  72. else 
  73. {
  74. *ppv = NULL;
  75. return E_NOINTERFACE;
  76. }
  77. AddRef();
  78. return S_OK;
  79. }
  80. // HRESULT SquareInteger([in] int myInteger, [out] int* square);
  81. HRESULT CTestIDL::SquareInteger(int myInteger, int* square)
  82. {
  83. *square = myInteger * myInteger;
  84. return S_OK;
  85. }
  86. // HRESULT SumOfIntegers1([in] int myIntegers[5], [out] int* sum);
  87. HRESULT CTestIDL::SumOfIntegers1(int myIntegers[5], int* sum)
  88. {
  89. *sum = 0;
  90. for(int i = 0; i < 5; i++)
  91. *sum = *sum + myIntegers[i];
  92. return S_OK;
  93. }
  94. // HRESULT SumOfIntegers2([in] int cMax, [in, size_is(cMax)] int* myIntegers, [out] int* sum);
  95. HRESULT CTestIDL::SumOfIntegers2(int cMax, int* myIntegers, int* sum)
  96. {
  97. *sum = 0;
  98. for(int i = 0; i < cMax; i++)
  99. *sum = *sum + myIntegers[i];
  100. return S_OK;
  101. }
  102. /* typedef struct tagSUM_STRUCT
  103. {
  104. int cMax;
  105. [size_is(cMax)] int* myIntegers;
  106. } SUM_STRUCT; */
  107. // HRESULT SumOfIntegers3([in] SUM_STRUCT* myIntegers, [out] int* sum);
  108. HRESULT CTestIDL::SumOfIntegers3(SUM_STRUCT* myIntegers, int* sum)
  109. {
  110. *sum = 0;
  111. for(int i = 0; i < myIntegers->cMax; i++)
  112. *sum = *sum + myIntegers->myIntegers[i];
  113. return S_OK;
  114. }
  115. // HRESULT SumOfIntegers4([in] int cFirst, [in] int cActual, [in, first_is(cFirst), length_is(cActual)] int* myIntegers[7], [out] int* sum);
  116. HRESULT CTestIDL::SumOfIntegers4(int cFirst, int cActual, int* myIntegers[7], int* sum)
  117. {
  118. *sum = 3;
  119. for(int i = cFirst; i < cFirst + cActual; i++)
  120. {
  121. cout << "i = " << i << " cFirst = " << cFirst << " cActual = " << cActual << endl;
  122. cout << "myIntegers = " << myIntegers[i][0] << endl;
  123. // *sum = *sum + *myIntegers[i];
  124. }
  125. _getch();
  126. return S_OK;
  127. }
  128. // HRESULT ProduceIntegers1([in] int cMax, [out, size_is(cMax)] int* myIntegers);
  129. HRESULT CTestIDL::ProduceIntegers1(int cMax, int* myIntegers)
  130. {
  131. for(int i = 0; i < cMax; i++)
  132. myIntegers[i] = i;
  133. return S_OK;
  134. }
  135. // HRESULT ProduceIntegers2([out] int* pcActual, [out, length_is(*pcActual)] int myIntegers[4096]);
  136. HRESULT CTestIDL::ProduceIntegers2(int* pcActual, int myIntegers[4096])
  137. {
  138. *pcActual = 400;
  139. for(int i = 0; i < *pcActual; i++)
  140. myIntegers[i] = i;
  141. return S_OK;
  142. }
  143. // HRESULT ProduceIntegers3([in] int cMax, [out] int* pcActual, [out, size_is(cMax), length_is(*pcActual)] int* myIntegers);
  144. HRESULT CTestIDL::ProduceIntegers3(int cMax, int* pcActual, int* myIntegers)
  145. {
  146. *pcActual = cMax / 2;
  147. for(int i = 0; i < *pcActual; i++)
  148. myIntegers[i] = i;
  149. return S_OK;
  150. }
  151. // HRESULT SendReceiveIntegers([in, out] int* pcActual, [in, out, length_is(*pcActual)] int myIntegers[4096]);
  152. HRESULT CTestIDL::SendReceiveIntegers(int* pcActual, int myIntegers[4096])
  153. {
  154. // In
  155. cout << "SendReceiveIntegers: << " << *pcActual << " integers received" << endl;
  156. for(int i = 0; i < *pcActual; i++)
  157. cout << "SendReceiveIntegers: " << myIntegers[i] << endl;
  158. // Out
  159. *pcActual = 400;
  160. for(i = 0; i < *pcActual; i++)
  161. myIntegers[i] = i;
  162. return S_OK;
  163. }
  164. // HRESULT SendString1([in] int cLength, [in, size_is(cLength)] wchar_t* myString);
  165. HRESULT CTestIDL::SendString1(int cLength, wchar_t* myString)
  166. {
  167. wprintf(L"String of %d characters contains %sn", cLength, myString);
  168. return S_OK;
  169. }
  170. // HRESULT SendString2([in, string] wchar_t* myString);
  171. HRESULT CTestIDL::SendString2(wchar_t* myString)
  172. {
  173. wprintf(L"String contains %sn", myString);
  174. return S_OK;
  175. }
  176. // HRESULT SendReceiveString1([in, out, string] wchar_t* myString);
  177. HRESULT CTestIDL::SendReceiveString1(wchar_t* myString)
  178. {
  179. wprintf(L"SendReceiveString1: %sn", myString); // Hello COM
  180. // This will cause a fault!
  181. // wcscpy(myString, L"Nice weather today Nice weather today Nice weather today Nice weather today Nice weather today Nice weather today Nice weather today"); // Oh-oh
  182. // Nine characters max
  183. wcscpy(myString, L"only nine"); // OK
  184. return S_OK;
  185. }
  186. // HRESULT SendReceiveString2([in] int cMax, [in, out, string, size_is(cMax)] wchar_t* myString);
  187. HRESULT CTestIDL::SendReceiveString2(int cMax, wchar_t* myString)
  188. {
  189. wprintf(L"SendReceiveString2: %sn", myString); // Hello COM
  190. for(int i = 0; i < cMax - 1; i++)
  191. myString[i] = L'A';
  192. myString[cMax - 1] = L'';
  193. return S_OK;
  194. }
  195. // HRESULT SendReceiveString3([in, out, string] wchar_t** myString);
  196. HRESULT CTestIDL::SendReceiveString3(wchar_t** myString)
  197. {
  198. wprintf(L"SendReceiveString3: %sn", *myString);
  199. CoTaskMemFree(*myString);
  200. wchar_t returnString[] = L"Nice weather today";
  201. *myString = (wchar_t*)CoTaskMemAlloc((wcslen(returnString)+1)*sizeof(wchar_t));
  202. wcscpy(*myString, returnString);
  203. return S_OK;
  204. }
  205. // HRESULT SendInteger([in] int** test);
  206. HRESULT CTestIDL::SendInteger(int** test)
  207. {
  208. cout << "SendInteger: test[0][0] = " << test[0][0] << endl;
  209. return S_OK;
  210. }
  211. // HRESULT SendIntegers1([in, size_is(, 2)] int** test);
  212. HRESULT CTestIDL::SendIntegers1(int** test)
  213. {
  214. cout << "SendIntegers1: test[0][0] = " << test[0][0] << endl;
  215. cout << "SendIntegers1: test[0][1] = " << test[0][1] << endl;
  216. return S_OK;
  217. }
  218. // HRESULT SendIntegers2([in, size_is(3, )] int** test);
  219. HRESULT CTestIDL::SendIntegers2(int** test)
  220. {
  221. cout << "SendIntegers2: test[0][0] = " << test[0][0] << endl;
  222. cout << "SendIntegers2: test[1][0] = " << test[1][0] << endl;
  223. cout << "SendIntegers2: test[2][0] = " << test[2][0] << endl;
  224. return S_OK;
  225. }
  226. // HRESULT SendIntegers3([in, size_is(3, 2)] int** test);
  227. HRESULT CTestIDL::SendIntegers3(int** test)
  228. {
  229. cout << "SendIntegers3: test[0][0] = " << test[0][0] << endl;
  230. cout << "SendIntegers3: test[0][1] = " << test[0][1] << endl;
  231. cout << "SendIntegers3: test[1][0] = " << test[1][0] << endl;
  232. cout << "SendIntegers3: test[1][1] = " << test[1][1] << endl;
  233. cout << "SendIntegers3: test[2][0] = " << test[2][0] << endl;
  234. cout << "SendIntegers3: test[2][1] = " << test[2][1] << endl;
  235. return S_OK;
  236. }
  237. class CFactory : public IClassFactory
  238. {
  239. public:
  240. // IUnknown
  241. ULONG __stdcall AddRef();
  242. ULONG __stdcall Release();
  243. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  244. // IClassFactory
  245. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  246. HRESULT __stdcall LockServer(BOOL bLock);
  247. CFactory() : m_cRef(1) { }
  248. ~CFactory() { }
  249. private:
  250. ULONG m_cRef;
  251. };
  252. ULONG CFactory::AddRef()
  253. {
  254. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  255. return ++m_cRef;
  256. }
  257. ULONG CFactory::Release()
  258. {
  259. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  260. if(--m_cRef != 0)
  261. return m_cRef;
  262. delete this;
  263. return 0;
  264. }
  265. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  266. {
  267. if((riid == IID_IUnknown) || (riid == IID_IClassFactory))
  268. {
  269. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  270. *ppv = (IClassFactory *)this;
  271. }
  272. else
  273. {
  274. *ppv = NULL;
  275. return E_NOINTERFACE;
  276. }
  277. AddRef();
  278. return S_OK;
  279. }
  280. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  281. {
  282. if(pUnknownOuter != NULL)
  283. return CLASS_E_NOAGGREGATION;
  284. CTestIDL *pTestIDL = new CTestIDL;
  285. cout << "Component: CFactory::CreateInstance() " << pTestIDL << endl;
  286. if(pTestIDL == NULL)
  287. return E_OUTOFMEMORY;
  288. // QueryInterface probably for IID_IUNKNOWN
  289. HRESULT hr = pTestIDL->QueryInterface(riid, ppv);
  290. pTestIDL->Release();
  291. return hr;
  292. }
  293. HRESULT CFactory::LockServer(BOOL bLock)
  294. {
  295. if(bLock)
  296. g_cServerLocks++;
  297. else
  298. g_cServerLocks--;
  299. return S_OK;
  300. }
  301. void RegisterComponent()
  302. {
  303. ITypeLib* pTypeLib;
  304. LoadTypeLibEx(L"Component.exe", REGKIND_DEFAULT, &pTypeLib);
  305. RegisterServer("Component.exe", CLSID_TestIDL, "Test IDL Sample", "Component.TestIDL", "Component.TestIDL.1", NULL);
  306. }
  307. void CommandLineParameters(int argc, char** argv)
  308. {
  309. RegisterComponent();
  310. if(argc < 2)
  311. {
  312. cout << "No parameter, but registered anyway" << endl;
  313. exit(false);
  314. }
  315. char* szToken = strtok(argv[1], "-/"); 
  316. if(_stricmp(szToken, "RegServer") == 0)
  317. {
  318. RegisterComponent();
  319. cout << "RegServer" << endl;
  320. exit(true);
  321. }
  322. if(_stricmp(szToken, "UnregServer") == 0)
  323. {
  324. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  325. UnregisterServer(CLSID_TestIDL, "Component.TestIDL", "Component.TestIDL.1");
  326. cout << "UnregServer" << endl;
  327. exit(true);
  328. }
  329. if(_stricmp(szToken, "Embedding") != 0)
  330. {
  331. cout << "Invalid parameter" << endl;
  332. exit(false);
  333. }
  334. }
  335. void main(int argc, char** argv)
  336. {
  337. CommandLineParameters(argc, argv);
  338. cout << "Component: CoInitializeEx()" << endl;
  339. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  340. IClassFactory *pClassFactory = new CFactory();
  341. cout << "Component: CoRegisterClassObject()" << endl;
  342. DWORD dwRegister;
  343. CoRegisterClassObject(CLSID_TestIDL, pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
  344. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  345. WaitForSingleObject(g_hEvent, INFINITE);
  346. CoRevokeClassObject(dwRegister);
  347. pClassFactory->Release();
  348. CoUninitialize();
  349. _getch();
  350. }