This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] regtool: Add load/unload commands and --binary option


Hi,

the attached patch adds commands "load" and "unload" and options "-b, --binary" to regtool.

Load a registry hive from PATH into new SUBKEY:

regtool load KEY\SUBKEY PATH

Unload and remove SUBKEY later:

regtool unload KEY\SUBKEY

Print REG_BINARY value as hex:

regtool -b get KEY\VALUE

Set REG_BINARY value from hex args:

regtool -b set KEY\VALUE XX XX XX XX ...


Example:
Suppose S:\ is a partition on a second HD which contains a copy of all files of XP system partition C:\.
The following script fixes the logical drive mappings of the backup installation.
This allows booting backup drive S:\ as C:\ after original C:\ drive has been removed.


#!/bin/sh
set -e

# Load backup SYSTEM hive as SYSTEM.TMP
regtool load /HKLM/SYSTEM.TMP /cygdrive/s/WINDOWS/system32/config/system
trap 'regtool unload /HKLM/SYSTEM.TMP' ERR

# Remove all logical drive mappings in backup
# (Somewhat tricky, because key value names contain backslashes)
for v in $(regtool list /HKLM/SYSTEM.TMP/MountedDevices |
         sed -n '/^\\DosDevices\\[C-Z]:$/s,\\,/,gp')
do
 regtool -K, unset "/HKLM/SYSTEM.TMP/MountedDevices,$v"
done

# Map current S:\ as C:\ in backup
m=$(regtool -K, -b get /HKLM/SYSTEM/MountedDevices/,/DosDevices/S:)
regtool -K, -b set /HKLM/SYSTEM.TMP/MountedDevices/,/DosDevices/C: $m

# Unload hive
trap '' ERR
regtool unload /HKLM/SYSTEM.TMP

# End of script
####################


Thanks for any comment


Christian

--- regtool.cc.orig	2005-09-12 01:48:05.001000000 +0200
+++ regtool.cc	2006-01-24 15:48:55.750000000 +0100
@@ -10,15 +10,17 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <ctype.h>
 #include <getopt.h>
 #include <windows.h>
+#include <sys/cygwin.h>
 
 #define DEFAULT_KEY_SEPARATOR '\\'
 
 enum
 {
-  KT_AUTO, KT_INT, KT_STRING, KT_EXPAND, KT_MULTI
+  KT_AUTO, KT_BINARY, KT_INT, KT_STRING, KT_EXPAND, KT_MULTI
 } key_type = KT_AUTO;
 
 char key_sep = DEFAULT_KEY_SEPARATOR;
@@ -32,6 +34,7 @@
 
 static struct option longopts[] =
 {
+  {"binary", no_argument, NULL, 'b' },
   {"expand-string", no_argument, NULL, 'e' },
   {"help", no_argument, NULL, 'h' },
   {"integer", no_argument, NULL, 'i' },
@@ -47,7 +50,7 @@
   {NULL, 0, NULL, 0}
 };
 
-static char opts[] = "ehiklmpqsvVK:";
+static char opts[] = "behiklmpqsvVK:";
 
 int listwhat = 0;
 int postfix = 0;
