Implementing Filter Handlers in Windows Search
It is important that you understand the required DLL structure of a filter handler (an implementation of the IFilter interface).
This topic is organized as follows:
- Implementing and Exporting the DLL Entry Points
- Implementing the IFilter Class and Class Factory
- Inheriting the COM Interfaces
- Implementing the COM Interface Methods
- Additional Resources
- Related topics
Implementing and Exporting the DLL Entry Points
Each IFilter DLL (denoted by Ifilter.dll in this section) must implement and export the following entry points. These entry points are typically exported using a module-definition (.def) file for the IFilter interface or by using the __declspec(dllexport) keyword. The DLL file can be registered to be in any folder, but it usually resides in the %SystemRoot%\system32 folder.
DLL entry points are listed and described in the following table.
|DLL name||DLL description|
|DllRegisterServer||The DllRegisterServer entry point registers the DLL as a filter in the registry. You register the DLL by running the regsvr32.exe program with the IFilter interface DLL file name as an argument:
|DllUnregisterServer Function||The DllUnregisterServer Function entry point removes the DLL as a persistent handler in the registry. You unregister the DLL by running the regsvr32.exe program with the
|DllGetClassObject Function||The content indexing client calls the DllGetClassObject Function entry point, through Component Object Model (COM), to create a class factory object for the IFilter interface and to get a pointer to the class factory interface of that object.|
|DllCanUnloadNow Function||The content-indexing client calls the DllCanUnloadNow Function entry point, through COM, to determine whether it is possible to unload the IFilter DLL. The IFilter interface is unloaded after it is unused for an interval of time, as specified by the FilterIdleTimeOut registry value.|
Implementing the IFilter Class and Class Factory
At least two classes, such as CFilter and CFilterCF, are typically implemented by each IFilter DLL. The CFilter class produces the IFilter interface object that implements the content-filtering functionality. Its member functions implement the interface methods of the IFilter interface. Each IFilter class requires a unique class identifier (CLSID), which the IFilter interface implementer generates.
The CFilterCF class produces the class-factory object for the IFilter interface. The class factory is called, through its IClassFactory Interface interface, by the DllGetClassObject Function entry point of the DLL. The CFilterCF class creates the CFilter object and returns a pointer to IUnknown. In more complex cases, an IFilter can implement a class hierarchy in place of the single CFilter class.
Inheriting the COM Interfaces
Windows Search 3.0 and later require that you use IPersistStream for the following reasons:
- To ensure performance and future compatibility.
- To help increase security. IFilters implemented with IPersistStream are more secure because the context in which the IFilter interface runs does not need the rights to open files on the disk or over the network.
- While Windows Search uses only IPersistStream, the IFilter interface class can also inherit the IPersistFile Interface and/or IPersistStorage Interface interface implementations for backward compatibility.
These interfaces are declared in files included from the mssdk\include directory and have pre-defined interface identifiers (IIDs). The content-indexing client queries the IFilter interface through IUnknown to determine which of these interfaces to use when filtering content.
Implementing the COM Interface Methods
The IFilter interface implements the IUnknown methods for both the IFilter interface class and the IFilter interface-class factory. The following table lists, in vtable order, the IFilter interface-specific interfaces and methods that the IFilter interface should implement. The IFilter interface must implement at least IPersistStream, but can implement additional IPersist-derived interfaces.
|IClassFactory Interface||CreateInstance, LockServer|
|IClassFactory2 Interface||GetLicInfo, RequestLicKey, CreateInstanceLic|
|IFilter||IFilter::Init, IFilter::GetChunk, IFilter::GetText, IFilter::GetValue, IFilter::BindRegion|
|IPersistFile Interface||IsDirty, Load, Save, SaveCompleted, GetCurFile|
|IPersistStorage Interface||IsDirty, Load, Save, GetSizeMax|
|IPersistStream||IsDirty, Load, Save, GetSizeMax|
The reference page for each method specifies the parameters and functional behavior for that method. Each reference page also gives the result codes to implement for that method. The reference pages for the IFilter methods give the interface-specific Codes in FACILITY_ITF result codes to be implemented, and the content-indexing client can also handle any of the generic result codes, such as FACILITY_NULL and FACILITY_WIN32. For more information, see Structure of COM Error Codes.
COM Methods that are not Implemented
Windows Search does not need to implement the COM methods listed in the following table.
|Method that is not required||Description|
|IPersistStream::IsDirty||Filters should return E_NOTIMPL.|
|IPersistStream::Save||Filters should return E_NOTIMPL.|
|IPersistStream::GetSizeMax||Filters should return E_NOTIMPL.|
|IFilter::BindRegion||Filters should return E_NOTIMPL.|
- The IFilterSample code sample, available on GitHub, demonstrates how to create an IFilter base class for implementing the IFilter interface.
- For an overview of the indexing process, see The Indexing Process.
- For an overview of file types, see File Types.
- To query file association attributes for a file type, see PerceivedTypes, SystemFileAssociations, and Application Registration.