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.

490 lines
13 KiB

  1. //--------------------------------------------------------------
  2. //
  3. // File: hook.cxx
  4. //
  5. // Contents: Test channel hooks
  6. //
  7. //---------------------------------------------------------------
  8. #include <windows.h>
  9. #include <stdio.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <errno.h>
  13. #include <io.h>
  14. #include <malloc.h>
  15. #include <ole2.h>
  16. #include <coguid.h>
  17. #include "hook.h"
  18. class CWhichHook : public IWhichHook
  19. {
  20. public:
  21. // Constructor/Destructor
  22. CWhichHook();
  23. ~CWhichHook() {};
  24. // IUnknown
  25. STDMETHOD (QueryInterface) (REFIID iid, void FAR * FAR * ppv);
  26. STDMETHOD_(ULONG,AddRef) ( void );
  27. STDMETHOD_(ULONG,Release) ( void );
  28. // IWhichHook
  29. STDMETHOD (Me) ( REFIID riid );
  30. STDMETHOD (Hooked)( REFIID riid );
  31. STDMETHOD (Clear) ();
  32. private:
  33. DWORD _iRef;
  34. static BOOL _f1;
  35. static BOOL _f2;
  36. };
  37. class CDllHook : public IChannelHook
  38. {
  39. public:
  40. CDllHook( REFGUID );
  41. ~CDllHook() {};
  42. STDMETHOD (QueryInterface) ( REFIID riid, LPVOID FAR* ppvObj);
  43. STDMETHOD_(ULONG,AddRef) ( void );
  44. STDMETHOD_(ULONG,Release) ( void );
  45. STDMETHOD_(void,ClientGetSize) ( REFGUID, REFIID, ULONG *DataSize );
  46. STDMETHOD_(void,ClientFillBuffer)( REFGUID, REFIID, ULONG *DataSize, void *DataBuffer );
  47. STDMETHOD_(void,ClientNotify) ( REFGUID, REFIID, ULONG DataSize, void *DataBuffer,
  48. DWORD DataRep, HRESULT );
  49. STDMETHOD_(void,ServerNotify) ( REFGUID, REFIID, ULONG DataSize, void *DataBuffer,
  50. DWORD DataRep );
  51. STDMETHOD_(void,ServerGetSize) ( REFGUID, REFIID, HRESULT, ULONG *DataSize );
  52. STDMETHOD_(void,ServerFillBuffer)( REFGUID, REFIID, ULONG *DataSize, void *DataBuffer, HRESULT );
  53. private:
  54. ULONG _iRef;
  55. GUID _extent;
  56. CWhichHook _cWhich;
  57. };
  58. class CHookCF: public IClassFactory
  59. {
  60. public:
  61. // Constructor/Destructor
  62. CHookCF( CLSID );
  63. ~CHookCF() {};
  64. // IUnknown
  65. STDMETHOD (QueryInterface) (REFIID iid, void FAR * FAR * ppv);
  66. STDMETHOD_(ULONG,AddRef) ( void );
  67. STDMETHOD_(ULONG,Release) ( void );
  68. // IClassFactory
  69. STDMETHODIMP CreateInstance(
  70. IUnknown FAR* pUnkOuter,
  71. REFIID iidInterface,
  72. void FAR* FAR* ppv);
  73. STDMETHODIMP LockServer(BOOL fLock);
  74. private:
  75. ULONG _iRef;
  76. CLSID _class;
  77. };
  78. const CLSID CLSID_Hook1 = {0x60000400, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
  79. const CLSID CLSID_Hook2 = {0x60000401, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
  80. const CLSID CLSID_WhichHook = {0x60000402, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
  81. const IID IID_IWhichHook = {0x60000403, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
  82. BOOL CWhichHook::_f1 = FALSE;
  83. BOOL CWhichHook::_f2 = FALSE;
  84. //+-------------------------------------------------------------------------
  85. //
  86. // Function: DllCanUnloadNow
  87. //
  88. // Synopsis: Dll entry point
  89. //
  90. //--------------------------------------------------------------------------
  91. STDAPI DllCanUnloadNow()
  92. {
  93. return S_FALSE;
  94. }
  95. //+-------------------------------------------------------------------------
  96. //
  97. // Function: DllGetClassObject
  98. //
  99. // Synopsis: Dll entry point
  100. //
  101. //--------------------------------------------------------------------------
  102. STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv)
  103. {
  104. CHookCF *pFactory;
  105. // Check for IPSFactoryBuffer
  106. if ((clsid == CLSID_Hook1 || clsid == CLSID_Hook2 || clsid == CLSID_WhichHook)
  107. && iid == IID_IClassFactory)
  108. {
  109. pFactory = new CHookCF( clsid );
  110. *ppv = pFactory;
  111. if (pFactory == NULL)
  112. return E_OUTOFMEMORY;
  113. else
  114. return S_OK;
  115. }
  116. return E_NOTIMPL;
  117. }
  118. //+-------------------------------------------------------------------
  119. //
  120. // Member: CHookCF::AddRef, public
  121. //
  122. // Synopsis: Adds a reference to an interface
  123. //
  124. //--------------------------------------------------------------------
  125. STDMETHODIMP_(ULONG) CHookCF::AddRef()
  126. {
  127. InterlockedIncrement( (long *) &_iRef );
  128. return _iRef;
  129. }
  130. //+-------------------------------------------------------------------
  131. //
  132. // Member: CHookCF::CHookCF
  133. //
  134. // Synopsis: Constructor
  135. //
  136. //--------------------------------------------------------------------
  137. CHookCF::CHookCF( CLSID clsid )
  138. {
  139. _iRef = 1;
  140. _class = clsid;
  141. }
  142. //+-------------------------------------------------------------------
  143. //
  144. // Member: CHookCF::CreateInstance, public
  145. //
  146. // Synopsis: Create an instance of the requested class
  147. //
  148. //--------------------------------------------------------------------
  149. STDMETHODIMP CHookCF::CreateInstance(
  150. IUnknown FAR* pUnkOuter,
  151. REFIID iidInterface,
  152. void FAR* FAR* ppv)
  153. {
  154. IUnknown *pUnk;
  155. HRESULT hr;
  156. *ppv = NULL;
  157. if (pUnkOuter != NULL)
  158. {
  159. printf( "Create instance failed, attempted agregation.\n" );
  160. return E_FAIL;
  161. }
  162. // Create the right class.
  163. if (_class == CLSID_WhichHook)
  164. pUnk = new CWhichHook();
  165. else
  166. pUnk = new CDllHook( _class );
  167. // Query for the requested interface.
  168. hr = pUnk->QueryInterface( iidInterface, ppv );
  169. pUnk->Release();
  170. return hr;
  171. }
  172. //+-------------------------------------------------------------------
  173. //
  174. // Member: CHookCF::LockServer, public
  175. //
  176. //--------------------------------------------------------------------
  177. STDMETHODIMP CHookCF::LockServer(BOOL fLock)
  178. {
  179. return E_FAIL;
  180. }
  181. //+-------------------------------------------------------------------
  182. //
  183. // Member: CHookCF::QueryInterface, public
  184. //
  185. // Synopsis: Returns a pointer to the requested interface.
  186. //
  187. //--------------------------------------------------------------------
  188. STDMETHODIMP CHookCF::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
  189. {
  190. if (IsEqualIID(riid, IID_IUnknown) ||
  191. IsEqualIID(riid, IID_IClassFactory))
  192. *ppvObj = (IClassFactory *) this;
  193. else
  194. {
  195. *ppvObj = NULL;
  196. return E_NOINTERFACE;
  197. }
  198. AddRef();
  199. return S_OK;
  200. }
  201. //+-------------------------------------------------------------------
  202. //
  203. // Member: CHookCF::Release, public
  204. //
  205. // Synopsis: Releases an interface
  206. //
  207. //--------------------------------------------------------------------
  208. STDMETHODIMP_(ULONG) CHookCF::Release()
  209. {
  210. ULONG lRef = _iRef - 1;
  211. if (InterlockedDecrement( (long*) &_iRef ) == 0)
  212. {
  213. delete this;
  214. return 0;
  215. }
  216. else
  217. return lRef;
  218. }
  219. //+-------------------------------------------------------------------
  220. //
  221. // Member: CDllHook::AddRef, public
  222. //
  223. // Synopsis: Adds a reference to an interface
  224. //
  225. //--------------------------------------------------------------------
  226. STDMETHODIMP_(ULONG) CDllHook::AddRef()
  227. {
  228. InterlockedIncrement( (long *) &_iRef );
  229. return _iRef;
  230. }
  231. //+-------------------------------------------------------------------
  232. //
  233. // Member: CDllHook::CDllHook, public
  234. //
  235. // Synopsis: Constructor
  236. //
  237. //--------------------------------------------------------------------
  238. CDllHook::CDllHook( REFGUID rExtent )
  239. {
  240. _iRef = 1;
  241. _extent = rExtent;
  242. }
  243. //+-------------------------------------------------------------------
  244. //
  245. // Member: CDllHook::QueryInterface, public
  246. //
  247. // Synopsis: Returns a pointer to the requested interface.
  248. //
  249. //--------------------------------------------------------------------
  250. STDMETHODIMP CDllHook::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
  251. {
  252. if (IsEqualIID(riid, IID_IUnknown) ||
  253. IsEqualIID(riid, IID_IChannelHook))
  254. *ppvObj = (IChannelHook *) this;
  255. else
  256. {
  257. *ppvObj = NULL;
  258. return E_NOINTERFACE;
  259. }
  260. AddRef();
  261. return S_OK;
  262. }
  263. //+-------------------------------------------------------------------
  264. //
  265. // Member: CDllHook::Release, public
  266. //
  267. // Synopsis: Releases an interface
  268. //
  269. //--------------------------------------------------------------------
  270. STDMETHODIMP_(ULONG) CDllHook::Release()
  271. {
  272. ULONG lRef = _iRef - 1;
  273. if (InterlockedDecrement( (long*) &_iRef ) == 0)
  274. {
  275. delete this;
  276. return 0;
  277. }
  278. else
  279. return lRef;
  280. }
  281. /***************************************************************************/
  282. STDMETHODIMP_(void) CDllHook::ClientGetSize( REFGUID ext, REFIID riid,
  283. ULONG *size )
  284. {
  285. _cWhich.Me( _extent );
  286. *size = sizeof(DWORD);
  287. }
  288. /***************************************************************************/
  289. STDMETHODIMP_(void) CDllHook::ClientFillBuffer( REFGUID ext, REFIID riid,
  290. ULONG *max, void *buffer )
  291. {
  292. _cWhich.Me( _extent );
  293. *max = sizeof(DWORD);
  294. if (_extent == CLSID_Hook1)
  295. *((DWORD *) buffer) = 'Blue';
  296. else
  297. *((DWORD *) buffer) = 'Grn';
  298. }
  299. /***************************************************************************/
  300. STDMETHODIMP_(void) CDllHook::ClientNotify( REFGUID ext, REFIID riid,
  301. ULONG size, void *buffer,
  302. DWORD data_rep, HRESULT result )
  303. {
  304. _cWhich.Me( _extent );
  305. }
  306. /***************************************************************************/
  307. STDMETHODIMP_(void) CDllHook::ServerNotify( REFGUID ext, REFIID riid,
  308. ULONG size, void *buffer,
  309. DWORD data_rep )
  310. {
  311. _cWhich.Me( _extent );
  312. }
  313. /***************************************************************************/
  314. STDMETHODIMP_(void) CDllHook::ServerGetSize( REFGUID ext, REFIID riid, HRESULT hr,
  315. ULONG *size )
  316. {
  317. _cWhich.Me( _extent );
  318. *size = sizeof(DWORD);
  319. }
  320. /***************************************************************************/
  321. STDMETHODIMP_(void) CDllHook::ServerFillBuffer( REFGUID ext, REFIID riid,
  322. ULONG *max, void *buffer, HRESULT hr )
  323. {
  324. _cWhich.Me( _extent );
  325. *max = sizeof(DWORD);
  326. if (_extent == CLSID_Hook1)
  327. *((DWORD *) buffer) = 'Blue';
  328. else
  329. *((DWORD *) buffer) = 'Grn';
  330. }
  331. //+-------------------------------------------------------------------
  332. //
  333. // Member: CWhichHook::AddRef, public
  334. //
  335. // Synopsis: Adds a reference to an interface
  336. //
  337. //--------------------------------------------------------------------
  338. STDMETHODIMP_(ULONG) CWhichHook::AddRef()
  339. {
  340. InterlockedIncrement( (long *) &_iRef );
  341. return _iRef;
  342. }
  343. //+-------------------------------------------------------------------
  344. //
  345. // Member: CWhichHook::CWhichHook, public
  346. //
  347. // Synopsis: Constructor
  348. //
  349. //--------------------------------------------------------------------
  350. CWhichHook::CWhichHook()
  351. {
  352. _iRef = 1;
  353. }
  354. //+-------------------------------------------------------------------
  355. //
  356. // Member: CWhichHook::QueryInterface, public
  357. //
  358. // Synopsis: Returns a pointer to the requested interface.
  359. //
  360. //--------------------------------------------------------------------
  361. STDMETHODIMP CWhichHook::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
  362. {
  363. if (IsEqualIID(riid, IID_IUnknown) ||
  364. IsEqualIID(riid, IID_IWhichHook))
  365. *ppvObj = (IWhichHook *) this;
  366. else
  367. {
  368. *ppvObj = NULL;
  369. return E_NOINTERFACE;
  370. }
  371. AddRef();
  372. return S_OK;
  373. }
  374. //+-------------------------------------------------------------------
  375. //
  376. // Member: CWhichHook::Release, public
  377. //
  378. // Synopsis: Releases an interface
  379. //
  380. //--------------------------------------------------------------------
  381. STDMETHODIMP_(ULONG) CWhichHook::Release()
  382. {
  383. ULONG lRef = _iRef - 1;
  384. if (InterlockedDecrement( (long*) &_iRef ) == 0)
  385. {
  386. delete this;
  387. return 0;
  388. }
  389. else
  390. return lRef;
  391. }
  392. //+-------------------------------------------------------------------
  393. //
  394. // Member: CWhichHook::Me, public
  395. //
  396. // Synopsis: Flags a hook as used.
  397. //
  398. //--------------------------------------------------------------------
  399. STDMETHODIMP CWhichHook::Me( REFIID riid )
  400. {
  401. if (riid == CLSID_Hook1)
  402. _f1 = TRUE;
  403. else if (riid == CLSID_Hook2)
  404. _f2 = TRUE;
  405. return S_OK;
  406. }
  407. //+-------------------------------------------------------------------
  408. //
  409. // Member: CWhichHook::Hooked, public
  410. //
  411. // Synopsis: Succeeds if the specified hook has been used.
  412. //
  413. //--------------------------------------------------------------------
  414. STDMETHODIMP CWhichHook::Hooked( REFIID riid )
  415. {
  416. if (riid == CLSID_Hook1)
  417. return _f1 ? S_OK : E_FAIL;
  418. else if (riid == CLSID_Hook2)
  419. return _f2 ? S_OK : E_FAIL;
  420. return E_INVALIDARG;
  421. }
  422. //+-------------------------------------------------------------------
  423. //
  424. // Member: CWhichHook::Clear, public
  425. //
  426. // Synopsis: Clears the used flags.
  427. //
  428. //--------------------------------------------------------------------
  429. STDMETHODIMP CWhichHook::Clear()
  430. {
  431. _f1 = FALSE;
  432. _f2 = FALSE;
  433. return S_OK;
  434. }