@@ -62,7 +65,7 @@
 usage (FILE *where = stderr)
 {
   fprintf (where, ""
-  "Usage: %s [OPTION] (add | check | get | list | remove | unset) KEY\n"
+  "Usage: %s [OPTION] (add|check|get|list|remove|unset|load|unload) KEY\n"
   "View or edit the Win32 registry\n"
   "\n"
   "", prog_name);
@@ -76,6 +79,8 @@
     " remove KEY                 remove KEY\n"
     " set KEY\\VALUE [data ...]   set VALUE\n"
     " unset KEY\\VALUE            removes VALUE from KEY\n"
+    " load KEY\\SUBKEY PATH       load hive from PATH into new SUBKEY\n"
+    " unload KEY\\SUBKEY          unload hive and remove SUBKEY\n"
     "\n");
   fprintf (where, ""
   "Options for 'list' Action:\n"
@@ -83,7 +88,11 @@
   " -l, --list           print only VALUEs\n"
   " -p, --postfix        like ls -p, appends '\\' postfix to KEY names\n"
   "\n"
+  "Options for 'get' Action:\n"
+  " -b, --binary         print REG_BINARY data as hex bytes\n"
+  "\n"
   "Options for 'set' Action:\n"
+  " -b, --binary         set type to REG_BINARY\n"
   " -e, --expand-string  set type to REG_EXPAND_SZ\n"
   " -i, --integer        set type to REG_DWORD\n"
   " -m, --multi-string   set type to REG_MULTI_SZ\n"
@@ -348,9 +357,30 @@
     key = base;
   else
     {
-      rv = RegOpenKeyEx (base, n, 0, access, &key);
-      if (rv != ERROR_SUCCESS)
-	Fail (rv);
+      if (access)
+	{ 
+	  rv = RegOpenKeyEx (base, n, 0, access, &key);
+	  if (rv != ERROR_SUCCESS)
+	    Fail (rv);
+	}
+      else if (argv[1])
+	{ 
+	  char win32_path[MAX_PATH];
+	  cygwin_conv_to_win32_path(argv[1], win32_path);
+	  rv = RegLoadKey(base, n, win32_path);
+	  if (rv != ERROR_SUCCESS)
+	    Fail (rv);
+	  if (verbose)
+	    printf("key %s loaded from file %s\n", n, win32_path);
+	}
+      else
+	{ 
+	  rv = RegUnLoadKey(base, n);
+	  if (rv != ERROR_SUCCESS)
+	    Fail (rv);
+	  if (verbose)
+	    printf("key %s unloaded\n", n);
+	}
     }
   //printf("key `%s' value `%s'\n", n, value);
 }
@@ -491,7 +521,7 @@
 {
   int i, n;
   DWORD v, rv;
-  char *a = argv[1], *data;
+  char *a = argv[1], *data = 0;
   find_key (2, KEY_ALL_ACCESS);
 
   if (key_type == KT_AUTO)
@@ -510,6 +540,27 @@
 
   switch (key_type)
     {
+    case KT_BINARY:
+      for (n = 0; argv[n+1]; n++)
+        ;
+      if (n > 0)
+	{
+	  data = (char *) malloc (n);
+	  for (i = 0; i < n; i++)
+	    {
+	      char *e;
+	      errno = 0;
+	      v = strtoul (argv[i+1], &e, 16);
+	      if (errno || v > 0xff || *e)
+		{
+		  fprintf (stderr, "Invalid hex constant `%s'\n", argv[i+1]);
+		  exit (1);
+		}
+	      data[i] = (char) v;
+	    }
+	}
+      rv = RegSetValueEx (key, value, 0, REG_BINARY, (const BYTE *) data, n);
+      break;
     case KT_INT:
       v = strtoul (a, 0, 0);
       rv = RegSetValueEx (key, value, 0, REG_DWORD, (const BYTE *) &v,
@@ -542,6 +593,9 @@
       rv = ERROR_INVALID_CATEGORY;
       break;
     }
+ 
+  if (data)
+    free(data);
 
   if (rv != ERROR_SUCCESS)
     Fail (rv);
@@ -577,7 +631,14 @@
   switch (vtype)
     {
     case REG_BINARY:
-      fwrite (data, dsize, 1, stdout);
+      if (key_type == KT_BINARY)	// hack
+	{
+	  for (unsigned i = 0; i < dsize; i++)
+	    printf ("%02x%c", (unsigned char)data[i],
+	      (i < dsize-1 ? ' ' : '\n'));
+	}
+      else
+ 	fwrite (data, dsize, 1, stdout);
       break;
     case REG_DWORD:
       printf ("%lu\n", *(DWORD *) data);
@@ -610,6 +671,31 @@
   return 0;
 }
 
+int
+cmd_load ()
+{
+  if (!argv[1])
+    {
+      usage();
+      return 1;
+    }
+  find_key(1, 0);
+  return 0;
+}
+
+int
+cmd_unload ()
+{
+  if (argv[1])
+    {
+      usage();
+      return 1;
+    }
+  find_key(1, 0);
+  return 0;
+}
+
+
 struct
 {
   const char *name;
@@ -623,6 +709,8 @@
   {"set", cmd_set},
   {"unset", cmd_unset},
   {"get", cmd_get},
+  {"load", cmd_load},
+  {"unload", cmd_unload},
   {0, 0}
 };
 
@@ -642,6 +730,9 @@
   while ((g = getopt_long (argc, _argv, opts, longopts, NULL)) != EOF)
     switch (g)
 	{
+	case 'b':
+	  key_type = KT_BINARY;
+	  break;
 	case 'e':
 	  key_type = KT_EXPAND;
 	  break;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]