Annotation of mstools/samples/registry/monkey.c, revision 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.