Site Archive (Complete)
Windows/.NET
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
May 01, 2001
Using the Windows 2000 Object Picker

(Page 1 of 3)
Arnaud Aubert
Windows 2000 supports Active Directory, an LDAP-compatible directory service that provides programmatic access to all kinds of objects across the network. One highly practical tool that Windows 2000 supplies is the Object Picker Dialog Box, an easy way for applications to allow users to select from a variety of objects, such as users, computers, groups, etc. This article demonstrates how to access this dialog box.
May 2001/Using the Windows 2000 Object Picker


Windows NT introduced some network-related dialog boxes (like that in Figure 1) integrated in the standard Windows NT administrative tools. That was fine for administrators, but there was no API for programmers to include such dialog boxes in their own application, so many programmers created custom code to let users perform tasks such as selecting users.

Windows 2000 offers an “object picker dialog” that can be used to let users select users, contacts, groups, and computers. It can access objects from the Active Directory global catalog, a Windows 2000 domain or computer, a Windows NT v4.0 domain or computer, or a workgroup. This article describes some of the abilities of this dialog and provides a code example.

Active Directory Introduction

Windows 2000 provides a brand new network common repository named “Active Directory.” Active Directory’s power consists of an extensible schema queryable with the standard LDAP protocol. The platform SDK provides large amounts of documentation for Active Directory.

Briefly, Active Directory is a hierarchical database for storing and retrieving arbitrary information. The items in the database are objects, named sets of attributes that describe something (e.g., a user, a printer, an application , etc.). Some aspects of the database are predefined, but you can extend the database and add new categories of information. You can refer to a particular position in this hierarchical database with something called a “distinguished name” (sometimes abbreviated “DN”). This is analogous to a path in a hierarchical file system.

Unlike a file system path, distinguished names require you to specify the “class” of each node in the path. For example, here is a string representation of a fictional distinguished name for an Active Directory object representing a user in company:

cn=John Smith,ou=Sales,dc=microsoft,dc=com
As you can see, the distinguished name format starts the leaf object, and works back towards the root (the opposite of how you normally write a file system path). The funny two-character codes are called “prefixes,” which I will explain next.

RFC 1779 (www.faqs.org/rfc/rfc1779.html) defined this string syntax for distinguished names. This RFC defined several prefixes for indicating the class of object being referred to, but Active Directory uses only three of the possible prefixes: cn, ou, and dc.

cn stands for “common name.” It specifies the name of the object searched for. All objects in the database have this attribute, and it must be unique for objects within a given container. That’s roughly the same thing as saying that no two files within a given directory can have the same name.

ou stands for “organizational name unit.” These are container objects, but they represent a security boundary. For example, if you wanted to give one manager authority to manage a section of the Active Directory representing the machines in just his department, you would probably place those objects underneath an ou object. It would be possible to grant him complete authority to add, delete, and modify objects beneath that organizational name unit, without granting any permissions to objects higher in the tree.

dc stands for “domain component,” and this prefix is used only for specifying domain roots.

The previous sample distinguished name:

cn=John Smith,ou=Sales,dc=microsoft,dc=com

can now be translated as: “user John Smith in the Sales organizational unit of the microsoft.com domain.”

The Object Picker

The object picker is a Windows 2000 COM component you can use to allow users to graphically select user, contact, group, or computer objects from the Active Directory. This provides dialog box services for some common tasks that were not available under Windows NT v4.0. I will illustrate how to use this COM object with the sample program in op.cpp (Listing 1). This month’s code archive contains the complete source code needed to build this application.

You will need to include objsel.h to get the appropriate object picker definitions. Depending upon how new your compiler is, you may have to obtain this file from the platform SDK. This is currently downloadable from www.microsoft.com/msdownload/platformsdk/setuplauncher.htm.

