Annotation of mstools/samples/registry/monkey.c, revision 1.1.1.2

1.1       root        1: /*************************************************************************\
                      2: *
                      3: *  PROGRAM: Monkey: the Registry Monkey Utility.
                      4: *  PURPOSE: To demonstrate Registry API.
                      5: *  COMMENTS:
                      6: *
                      7: \*************************************************************************/
                      8: 
                      9: 
1.1.1.2 ! root       10: #define STRICT
1.1       root       11: #include <windows.h>
                     12: #include <string.h>
                     13: #include <stdlib.h>
                     14: #include <stdio.h>
                     15: #include "monkey.h"
                     16: 
                     17: 
                     18: HANDLE hInst;
                     19: HWND   hDlg;
                     20: 
                     21: HANDLE hHeap;
                     22: 
                     23: 
                     24: /*************************************************************************\
                     25: *
                     26: *  FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
                     27: *
                     28: *  PURPOSE: Creates the dialogbox.
                     29: *
                     30: *  COMMENTS:
                     31: *
                     32: \*************************************************************************/
                     33: 
                     34: int APIENTRY WinMain (HINSTANCE hInstance,
                     35:                       HINSTANCE hPrevInstance,
                     36:                       LPSTR     lpCmdLine,
                     37:                       int       nCmdShow)
                     38: 
                     39: 
                     40: {
                     41:   DWORD retCode;
                     42: 
                     43:   UNREFERENCED_PARAMETER( nCmdShow );
                     44:   UNREFERENCED_PARAMETER( lpCmdLine );
                     45:   UNREFERENCED_PARAMETER( hPrevInstance );
                     46: 
                     47:   hInst   = hInstance;
                     48:   hHeap   = HeapCreate (HEAP_SERIALIZE, 0, 0);
                     49: 
                     50:   retCode = DialogBox ((HANDLE)hInst, (LPCSTR)"MonkeyDlg",
                     51:                         NULL, (DLGPROC)MonkeyDlgProc);
                     52: 
                     53:   HeapDestroy (hHeap);
                     54:   return  (retCode);
                     55: 
                     56: }
                     57: 
                     58: /************************************************************************\
                     59: *
                     60: *  FUNCTION: MonkeyDlgProc();
                     61: *
                     62: *  PURPOSE:  Handle the Monkey dialog box messages.
                     63: *
                     64: *  MESSAGES:
                     65: *
                     66: *    WM_INITDIALOG  - Posts WM_GETFIRSTKEY message.
                     67: *
                     68: *    WM_GETFIRSTKEY - Puts the first 4 pre-defined keys in the listbox.
                     69: *
                     70: *    IDL_LISTBOX    - Trapped when an item in the left hand listbox
                     71: *                     has been double clicked.  It posts a IDB_NEXT message.
                     72: *
                     73: *    IDL_LISTBOX2   - Trapped when an item in the right hand listbox has
                     74: *                     been double clicked.  It basically calls DisplayKeyData,
                     75: *                     which fills the Value edit fields with the data from
                     76: *                     the current key's specified value information.
                     77: *
                     78: *    IDB_PRINT      - Basically calls PrintTree() which does a recursive
                     79: *                     print of the Registry from the current key to the
                     80: *                     end of it's branches.
                     81: *
                     82: *    IDB_BACK       - Sets the dialog box with the information from the
                     83: *                     previously selected key (one closer to the root of
                     84: *                     the registry, the parent of the current key).
                     85: *
                     86: *    IDB_NEXT       - Sets the dialog box with the information on the
                     87: *                     selected key child.
                     88: *
                     89: *    IDR_FULL       - Sets a global variable used to determine if the
                     90: *                     user wants to print full Registry information
                     91: *                     or only information from keys that have value
                     92: *                     associated with it.  Variable is set to TRUE.
                     93: *
                     94: *    IDR_TRIMMED    - Same as above, only the variable is set to FALSE.
                     95: *
                     96: \************************************************************************/
                     97: 
                     98: int APIENTRY MonkeyDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
                     99:   {
                    100:    ULONG    KeyClassLength = 256;
                    101:    ULONG    KeyNameLength = 256;
                    102:    DWORD    indexLB;
                    103:    CHAR     *putNullAt;
                    104: 
                    105:    static   CHAR     RegPath[MAX_PATH]  = "";
                    106:    static   CHAR     NameLBSelect[256]  = "";
                    107:    static   HKEY     hKeyRoot;
                    108:    static   DWORD    RegLevel;
                    109:    static   BOOL     FullBranches = TRUE;
                    110: 
                    111:    static   HANDLE   hFile = INVALID_HANDLE_VALUE;
                    112:    static   HANDLE   hBootIni;
                    113: 
                    114:   UNREFERENCED_PARAMETER( lParam );
                    115: 
                    116:   switch (wMsg)
                    117:     {
                    118:       case WM_INITDIALOG:
                    119:           // Post a message to get the first 4 pre-defined keys, and set
                    120:           // Full Branches to be the print default.
                    121:         PostMessage (hDlg, WM_GETFIRSTKEY, 0, 0);
                    122:         CheckDlgButton (hDlg, IDR_FULL, TRUE);
                    123:         return (0);
                    124: 
                    125:       case WM_GETFIRSTKEY:
                    126:           // Initialize by putting the first 4 predefined keys of the
                    127:           // registry in the list box.
                    128: 
                    129:         SendMessage (GetDlgItem(hDlg, IDL_LISTBOX),
                    130:                      LB_ADDSTRING, 0, (LONG)"HKEY_LOCAL_MACHINE");
                    131: 
                    132:         SendMessage (GetDlgItem(hDlg, IDL_LISTBOX),
                    133:                      LB_ADDSTRING, 0, (LONG)"HKEY_CURRENT_USER");
                    134: 
                    135:         SendMessage (GetDlgItem(hDlg, IDL_LISTBOX),
                    136:                      LB_ADDSTRING, 0, (LONG)"HKEY_USERS");
                    137: 
                    138:         SendMessage (GetDlgItem(hDlg, IDL_LISTBOX),
                    139:                      LB_ADDSTRING, 0, (LONG)"HKEY_CLASSES_ROOT");
                    140: 
                    141:         hKeyRoot = 0;                   // Initialize hKeyRoot.
                    142:         return (0);
                    143: 
                    144:       case WM_SYSCOMMAND:
                    145:         if (wParam == SC_CLOSE)
                    146:           {
                    147:           EndDialog (hDlg, TRUE);
                    148:           if (hFile != INVALID_HANDLE_VALUE)
                    149:             CloseHandle (hFile);
                    150:           return (TRUE);
                    151:           }
                    152:         break;
                    153: 
                    154:       case WM_COMMAND:
                    155: 
                    156:         switch (LOWORD(wParam))
                    157:           {
                    158:             case IDR_FULL:
                    159:                 // If Full Branches pressed, set global var to TRUE.
                    160:               FullBranches = TRUE;
                    161:               return (0);
                    162: 
                    163:             case IDR_TRIMMED:
                    164:                 // If Trimmed Branches pressed, set global var to FALSE.
                    165:               FullBranches = FALSE;
                    166:               return (0);
                    167: 
                    168:             case IDL_LISTBOX:
                    169:                  // If double click in left hand listbox, clear Value
                    170:                  // edit fields, and execute Next functionality.
                    171:                if ( HIWORD (wParam) == LBN_DBLCLK)
                    172:                 {
                    173:                  SetDlgItemText (hDlg, IDE_VALUE1, "");
                    174:                  SetDlgItemText (hDlg, IDE_VALUE2, "");
                    175:                  PostMessage (hDlg, WM_COMMAND, IDB_NEXT, 0);
                    176:                 }
                    177:                return (0);
                    178: 
                    179:             case IDL_LISTBOX2:
                    180:                  // If double click right hand listbox, clear Value edit
                    181:                  // fields, then display the key's data.
                    182:                if ( HIWORD (wParam) == LBN_DBLCLK)
                    183:                 {
                    184:                  SetDlgItemText (hDlg, IDE_VALUE1, "");
                    185:                  SetDlgItemText (hDlg, IDE_VALUE2, "");
                    186:                  DisplayKeyData (hDlg, RegPath, hKeyRoot);
                    187:                 }
                    188:                return (0);
                    189: 
                    190:             case IDB_PRINT:
                    191: 
                    192:               MessageBox (NULL, "Sorry, due to last minute changes in the system, this feature was removed.  It may be replaced in a future version.",
                    193:                             "Last Minute Note.", MB_OK);
                    194:               return (0);
                    195: 
                    196:             case IDB_NEXT:
                    197:                  // Get the index of the cursor selection
                    198:                  // in the list box.
                    199:                indexLB = SendMessage (GetDlgItem (hDlg, IDL_LISTBOX),
                    200:                                       LB_GETCURSEL, 0, 0);
                    201: 
                    202:                  // If nothing is selected, flag user and return, otherwise
                    203:                  // process the selected key.
                    204:                                        // LB_ERR indicates nothing selected.
                    205:                if (indexLB == LB_ERR)
                    206:                  {
                    207:                  MessageBox (hDlg, "Please select an item from the list box",
                    208:                              "Registry Monkey Utility", MB_OK);
                    209:                  return (0);
                    210:                  }
                    211: 
                    212:                  // If listbox item 0 is pressed, user wants to move
                    213:                  // back up.  Execute the Back functionality.
                    214:                if (indexLB == 0 && hKeyRoot)
                    215:                 {
                    216:                 PostMessage (hDlg, WM_COMMAND, IDB_BACK, 0);
                    217:                 return (0);
                    218:                 }
                    219: 
                    220: 
                    221:                                        // Get text from selection in LB.
                    222:                SendMessage (GetDlgItem (hDlg, IDL_LISTBOX),
                    223:                             LB_GETTEXT, indexLB, (LPARAM)NameLBSelect);
                    224: 
                    225:                                        // Put name of chosen item in Name field.
                    226:                SetDlgItemText (hDlg, IDE_NAME, NameLBSelect);
                    227: 
                    228:                                        // Then clear ListBox entries.
                    229:                SendMessage (GetDlgItem (hDlg, IDL_LISTBOX),
                    230:                             LB_RESETCONTENT, 0, 0);
                    231:                SendMessage (GetDlgItem (hDlg, IDL_LISTBOX2),
                    232:                             LB_RESETCONTENT, 0, 0);
                    233: 
                    234:                EnumerateLevel (hDlg, NameLBSelect, RegPath, &hKeyRoot);
                    235: 
                    236:                return (0);
                    237: 
                    238: 
                    239: 
                    240:             case IDB_BACK:
                    241: 
                    242:                  // For this case (hRootKey = 0)you're at the top level already.
                    243:                  // Tell the user, then return
                    244:                if (!hKeyRoot)
                    245:                  {
                    246:                  MessageBox (hDlg, "Top Level: You can not backup any further.",
                    247:                              "Registry Monkey Utility", MB_OK);
                    248:                  return (0);
                    249:                  }
                    250: 
                    251:                  //For all remaining cases, clear the listboxes.
                    252:                SendMessage (GetDlgItem (hDlg, IDL_LISTBOX),
                    253:                             LB_RESETCONTENT, 0, 0);
                    254:                SendMessage (GetDlgItem (hDlg, IDL_LISTBOX2),
                    255:                             LB_RESETCONTENT, 0, 0);
                    256: 
                    257: 
                    258: 
                    259:                  // If hRootKey has a value, but the pathname is blank,
                    260:                  // then you must be 1 level deep, reset to level 0 by
                    261:                  // posting WM_GETFIRSTKEY.
                    262:                if (strcmp (RegPath, "") == 0)
                    263:                  {
                    264:                  SetDlgItemText (hDlg, IDE_NAME, "");
                    265:                  PostMessage (hDlg, WM_GETFIRSTKEY, 0, 0);
                    266:                  return (0);
                    267:                  }
                    268: 
                    269: 
                    270:                  // Two cases left.  One in which the path has only one
                    271:                  // key name in it, and no back slash character (meaning
                    272:                  // strrchr() will return NULL); and one the other case
                    273:                  // where there are more than one key name in the path (
                    274:                  // and at least one back slash for strrchr().  If this
                    275:                  // is the first case, we want to fakeout EnumerateLevel
                    276:                  // into thinking we just picked one of the pre-defined keys,
                    277:                  // and then re-enumerate it's child keys.
                    278:                if ((putNullAt = strrchr (RegPath, '\\')) == NULL)
                    279:                  {
                    280:                  RegPath[0] = '\0';
                    281: 
                    282:                  switch ((DWORD)hKeyRoot)
                    283:                    {
                    284:                    case (DWORD)HKEY_LOCAL_MACHINE:
                    285:                      strcpy (NameLBSelect, "HKEY_LOCAL_MACHINE");
                    286:                      break;
                    287: 
                    288:                    case (DWORD)HKEY_USERS:
                    289:                      strcpy (NameLBSelect, "HKEY_USERS");
                    290:                      break;
                    291: 
                    292:                    case (DWORD)HKEY_CURRENT_USER:
                    293:                      strcpy (NameLBSelect, "HKEY_CURRENT_USER");
                    294:                      break;
                    295: 
                    296:                    case (DWORD)HKEY_CLASSES_ROOT:
                    297:                      strcpy (NameLBSelect, "HKEY_CLASSES_ROOT");
                    298:                      break;
                    299:                    }
                    300:                  SetDlgItemText (hDlg, IDE_NAME, NameLBSelect);
                    301:                  hKeyRoot = 0;
                    302:                  EnumerateLevel (hDlg, NameLBSelect, RegPath, &hKeyRoot);
                    303:                  }
                    304:                else
                    305:                  {
                    306:                    // In the final case, we can just trim the last key
                    307:                    // name off the path, and re-enumerate the level.
                    308:                  *putNullAt = '\0';
                    309:                  putNullAt = strrchr (RegPath, '\\');
                    310: 
                    311:                  if (putNullAt)
                    312:                    {
                    313:                    strcpy (NameLBSelect, putNullAt+1);
                    314:                    *putNullAt = '\0';
                    315:                    }
                    316:                  else
                    317:                    {
                    318:                    strcpy (NameLBSelect, RegPath);
                    319:                    *RegPath = '\0';
                    320:                    }
                    321:                  SetDlgItemText (hDlg, IDE_NAME, NameLBSelect);
                    322:                  EnumerateLevel (hDlg, NameLBSelect, RegPath, &hKeyRoot);
                    323:                  }
                    324:                return (0);
                    325: 
                    326:             default:
                    327:                return (0);
                    328: 
                    329:           }
                    330: 
                    331:      }
                    332:     return (FALSE);
                    333: 
                    334:   }
                    335: 
                    336: 
                    337: 
                    338: 
                    339: /************************************************************************\
                    340: *
                    341: *  FUNCTION: EnumerateLevel();
                    342: *
                    343: *  PURPOSE: To get a valid key handle (either to determine if the one sent
                    344: *           to the function was one of the pre-defined, or to open a key
                    345: *           specified by the path), and to pass that key handle along
                    346: *           to QueryKey().
                    347: *
                    348: *           To enumerate the children of a key, you must have
                    349: *           an open handle to it.  The four top keys of the
                    350: *           Registry are predefined and open for use:
                    351: *           HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_USER,
                    352: *           and HKEY_CLASSES_ROOT.  These 4 can be used for
                    353: *           RegEnumKey as is; but to RegEnumKey on any of the
                    354: *           children of these you must first have an open key
                    355: *           handle to the child.
                    356: *
                    357: *           If hKeyRoot != 0, assume you are lower than the
                    358: *           first level of the Registry and the user is trying
                    359: *           to enumerate one of the children.  First calculate
                    360: *           the name of the child, and then use RegOpenKey to
                    361: *           get an open handle.
                    362: *
                    363: *           If hKeyRoot == 0, assume you are at the top level
                    364: *           of the Registry, and set the hKey to be enumerated
                    365: *           to be one of the 4 predefined values, the specific
                    366: *           one indicated by the ListBox selection.
                    367: *
                    368: \************************************************************************/
