Leaked source code of windows server 2003
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.

525 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: GENFLT.CXX
  7. //
  8. // Contents: C and Cxx Filter
  9. //
  10. // History: 07-Oct-93 AmyA Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <queryexp.hxx>
  16. #include "gen.hxx"
  17. #include "genifilt.hxx"
  18. #include "genflt.hxx"
  19. extern "C" GUID CLSID_GenIFilter;
  20. GUID guidCPlusPlus = { 0x8DEE0300, \
  21. 0x16C2, 0x101B, \
  22. 0xB1, 0x21, 0x08, 0x00, 0x2B, 0x2E, 0xCD, 0xA9 };
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Member: GenIFilter::GenIFilter, public
  26. //
  27. // Synopsis: Constructor
  28. //
  29. // History: 07-Oct-93 AmyA Created.
  30. //
  31. //----------------------------------------------------------------------------
  32. GenIFilter::GenIFilter()
  33. : _state(FilterDone),
  34. _ulLastTextChunkID(0),
  35. _ulChunkID(0),
  36. _pTextFilt(0),
  37. _pPersFile(0),
  38. _cAttrib(0),
  39. _pAttrib(0),
  40. _pTextStream(0),
  41. _locale(0) // the default locale
  42. {
  43. }
  44. //+---------------------------------------------------------------------------
  45. //
  46. // Member: GenIFilter::~GenIFilter, public
  47. //
  48. // Synopsis: Destructor
  49. //
  50. // History: 07-Oct-93 AmyA Created.
  51. //
  52. //----------------------------------------------------------------------------
  53. GenIFilter::~GenIFilter()
  54. {
  55. delete [] _pAttrib;
  56. if ( _pTextFilt )
  57. _pTextFilt->Release();
  58. if ( _pPersFile )
  59. _pPersFile->Release();
  60. delete _pTextStream;
  61. }
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Member: GenIFilter::Init, public
  65. //
  66. // Synopsis: Initializes instance of text filter
  67. //
  68. // Arguments: [grfFlags] -- flags for filter behavior
  69. // [cAttributes] -- number of attributes in array aAttributes
  70. // [aAttributes] -- array of attributes
  71. // [pfBulkyObject] -- indicates whether this object is a
  72. // bulky object
  73. //
  74. // History: 07-Oct-93 AmyA Created.
  75. //
  76. //----------------------------------------------------------------------------
  77. SCODE STDMETHODCALLTYPE GenIFilter::Init( ULONG grfFlags,
  78. ULONG cAttributes,
  79. FULLPROPSPEC const * aAttributes,
  80. ULONG * pFlags )
  81. {
  82. CTranslateSystemExceptions translate;
  83. SCODE sc = S_OK;
  84. TRY
  85. {
  86. _ulLastTextChunkID = 0;
  87. _ulChunkID = 0;
  88. if( cAttributes > 0 )
  89. {
  90. _state = FilterProp;
  91. _cAttrib = cAttributes;
  92. _pAttrib = new CFullPropSpec [_cAttrib];
  93. //
  94. // Known, safe cast
  95. //
  96. CCiPropSpec const * pAttrib = (CCiPropSpec const *)aAttributes;
  97. for ( ULONG i = 0; i < cAttributes; i++ )
  98. {
  99. if ( _state != FilterContents && pAttrib[i].IsContents() )
  100. _state = FilterContents;
  101. _pAttrib[i] = pAttrib[i];
  102. }
  103. }
  104. else if ( 0 == grfFlags || (grfFlags & IFILTER_INIT_APPLY_INDEX_ATTRIBUTES) )
  105. {
  106. _state = FilterContents;
  107. }
  108. else
  109. {
  110. _state = FilterDone;
  111. }
  112. }
  113. CATCH(CException, e)
  114. {
  115. sc = e.GetErrorCode();
  116. }
  117. END_CATCH;
  118. if ( FAILED( sc ) )
  119. return sc;
  120. CFullPropSpec ps( guidStorage, PID_STG_CONTENTS );
  121. return _pTextFilt->Init( 0,
  122. 1,
  123. (FULLPROPSPEC const *)&ps,
  124. pFlags );
  125. }
  126. //+---------------------------------------------------------------------------
  127. //
  128. // Member: GenIFilter::GetChunk, public
  129. //
  130. // Synopsis: Gets the next chunk and returns chunk information in pStat
  131. //
  132. // Arguments: [pStat] -- for chunk information
  133. //
  134. // History: 07-Oct-93 AmyA Created.
  135. //
  136. //----------------------------------------------------------------------------
  137. SCODE STDMETHODCALLTYPE GenIFilter::GetChunk( STAT_CHUNK * pStat )
  138. {
  139. SCODE sc = S_OK;
  140. CTranslateSystemExceptions translate;
  141. TRY
  142. {
  143. if (_state == FilterNextProp)
  144. {
  145. _state = FilterProp;
  146. }
  147. //
  148. // All chunks of plain text come first.
  149. //
  150. if ( _state == FilterContents )
  151. {
  152. sc = _pTextFilt->GetChunk( pStat );
  153. if ( SUCCEEDED(sc) )
  154. {
  155. pStat->locale = 0; // use the default word breaker
  156. _locale = 0;
  157. _ulLastTextChunkID = pStat->idChunk;
  158. }
  159. else if ( sc == FILTER_E_END_OF_CHUNKS )
  160. {
  161. _ulChunkID = _ulLastTextChunkID;
  162. ULONG Flags;
  163. CFullPropSpec ps( guidStorage, PID_STG_CONTENTS );
  164. sc = _pTextFilt->Init( 0,
  165. 1,
  166. (FULLPROPSPEC const *)&ps,
  167. &Flags );
  168. if ( SUCCEEDED(sc) )
  169. {
  170. delete _pTextStream;
  171. _pTextStream = new CFilterTextStream (_pTextFilt);
  172. if (SUCCEEDED (_pTextStream->GetStatus()))
  173. {
  174. _genParse.Init( _pTextStream );
  175. _state = FilterProp;
  176. }
  177. else
  178. _state = FilterDone;
  179. }
  180. else
  181. _state = FilterDone;
  182. }
  183. }
  184. if ( _state == FilterProp && SUCCEEDED(sc) )
  185. {
  186. while ( TRUE )
  187. {
  188. if (_genParse.Parse())
  189. {
  190. pStat->attribute.guidPropSet = guidCPlusPlus;
  191. pStat->attribute.psProperty = _genParse.GetAttribute();
  192. for ( unsigned i = 0; i < _cAttrib; i++ )
  193. if ( *(CFullPropSpec *)(&pStat->attribute) == _pAttrib[i] )
  194. break;
  195. if ( _cAttrib == 0 || i < _cAttrib ) // Property should be returned
  196. {
  197. pStat->idChunk = ++_ulChunkID;
  198. pStat->breakType = CHUNK_EOS;
  199. pStat->flags = CHUNK_TEXT;
  200. pStat->locale = _locale;
  201. FILTERREGION regionSource;
  202. // what's the source of this derived property?
  203. _genParse.GetRegion ( regionSource );
  204. pStat->idChunkSource = regionSource.idChunk;
  205. pStat->cwcStartSource = regionSource.cwcStart;
  206. pStat->cwcLenSource = regionSource.cwcExtent;
  207. sc = S_OK;
  208. break;
  209. }
  210. }
  211. else
  212. {
  213. _state = FilterValue;
  214. break;
  215. }
  216. }
  217. }
  218. if ( _state == FilterNextValue )
  219. {
  220. _genParse.SkipValue();
  221. _state = FilterValue;
  222. }
  223. if ( _state == FilterValue )
  224. {
  225. while ( TRUE )
  226. {
  227. if ( _genParse.GetValueAttribute( pStat->attribute.psProperty ) )
  228. {
  229. pStat->attribute.guidPropSet = guidCPlusPlus;
  230. for ( unsigned i = 0; i < _cAttrib; i++ )
  231. if ( *(CFullPropSpec *)(&pStat->attribute) == _pAttrib[i] )
  232. break;
  233. if ( _cAttrib == 0 || i < _cAttrib ) // Property should be returned
  234. {
  235. pStat->flags = CHUNK_VALUE;
  236. pStat->locale = _locale;
  237. _state = FilterNextValue;
  238. sc = S_OK;
  239. break;
  240. }
  241. else
  242. _genParse.SkipValue();
  243. }
  244. else
  245. {
  246. _state = FilterDone;
  247. break;
  248. }
  249. }
  250. }
  251. if (_state == FilterDone || !SUCCEEDED(sc))
  252. {
  253. sc = FILTER_E_END_OF_CHUNKS;
  254. _state = FilterDone;
  255. }
  256. }
  257. CATCH(CException, e)
  258. {
  259. sc = e.GetErrorCode();
  260. }
  261. END_CATCH;
  262. return sc;
  263. }
  264. //+---------------------------------------------------------------------------
  265. //
  266. // Member: GenIFilter::GetText, public
  267. //
  268. // Synopsis: Retrieves text from current chunk
  269. //
  270. // Arguments: [pcwcBuffer] -- count of characters in buffer
  271. // [awcBuffer] -- buffer for text
  272. //
  273. // History: 07-Oct-93 AmyA Created.
  274. //
  275. //----------------------------------------------------------------------------
  276. SCODE STDMETHODCALLTYPE GenIFilter::GetText( ULONG * pcwcBuffer,
  277. WCHAR * awcBuffer )
  278. {
  279. if ( _state == FilterValue || _state == FilterNextValue )
  280. return FILTER_E_NO_TEXT;
  281. if ( _state == FilterContents )
  282. {
  283. return _pTextFilt->GetText( pcwcBuffer, awcBuffer );
  284. }
  285. else if ( _state == FilterProp )
  286. {
  287. if ( _genParse.GetTokens( pcwcBuffer, awcBuffer ))
  288. {
  289. _state = FilterNextProp;
  290. return FILTER_S_LAST_TEXT;
  291. }
  292. else
  293. return S_OK;
  294. }
  295. else if ( _state == FilterNextProp )
  296. {
  297. return FILTER_E_NO_MORE_TEXT;
  298. }
  299. else
  300. {
  301. Win4Assert ( _state == FilterDone );
  302. return FILTER_E_NO_MORE_TEXT;
  303. }
  304. }
  305. //+---------------------------------------------------------------------------
  306. //
  307. // Member: GenIFilter::GetValue, public
  308. //
  309. // Synopsis: Not implemented for the text filter
  310. //
  311. // History: 07-Oct-93 AmyA Created.
  312. //
  313. //----------------------------------------------------------------------------
  314. SCODE STDMETHODCALLTYPE GenIFilter::GetValue( VARIANT ** ppPropValue )
  315. {
  316. if ( _state == FilterContents )
  317. return _pTextFilt->GetValue( ppPropValue );
  318. if ( _state == FilterDone )
  319. return FILTER_E_NO_MORE_VALUES;
  320. if ( _state != FilterNextValue )
  321. return FILTER_E_NO_VALUES;
  322. *ppPropValue = _genParse.GetValue();
  323. _state = FilterValue;
  324. if ( 0 == *ppPropValue )
  325. return FILTER_E_NO_MORE_VALUES;
  326. else
  327. return S_OK;
  328. }
  329. //+---------------------------------------------------------------------------
  330. //
  331. // Member: GenIFilter::BindRegion, public
  332. //
  333. // Synopsis: Creates moniker or other interface for text indicated
  334. //
  335. // Arguments: [origPos] -- location of text
  336. // [riid] -- Interface Id
  337. // [ppunk] -- returned interface
  338. //
  339. // History: 07-Oct-93 AmyA Created.
  340. //
  341. //----------------------------------------------------------------------------
  342. SCODE STDMETHODCALLTYPE GenIFilter::BindRegion( FILTERREGION origPos,
  343. REFIID riid,
  344. void ** ppunk )
  345. {
  346. return _pTextFilt->BindRegion( origPos, riid, ppunk );
  347. }
  348. //+---------------------------------------------------------------------------
  349. //
  350. // Member: GenIFilter::GetClassID, public
  351. //
  352. // Synopsis: Returns the class id of this class.
  353. //
  354. // Arguments: [pClassID] -- the class id
  355. //
  356. // History: 07-Oct-93 AmyA Created.
  357. //
  358. //----------------------------------------------------------------------------
  359. SCODE STDMETHODCALLTYPE GenIFilter::GetClassID( CLSID * pClassID )
  360. {
  361. *pClassID = CLSID_GenIFilter;
  362. return S_OK;
  363. }
  364. //+---------------------------------------------------------------------------
  365. //
  366. // Member: GenIFilter::IsDirty, public
  367. //
  368. // Synopsis: Always returns S_FALSE since this class is read-only.
  369. //
  370. // History: 07-Oct-93 AmyA Created.
  371. //
  372. //----------------------------------------------------------------------------
  373. SCODE STDMETHODCALLTYPE GenIFilter::IsDirty()
  374. {
  375. return S_FALSE; // Since the filter is read-only, there will never be
  376. // changes to the file.
  377. }
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Member: GenIFilter::Load, public
  381. //
  382. // Synopsis: Loads the indicated file
  383. //
  384. // Arguments: [pszFileName] -- the file name
  385. // [dwMode] -- the mode to load the file in
  386. //
  387. // History: 07-Oct-93 AmyA Created.
  388. //
  389. // Notes: dwMode must be either 0 or STGM_READ.
  390. //
  391. //----------------------------------------------------------------------------
  392. SCODE STDMETHODCALLTYPE GenIFilter::Load(LPCWSTR pszFileName, DWORD dwMode)
  393. {
  394. SCODE sc = LoadTextFilter( pszFileName, &_pTextFilt );
  395. if ( SUCCEEDED(sc) )
  396. {
  397. //
  398. // Load file
  399. //
  400. sc = _pTextFilt->QueryInterface( IID_IPersistFile, (void **) &_pPersFile );
  401. if ( SUCCEEDED(sc) )
  402. {
  403. sc = _pPersFile->Load( pszFileName, dwMode );
  404. }
  405. else
  406. {
  407. _pTextFilt->Release();
  408. _pTextFilt = 0;
  409. }
  410. }
  411. return sc;
  412. }
  413. //+---------------------------------------------------------------------------
  414. //
  415. // Member: GenIFilter::Save, public
  416. //
  417. // Synopsis: Always returns E_FAIL, since the file is opened read-only
  418. //
  419. // History: 16-Jul-93 AmyA Created.
  420. //
  421. //----------------------------------------------------------------------------
  422. SCODE STDMETHODCALLTYPE GenIFilter::Save(LPCWSTR pszFileName, BOOL fRemember)
  423. {
  424. return E_FAIL; // cannot be saved since it is read-only
  425. }
  426. //+---------------------------------------------------------------------------
  427. //
  428. // Member: GenIFilter::SaveCompleted, public
  429. //
  430. // Synopsis: Always returns S_OK since the file is opened read-only
  431. //
  432. // History: 16-Jul-93 AmyA Created.
  433. //
  434. //----------------------------------------------------------------------------
  435. SCODE STDMETHODCALLTYPE GenIFilter::SaveCompleted(LPCWSTR pszFileName)
  436. {
  437. return E_FAIL;
  438. }
  439. //+---------------------------------------------------------------------------
  440. //
  441. // Member: GenIFilter::GetCurFile, public
  442. //
  443. // Synopsis: Returns a copy of the current file name
  444. //
  445. // Arguments: [ppszFileName] -- where the copied string is returned.
  446. //
  447. // History: 09-Aug-93 AmyA Created.
  448. //
  449. //----------------------------------------------------------------------------
  450. SCODE STDMETHODCALLTYPE GenIFilter::GetCurFile(LPWSTR * ppszFileName)
  451. {
  452. return _pPersFile->GetCurFile( ppszFileName );
  453. }