The object picker COM object has two main methods of interest: Initialize() and InvokeDialog(). The Initialize() method takes a pointer to a DSOP_INIT_INFO structure specifying:

  • the kind of objects that should be selected through standard filters like DSOP_DOWNLEVEL_FILTER_COMPUTERS for computers or DSOP_DOWNLEVEL_FILTER_USERS for users
  • if multi-selection should be enabled or not with the DSOP_FLAG_MULTISELECT option
  • which domains should be browsed (parent domains, child domains, workgroups, etc.) through the flType member flags.

InvokeDialog() simply displays the standard dialog box using the parameters specified in the last call to Initialize(). It takes the handle of the parent window and returns a data object using the CFSTR_DSOP_DS_SELECTION_LIST clipboard format. This format handles an HGLOBAL containing a DS_SELECTION_LIST structure.

Sample Program

I wrote a demonstration program in op.cpp (Listing 1) showing how to invoke the object picker dialog box. SelectUsersOrComputers() will show a list of the users or computers depending on whether the bUsers parameter is TRUE or not. After creating the object picker COM object, I initialize it to use a scope that will include all the up and down-level joined domains in the DSOP_SCOPE_INIT_INFO flType member. I also specify which objects (users or computers) I want to filter, using the FilterFlags member. Once my scope is fully initialized, I fill in the DSOP_INIT_INFO main structure by setting a pointer to the previously created scope in aDsScopeInfos and enabling multi-selection with the DSOP_FLAG_MULTISELECT flag in flOptions. I then only need to call Initialize() and InvokeDialog() to get the IDataObject in return. Note that S_FALSE will be returned if the user clicks on Cancel.

The example also includes a function named PrintSelection() that will iterate through the selected elements. I simply initialize my FORMATETC and STGMEDIUM structures for the CFSTR_DSOP_DS_SELECTION_LIST clipboard format and ask for the HGLOBAL by calling its GetData() method. I then only need to lock the HGLOBAL memory and cast my pDsSelList pointer to a PDS_SELECTION_LIST. This structure will contain a cItems member containing the number of selected items and an array of DS_SELECTION structures in the aDsSelection member specifying for each Active Directory object: the name, Active Directory path, class name, and principal name.

Fetching Attributes

The sample program shows how to select users or computers, but you can go further by fetching attributes to the user-selected objects. As described previously, the Active Directory is composed of objects. Each object belongs to a class having several attributes. You can browse for your Active Directory classes structure using the Active Directory Schema snap-in and see, for example, that the class “user” has attributes like “mail” for the email address or “company.” You can ask the object picker to store in the data object attributes you are interested in. I added to my sample some lines of code to fetch those two attributes by setting cAttributesToFetch to two and apwzAttributeNames to “mail” and “company” in the DSOP_INIT_INFO structure. I also added the necessary code to read the attributes in PrintSelection() in the pvarFetchedAttributes member of each DS_SELECTION structure. It points to VARIANTs I convert to VT_BSTR type before printing them.

Conclusion

COM and the object picker provide dialog box services that were not available on Windows NT v4.0 but it goes far beyond that. It allows the developer to select any kind of Active Directory objects including printers, groups, domains, and even to get directly their attributes.

Arnaud Aubert is the R&D manager of IS Decisions and is available for independent Windows Development short-term debugging/consulting. He can be reached at info@arnaudaubert.com.

1 | 2 | 3 Next Page
TOP 5 ARTICLES
No Top Articles.
DR. DOBB'S CAREER CENTER
Ready to take that job and shove it? open | close
Search jobs on Dr. Dobb's TechCareers
Function:

Keyword(s):

State:  
  • Post Your Resume
  • Employers Area
  • News & Features
  • Blogs & Forums
  • Career Resources

    Browse By:
    Location | Employer | City
  • Most Recent Posts:



    MICROSITES
    FEATURED TOPIC

    ADDITIONAL TOPICS

    INFO-LINK



     



    Related Sites: DotNetJunkies, SD Expo, SqlJunkies