1.1.1.2 ! root      369:   VOID EnumerateLevel (HWND hDlg, LPTSTR NameLBSelect,
        !           370:                        LPTSTR RegPath, HKEY *hKeyRoot)
1.1       root      371:   {
                    372: 
1.1.1.2 ! root      373:     HKEY hKey;
1.1       root      374:     HDC    hDC;
                    375:     DWORD  retCode;
                    376:     CHAR   Buf[80];
                    377:     RECT   rect;
                    378: 
                    379: 
                    380:     if (*hKeyRoot)
                    381:       {
                    382:                                        // If RegPath is not NULL, then
                    383:                                        // you have to add a backslash to the
                    384:                                        // path name before appending the next
                    385:                                        // level child name.
                    386:       if (strcmp (RegPath, "") != 0)
                    387:         strcat (RegPath, "\\");
                    388: 
                    389:                                        // Add the next level child name.
                    390:       strcat (RegPath, NameLBSelect);
                    391: 
                    392:                                        // Use RegOpenKeyEx() with the new
                    393:                                        // Registry path to get an open handle
                    394:                                        // to the child key you want to
                    395:                                        // enumerate.
1.1.1.2 ! root      396:       retCode = RegOpenKeyEx (*hKeyRoot,
        !           397:                               RegPath,
1.1       root      398:                               0,
                    399:                               KEY_ENUMERATE_SUB_KEYS |
                    400:                               KEY_EXECUTE |
                    401:                               KEY_QUERY_VALUE,
                    402:                               &hKey);
                    403: 
                    404:       if (retCode != ERROR_SUCCESS)
                    405:         {
                    406:         if (retCode == ERROR_ACCESS_DENIED)
                    407:           wsprintf (Buf, "Error: unable to open key.  Probably due to security reasons.");
                    408:         else
                    409:           wsprintf (Buf, "Error: Unable to open key, RegOpenKey = %d, Line = %d",
                    410:                   retCode, __LINE__);
                    411: 
                    412:         MessageBox (hDlg, Buf, "", MB_OK);
                    413:         PostMessage (hDlg, WM_COMMAND, IDB_BACK, 0);
                    414:         return;
                    415:         }
                    416: 
                    417:       }
                    418:     else
                    419:       {
                    420:                                        // Set the *hKeyRoot handle based
                    421:                                        // on the text taken from the ListBox.
                    422: 
                    423:       if (strcmp (NameLBSelect, "HKEY_CLASSES_ROOT") == 0)
                    424:         *hKeyRoot = HKEY_CLASSES_ROOT;
                    425: 
                    426:       if (strcmp (NameLBSelect, "HKEY_USERS") == 0)
                    427:         *hKeyRoot = HKEY_USERS;
                    428: 
                    429:       if (strcmp (NameLBSelect, "HKEY_LOCAL_MACHINE") == 0)
                    430:         *hKeyRoot = HKEY_LOCAL_MACHINE;
                    431: 
                    432:       if (strcmp (NameLBSelect, "HKEY_CURRENT_USER") == 0)
                    433:         *hKeyRoot = HKEY_CURRENT_USER;
                    434: 
                    435:       hKey = *hKeyRoot;     // hKey is used in RegEnumKey().
                    436: 
                    437:       }//end if/else *hKeyRoot
                    438: 
                    439:       QueryKey (hDlg, hKey);
                    440: 
                    441: 
                    442:       RegCloseKey (hKey);   // Close the key handle.
                    443: 
                    444:       rect.top = 0; rect.left = 5; rect.right = 1200; rect.bottom = 25;
                    445:       hDC = GetDC (hDlg);
                    446:       FillRect (hDC, &rect, GetStockObject(WHITE_BRUSH));
                    447:       TextOut (hDC, 5, 5, RegPath, strlen(RegPath));
                    448:       ReleaseDC (hDlg, hDC);
                    449: 
                    450: 
                    451: 
                    452:   }
                    453: 
                    454: 
                    455: /************************************************************************\
                    456: *
                    457: *  FUNCTION: QueryKey();
                    458: *
                    459: *  PURPOSE:  To display the key's children (subkeys) and the names of
                    460: *            the Values associated with it.  This function uses RegEnumKey,
                    461: *            RegEnumValue, and RegQueryInfoKey.
                    462: *
                    463: \************************************************************************/
                    464: VOID QueryKey (HWND hDlg, HANDLE hKey)
                    465:   {
                    466:   CHAR     KeyName[MAX_PATH];
                    467:   CHAR     ClassName[MAX_PATH] = ""; // Buffer for class name.
                    468:   DWORD    dwcClassLen = MAX_PATH;   // Length of class string.
                    469:   DWORD    dwcSubKeys;               // Number of sub keys.
                    470:   DWORD    dwcMaxSubKey;             // Longest sub key size.
                    471:   DWORD    dwcMaxClass;              // Longest class string.
                    472:   DWORD    dwcValues;                // Number of values for this key.
                    473:   DWORD    dwcMaxValueName;          // Longest Value name.
                    474:   DWORD    dwcMaxValueData;          // Longest Value data.
                    475:   DWORD    dwcSecDesc;               // Security descriptor.
                    476:   FILETIME ftLastWriteTime;          // Last write time.
                    477: 
                    478:   DWORD i;
                    479:   DWORD retCode;
                    480: 
                    481:   DWORD j;
                    482:   DWORD retValue;
                    483:   CHAR  ValueName[MAX_VALUE_NAME];
                    484:   DWORD dwcValueName = MAX_VALUE_NAME;
                    485:   CHAR  Buf[80];
                    486: 
                    487: 
                    488:   // Get Class name, Value count.
                    489: 
                    490:   RegQueryInfoKey (hKey,              // Key handle.
                    491:                    ClassName,         // Buffer for class name.
                    492:                    &dwcClassLen,      // Length of class string.
                    493:                    NULL,              // Reserved.
                    494:                    &dwcSubKeys,       // Number of sub keys.
                    495:                    &dwcMaxSubKey,     // Longest sub key size.
                    496:                    &dwcMaxClass,      // Longest class string.
                    497:                    &dwcValues,        // Number of values for this key.
                    498:                    &dwcMaxValueName,  // Longest Value name.
                    499:                    &dwcMaxValueData,  // Longest Value data.
                    500:                    &dwcSecDesc,       // Security descriptor.
                    501:                    &ftLastWriteTime); // Last write time.
                    502: 
                    503:   SetDlgItemText (hDlg, IDE_CLASS, ClassName);
                    504:   SetDlgItemInt  (hDlg, IDE_CVALUES, dwcValues, FALSE);
                    505: 
                    506:   SendMessage (GetDlgItem (hDlg, IDL_LISTBOX),
                    507:                LB_ADDSTRING, 0, (LONG)"..");
                    508: 
                    509:                                        // Loop until RegEnumKey fails, get
                    510:                                        // the name of each child and enter
                    511:                                        // it into the box.
                    512: 
                    513:   // Enumerate the Child Keys.
                    514: 
                    515:   SetCursor (LoadCursor (NULL, IDC_WAIT));
                    516:   for (i=0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
                    517:     {
                    518:     retCode = RegEnumKey (hKey, i,
                    519:                           KeyName, MAX_PATH);
                    520: 
                    521:     if (retCode == (DWORD)ERROR_SUCCESS)
                    522:       SendMessage (GetDlgItem(hDlg, IDL_LISTBOX),
                    523:                    LB_ADDSTRING, 0, (LONG)KeyName);
                    524:     }
                    525:   SetCursor (LoadCursor (NULL, IDC_ARROW));
                    526: 
                    527: 
                    528:   // Enumerate the Key Values
                    529:         SetCursor (LoadCursor (NULL, IDC_WAIT));
                    530: 
                    531:         if (dwcValues)
                    532:           for (j = 0, retValue = ERROR_SUCCESS; j < dwcValues; j++)
                    533:             {
                    534:             dwcValueName = MAX_VALUE_NAME;
                    535:             ValueName[0] = '\0';
                    536:             retValue = RegEnumValue (hKey, j, ValueName,
                    537:                                      &dwcValueName,
                    538:                                      NULL,
                    539:                                      NULL,               //&dwType,
                    540:                                      NULL,               //&bData,
                    541:                                      NULL);              //&bcData);
                    542:             if (retValue != (DWORD)ERROR_SUCCESS &&
                    543:                 retValue != ERROR_INSUFFICIENT_BUFFER)
                    544:               {
                    545:               wsprintf (Buf, "Line:%d 0 based index = %d, retValue = %d, ValueLen = %d",
                    546:                         __LINE__, j, retValue, dwcValueName);
                    547:               MessageBox (hDlg, Buf, "Debug", MB_OK);
                    548:               }
                    549: 
                    550:             Buf[0] = '\0';
                    551:             if (!strlen(ValueName))
                    552:               strcpy (ValueName, "<NO NAME>");
                    553:             wsprintf (Buf, "%d) %s ", j, ValueName);
                    554:             SendMessage (GetDlgItem (hDlg, IDL_LISTBOX2),
                    555:                            LB_ADDSTRING, 0, (LONG)Buf);
                    556: 
                    557:             }// end for(;;)
                    558: 
                    559:         SetCursor (LoadCursor (NULL, IDC_ARROW));
                    560: 
                    561:   }
                    562: 
                    563: 
                    564: 
                    565: /************************************************************************\
                    566: *
                    567: *  FUNCTION: DisplayKeyData();
                    568: *
                    569: *  PURPOSE:  To display the keys values and value types to the Value edit
                    570: *            field.  This function is called when the right hand listbox
                    571: *            is double clicked.  The functionality is much like that found
                    572: *            in the function PrintTree, please see it for more details.
                    573: *
                    574: \************************************************************************/
                    575: 
                    576: 
                    577: VOID DisplayKeyData (HWND hDlg, CHAR *RegPath, HANDLE hKeyRoot)
                    578:   {
1.1.1.2 ! root      579:   HKEY   hKey;
1.1       root      580:   DWORD  dwLBIndex;
                    581:   CHAR   Buf[LINE_LEN];
                    582:   CHAR   ValueName[MAX_VALUE_NAME];
                    583:   DWORD  cbValueName = MAX_VALUE_NAME;
                    584:   DWORD  dwType;
                    585:   DWORD  retCode;
                    586: 
                    587:   CHAR   ClassName[MAX_PATH];
                    588:   DWORD  dwcClassLen = MAX_PATH;
                    589:   DWORD  dwcSubKeys;
                    590:   DWORD  dwcMaxSubKey;
                    591:   DWORD  dwcMaxClass;
                    592:   DWORD  dwcValues;
                    593:   DWORD  dwcMaxValueName;
                    594:   DWORD  dwcMaxValueData;
                    595:   DWORD  dwcSecDesc;
                    596:   FILETIME  ftLastWriteTime;
                    597: 
                    598: 
                    599:   BYTE   *bData;
                    600:   DWORD  cbData;
                    601: 
                    602:   CHAR   *outBuf;
                    603:   DWORD  i;
                    604:   DWORD  cStrLen;
                    605: 
                    606:   CHAR   *BinaryStrBuf;
                    607:   CHAR   ByteBuf[4];
                    608: 
                    609:   CHAR   *ptr;
                    610: 
                    611:   // OPEN THE KEY.
                    612: 
                    613:                                 // LBIndex should == value index.
                    614:   dwLBIndex = SendMessage (GetDlgItem (hDlg, IDL_LISTBOX2),
                    615:                            LB_GETCURSEL, 0, 0);
                    616: 
                    617:   retCode = RegOpenKeyEx (hKeyRoot,    // Key handle at root level.
                    618:                           RegPath,     // Path name of child key.
                    619:                           0,           // Reserved.
                    620:                           KEY_EXECUTE, // Requesting read access.
                    621:                           &hKey);      // Address of key to be returned.
                    622: 
                    623:   if (retCode)
                    624:     {
                    625:     wsprintf (Buf, "Error: RegOpenKeyEx = %d", retCode);
                    626:     MessageBox (hDlg, Buf, "DisplayKeyData()", MB_OK);
                    627:     return;
                    628:     }
                    629: 
                    630: // ADD A QUERY AND ALLOCATE A BUFFER FOR BDATA.
                    631: 
                    632:   retCode =
                    633:   RegQueryInfoKey (hKey,              // Key handle.
                    634:                    ClassName,         // Buffer for class name.
                    635:                    &dwcClassLen,      // Length of class string.
                    636:                    NULL,              // Reserved.
                    637:                    &dwcSubKeys,       // Number of sub keys.
                    638:                    &dwcMaxSubKey,     // Longest sub key size.
                    639:                    &dwcMaxClass,      // Longest class string.
                    640:                    &dwcValues,        // Number of values for this key.
                    641:                    &dwcMaxValueName,  // Longest Value name.
                    642:                    &dwcMaxValueData,  // Longest Value data.
                    643:                    &dwcSecDesc,       // Security descriptor.
                    644:                    &ftLastWriteTime); // Last write time.
                    645: 
                    646:    if (retCode)
                    647:     {
                    648:     wsprintf (Buf, "Error: RegQIK = %d, %d", retCode, __LINE__);
                    649:     MessageBox (hDlg, Buf, "", MB_OK);
                    650:     }
                    651: 
                    652:    bData = HeapAlloc (hHeap, dwcMaxValueData);
                    653:    cbData = dwcMaxValueData;
                    654: 
                    655: 
                    656:   // ENUMERATE THE KEY.
                    657: 
                    658:   retCode = RegEnumValue (hKey,        // Key handle returned from RegOpenKeyEx.
                    659:                           dwLBIndex,   // Value index, taken from listbox.
                    660:                           ValueName,   // Name of value.
                    661:                           &cbValueName,// Size of value name.
                    662:                           NULL,        // Reserved, dword = NULL.
                    663:                           &dwType,     // Type of data.
                    664:                           bData,       // Data buffer.
                    665:                           &cbData);    // Size of data buffer.
                    666: 
                    667:   if (retCode)
                    668:     {
                    669: 
                    670:     if (dwType < REG_FULL_RESOURCE_DESCRIPTOR)
                    671:       {
                    672:       wsprintf (Buf, "Error: RegEnumValue = %d, cbData = %d, line %d",
                    673:                 retCode, cbData, __LINE__);
                    674:       MessageBox (hDlg, Buf, "", MB_OK);
                    675:       }
                    676:     }
                    677: 
                    678: 
                    679:   switch (dwType)
                    680:     {
                    681: //    REG_NONE                    ( 0 )   // No value type
                    682: //    REG_SZ                      ( 1 )   // Unicode nul terminated string
                    683: //    REG_EXPAND_SZ               ( 2 )   // Unicode nul terminated string
                    684:                                             // (with environment variable references)
                    685: //    REG_BINARY                  ( 3 )   // Free form binary
                    686: //    REG_DWORD                   ( 4 )   // 32-bit number
                    687: //    REG_DWORD_LITTLE_ENDIAN     ( 4 )   // 32-bit number (same as REG_DWORD)
                    688: //    REG_DWORD_BIG_ENDIAN        ( 5 )   // 32-bit number
                    689: //    REG_LINK                    ( 6 )   // Symbolic Link (unicode)
                    690: //    REG_MULTI_SZ                ( 7 )   // Multiple Unicode strings
                    691: //    REG_RESOURCE_LIST           ( 8 )   // Resource list in the resource map
                    692: //    REG_FULL_RESOURCE_DESCRIPTOR ( 9 )  // Resource list in the hardware description
                    693: 
                    694:     case REG_NONE:
                    695:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_NONE: No defined value type.");
                    696:       break;
                    697: 
                    698:     case REG_SZ:
                    699:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_SZ: A null-terminated Unicode string.");
                    700: 
                    701:       outBuf = HeapAlloc (hHeap, cbData + 2);
                    702:       *outBuf = '\0';
                    703: 
                    704:       strcat (outBuf, "\"");
                    705:       strcat (outBuf, bData);
                    706:       strcat (outBuf, "\"");
                    707: 
                    708:       SetDlgItemText (hDlg, IDE_VALUE2, outBuf);
                    709:       HeapFree (hHeap, outBuf);
                    710:       break;
                    711: 
                    712:     case REG_EXPAND_SZ:
                    713:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_EXPAND_SZ: A String referencing environment variables i.e. PATH.");
                    714:       outBuf = HeapAlloc (hHeap, cbData + 2);
                    715:       *outBuf = '\0';
                    716: 
                    717:       strcat (outBuf, "\"");
                    718:       strcat (outBuf, bData);
                    719:       strcat (outBuf, "\"");
                    720: 
                    721:       SetDlgItemText (hDlg, IDE_VALUE2, outBuf);
                    722:       HeapFree (hHeap, outBuf);
                    723:       break;
                    724: 
                    725:     case REG_BINARY:
                    726: 
                    727:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_BINARY: Freeform binary data.");
                    728:       SetCursor (LoadCursor (NULL, IDC_WAIT));
                    729: 
                    730:       BinaryStrBuf = HeapAlloc (hHeap, (3 * cbData) + 1);
                    731:       if (BinaryStrBuf)
                    732:         {
                    733:         *BinaryStrBuf = '\0';
                    734:         *ByteBuf = '\0';
                    735:         for (i = 0; i < cbData; i++)
                    736:           {
                    737:           sprintf (ByteBuf, "%02x ", (BYTE)bData[i]);
                    738:           strcat (BinaryStrBuf, ByteBuf);
                    739:           }
                    740:         SetDlgItemText (hDlg, IDE_VALUE2, BinaryStrBuf);
                    741:         }
                    742:       else
                    743:         {
                    744:         MessageBox (hDlg, "Error: BinaryStrBuf = malloc failed",
                    745:                     "Debug: DisplayKeyData", MB_OK);
                    746:         }
                    747:       SetDlgItemText (hDlg, IDL_LISTBOX2, BinaryStrBuf);
                    748:       HeapFree (hHeap, BinaryStrBuf);
                    749:       SetCursor (LoadCursor (NULL, IDC_ARROW));
                    750: 
                    751:       break;
                    752: 
                    753:     case REG_DWORD:
                    754:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_DWORD: A 32 bit number.");
                    755:       SetDlgItemInt (hDlg, IDE_VALUE2, *bData, TRUE);
                    756:       break;
                    757: 
                    758:     case REG_DWORD_BIG_ENDIAN:
                    759:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_DWORD_BIG_ENDIAN: A 32 bit number in big endian format.");
                    760:       SetDlgItemInt (hDlg, IDE_VALUE2, *bData, TRUE);
                    761:       break;
                    762: 
                    763:     case REG_LINK:
                    764:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_LINK: A Unicode symbolic link.");
                    765:       SetDlgItemText (hDlg, IDE_VALUE2, bData);
                    766:       break;
                    767: 
                    768:     case REG_MULTI_SZ:
                    769:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_MULTI_SZ: An array of null-terminated strings.");
                    770:       SetCursor (LoadCursor (NULL, IDC_WAIT));
                    771:                                        // Count the NULLs in the buffer to
                    772:                                        // find out how many strings there are.
                    773: 
                    774:       for (i=0, cStrLen=4; i < cbData; i++)
                    775:         if (!bData[i])
                    776:           cStrLen+=4;                  // Add room for two quotes and two
                    777:                                        // spaced per string.
                    778: 
                    779:       outBuf = HeapAlloc (hHeap, cbData + cStrLen);
                    780: 
                    781:       ptr = bData;                     // Set ptr to beginning of buffer.
                    782:       *outBuf = '\0';                  // Initialize output string.
                    783: 
                    784:       strcat (outBuf, "{ ");           // Do first bracket.
                    785:       while (*ptr)                     // Loop til you hit 2 NULLs in a row.
                    786:         {
                    787:          strcat (outBuf, "\"");        // Put quotes around each string.
                    788:          strcat (outBuf, ptr);
                    789:          strcat (outBuf, "\"  ");
                    790:          ptr += strlen(ptr)+1;
                    791:         }
                    792:       strcat (outBuf, "}");            // Add final bracket.
                    793:       SetDlgItemText (hDlg, IDE_VALUE2, outBuf);
                    794: 
                    795:       SetCursor (LoadCursor (NULL, IDC_ARROW));
                    796:       HeapFree (hHeap, outBuf);                   // free output string.
                    797:       break;
                    798: 
                    799: 
                    800:     case REG_RESOURCE_LIST:            // CM_RESOURCE_LIST is kind of complex,
                    801:                                        // it's defined in ntconfig.h.  Print
                    802:                                        // it as a free formed binary data now,
                    803:                                        // and structure it later with a
                    804:                                        // different release.
                    805:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_RESOURCE_LIST: A device-driver resource list.");
                    806: 
                    807:       BinaryStrBuf = HeapAlloc (hHeap, (3 * cbData) + 1);
                    808:       if (BinaryStrBuf)
                    809:         {
                    810:         *BinaryStrBuf = '\0';
                    811:         *ByteBuf = '\0';
                    812:         for (i = 0; i < cbData; i++)
                    813:           {
                    814:           sprintf (ByteBuf, "%02x ", (BYTE)bData[i]);
                    815:           strcat (BinaryStrBuf, ByteBuf);
                    816:           }
                    817:         SetDlgItemText (hDlg, IDE_VALUE2, BinaryStrBuf);
                    818:         }
                    819:       else
                    820:         {
                    821:         MessageBox (hDlg, "Error: BinaryStrBuf = malloc failed",
                    822:                     "Debug: DisplayKeyData", MB_OK);
                    823:         }
                    824:       SetDlgItemText (hDlg, IDL_LISTBOX2, BinaryStrBuf);
                    825:       HeapFree (hHeap, BinaryStrBuf);
                    826: 
                    827:       break;
                    828: 
                    829:     case REG_FULL_RESOURCE_DESCRIPTOR:
                    830:       SetDlgItemText (hDlg, IDE_VALUE1, "REG_FULL_RESOURCE_DESCRIPTOR: A resource list in the hardware description.");
                    831:       break;
                    832: 
                    833: 
                    834: 
                    835:     default:
                    836:       wsprintf (Buf, "Undefine in this verion of the Registry Monkey. %d",
                    837:                dwType);
                    838:       SetDlgItemText (hDlg, IDE_VALUE1, Buf);
                    839:       break;
                    840: 
                    841:     } // end switch
                    842: 
                    843: 
                    844:     HeapFree (hHeap, bData);
                    845:   }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.