February 18, 2019
Hot Topics:

Walking The Registry Tree

  • September 28, 2004
  • By Nancy Nicolaisen
  • Send Email »
  • More Articles »

In this installment, we'll take a detailed look at the recursive function we use to walk the Registry, WalkRegTree(), initializing the tree control to depict the structure of the Registry. The parameters, in the order shown, are the handle to an open Registry key and the handle to a tree item.

BOOL CWalkReg::WalkRegTree(HKEY hKey, HTREEITEM htiParent)

   DWORD dwNSize;
   DWORD dwCSize;
   WCHAR wszName[MAX_PATH];
   WCHAR wszClass[256];
   TVITEM tviTreeViewItem;
   DWORD dwNumChildren = 0;
   DWORD dwNumGrandChildren = 0;
   LONG rc;
   HTREEITEM      htiChild;
   HKEY           hSubKey;

Using the handle to the key passed into the function, we query to find out whether the key has any children. We do this with the CeRegQueryInfoKey() function, passing NULLs for all parameters except dwNumChildren. This instructs the function to return only a count of the child keys of this key.

// query for count of children
rc = CeRegQueryInfoKey (hKey, NULL, NULL, 0,
                        &dwNumChildren, NULL, NULL, NULL,
                        NULL, NULL, NULL, NULL);

Here's the declaration for CeRegQueryInfoKey(), which shows the other items of information you can retrieve about the key:

LONG RegQueryInfoKey ( HKEY hKey,    //Handle to open reg key
     LPWSTR lpClass,                 //Unicode key class name
     LPDWORD lpcbClass,              //Unicode buffer size for
                                     //class name
     LPDWORD lpReserved              //unused
     LPDWORDlpcSubKeys,              //count of child keys
     LPDWORD lpcbMaxSubKeyLen,       //size of longest child key name
     LPDWORD lpcbMaxClassLen         //longest child key class name
     LPDWORD lpcValues,              //count of key values
     LPDWORD lpcbMaxValueNameLen,    //longest value name
     LPDWORD lpcbMaxValueLen,        //unused
     PDWORD lpcbSecurityDescriptor,  //unused
     PFILETIME lpftLastWriteTime     //unused

Passing valid addresses in any of the parameters causes the corresponding data to be returned. To get the class name for a key, you must initialize both the lpClass and lpcbClass parameters.

Now we use the returned count of child keys, dwNumChildren, to enumerate the child keys of the key passed to the function.

//Iterate child keys
for( int iChildKeyEnumIndex = 0;
     iChildKeyEnumIndex < dwNumChildren; iChildKeyEnumIndex++ )
      //get child key name
      dwNSize = dim(wszName);
      dwCSize = dim(wszClass);
      rc = CeRegEnumKeyEx (hKey, iChildKeyEnumIndex,
                           wszName, &dwNSize, NULL,
                           wszClass, &dwCSize, &ft);

      if(rc != ERROR_SUCCESS)
        { return FALSE; }

When we find a child key, we open it by using the name returned by CeRegEnumKeyEx() and capture the child key's handle in hSubKey.

//open child key by name, capture HKEY

rc = CeRegOpenKeyEx(hKey, wszName, 0,
                    KEY_ALL_ACCESS, &amp;hSubKey );
if( rc != ERROR_SUCCESS )
{ return FALSE; }

Now we find out whether the child key has children by passing its handle to CeRegQueryInfoKey().

// query for count of grand children
rc = CeRegQueryInfoKey (hSubKey, NULL, NULL, 0,
                        &dwNumGrandChildren, NULL, NULL, NULL,
                        NULL, NULL, NULL, NULL);

Every time we find hSubKey exists, we insert a new item in the tree control. First, we translate the key's Unicode name to multibyte format to make a caption for the tree item, and then we call our CWalkReg class member InsertTreeItem() to create and position the new tree item.

//convert the name string from WCS to MBCS
wcstombs( szMBCSName, wszName, sizeof(szMBCSName) );

// Add key to tree view.
htiChild = InsertTreeItem (htiParent, szMBCSName, 0, 
                           dwNumGrandChildren, hSubKey);

If we know that the item has no children, we tell it so by passing a 0 (FALSE) flag in the children member of the TVITEM structure and setting this new item data with the CTreeCtrl member SetItem().

if(dwNumChildren == 0)
   tviTreeViewItem.hItem = htiChild;
   tviTreeViewItem.mask = TVIF_CHILDREN | TVIF_HANDLE;
   tviTreeViewItem.cChildren = 0;
   m_RegTree.SetItem( &tviTreeViewItem );

If the subkey has children, we need to recurse to continue walking out the Registry tree.

      //if !children, return TRUE
      if( dwNumChildren != 0 )
         //recurse walk tree
         WalkRegTree( hSubKey, htiChild );
         m_RegTree.Expand(htiChild, TVE_COLLAPSE );

      }//end if(dwNumChildren)

   } //end for(iterate children )  

return TRUE;

Page 1 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