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

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

unix.superglobalmegacorp.com

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