February 17, 2019
Hot Topics:

Initializing The DesktopView With A List Of Remote Databases

  • October 27, 2004
  • By Nancy Nicolaisen
  • Send Email »
  • More Articles »

Enumerating Remote Databases

Setting up to enumerate the databases is a two-step process. First, we call CeFindFirstDatabase(). The parameter we pass indicates what type of database we want to enumerate. The database type is an arbitrary constant that is set by the application that initially creates the database. It's not a required parameter for database creation, but it can be useful if an application creates and uses a family of databases. Setting their types equal makes it easy to find all of them again if you need to manipulate them as a group. Passing 0 as the parameter to CeFindFirstDatabase() causes all databases to be enumerated, regardless of type. On success, CeFindFirstDatabase() returns a handle to an enumeration context.

To actually find a database, we call CeFindNextDatabase(), passing the handle returned by CeFindFirstDatabase() as its only parameter. CeFindNextDatabase() returns the CE object identifier (CEOID) of the found database. An OID can uniquely identify many types of objects: files, directories, databases, or individual database records. We don't have a special function for getting information for each of these types of objects. Instead, we have a function that returns attribute information for any of the object types, CeOidGetInfo().

CeOidGetInfo() takes two parameters: the CEOID for the object being queried, and the address of a CEOIDINFO structure. Here is the typedef for CEOIDINFO:

typedef struct _CEOIDINFO {
        WORD wObjType;          //the type of object being queried
        DWORD dwSize;           //the size of this structure
        WORD wPad;              //used for structure alignment
        union {                           //object specific member
                CEFILEINFO infFile;       //of the union is returned
                CEDIRINFO infDirectory;   //populated with
                CEDBASEINFO infDatabase;  //attribute data
                CERECORDINFO infRecord;

The information in which we are interested is returned in the CEDBASEINFO member of the union. We'll get down to business populating the list after we take a look at this key structure:

typedef struct _CEDBASEINFO { 
        DWORD dwFlags;            //which structure members are
                                  //valid database name
        DWORD dwDbaseType;        //application defined database type
        WORD wNumRecords;         //number records in this database
        WORD wNumSortOrder;       //number of active sort orders
        DWORD dwSize;             //database size in bytes
        FILETIME ftLastModified;  //last modified time
                                  //an array of structures defining
                                  // sort order specs
        } CEDBASEINFO;

The information returned in the CEDBASEINFO structure gives you all of the information you need to open any database on the CE device, applying sort orders if they exist. You can use the dwFlags member to detect which other structure members are valid. The flags are found in the low order word of dwFlags, and can be isolated like this:

//get the aggregated flags
WORD wFlagWord = LOWORD( dwFlags );

//is the CEDB_VALIDDBFLAGS flag set
WORD wFlagTest;
WFlagTest = wFlagWord & CEDB_VALIDDBFLAGS;
if( wFlagWord )
   //do something with the flags

Here are the possible values of dwFlags:

Table 3: CEDBASEINFO Flags

dwFlags Value Meaning
CEDB_VALIDMODTIME ftLastModified member is valid and
CEDB_VALIDNAME szDbaseName member is valid.
CEDB_VALIDTYPE dwDbaseType member is valid.
CEDB_VALIDSORTSPEC rgSortSpecs member is valid.
CEDB_VALIDDBFLAGS The low-order word of the dwFlags member is valid.

The following code enumerates the remote databases and adds them to our list control on the desktop. This continues until the value returned in enumCeoid becomes FALSE, indicating that we've retrieved everything matching our criteria.

CEOID enumCeoid;

//enum databases
hEnum = CeFindFirstDatabase(0);
while(  enumCeoid = CeFindNextDatabase( hEnum))
   CeOidGetInfo(enumCeoid, &oidInfo);

   AddRowToList( enumCeoid, &oidInfo );


Before we move on, notice that after we've exhausted the enumeration loop, we close OnInitialUpdate() by uninitializing RAPI.



Looking Ahead

In the next installment, we'll see the mechanics of adding a row of database attributes to the desktop list control with a call to AddRowToList(). This is a somewhat more complicated job than you might suspect, because the list control treats its contents as a matrix of individual elements, rather than as a collection of rows.

About the Author

Nancy Nicolaisen is a software engineer who has designed and implemented highly modular Windows CE products that include features such as full remote diagnostics, CE-side data compression, dynamically constructed user interface, automatic screen size detection, and entry time data validation.

In addition to writing for Developer.com, she has written several books, including Making Win 32 Applications Mobile.

Page 2 of 2

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date