/* regtool.cc Copyright 2000 Red Hat Inc. This file is part of Cygwin. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include #include #include #include #include enum { KT_AUTO, KT_INT, KT_STRING, KT_EXPAND, KT_MULTI } key_type = KT_AUTO; int verbose = 0; int quiet = 0; char **argv; HKEY key; char *value; const char *usage_msg[] = { "Regtool Copyright (c) 2000 Red Hat Inc", " regtool -h - print this message", " regtool [-v] list [key] - list subkeys and values", " regtool [-v] add [key\\subkey] - add new subkey", " regtool [-v] remove [key] - remove key", " regtool [-v|-q] check [key] - exit 0 if key exists, 1 if not", " regtool [-i|-s|-e|-m] set [key\\value] [data ...] - set value", " -i=integer -s=string -e=expand-string -m=multi-string", " regtool [-v] unset [key\\value] - removes value from key", " regtool [-q] get [key\\value] - prints value to stdout", " -q=quiet, no error msg, just return nonzero exit if key/value missing", " keys are like \\prefix\\key\\key\\key\\value, where prefix is any of:", " root HKCR HKEY_CLASSES_ROOT", " config HKCC HKEY_CURRENT_CONFIG", " user HKCU HKEY_CURRENT_USER", " machine HKLM HKEY_LOCAL_MACHINE", " users HKU HKEY_USERS", " example: \\user\\software\\Microsoft\\Clock\\iFormat", 0 }; void usage(void) { int i; for (i=0; usage_msg[i]; i++) fprintf(stderr, "%s\n", usage_msg[i]); exit(1); } void Fail(DWORD rv) { char *buf; if (!quiet) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, rv, 0, (CHAR *)&buf, 0, 0); fprintf(stderr, "Error: %s\n", buf); } exit(1); } struct { const char *string; HKEY key; } wkprefixes[] = { { "root", HKEY_CLASSES_ROOT }, { "HKCR", HKEY_CLASSES_ROOT }, { "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT }, { "config", HKEY_CURRENT_CONFIG }, { "HKCC", HKEY_CURRENT_CONFIG }, { "HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG }, { "user", HKEY_CURRENT_USER }, { "HKCU", HKEY_CURRENT_USER }, { "HKEY_CURRENT_USER", HKEY_CURRENT_USER }, { "machine", HKEY_LOCAL_MACHINE }, { "HKLM", HKEY_LOCAL_MACHINE }, { "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE }, { "users", HKEY_USERS }, { "HKU", HKEY_USERS }, { "HKEY_USERS", HKEY_USERS }, { 0, 0 } }; void translate(char *key) { #define isodigit(c) (strchr("01234567", c)) #define tooct(c) ((c)-'0') #define tohex(c) (strchr(_hs,tolower(c))-_hs) static char _hs[] = "0123456789abcdef"; char *d = key; char *s = key; char c; while (*s) { if (*s == '\\') switch (*++s) { case 'a': *d++ = '\007'; break; case 'b': *d++ = '\b'; break; case 'e': *d++ = '\033'; break; case 'f': *d++ = '\f'; break; case 'n': *d++ = '\n'; break; case 'r': *d++ = '\r'; break; case 't': *d++ = '\t'; break; case 'v': *d++ = '\v'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c = tooct(*s); if (isodigit(s[1])) { c = (c << 3) | tooct(*++s); if (isodigit(s[1])) c = (c << 3) | tooct(*++s); } *d++ = c; break; case 'x': if (isxdigit(s[1])) { c = tohex(*++s); if (isxdigit(s[1])) c = (c << 4) | tohex(*++s); } *d++ = c; break; default: /* before non-special char: just add the char */ *d++ = *s; break; } else if (*s == '/') *d++ = '\\'; else *d++ = *s; ++s; } *d = '\0'; } void find_key(int howmanyparts) { char *n = argv[0], *e, c; int i; if (*n == '/') translate(n); while (*n == '\\') n++; for (e=n; *e && *e != '\\'; e++); c = *e; *e = 0; for (i=0; wkprefixes[i].string; i++) if (strcmp(wkprefixes[i].string, n) == 0) break; if (!wkprefixes[i].string) { fprintf(stderr, "Unknown key prefix. Valid prefixes are:\n"); for (i=0; wkprefixes[i].string; i++) fprintf(stderr, "\t%s\n", wkprefixes[i].string); exit(1); } n = e; *e = c; while (*n && *n == '\\') n++; e = n+strlen(n); if (howmanyparts > 1) { while (n < e && *e != '\\') e--; if (*e != '\\') { fprintf(stderr, "Invalid key\n"); exit(1); } *e = 0; value = e+1; } if (n[0] == 0) { key = wkprefixes[i].key; return; } int rv = RegOpenKeyEx(wkprefixes[i].key, n, 0, KEY_ALL_ACCESS, &key); if (rv != ERROR_SUCCESS) Fail(rv); //printf("key `%s' value `%s'\n", n, value); } int cmd_list() { DWORD num_subkeys, maxsubkeylen, num_values, maxvalnamelen, maxvaluelen; DWORD maxclasslen; char *subkey_name, *value_name, *class_name; unsigned char *value_data, *vd; DWORD i, j, m, n, t; int v; find_key(1); RegQueryInfoKey(key, 0, 0, 0, &num_subkeys, &maxsubkeylen, &maxclasslen, &num_values, &maxvalnamelen, &maxvaluelen, 0, 0); subkey_name = (char *)malloc(maxsubkeylen+1); class_name = (char *)malloc(maxclasslen+1); value_name = (char *)malloc(maxvalnamelen+1); value_data = (unsigned char *)malloc(maxvaluelen+1); for (i=0; i