Enumerating Data Source Objects and Enumerators
Generic consumers that do not want to use the OLE DB Data Links component to select a data source and set initialization properties can use enumerators to search for data source objects and other enumerators. By using enumerators, rather than searching the registry directly, consumers will continue to work if the registry information changes or if new root enumerators with additional functionality, such as the ability to enumerate data source objects on other machines, become available later. To create an instance of an enumerator, the consumer calls CoCreateInstance with the class ID of the enumerator.
To list the data source objects and enumerators visible to the current enumerator, the consumer calls ISourcesRowset::GetSourcesRowset. This method returns a rowset containing information about the currently visible data source objects and enumerators. To create an instance of a data source object or enumerator listed in this rowset, the consumer first calls IParseDisplayName::ParseDisplayName for the returned display name. This method returns a moniker that the consumer can then use to instantiate the data source object or enumerator.
Each row in the rowset returned by ISourcesRowset contains a SOURCES_ISPARENT column. If the row describes an enumerator, this column contains the value VARIANT_TRUE if the enumerator is the same one that can enumerate the current one. For example, if the enumerator lists files and directories in the file system, this is the parent directory. The SOURCES_ISPARENT column thus allows the consumer to traverse backward through a hierarchy of enumerators, such as might be found over a file system. If the row describes a data source object, the SOURCES_ISPARENT column should be ignored by the consumer.
There is a root enumerator that traverses the registry searching for providers and enumerators. For more information, see Root Enumerator Object.
Providers can choose to support their own enumerators, in addition to the root enumerator, although they are not required to do so. Provider-specific enumerators search for data source objects and enumerators known to the provider. For example, suppose a provider exposes data in an SQL DBMS that supports multiple, separate databases in a single installation where the DBMS treats each database as a separate data store. The enumerator for this provider might search the DBMS for databases, which the provider could then expose as separate data source objects, one for each database. The rowset returned by the enumerator would include one row for each database it finds, marking that database as a data source object.
Or suppose a provider exposes data that is stored in text files and treats each directory as a separate data store and each text file in that directory as a table. The enumerator for this provider might traverse the file system for text files, which the provider could then expose as separate data source objects, one for each text file. For each directory it finds, the rowset returned by the enumerator would include one row as an enumerator and one or more rows as data source objects. To access the files in a directory, the consumer would create an instance of a data source object over the directory, using the display name from the row marked as a data source object. To search for subdirectories, the consumer would create an instance of an enumerator over the directory, using the display name from the row marked as an enumerator.
For information about the registry entries used by enumerators, see Enumerator Registry Entries.