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.

558 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1998.
  5. //
  6. // File: nullfilt.cxx
  7. //
  8. // Contents: Null IFilter implementation
  9. //
  10. // History: 23-Aug-94 Created t-jeffc
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <nullfilt.hxx>
  16. extern long gulcInstances;
  17. extern "C" GUID CLSID_CNullIFilter = {
  18. 0xC3278E90,
  19. 0xBEA7,
  20. 0x11CD,
  21. { 0xB5, 0x79, 0x08, 0x00, 0x2B, 0x30, 0xBF, 0xEB }
  22. };
  23. //+-------------------------------------------------------------------------
  24. //
  25. // Method: CNullIFilter::CNullIFilter
  26. //
  27. // Synopsis: Class constructor
  28. //
  29. // Effects: Manages global refcount
  30. //
  31. // History: 23-Aug-1994 t-jeffc Created
  32. //
  33. //--------------------------------------------------------------------------
  34. CNullIFilter::CNullIFilter()
  35. : _cRefs(1),
  36. _pwszFileName( 0 )
  37. {
  38. InterlockedIncrement( &gulcInstances );
  39. }
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Method: CNullIFilter::~CNullIFilter
  43. //
  44. // Synopsis: Class destructor
  45. //
  46. // Effects: Manages global refcount
  47. //
  48. // History: 23-Aug-1994 t-jeffc Created
  49. //
  50. //--------------------------------------------------------------------------
  51. CNullIFilter::~CNullIFilter()
  52. {
  53. delete [] _pwszFileName;
  54. InterlockedDecrement( &gulcInstances );
  55. }
  56. //+-------------------------------------------------------------------------
  57. //
  58. // Method: CNullIFilter::QueryInterface
  59. //
  60. // Synopsis: Rebind to other interface
  61. //
  62. // Arguments: [riid] -- IID of new interface
  63. // [ppvObject] -- New interface * returned here
  64. //
  65. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  66. //
  67. // History: 23-Aug-1994 t-jeffc Created
  68. //
  69. //--------------------------------------------------------------------------
  70. SCODE STDMETHODCALLTYPE CNullIFilter::QueryInterface( REFIID riid,
  71. void ** ppvObject)
  72. {
  73. SCODE sc = S_OK;
  74. if ( 0 == ppvObject )
  75. return E_INVALIDARG;
  76. *ppvObject = 0;
  77. if ( IID_IFilter == riid )
  78. *ppvObject = (IFilter *)this;
  79. else if ( IID_IPersist == riid )
  80. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  81. else if ( IID_IPersistFile == riid )
  82. *ppvObject = (IUnknown *)(IPersistFile *)this;
  83. else if ( IID_IUnknown == riid )
  84. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  85. else
  86. sc = E_NOINTERFACE;
  87. if ( SUCCEEDED( sc ) )
  88. AddRef();
  89. return sc;
  90. } //QueryInterface
  91. //+-------------------------------------------------------------------------
  92. //
  93. // Method: CNullIFilter::AddRef
  94. //
  95. // Synopsis: Increments refcount
  96. //
  97. // History: 23-Aug-1994 t-jeffc Created
  98. //
  99. //--------------------------------------------------------------------------
  100. ULONG STDMETHODCALLTYPE CNullIFilter::AddRef()
  101. {
  102. return InterlockedIncrement( &_cRefs );
  103. }
  104. //+-------------------------------------------------------------------------
  105. //
  106. // Method: CNullIFilter::Release
  107. //
  108. // Synopsis: Decrement refcount. Delete if necessary.
  109. //
  110. // History: 23-Aug-1994 t-jeffc Created
  111. //
  112. //--------------------------------------------------------------------------
  113. ULONG STDMETHODCALLTYPE CNullIFilter::Release()
  114. {
  115. unsigned long uTmp = InterlockedDecrement( &_cRefs );
  116. if ( 0 == uTmp )
  117. delete this;
  118. return(uTmp);
  119. }
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Member: CNullIFilter::Init, public
  123. //
  124. // Synopsis: Initializes instance (essentially do nothing)
  125. //
  126. // Arguments: [grfFlags] -- Flags for filter behavior
  127. // [cAttributes] -- Number of strings in array ppwcsAttributes
  128. // [aAttributes] -- Array of attribute strings
  129. // [pFlags] -- Return flags
  130. //
  131. // History: 23-Aug-94 t-jeffc Created.
  132. //
  133. //----------------------------------------------------------------------------
  134. SCODE STDMETHODCALLTYPE CNullIFilter::Init( ULONG grfFlags,
  135. ULONG cAttributes,
  136. FULLPROPSPEC const * aAttributes,
  137. ULONG * pFlags )
  138. {
  139. //
  140. // Can't hurt to try and look for properties. In NT5 any file can have
  141. // properties.
  142. //
  143. *pFlags = IFILTER_FLAGS_OLE_PROPERTIES;
  144. return S_OK;
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Member: CNullIFilter::GetChunk, public
  149. //
  150. // Synopsis: Pretends there aren't any chunks
  151. //
  152. // Arguments: [ppStat] -- for chunk information (not modified)
  153. //
  154. // History: 23-Aug-94 t-jeffc Created.
  155. //
  156. //----------------------------------------------------------------------------
  157. SCODE STDMETHODCALLTYPE CNullIFilter::GetChunk( STAT_CHUNK * pStat )
  158. {
  159. return FILTER_E_END_OF_CHUNKS;
  160. }
  161. //+---------------------------------------------------------------------------
  162. //
  163. // Member: CNullIFilter::GetText, public
  164. //
  165. // Synopsis: Retrieves text (again, pretend there isn't any text)
  166. //
  167. // Arguments: [pcwcBuffer] -- count of UniCode characters in buffer
  168. // [awcBuffer] -- buffer for text
  169. //
  170. // History: 23-Aug-94 t-jeffc Created.
  171. //
  172. //----------------------------------------------------------------------------
  173. SCODE STDMETHODCALLTYPE CNullIFilter::GetText( ULONG * pcwcBuffer,
  174. WCHAR * awcBuffer )
  175. {
  176. return FILTER_E_NO_MORE_TEXT;
  177. }
  178. //+---------------------------------------------------------------------------
  179. //
  180. // Member: CNullIFilter::GetValue, public
  181. //
  182. // Synopsis: No value chunks.
  183. //
  184. // History: 23-Aug-94 t-jeffc Created.
  185. //
  186. //----------------------------------------------------------------------------
  187. SCODE STDMETHODCALLTYPE CNullIFilter::GetValue( PROPVARIANT ** ppPropValue )
  188. {
  189. return FILTER_E_NO_VALUES;
  190. }
  191. //+---------------------------------------------------------------------------
  192. //
  193. // Member: CNullIFilter::BindRegion, public
  194. //
  195. // Synopsis: Creates moniker or other interface for text indicated
  196. //
  197. // Arguments: [origPos] -- the region of text to be mapped to a moniker
  198. // [riid] -- Interface to bind
  199. // [ppunk] -- Output pointer to interface
  200. //
  201. // History: 16-Jul-93 AmyA Created.
  202. //
  203. //----------------------------------------------------------------------------
  204. SCODE STDMETHODCALLTYPE CNullIFilter::BindRegion( FILTERREGION origPos,
  205. REFIID riid,
  206. void ** ppunk )
  207. {
  208. return E_NOTIMPL;
  209. }
  210. //+---------------------------------------------------------------------------
  211. //
  212. // Member: CNullIFilter::GetClassID, public
  213. //
  214. // Synopsis: Returns the class id of this class.
  215. //
  216. // Arguments: [pClassID] -- the class id
  217. //
  218. // History: 23-Aug-94 t-jeffc Created.
  219. //
  220. //----------------------------------------------------------------------------
  221. SCODE STDMETHODCALLTYPE CNullIFilter::GetClassID( CLSID * pClassID )
  222. {
  223. *pClassID = CLSID_CNullIFilter;
  224. return S_OK;
  225. }
  226. //+---------------------------------------------------------------------------
  227. //
  228. // Member: CNullIFilter::IsDirty, public
  229. //
  230. // Synopsis: Always returns S_FALSE since this class is read-only.
  231. //
  232. // History: 23-Aug-94 t-jeffc Created.
  233. //
  234. //----------------------------------------------------------------------------
  235. SCODE STDMETHODCALLTYPE CNullIFilter::IsDirty()
  236. {
  237. return S_FALSE; // Since the filter is read-only, there will never be
  238. // changes to the file.
  239. }
  240. //+---------------------------------------------------------------------------
  241. //
  242. // Member: CNullIFilter::Load, public
  243. //
  244. // Synopsis: Pretend to load the indicated file
  245. //
  246. // Arguments: [pszFileName] -- the file name
  247. // [dwMode] -- the mode to load the file in
  248. //
  249. // History: 23-Aug-94 t-jeffc Created.
  250. //
  251. //----------------------------------------------------------------------------
  252. SCODE STDMETHODCALLTYPE CNullIFilter::Load(LPCWSTR pszFileName, DWORD dwMode)
  253. {
  254. SCODE sc = S_OK;
  255. TRY
  256. {
  257. int cc = wcslen( pszFileName ) + 1;
  258. _pwszFileName = new WCHAR [cc];
  259. wcscpy( _pwszFileName, pszFileName );
  260. }
  261. CATCH( CException, e )
  262. {
  263. sc = e.GetErrorCode();
  264. }
  265. END_CATCH
  266. return S_OK;
  267. }
  268. //+---------------------------------------------------------------------------
  269. //
  270. // Member: CNullIFilter::Save, public
  271. //
  272. // Synopsis: Always returns E_FAIL, since the file is opened read-only
  273. //
  274. // History: 23-Aug-94 t-jeffc Created.
  275. //
  276. //----------------------------------------------------------------------------
  277. SCODE STDMETHODCALLTYPE CNullIFilter::Save(LPCWSTR pszFileName, BOOL fRemember)
  278. {
  279. return E_FAIL; // cannot be saved since it is read-only
  280. }
  281. //+---------------------------------------------------------------------------
  282. //
  283. // Member: CNullIFilter::SaveCompleted, public
  284. //
  285. // Synopsis: Always returns E_FAIL since the file is opened read-only
  286. //
  287. // History: 23-Aug-94 t-jeffc Created.
  288. //
  289. //----------------------------------------------------------------------------
  290. SCODE STDMETHODCALLTYPE CNullIFilter::SaveCompleted(LPCWSTR pszFileName)
  291. {
  292. return E_FAIL;
  293. }
  294. //+---------------------------------------------------------------------------
  295. //
  296. // Member: CNullIFilter::GetCurFile, public
  297. //
  298. // Synopsis: Returns a copy of the current file name
  299. //
  300. // Arguments: [ppszFileName] -- where the copied string is returned.
  301. //
  302. // History: 24-Aug-94 t-jeffc Created.
  303. //
  304. //----------------------------------------------------------------------------
  305. SCODE STDMETHODCALLTYPE CNullIFilter::GetCurFile(LPWSTR * ppszFileName)
  306. {
  307. if ( _pwszFileName == 0 )
  308. return E_FAIL;
  309. SCODE sc = S_OK;
  310. unsigned cc = wcslen( _pwszFileName ) + 1;
  311. *ppszFileName = (WCHAR *)CoTaskMemAlloc(cc*sizeof(WCHAR));
  312. if ( *ppszFileName )
  313. wcscpy( *ppszFileName, _pwszFileName );
  314. else
  315. sc = E_OUTOFMEMORY;
  316. return sc;
  317. }
  318. //+-------------------------------------------------------------------------
  319. //
  320. // Method: CNullIFilterCF::CNullIFilterCF
  321. //
  322. // Synopsis: Text IFilter class factory constructor
  323. //
  324. // History: 23-Aug-1994 t-jeffc Created
  325. //
  326. //--------------------------------------------------------------------------
  327. CNullIFilterCF::CNullIFilterCF()
  328. : _cRefs( 1 )
  329. {
  330. InterlockedIncrement( &gulcInstances );
  331. }
  332. //+-------------------------------------------------------------------------
  333. //
  334. // Method: CNullIFilterCF::~CNullIFilterCF
  335. //
  336. // Synopsis: Text IFilter class factory constructor
  337. //
  338. // History: 23-Aug-1994 t-jeffc Created
  339. //
  340. //--------------------------------------------------------------------------
  341. CNullIFilterCF::~CNullIFilterCF()
  342. {
  343. InterlockedDecrement( &gulcInstances );
  344. }
  345. //+-------------------------------------------------------------------------
  346. //
  347. // Method: CNullIFilterCF::QueryInterface
  348. //
  349. // Synopsis: Rebind to other interface
  350. //
  351. // Arguments: [riid] -- IID of new interface
  352. // [ppvObject] -- New interface * returned here
  353. //
  354. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  355. //
  356. // History: 23-Aug-1994 t-jeffc Created
  357. //
  358. //--------------------------------------------------------------------------
  359. SCODE STDMETHODCALLTYPE CNullIFilterCF::QueryInterface( REFIID riid,
  360. void ** ppvObject )
  361. {
  362. //
  363. // Optimize QueryInterface by only checking minimal number of bytes.
  364. //
  365. // IID_IUnknown = 00000000-0000-0000-C000-000000000046
  366. // IID_IClassFactory = 00000001-0000-0000-C000-000000000046
  367. // --
  368. // |
  369. // +--- Unique!
  370. //
  371. Win4Assert( (IID_IUnknown.Data1 & 0x000000FF) == 0x00 );
  372. Win4Assert( (IID_IClassFactory.Data1 & 0x000000FF) == 0x01 );
  373. IUnknown *pUnkTemp;
  374. SCODE sc;
  375. if ( IID_IClassFactory == riid )
  376. pUnkTemp = (IUnknown *)(IClassFactory *)this;
  377. else if ( IID_IUnknown == riid )
  378. pUnkTemp = (IUnknown *)this;
  379. else
  380. pUnkTemp = 0;
  381. if( 0 != pUnkTemp )
  382. {
  383. *ppvObject = (void * )pUnkTemp;
  384. pUnkTemp->AddRef();
  385. sc = S_OK;
  386. }
  387. else
  388. sc = E_NOINTERFACE;
  389. return(sc);
  390. }
  391. //+-------------------------------------------------------------------------
  392. //
  393. // Method: CNullIFilterCF::AddRef
  394. //
  395. // Synopsis: Increments refcount
  396. //
  397. // History: 23-Aug-1994 t-jeffc Created
  398. //
  399. //--------------------------------------------------------------------------
  400. ULONG STDMETHODCALLTYPE CNullIFilterCF::AddRef()
  401. {
  402. return InterlockedIncrement( &_cRefs );
  403. }
  404. //+-------------------------------------------------------------------------
  405. //
  406. // Method: CNullIFilterCF::Release
  407. //
  408. // Synopsis: Decrement refcount. Delete if necessary.
  409. //
  410. // History: 23-Aug-1994 t-jeffc Created
  411. //
  412. //--------------------------------------------------------------------------
  413. ULONG STDMETHODCALLTYPE CNullIFilterCF::Release()
  414. {
  415. unsigned long uTmp = InterlockedDecrement( &_cRefs );
  416. if ( 0 == uTmp )
  417. delete this;
  418. return(uTmp);
  419. }
  420. //+-------------------------------------------------------------------------
  421. //
  422. // Method: CNullIFilterCF::CreateInstance
  423. //
  424. // Synopsis: Creates new TextIFilter object
  425. //
  426. // Arguments: [pUnkOuter] -- 'Outer' IUnknown
  427. // [riid] -- Interface to bind
  428. // [ppvObject] -- Interface returned here
  429. //
  430. // History: 23-Aug-1994 t-jeffc Created
  431. //
  432. //--------------------------------------------------------------------------
  433. SCODE STDMETHODCALLTYPE CNullIFilterCF::CreateInstance( IUnknown * pUnkOuter,
  434. REFIID riid,
  435. void * * ppvObject )
  436. {
  437. CNullIFilter * pIUnk = 0;
  438. SCODE sc = S_OK;
  439. TRY
  440. {
  441. pIUnk = new CNullIFilter();
  442. sc = pIUnk->QueryInterface( riid , ppvObject );
  443. pIUnk->Release(); // Release extra refcount from QueryInterface
  444. }
  445. CATCH(CException, e)
  446. {
  447. Win4Assert( 0 == pIUnk );
  448. switch( e.GetErrorCode() )
  449. {
  450. case E_OUTOFMEMORY:
  451. sc = (E_OUTOFMEMORY);
  452. break;
  453. default:
  454. sc = (E_UNEXPECTED);
  455. }
  456. }
  457. END_CATCH;
  458. return (sc);
  459. }
  460. //+-------------------------------------------------------------------------
  461. //
  462. // Method: CNullIFilterCF::LockServer
  463. //
  464. // Synopsis: Force class factory to remain loaded
  465. //
  466. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  467. //
  468. // Returns: S_OK
  469. //
  470. // History: 23-Aug-1994 t-jeffc Created
  471. //
  472. //--------------------------------------------------------------------------
  473. SCODE STDMETHODCALLTYPE CNullIFilterCF::LockServer(BOOL fLock)
  474. {
  475. if(fLock)
  476. InterlockedIncrement( &gulcInstances );
  477. else
  478. InterlockedDecrement( &gulcInstances );
  479. return(S_OK);
  480. }