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