title: Enumerating all subkeys and values in a Windows registry key
body: <p>I am trying to write a Windows application that gives me back all the subkeys and values given a certain key. I've written code that appears to work as far as providing subkeys within the given key, but doesn't work at properly enumerating the values; it successfully enumerates subkeys without values and returns the results in kind of tabbed tree arrangement. However, when enumerating values, the program gives back a random value for each value present (the same random value each time), and then crashes afterwards with a debug error.</p>
  
  <p>It's intended output is basically:</p>
  
  <pre><code>(1) KEY
      (1) SUBKEY
      (1) SUBKEYWITHINSUBKEY
          Code: value1data
          Code: value2data
          Code: value3data
  (2) SUBKEY
      (1) SUBKEYWITHINSUBKEY
  (3) SUBKEY
  </code></pre>
  
  <p>...and so on.</p>
  
  <p>The output I get instead is something like:</p>
  
  <pre><code>(1) KEY
  (1) SUBKEY
      (1) SUBKEYWITHINSUBKEY
          Code: someValue
          Code: someValue
          Code: someValue
  </code></pre>
  
  <p>(...and then the crash)<br/><br/>
  This is followed with the following error:<br/>
  "Debug Error! "Run-Time Check Failure #2 - Stack around the variable 'valNameLen' was corrupted."</p>
  
  <p>The code is a bit messy currently (I'm a Windows API newbie), but if anyone could show me what I'm doing wrong, or critique my coding style in anyway they feel fit, that would be great.</p>
  
  <p>Thanks!</p>
  
  <p>-R</p>
  
  <pre><code>/*
  Windows Registry Subkey Enumeration Example
  Based on example found at code-blue.org
  */
  
  #include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  
  void EnumerateValues(HKEY hKey, DWORD numValues)
  {
   DWORD dwIndex = 0;
      LPSTR valueName = new CHAR[64];
   DWORD valNameLen;
   DWORD dataType;
   DWORD data;
   DWORD dataSize;
  
      for (int i = 0; i &lt; numValues; i++)
   {
    RegEnumValue(hKey,
       dwIndex,
       valueName,
       &amp;valNameLen,
       NULL,
       &amp;dataType,
       (BYTE*)&amp;data,
       &amp;dataSize);
  
    dwIndex++;
  
          printf("Code: 0x%08X\n", data);
   }
  }
  
  
  void EnumerateSubKeys(HKEY RootKey, char* subKey, unsigned int tabs = 0) 
  {
   HKEY hKey;
      DWORD cSubKeys;        //Used to store the number of Subkeys
      DWORD maxSubkeyLen;    //Longest Subkey name length
      DWORD cValues;        //Used to store the number of Subkeys
      DWORD maxValueLen;    //Longest Subkey name length
      DWORD retCode;        //Return values of calls
  
   RegOpenKeyEx(RootKey, subKey, 0, KEY_ALL_ACCESS, &amp;hKey);
  
      RegQueryInfoKey(hKey,            // key handle
                      NULL,            // buffer for class name
                      NULL,            // size of class string
                      NULL,            // reserved
                      &amp;cSubKeys,        // number of subkeys
                      &amp;maxSubkeyLen,    // longest subkey length
                      NULL,            // longest class string 
                      &amp;cValues,        // number of values for this key 
                      &amp;maxValueLen,    // longest value name 
                      NULL,            // longest value data 
                      NULL,            // security descriptor 
                      NULL);            // last write time
  
      if(cSubKeys&gt;0)
   {
          char currentSubkey[MAX_PATH];
  
          for(int i=0;i &lt; cSubKeys;i++){
     DWORD currentSubLen=MAX_PATH;
  
              retCode=RegEnumKeyEx(hKey,    // Handle to an open/predefined key
              i,                // Index of the subkey to retrieve.
              currentSubkey,            // buffer to receives the name of the subkey
              &amp;currentSubLen,            // size of that buffer
              NULL,                // Reserved
              NULL,                // buffer for class string 
              NULL,                // size of that buffer
              NULL);                // last write time
  
              if(retCode==ERROR_SUCCESS)
     {
                  for (int i = 0; i &lt; tabs; i++)
                      printf("\t");
                  printf("(%d) %s\n", i+1, currentSubkey);
  
                  char* subKeyPath = new char[currentSubLen + strlen(subKey)];
                  sprintf(subKeyPath, "%s\\%s", subKey, currentSubkey);
      EnumerateSubKeys(RootKey, subKeyPath, (tabs + 1));
     }
    }
   }
      else
   {
    EnumerateValues(hKey, cValues);
   }
  
   RegCloseKey(hKey); 
  }
  
  
  int main()
  {
      EnumerateSubKeys(HKEY_CURRENT_USER,"SOFTWARE\\MyKeyToSearchIn");
      return 0;
  }
  </code></pre>