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