3 Copyright 2000 Red Hat Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
19 KT_AUTO, KT_INT, KT_STRING, KT_EXPAND, KT_MULTI
22 #define LIST_KEYS 0x01
23 #define LIST_VALS 0x02
24 #define LIST_ALL (LIST_KEYS | LIST_VALS)
35 const char *usage_msg[] = {
36 "Regtool Copyright (c) 2000 Red Hat Inc",
37 " regtool -h - print this message",
38 " regtool [-v|-p|-k|-l] list [key] - list subkeys and values",
39 " -p=postfix, like ls -p, appends / postfix to key names",
40 " -k=keys, lists only keys",
41 " -l=values, lists only values",
42 " regtool [-v] add [key\\subkey] - add new subkey",
43 " regtool [-v] remove [key] - remove key",
44 " regtool [-v|-q] check [key] - exit 0 if key exists, 1 if not",
45 " regtool [-i|-s|-e|-m] set [key\\value] [data ...] - set value",
46 " -i=integer -s=string -e=expand-string -m=multi-string",
47 " regtool [-v] unset [key\\value] - removes value from key",
48 " regtool [-q] get [key\\value] - prints value to stdout",
49 " -q=quiet, no error msg, just return nonzero exit if key/value missing",
50 " keys are like \\prefix\\key\\key\\key\\value, where prefix is any of:",
51 " root HKCR HKEY_CLASSES_ROOT",
52 " config HKCC HKEY_CURRENT_CONFIG",
53 " user HKCU HKEY_CURRENT_USER",
54 " machine HKLM HKEY_LOCAL_MACHINE",
55 " users HKU HKEY_USERS",
56 " example: \\user\\software\\Microsoft\\Clock\\iFormat",
64 for (i = 0; usage_msg[i]; i++)
65 fprintf (stderr, "%s\n", usage_msg[i]);
75 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
76 | FORMAT_MESSAGE_FROM_SYSTEM,
77 0, rv, 0, (CHAR *) & buf, 0, 0);
78 fprintf (stderr, "Error: %s\n", buf);
90 {"root", HKEY_CLASSES_ROOT},
91 {"HKCR", HKEY_CLASSES_ROOT},
92 {"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT},
93 {"config", HKEY_CURRENT_CONFIG},
94 {"HKCC", HKEY_CURRENT_CONFIG},
95 {"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG},
96 {"user", HKEY_CURRENT_USER},
97 {"HKCU", HKEY_CURRENT_USER},
98 {"HKEY_CURRENT_USER", HKEY_CURRENT_USER},
99 {"machine", HKEY_LOCAL_MACHINE},
100 {"HKLM", HKEY_LOCAL_MACHINE},
101 {"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE},
102 {"users", HKEY_USERS},
104 {"HKEY_USERS", HKEY_USERS},
109 translate (char *key)
111 #define isodigit(c) (strchr("01234567", c))
112 #define tooct(c) ((c)-'0')
113 #define tohex(c) (strchr(_hs,tolower(c))-_hs)
114 static char _hs[] = "0123456789abcdef";
160 c = (c << 3) | tooct (*++s);
162 c = (c << 3) | tooct (*++s);
167 if (!isxdigit (s[1]))
173 c = (c << 4) | tohex (*++s);
177 default: /* before non-special char: just add the char */
191 find_key (int howmanyparts, REGSAM access)
193 char *n = argv[0], *e, c;
197 while ((*n == '\\') || (*n == '/'))
199 for (e = n; *e && *e != '\\' && *e != '/'; e++);
205 for (i = 0; wkprefixes[i].string; i++)
206 if (strcmp (wkprefixes[i].string, n) == 0)
208 if (!wkprefixes[i].string)
210 fprintf (stderr, "Unknown key prefix. Valid prefixes are:\n");
211 for (i = 0; wkprefixes[i].string; i++)
212 fprintf (stderr, "\t%s\n", wkprefixes[i].string);
218 while (*n && *n == '\\')
221 if (howmanyparts > 1)
223 while (n < e && *e != '\\')
227 fprintf (stderr, "Invalid key\n");
235 key = wkprefixes[i].key;
238 int rv = RegOpenKeyEx (wkprefixes[i].key, n, 0, access, &key);
239 if (rv != ERROR_SUCCESS)
241 //printf("key `%s' value `%s'\n", n, value);
248 DWORD num_subkeys, maxsubkeylen, num_values, maxvalnamelen, maxvaluelen;
250 char *subkey_name, *value_name, *class_name;
251 unsigned char *value_data, *vd;
255 find_key (1, KEY_READ);
256 RegQueryInfoKey (key, 0, 0, 0, &num_subkeys, &maxsubkeylen, &maxclasslen,
257 &num_values, &maxvalnamelen, &maxvaluelen, 0, 0);
259 subkey_name = (char *) malloc (maxsubkeylen + 1);
260 class_name = (char *) malloc (maxclasslen + 1);
261 value_name = (char *) malloc (maxvalnamelen + 1);
262 value_data = (unsigned char *) malloc (maxvaluelen + 1);
267 if (listwhat & LIST_KEYS)
268 for (i = 0; i < num_subkeys; i++)
270 m = maxsubkeylen + 1;
272 RegEnumKeyEx (key, i, subkey_name, &m, 0, class_name, &n, 0);
273 printf ("%s%s", subkey_name, (postfix || verbose) ? "\\" : "");
276 printf (" (%s)", class_name);
281 if (listwhat & LIST_VALS)
282 for (i = 0; i < num_values; i++)
284 m = maxvalnamelen + 1;
286 RegEnumValue (key, i, value_name, &m, 0, &t, (BYTE *) value_data, &n);
288 printf ("%s\n", value_name);
291 printf ("%s = ", value_name);
295 for (j = 0; j < 8 && j < n; j++)
296 printf ("%02x ", value_data[j]);
300 printf ("0x%08lx (%lu)\n", *(DWORD *) value_data,
301 *(DWORD *) value_data);
303 case REG_DWORD_BIG_ENDIAN:
304 v = ((value_data[0] << 24)
305 | (value_data[1] << 16)
306 | (value_data[2] << 8) | (value_data[3]));
307 printf ("0x%08x (%d)\n", v, v);
311 printf ("\"%s\"\n", value_data);
317 printf ("\"%s\"", vd);
318 vd = vd + strlen ((const char *) vd) + 1;
325 printf ("? (type %d)\n", (int) t);
335 find_key (2, KEY_ALL_ACCESS);
338 int rv = RegCreateKeyEx (key, value, 0, (char *) "", REG_OPTION_NON_VOLATILE,
339 KEY_ALL_ACCESS, 0, &newkey, &newtype);
340 if (rv != ERROR_SUCCESS)
345 if (newtype == REG_OPENED_EXISTING_KEY)
346 printf ("Key %s already exists\n", value);
348 printf ("Key %s created\n", value);
356 find_key (2, KEY_ALL_ACCESS);
357 DWORD rv = RegDeleteKey (key, value);
358 if (rv != ERROR_SUCCESS)
361 printf ("subkey %s deleted\n", value);
368 find_key (1, KEY_READ);
370 printf ("key %s exists\n", argv[0]);
379 char *a = argv[1], *data;
380 find_key (2, KEY_ALL_ACCESS);
382 if (key_type == KT_AUTO)
387 key_type = KT_EXPAND;
388 else if (a[0] && !*e)
393 key_type = KT_STRING;
399 v = strtoul (a, 0, 0);
400 rv = RegSetValueEx (key, value, 0, REG_DWORD, (const BYTE *) &v,
404 rv = RegSetValueEx (key, value, 0, REG_SZ, (const BYTE *) a, strlen (a));
407 rv = RegSetValueEx (key, value, 0, REG_EXPAND_SZ, (const BYTE *) a,
411 for (i = 1, n = 1; argv[i]; i++)
412 n += strlen (argv[i]) + 1;
413 data = (char *) malloc (n);
414 for (i = 1, n = 0; argv[i]; i++)
416 strcpy (data + n, argv[i]);
417 n += strlen (argv[i]) + 1;
420 rv = RegSetValueEx (key, value, 0, REG_MULTI_SZ, (const BYTE *) data,
427 rv = ERROR_INVALID_CATEGORY;
431 if (rv != ERROR_SUCCESS)
440 find_key (2, KEY_ALL_ACCESS);
441 DWORD rv = RegDeleteValue (key, value);
442 if (rv != ERROR_SUCCESS)
445 printf ("value %s deleted\n", value);
452 find_key (2, KEY_READ);
453 DWORD vtype, dsize, rv;
455 rv = RegQueryValueEx (key, value, 0, &vtype, 0, &dsize);
456 if (rv != ERROR_SUCCESS)
459 data = (char *) malloc (dsize);
460 rv = RegQueryValueEx (key, value, 0, &vtype, (BYTE *) data, &dsize);
461 if (rv != ERROR_SUCCESS)
466 fwrite (data, dsize, 0, stdout);
469 printf ("%lu\n", *(DWORD *) data);
472 printf ("%s\n", data);
475 if (key_type == KT_EXPAND) // hack
479 bufsize = ExpandEnvironmentStrings (data, 0, 0);
480 buf = (char *) malloc (bufsize + 1);
481 ExpandEnvironmentStrings (data, buf, bufsize + 1);
484 printf ("%s\n", data);
491 vd = vd + strlen ((const char *) vd) + 1;
506 {"remove", cmd_remove},
507 {"check", cmd_check},
509 {"unset", cmd_unset},
515 main (int argc, char **_argv)
519 int g = getopt (argc, _argv, "hvqisempkl");
534 listwhat |= LIST_KEYS;
537 listwhat |= LIST_VALS;
544 key_type = KT_STRING;
547 key_type = KT_EXPAND;
558 if (_argv[optind] == NULL)
561 argv = _argv + optind;
563 for (i = 0; commands[i].name; i++)
564 if (strcmp (commands[i].name, argv[0]) == 0)
567 return commands[i].func ();