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.

650 lines
17 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1998.
  5. //
  6. // File: TxtSinkDump.cxx
  7. //
  8. // Contents: Contains an implementation of ICiCTextSink interface.
  9. //
  10. // History: Jan-13-97 KLam Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #define WIN32_LEAN_AND_MEAN
  14. extern "C"
  15. {
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. }
  20. #include <windows.h>
  21. #include <cierror.h>
  22. #include <query.h>
  23. #include <cidebnot.h>
  24. #include <ciexcpt.hxx>
  25. #include <tgrow.hxx>
  26. #include <regacc.hxx>
  27. #include <ciregkey.hxx>
  28. #include <filtreg.hxx> // registration functions
  29. #include "FiltStat.hxx"
  30. static long glcInstances = 0;
  31. static WCHAR gwszModule[MAX_PATH];
  32. static WCHAR gwszFilterStatusDumpCLSID[] = L"{3ce7c910-8d72-11d1-8f76-00a0c91917f5}";
  33. static GUID CLSID_CFilterStatusDump = { 0x3ce7c910, 0x8d72, 0x11d1,
  34. { 0x8f, 0x76, 0x00, 0xa0, 0xc9, 0x19, 0x17, 0xf5 } };
  35. static const WCHAR gwszDescription [] = L"Filtering Status Dumper";
  36. //
  37. // CFilterStatusDump Methods
  38. //
  39. CFilterStatusDump::CFilterStatusDump ()
  40. : _pfOutput(0),
  41. _fSuccessReport( FALSE ),
  42. _cRefs ( 1 )
  43. {
  44. InterlockedIncrement ( &glcInstances );
  45. }
  46. CFilterStatusDump::~CFilterStatusDump ()
  47. {
  48. if ( 0 != _pfOutput )
  49. fclose( _pfOutput );
  50. InterlockedDecrement( &glcInstances );
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Member: CFilterStatusDump::QueryInterface
  55. //
  56. // Synopsis: Returns interfaces to IID_IUknown, IID_ICiCTextSink
  57. //
  58. // Arguments: [riid] -- IID of new interface
  59. // [ppvObject] -- New interface * returned here
  60. //
  61. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  62. //
  63. // History: Jan-13-98 KLam Created
  64. //
  65. //----------------------------------------------------------------------------
  66. STDMETHODIMP CFilterStatusDump::QueryInterface ( REFIID riid,
  67. void ** ppvObject )
  68. {
  69. //Win4Assert ( 0 != ppvObject );
  70. if ( IID_IUnknown == riid )
  71. {
  72. AddRef ();
  73. *ppvObject = (void *)(IUnknown *) this;
  74. return S_OK;
  75. }
  76. else if ( IID_IFilterStatus == riid )
  77. {
  78. AddRef ();
  79. *ppvObject = (void *)(IFilterStatus *) this;
  80. return S_OK;
  81. }
  82. else
  83. {
  84. *ppvObject = 0;
  85. return E_NOINTERFACE;
  86. }
  87. }
  88. //+---------------------------------------------------------------------------
  89. //
  90. // Member: CFilterStatusDump::AddRef
  91. //
  92. // Synopsis: Increments the reference count on the object
  93. //
  94. // History: Jan-13-98 KLam Created
  95. //
  96. //----------------------------------------------------------------------------
  97. ULONG STDMETHODCALLTYPE CFilterStatusDump::AddRef ()
  98. {
  99. return InterlockedIncrement ( (long *)&_cRefs );
  100. }
  101. //+---------------------------------------------------------------------------
  102. //
  103. // Member: CFilterStatusDump::Release
  104. //
  105. // Synopsis: Decrements the reference count on the object.
  106. // If the reference count reaches 0, the object is deleted.
  107. //
  108. // History: Jan-13-98 KLam Created
  109. //
  110. //----------------------------------------------------------------------------
  111. ULONG STDMETHODCALLTYPE CFilterStatusDump::Release ()
  112. {
  113. ULONG cTemp = InterlockedDecrement ( (long *)&_cRefs );
  114. if ( 0 == cTemp )
  115. delete this;
  116. return cTemp;
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Member: CFilterStatusDump::Initialize
  121. //
  122. // Synopsis: Creates or opens the text sink dump file. If the file already
  123. // exists, it sets the file pointer to the end of the file.
  124. //
  125. // Arguments: [pwszSessionId] -- String identifying current session
  126. // [pwszSessionPath] -- Path containing current session catalog
  127. // [pIndexClientInfo] -- Pointer to Client Info context
  128. // [fQuery] -- Boolean indicating whether the incoming
  129. // text is a query
  130. //
  131. // History: Jan-13-98 KLam Created
  132. //
  133. //----------------------------------------------------------------------------
  134. STDMETHODIMP CFilterStatusDump::Initialize ( WCHAR const * pwszCatalog,
  135. WCHAR const * pwszCatalogPath )
  136. {
  137. CLock lock( _mutex );
  138. SCODE sc = E_FAIL;
  139. //
  140. // Clean up from previous state, if any.
  141. //
  142. if ( 0 != _pfOutput )
  143. {
  144. fclose( _pfOutput );
  145. _pfOutput = 0;
  146. }
  147. CTranslateSystemExceptions translate;
  148. TRY
  149. {
  150. //
  151. // Locate path of dump file in registry.
  152. //
  153. unsigned ccCat = wcslen( pwszCatalog );
  154. unsigned const ccBase = sizeof(wcsRegJustCatalogsSubKey)/sizeof(WCHAR) - 1;
  155. XGrowable<WCHAR> xTemp;
  156. xTemp.SetSize( ccBase + ccCat + 2 );
  157. RtlCopyMemory( xTemp.Get(), wcsRegJustCatalogsSubKey, ccBase * sizeof(WCHAR) );
  158. xTemp[ccBase] = L'\\';
  159. RtlCopyMemory( xTemp.Get() + ccBase + 1, pwszCatalog, (ccCat + 1) * sizeof(WCHAR) ); // 1 for null
  160. CRegAccess reg( RTL_REGISTRY_CONTROL, xTemp.Get() );
  161. XGrowable<WCHAR> xFile;
  162. reg.Get( L"FilterStatusLog", xFile.Get(), xFile.Count() );
  163. _fSuccessReport = (reg.Read( L"FilterStatusReportSuccess", 0, 0, 1 ) != 0);
  164. //
  165. // Open file
  166. //
  167. _pfOutput = _wfopen( xFile.Get(), L"a+" );
  168. if ( 0 == _pfOutput )
  169. {
  170. THROW( CException( ERROR_FILE_NOT_FOUND ) );
  171. }
  172. sc = S_OK;
  173. }
  174. CATCH( CException, e )
  175. {
  176. sc = GetOleError( e );
  177. }
  178. END_CATCH
  179. return sc;
  180. }
  181. STDMETHODIMP CFilterStatusDump::PreFilter( WCHAR const * pwszPath )
  182. {
  183. return S_OK;
  184. }
  185. STDMETHODIMP CFilterStatusDump::FilterLoad( WCHAR const * pwszPath, SCODE scFilterStatus )
  186. {
  187. if ( FAILED(scFilterStatus) && 0 != _pfOutput )
  188. {
  189. //
  190. // Convert to narrow string.
  191. //
  192. XGrowable<char, MAX_PATH*2> xTemp;
  193. DWORD cbConvert = WideCharToMultiByte( CP_ACP,
  194. WC_COMPOSITECHECK,
  195. pwszPath,
  196. wcslen( pwszPath ) + 1,
  197. xTemp.Get(),
  198. xTemp.Count(),
  199. 0,
  200. 0 );
  201. CLock lock( _mutex );
  202. if ( 0 == cbConvert )
  203. {
  204. xTemp[cbConvert] = 0;
  205. fprintf( _pfOutput, "Error %#x loading filter for \"%ws\"\n", scFilterStatus, pwszPath );
  206. }
  207. else
  208. {
  209. xTemp[cbConvert] = 0;
  210. fprintf( _pfOutput, "Error %#x loading filter for \"%s\"\n", scFilterStatus, xTemp.Get() );
  211. }
  212. fflush( _pfOutput );
  213. }
  214. return S_OK;
  215. }
  216. STDMETHODIMP CFilterStatusDump::PostFilter( WCHAR const * pwszPath, SCODE scFilterStatus )
  217. {
  218. if ( (_fSuccessReport || FAILED(scFilterStatus)) && 0 != _pfOutput )
  219. {
  220. //
  221. // Convert to narrow string.
  222. //
  223. XGrowable<char, MAX_PATH*2> xTemp;
  224. DWORD cbConvert = WideCharToMultiByte( CP_ACP,
  225. WC_COMPOSITECHECK,
  226. pwszPath,
  227. wcslen( pwszPath ) + 1,
  228. xTemp.Get(),
  229. xTemp.Count(),
  230. 0,
  231. 0 );
  232. CLock lock( _mutex );
  233. if ( 0 == cbConvert )
  234. {
  235. xTemp[cbConvert] = 0;
  236. if ( SUCCEEDED(scFilterStatus) )
  237. fprintf( _pfOutput, "ok: \"%ws\"\n", pwszPath );
  238. else
  239. fprintf( _pfOutput, "Error %#x indexing \"%ws\"\n", scFilterStatus, pwszPath );
  240. }
  241. else
  242. {
  243. xTemp[cbConvert] = 0;
  244. if ( SUCCEEDED(scFilterStatus) )
  245. fprintf( _pfOutput, "ok \"%s\"\n", xTemp.Get() );
  246. else
  247. fprintf( _pfOutput, "Error %#x indexing \"%s\"\n", scFilterStatus, xTemp.Get() );
  248. }
  249. fflush( _pfOutput );
  250. }
  251. return S_OK;
  252. }
  253. //
  254. // CFilterStatusCF Methods
  255. //
  256. //+---------------------------------------------------------------------------
  257. //
  258. // Member: CFilterStatusCF::CFilterStatusCF
  259. //
  260. // Synopsis: Constructor
  261. //
  262. // History: Jan-13-98 KLam Created
  263. //
  264. //----------------------------------------------------------------------------
  265. CFilterStatusCF::CFilterStatusCF () : _cRefs (1)
  266. {
  267. InterlockedIncrement ( &glcInstances );
  268. }
  269. //+---------------------------------------------------------------------------
  270. //
  271. // Member: CFilterStatusCF::~CFilterStatusCF
  272. //
  273. // Synopsis: Destructor
  274. //
  275. // History: Jan-13-98 KLam Created
  276. //
  277. //----------------------------------------------------------------------------
  278. CFilterStatusCF::~CFilterStatusCF ()
  279. {
  280. //Win4Assert( _cRefs == 0);
  281. //Win4Assert( glcInstances != 0 );
  282. InterlockedDecrement( &glcInstances );
  283. }
  284. //+---------------------------------------------------------------------------
  285. //
  286. // Member: CFilterStatusCF::QueryInterface
  287. //
  288. // Synopsis: Rebind to other interface
  289. //
  290. // Arguments: [riid] -- IID of new interface
  291. // [ppvObject] -- New interface * returned here
  292. //
  293. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  294. //
  295. // History: Jan-13-98 KLam Created
  296. //
  297. //----------------------------------------------------------------------------
  298. STDMETHODIMP CFilterStatusCF::QueryInterface ( REFIID riid,
  299. void ** ppvObject )
  300. {
  301. //Win4Assert ( NULL != ppvObject );
  302. if ( IID_IUnknown == riid )
  303. {
  304. AddRef ();
  305. *ppvObject = (void *) ((IUnknown *) this);
  306. return S_OK;
  307. }
  308. else if ( IID_IClassFactory == riid )
  309. {
  310. AddRef ();
  311. *ppvObject = (void *) ((IClassFactory *) this);
  312. return S_OK;
  313. }
  314. else
  315. {
  316. *ppvObject = NULL;
  317. return E_NOINTERFACE;
  318. }
  319. }
  320. //+---------------------------------------------------------------------------
  321. //
  322. // Member: CFilterStatusCF::AddRef
  323. //
  324. // Synopsis: Increments the reference count on the object
  325. //
  326. // History: Jan-13-98 KLam Created
  327. //
  328. //----------------------------------------------------------------------------
  329. ULONG STDMETHODCALLTYPE CFilterStatusCF::AddRef ()
  330. {
  331. return InterlockedIncrement ( (long *)&_cRefs );
  332. }
  333. //+---------------------------------------------------------------------------
  334. //
  335. // Member: CFilterStatusCF::Release
  336. //
  337. // Synopsis: Decrements the reference count on the object.
  338. // If the reference count reaches 0, the object is deleted.
  339. //
  340. // History: Jan-13-98 KLam Created
  341. //
  342. //----------------------------------------------------------------------------
  343. ULONG STDMETHODCALLTYPE CFilterStatusCF::Release ()
  344. {
  345. //Win4Assert ( 0 < _cRefs );
  346. unsigned long cTemp = InterlockedDecrement ( (long *)&_cRefs );
  347. if ( 0 == cTemp )
  348. delete this;
  349. return cTemp;
  350. }
  351. //+-------------------------------------------------------------------------
  352. //
  353. // Method: CFilterStatusCF::CreateInstance
  354. //
  355. // Synopsis: Create new CFilterStatus instance
  356. //
  357. // Arguments: [pUnkOuter] -- 'Outer' IUnknown; IGNORED
  358. // [riid] -- Interface to bind
  359. // [ppvObject] -- Interface returned here
  360. //
  361. // History: Jan-13-1998 KLam Created
  362. //
  363. //--------------------------------------------------------------------------
  364. STDMETHODIMP CFilterStatusCF::CreateInstance ( IUnknown * pUnkOuter,
  365. REFIID riid,
  366. void ** ppvObject )
  367. {
  368. if ( 0 != pUnkOuter )
  369. return ResultFromScode ( CLASS_E_NOAGGREGATION );
  370. CFilterStatusDump *pSink = NULL;
  371. SCODE sc = S_OK;
  372. CTranslateSystemExceptions translate;
  373. TRY
  374. {
  375. // Create a new CFilterStatus
  376. pSink = new CFilterStatusDump;
  377. // Query the object to see if it supports the desired interface
  378. sc = pSink->QueryInterface ( riid, ppvObject );
  379. // Release the class factory's instance of the object
  380. pSink->Release ();
  381. }
  382. CATCH(CException, e)
  383. {
  384. Win4Assert( 0 == pSink );
  385. sc = GetOleError( e );
  386. }
  387. END_CATCH;
  388. return sc;
  389. }
  390. //+-------------------------------------------------------------------------
  391. //
  392. // Method: CFilterStatusCF::LockServer
  393. //
  394. // Synopsis: Force class factory to remain loaded
  395. //
  396. // Arguments: [fLock] -- TRUE to lock ther server. FALSE to unlock the server
  397. //
  398. // History: Jan-13-1998 KLam Created
  399. //
  400. //--------------------------------------------------------------------------
  401. STDMETHODIMP CFilterStatusCF::LockServer ( BOOL fLock )
  402. {
  403. if ( fLock )
  404. InterlockedIncrement ( &glcInstances );
  405. else
  406. InterlockedDecrement ( &glcInstances );
  407. return S_OK;
  408. }
  409. //
  410. // Exported Routines
  411. //
  412. //+-------------------------------------------------------------------------
  413. //
  414. // Function: DllGetClassObject
  415. //
  416. // Synopsis: Ole DLL load class routine
  417. //
  418. // Arguments: [cid] -- Class to load
  419. // [iid] -- Interface to bind to on class object
  420. // [ppvObject] -- Interface pointer returned here
  421. //
  422. // Returns: Text sink dump object
  423. //
  424. // History: 13-Jan-1998 KLam Created
  425. //
  426. //--------------------------------------------------------------------------
  427. STDAPI DllGetClassObject( REFCLSID cid,
  428. REFIID iid,
  429. void ** ppvObject )
  430. {
  431. CFilterStatusCF * pFactory = NULL;
  432. SCODE sResult = S_OK;
  433. CTranslateSystemExceptions translate;
  434. TRY
  435. {
  436. if ( CLSID_CFilterStatusDump == cid )
  437. {
  438. pFactory = new CFilterStatusCF;
  439. if ( NULL != pFactory )
  440. {
  441. sResult = pFactory->QueryInterface( iid, ppvObject );
  442. pFactory->Release ( );
  443. }
  444. else
  445. sResult = E_OUTOFMEMORY;
  446. }
  447. else
  448. sResult = E_NOINTERFACE;
  449. }
  450. CATCH(CException, e)
  451. {
  452. sResult = GetOleError(e);
  453. }
  454. END_CATCH;
  455. return sResult;
  456. }
  457. //+-------------------------------------------------------------------------
  458. //
  459. // Method: DllCanUnloadNow
  460. //
  461. // Synopsis: Queries DLL to see if it can be unloaded
  462. //
  463. // Returns: S_OK if it is acceptable for caller to unload DLL.
  464. //
  465. // History: 13-Jan-1998 KLam Created
  466. //
  467. //--------------------------------------------------------------------------
  468. STDAPI DllCanUnloadNow ( )
  469. {
  470. return ( glcInstances <= 0 ) ? S_OK : S_FALSE;
  471. }
  472. //+-------------------------------------------------------------------------
  473. //
  474. // Method: DllRegisterServer
  475. //
  476. // Synopsis: Registers this server with the registry
  477. //
  478. // Returns: S_OK if registration succeeded, otherwise SELFREG_E_CLASS
  479. //
  480. // History: 13-Jan-1998 KLam Created
  481. //
  482. //--------------------------------------------------------------------------
  483. STDAPI DllRegisterServer ()
  484. {
  485. WCHAR const * aKeyValues[4] = { gwszFilterStatusDumpCLSID,
  486. gwszDescription,
  487. L"InprocServer32",
  488. gwszModule };
  489. long retVal = BuildKeyValues( aKeyValues, sizeof(aKeyValues)/sizeof(aKeyValues[0]) );
  490. if ( ERROR_SUCCESS == retVal )
  491. retVal = AddThreadingModel( L"{3ce7c910-8d72-11d1-8f76-00a0c91917f5}",
  492. L"Both" );
  493. if ( ERROR_SUCCESS == retVal )
  494. return S_OK;
  495. else
  496. return SELFREG_E_CLASS;
  497. }
  498. //+-------------------------------------------------------------------------
  499. //
  500. // Method: DllUnregisterServer
  501. //
  502. // Synopsis: Unregisters this server
  503. //
  504. // Returns: S_OK if unregistration succeeded, otherwise SELFREG_E_CLASS
  505. //
  506. // History: 13-Jan-1998 KLam Created
  507. //
  508. //--------------------------------------------------------------------------
  509. STDAPI DllUnregisterServer ()
  510. {
  511. WCHAR const * aKeyValues[4] = { gwszFilterStatusDumpCLSID,
  512. gwszDescription,
  513. L"InprocServer32",
  514. gwszModule };
  515. long retval = DestroyKeyValues( aKeyValues,
  516. sizeof(aKeyValues)/sizeof(aKeyValues[0]) );
  517. if ( ERROR_SUCCESS == retval )
  518. return S_OK;
  519. else
  520. return SELFREG_E_CLASS;
  521. }
  522. //+-------------------------------------------------------------------------
  523. //
  524. // Method: DllMain
  525. //
  526. // Synopsis: Main routine for DLL. Saves the module name for this dll.
  527. //
  528. // Returns: TRUE
  529. //
  530. // History: 13-Jan-1998 KLam Created
  531. //
  532. //--------------------------------------------------------------------------
  533. BOOL APIENTRY DllMain ( HANDLE hModule,
  534. DWORD dwReason,
  535. void * pReserved )
  536. {
  537. if ( DLL_PROCESS_ATTACH == dwReason )
  538. {
  539. DisableThreadLibraryCalls( (HINSTANCE)hModule );
  540. //
  541. // Get the name of the module
  542. //
  543. DWORD dwResult = GetModuleFileName ( (HMODULE)hModule,
  544. gwszModule,
  545. sizeof(gwszModule)/sizeof(WCHAR) );
  546. //Win4Assert( 0 != dwResult );
  547. }
  548. return TRUE;
  549. }