Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

474 lines
10 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // File: olebt.cpp
  4. //
  5. // Contents: Test DLL class code that be used multithreaded.
  6. //
  7. // Classes:
  8. //
  9. // Functions:
  10. //
  11. // History: 03-Nov-94 Ricksa
  12. //
  13. //--------------------------------------------------------------------
  14. #undef _UNICODE
  15. #undef UNICODE
  16. #include <windows.h>
  17. #include <ole2.h>
  18. #include <uthread.h>
  19. // Global count of
  20. ULONG g_UseCount = 0;
  21. void PrintDebugMsg(char *pszMsg, DWORD dwData)
  22. {
  23. char wszBuf[256];
  24. wsprintf(wszBuf, "olebt.dll: %s %d\n", pszMsg, dwData);
  25. OutputDebugString(wszBuf);
  26. }
  27. //+-------------------------------------------------------------------
  28. //
  29. // Class: CBasicBndCF
  30. //
  31. // Synopsis: Class Factory for CBasicBnd
  32. //
  33. // Methods: IUnknown - QueryInterface, AddRef, Release
  34. // IClassFactory - CreateInstance
  35. //
  36. // History: 03-Nov-94 Ricksa Created
  37. //
  38. //--------------------------------------------------------------------
  39. class FAR CBasicBndCF: public IClassFactory
  40. {
  41. public:
  42. // Constructor/Destructor
  43. CBasicBndCF(void);
  44. ~CBasicBndCF();
  45. // IUnknown
  46. STDMETHODIMP QueryInterface(REFIID iid, void FAR * FAR * ppv);
  47. STDMETHODIMP_(ULONG) AddRef(void);
  48. STDMETHODIMP_(ULONG) Release(void);
  49. // IClassFactory
  50. STDMETHODIMP CreateInstance(
  51. IUnknown FAR* pUnkOuter,
  52. REFIID iidInterface,
  53. void FAR* FAR* ppv);
  54. STDMETHODIMP LockServer(BOOL fLock);
  55. private:
  56. ULONG _cRefs;
  57. IUnknown * _punkFm;
  58. };
  59. //+-------------------------------------------------------------------
  60. //
  61. // Class: CBasicBnd
  62. //
  63. // Synopsis: Test class CBasicBnd
  64. //
  65. // Methods:
  66. //
  67. // History: 03-Nov-94 Ricksa Created
  68. //
  69. //--------------------------------------------------------------------
  70. class FAR CBasicBnd: public IPersist
  71. {
  72. public:
  73. // Constructor/Destructor
  74. CBasicBnd(void);
  75. ~CBasicBnd();
  76. // IUnknown
  77. STDMETHODIMP QueryInterface(REFIID iid, void FAR * FAR * ppv);
  78. STDMETHODIMP_(ULONG) AddRef(void);
  79. STDMETHODIMP_(ULONG) Release(void);
  80. // IPersist - only thing we implement because it
  81. // gives us a nice way to figure who we are talking to.
  82. STDMETHODIMP GetClassID(LPCLSID lpClassID);
  83. private:
  84. ULONG _cRefs;
  85. IUnknown * _punkFm;
  86. };
  87. extern "C" BOOL WINAPI DllMain(
  88. HANDLE,
  89. DWORD,
  90. LPVOID)
  91. {
  92. return TRUE;
  93. }
  94. //+-------------------------------------------------------------------
  95. //
  96. // Function: DllGetClassObject
  97. //
  98. // Synopsis: Called by client (from within BindToObject et al)
  99. // interface requested should be IUnknown or IClassFactory -
  100. // Creates ClassFactory object and returns pointer to it
  101. //
  102. // Arguments: REFCLSID clsid - class id
  103. // REFIID iid - interface id
  104. // void FAR* FAR* ppv- pointer to class factory interface
  105. //
  106. // Returns: TRUE
  107. //
  108. // History: 03-Nov-94 Ricksa Created
  109. //
  110. //--------------------------------------------------------------------
  111. STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void FAR* FAR* ppv)
  112. {
  113. *ppv = NULL;
  114. if (!IsEqualGUID(iid, IID_IUnknown)
  115. && !IsEqualGUID(iid, IID_IClassFactory)
  116. && !IsEqualGUID(iid, IID_IMarshal))
  117. {
  118. return E_NOINTERFACE;
  119. }
  120. if (IsEqualGUID(clsid, clsidBothThreadedDll))
  121. {
  122. IUnknown *punk = new CBasicBndCF();
  123. HRESULT hr = punk->QueryInterface(iid, ppv);
  124. punk->Release();
  125. return hr;
  126. }
  127. return E_FAIL;
  128. }
  129. STDAPI DllCanUnloadNow(void)
  130. {
  131. return (g_UseCount == 0)
  132. ? S_OK
  133. : S_FALSE;
  134. }
  135. //+-------------------------------------------------------------------
  136. //
  137. // Member: CBasicBndCF::CBasicBndCF()
  138. //
  139. // Synopsis: The constructor for CBAsicBnd.
  140. //
  141. // Arguments: None
  142. //
  143. // History: 21-Nov-92 Ricksa Created
  144. //
  145. //--------------------------------------------------------------------
  146. CBasicBndCF::CBasicBndCF(void)
  147. : _cRefs(1), _punkFm(NULL)
  148. {
  149. PrintDebugMsg("Creating Class Factory", (DWORD) this);
  150. g_UseCount++;
  151. }
  152. //+-------------------------------------------------------------------
  153. //
  154. // Member: CBasicBnd::~CBasicBndCF()
  155. //
  156. // Synopsis: The destructor for CBasicCF.
  157. //
  158. // History: 03-Nov-94 Ricksa Created
  159. //
  160. //--------------------------------------------------------------------
  161. CBasicBndCF::~CBasicBndCF()
  162. {
  163. PrintDebugMsg("Deleting Class Factory", (DWORD) this);
  164. g_UseCount--;
  165. if (_punkFm != NULL)
  166. {
  167. _punkFm->Release();
  168. }
  169. return;
  170. }
  171. //+-------------------------------------------------------------------
  172. //
  173. // Method: CBasicBndCF::QueryInterface
  174. //
  175. // Synopsis: Only IUnknown and IClassFactory supported
  176. //
  177. // History: 03-Nov-94 Ricksa Created
  178. //
  179. //--------------------------------------------------------------------
  180. STDMETHODIMP CBasicBndCF::QueryInterface(REFIID iid, void **ppv)
  181. {
  182. HRESULT hr = E_NOINTERFACE;
  183. *ppv = NULL;
  184. if (IsEqualGUID(iid, IID_IUnknown) || IsEqualGUID(iid, IID_IClassFactory))
  185. {
  186. *ppv = this;
  187. AddRef();
  188. hr = S_OK;
  189. }
  190. else if (IsEqualGUID(iid, IID_IMarshal))
  191. {
  192. if (NULL == _punkFm)
  193. {
  194. hr = CoCreateFreeThreadedMarshaler(this, &_punkFm);
  195. }
  196. if (_punkFm != NULL)
  197. {
  198. return _punkFm->QueryInterface(iid, ppv);
  199. }
  200. }
  201. return hr;
  202. }
  203. //+-------------------------------------------------------------------
  204. //
  205. // Method: CBasicBndCF::AddRef
  206. //
  207. // Synopsis: Increment reference count
  208. //
  209. // History: 03-Nov-94 Ricksa Created
  210. //
  211. //--------------------------------------------------------------------
  212. STDMETHODIMP_(ULONG) CBasicBndCF::AddRef(void)
  213. {
  214. return ++_cRefs;
  215. }
  216. //+-------------------------------------------------------------------
  217. //
  218. // Method: CBasicBndCF::Release
  219. //
  220. // Synopsis: Decrement reference count
  221. //
  222. // History: 03-Nov-94 Ricksa Created
  223. //
  224. //--------------------------------------------------------------------
  225. STDMETHODIMP_(ULONG) CBasicBndCF::Release(void)
  226. {
  227. ULONG cRefs = --_cRefs;
  228. if (cRefs == 0)
  229. {
  230. delete this;
  231. }
  232. return cRefs;
  233. }
  234. //+-------------------------------------------------------------------
  235. //
  236. // Method: CBasicBndCF::CreateInstance
  237. //
  238. // Synopsis: This is called by Binding process to create the
  239. // actual class object
  240. //
  241. //--------------------------------------------------------------------
  242. STDMETHODIMP CBasicBndCF::CreateInstance(
  243. IUnknown FAR* pUnkOuter,
  244. REFIID iidInterface,
  245. void FAR* FAR* ppv)
  246. {
  247. HRESULT hresult = S_OK;
  248. if (pUnkOuter != NULL)
  249. {
  250. return CLASS_E_NOAGGREGATION;
  251. }
  252. CBasicBnd *pbb = new FAR CBasicBnd();
  253. if (pbb == NULL)
  254. {
  255. return E_OUTOFMEMORY;
  256. }
  257. hresult = pbb->QueryInterface(iidInterface, ppv);
  258. pbb->Release();
  259. return hresult;
  260. }
  261. //+-------------------------------------------------------------------
  262. //
  263. // Method: CBasicBndCF::LockServer
  264. //
  265. // Synopsis: Inc/Dec stay alive count
  266. //
  267. // History: 03-Nov-94 Ricksa Created
  268. //
  269. //--------------------------------------------------------------------
  270. STDMETHODIMP CBasicBndCF::LockServer(BOOL fLock)
  271. {
  272. if (fLock)
  273. {
  274. g_UseCount++;
  275. }
  276. else
  277. {
  278. g_UseCount--;
  279. }
  280. return S_OK;
  281. }
  282. //+-------------------------------------------------------------------
  283. //
  284. // Member: CBasicBnd::CBasicBnd()
  285. //
  286. // Synopsis: The constructor for CBAsicBnd. I
  287. //
  288. // Arguments: None
  289. //
  290. // History: 03-Nov-94 Ricksa Created
  291. //
  292. //--------------------------------------------------------------------
  293. CBasicBnd::CBasicBnd(void)
  294. : _cRefs(1), _punkFm(NULL)
  295. {
  296. PrintDebugMsg("Creating App Object", (DWORD) this);
  297. g_UseCount++;
  298. }
  299. //+-------------------------------------------------------------------
  300. //
  301. // Member: CBasicBnd::~CBasicBndObj()
  302. //
  303. // Synopsis: The destructor for CBAsicBnd.
  304. //
  305. // History: 03-Nov-94 Ricksa Created
  306. //
  307. //--------------------------------------------------------------------
  308. CBasicBnd::~CBasicBnd(void)
  309. {
  310. PrintDebugMsg("Deleting App Object", (DWORD) this);
  311. g_UseCount--;
  312. return;
  313. }
  314. //+-------------------------------------------------------------------
  315. //
  316. // Member: CBasicBnd::QueryInterface
  317. //
  318. // Returns: S_OK
  319. //
  320. // History: 03-Nov-94 Ricksa Created
  321. //
  322. //--------------------------------------------------------------------
  323. STDMETHODIMP CBasicBnd::QueryInterface(REFIID iid, void **ppv)
  324. {
  325. if (IsEqualGUID(iid, IID_IUnknown) || IsEqualGUID(iid, IID_IPersist))
  326. {
  327. *ppv = this;
  328. AddRef();
  329. return S_OK;
  330. }
  331. else if (IsEqualGUID(iid, IID_IMarshal))
  332. {
  333. HRESULT hr;
  334. if (NULL == _punkFm)
  335. {
  336. hr = CoCreateFreeThreadedMarshaler(this, &_punkFm);
  337. }
  338. if (_punkFm != NULL)
  339. {
  340. hr = _punkFm->QueryInterface(iid, ppv);
  341. }
  342. return hr;
  343. }
  344. else
  345. {
  346. *ppv = NULL;
  347. return E_NOINTERFACE;
  348. }
  349. }
  350. //+-------------------------------------------------------------------
  351. //
  352. // Member: CBasicBnd::AddRef
  353. //
  354. // Synopsis: Standard stuff
  355. //
  356. // History: 03-Nov-94 Ricksa Created
  357. //
  358. //--------------------------------------------------------------------
  359. STDMETHODIMP_(ULONG) CBasicBnd::AddRef(void)
  360. {
  361. return _cRefs++;
  362. }
  363. //+-------------------------------------------------------------------
  364. //
  365. // Member: CBasicBnd::Release
  366. //
  367. // Synopsis: Standard stuff
  368. //
  369. // History: 03-Nov-94 Ricksa Created
  370. //
  371. //--------------------------------------------------------------------
  372. STDMETHODIMP_(ULONG) CBasicBnd::Release(void)
  373. {
  374. ULONG cRefs;
  375. if ((cRefs = --_cRefs) == 0)
  376. {
  377. delete this;
  378. }
  379. return cRefs;
  380. }
  381. //+-------------------------------------------------------------------
  382. //
  383. // Member: CBasicBnd::GetClassID
  384. //
  385. // Synopsis: Return the class id
  386. //
  387. // History: 03-Nov-94 Ricksa Created
  388. //
  389. //--------------------------------------------------------------------
  390. STDMETHODIMP CBasicBnd::GetClassID(LPCLSID classid)
  391. {
  392. *classid = clsidBothThreadedDll;
  393. return S_OK;
  394. }