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

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

unix.superglobalmegacorp.com

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