Re: [Libguestfs] [PATCH] Add a minimal hive with special keys and values
On Fri, Jan 10, 2014 at 01:14:51AM +0100, Hilko Bengen wrote: + was created using the 'mkzero/mkzero.c'. (\0 = zero character) Extra whitespace at the end of this ^ line ... + InitializeObjectAttributes (key_obj, key_name, .. and this line. --- So there's no problem with adding this test data, but are you planning to also add some tests :-? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [Bug 1046905] New: RFE: add argument to virt-sysprep to disable individual default operations
On Thu, Jan 09, 2014 at 03:45:54PM +, Richard W.M. Jones wrote: On Thu, Jan 09, 2014 at 04:21:10PM +0100, Pino Toscano wrote: + and set_operations op_string = +let currentopset = + match (!operations) with No need for parentheses around !operations. +let n = ref op_name in +let remove = string_prefix op_name - in +if remove then + n := String.sub op_name 1 (String.length op_name - 1); +match !n with This can be written a bit more naturally as ... let n, remove = if string_prefix op_name - then String.sub op_name 1 (String.length op_name-1), true else op_name, false in match n with ... An even more natural way to write this is: let op = if string_prefix op_name - then `Remove (String.sub op_name 1 (String.length op_name-1)) else `Add op_name match op with | `Add | `Remove - (* error *) | `Add defaults - Sysprep_operation.add_defaults_to_set opset | `Remove defaults - Sysprep_operation.remove_defaults_from_set opset | etc The type of op will be [ `Add of string | `Remove of string ]. Actually you never need to write that type out, as OCaml will infer it (and check it). It will only appear in error messages if you get the code wrong. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH] Add a minimal hive with special keys and values
* Richard W.M. Jones: So there's no problem with adding this test data, but are you planning to also add some tests :-? Sure. Working on it. Good that you asked for tests, btw. Another bugfix patch or two will be on the way. :-) Cheers, -Hilko ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] RFC: copy-attributes command
On Tuesday 07 January 2014 21:04:36 Richard W.M. Jones wrote: On Tue, Jan 07, 2014 at 04:06:43PM +0100, Pino Toscano wrote: Hi, attached there is a prototype of patch for adding a new copy-attributes command. Such command would allow copy the attributes of a file to another, so for example in guestfish: copy-attributes foo bar permissions:true xattributes:false would only copy the permissions of foo to bar, not copying its extended attributes too. I think the general idea of the new API is fine. More comments about the code below. Just few notes: - my first daemon command, so possibly I could be missing something - copy_xattrs is in xattr.c to avoid spreading the usage of xattr API in many places - copy_xattrs does a bit of code repetition with other stuff in xattr.c, but I'm not sure how to avoid it without making the xattr listing code (getxattrs) a bit more complex that what it is already Comments? diff --git a/daemon/daemon.h b/daemon/daemon.h index b77d764..6535658 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -231,6 +231,9 @@ extern void journal_finalize (void); /*-- in proto.c --*/ extern void main_loop (int sock) __attribute__((noreturn)); +/*-- in xattr.c --*/ +extern int copy_xattrs (const char *src, const char *dest); + /* ordinary daemon functions use these to indicate errors * NB: you don't need to prefix the string with the current command, * it is added automatically by the client-side RPC stubs. diff --git a/daemon/file.c b/daemon/file.c index f348f87..fd6da71 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -28,6 +28,7 @@ #include guestfs_protocol.h #include daemon.h #include actions.h +#include optgroups.h GUESTFSD_EXT_CMD(str_file, file); GUESTFSD_EXT_CMD(str_zcat, zcat); @@ -584,3 +585,46 @@ do_filesize (const char *path) return buf.st_size; } + +int +do_copy_attributes (const char *src, const char *dest, int permissions, int xattributes) +{ + int r; + struct stat srcstat, deststat; + + CHROOT_IN; + r = stat (src, srcstat); + CHROOT_OUT; + + if (r == -1) { +reply_with_perror (stat: %s, src); +return -1; + } + + CHROOT_IN; + r = stat (dest, deststat); + CHROOT_OUT; + + if (r == -1) { +reply_with_perror (stat: %s, dest); +return -1; + } + + if (permissions ((srcstat.st_mode 0777) != (deststat.st_mode 0777))) { +CHROOT_IN; +r = chmod (dest, (srcstat.st_mode 0777)); I suspect you want 0 in order to copy sticky/setuid/setgid bits. Perhaps those should be a separate flag, but we definitely want to copy them! Right, fixed to be part of the permissions (or mode actually, see below). + ssize_t len, vlen, ret; + CLEANUP_FREE char *buf = NULL, *attrval = NULL; + size_t i, attrval_len = 0; + + CHROOT_IN; + len = listxattr (src, NULL, 0); + CHROOT_OUT; + if (len == -1) { +reply_with_perror (listxattr: %s, src); +goto error; + } + + buf = malloc (len); + if (buf == NULL) { +reply_with_perror (malloc); +goto error; + } + + CHROOT_IN; + len = listxattr (src, buf, len); + CHROOT_OUT; + if (len == -1) { +reply_with_perror (listxattr: %s, src); +goto error; + } This two-pass snippet to do (l)listxattr is already elsewhere in xattr.c, I will move it to an own function. + /* What we get from the kernel is a string foo\0bar\0baz of length + * len. + */ + for (i = 0; i (size_t) len; i += strlen (buf[i]) + 1) { +CHROOT_IN; +vlen = getxattr (src, buf[i], NULL, 0); +CHROOT_OUT; +if (vlen == -1) { + reply_with_perror (getxattr: %s, %s, src, buf[i]); + goto error; +} + +if (vlen XATTR_SIZE_MAX) { + /* The next call to getxattr will fail anyway, so ... */ + reply_with_error (extended attribute is too large); + goto error; +} + +if (vlen attrval_len) { + char *new = realloc (attrval, vlen); + if (new == NULL) { +reply_with_perror (realloc); +goto error; + } + attrval = new; + attrval_len = vlen; +} + +CHROOT_IN; +vlen = getxattr (src, buf[i], attrval, vlen); +CHROOT_OUT; +if (vlen == -1) { + reply_with_perror (getxattr: %s, %s, src, buf[i]); + goto error; +} + +CHROOT_IN; +ret = setxattr (dest, buf[i], attrval, vlen, 0); +CHROOT_OUT; +if (vlen == -1) { + reply_with_perror (setxattr: %s, %s, dest, buf[i]); + goto error; +} + } This code looks as if it will copy the xattrs, but it won't remove any which don't exist in the source. eg: source xattrs before: user.foo = 1 dest xattrs before: user.bar = 2 dest xattrs after: user.foo = 1
Re: [Libguestfs] RFC: copy-attributes command
On Fri, Jan 10, 2014 at 02:17:48PM +0100, Pino Toscano wrote: This code looks as if it will copy the xattrs, but it won't remove any which don't exist in the source. eg: source xattrs before: user.foo = 1 dest xattrs before: user.bar = 2 dest xattrs after: user.foo = 1 user.bar = 2 That may or may not be what we want, but I would say it's a bit unexpected. Yes, the current behaviour is done on purpose; my thought that, given the command is copy attributes, it would just copy what specified from the source to the destination. I see reasons for both the behaviours, so I'm not totally sure which one pick. On the basis that most users will be creating a new file (which will have no xattrs except in some very odd corner cases), just leave your implementation for now, but don't specify it in the documentation so we could change it later. - Should it default to copying attributes? You've convinced me, so I've turned the permissions flag into skipmode, so specifying nothing now copies the file mode (so permissions + bits). The common use case (for virt-edit) is: I want this other file which is identical to this original file, except in name and content. That is (I think) an argument for copying everything by default. I've added a all argument which would enable every change, overriding even mode:false. The API is now pretty confusing. Each OBool flag is really a tristate. It can either be true, false or not specified. Therefore I think it should be: xattributes:true# copies only xattrs and nothing else all:true# copies everything all:true xattributes:false # copies everything except xattrs In other words, 'all' changes the default (ie. not specified) state of the other flags. To be clearer, the four OBool parameters would be: [OBool all; OBool mode; OBool ownership; OBool xattributes] I would have thought owner uid and group gid should be copied. Oh true, forgot about them; added a new ownership argument. - Is there anything else which is useful to copy? Maybe there's also copying atime/mtime too; worth having a single argument (time) for both, or two separate? For virt-edit, I would _not_ want it to copy the old time(s). The time would be updated. But I guess there's a use for copying the time(s), so this could be another flag. We're allowed to extend the API later by adding optional flags (see Note about extending functions in generator/README for the complicated rules about extending APIs while preserving binary compatibility). +=over 4 + +=item Cxattributes + +Copy the Linux extended attributes (xattrs) from Csource to Cdestination. +This flag does nothing if the Ilinuxxattrs feature is not available +(see Cguestfs_feature_available). + +=item Call ^ Typo in this line. +Copy the owner uid and the group gid of Csource to Cdestination. + +=item Call + +Copy Ball the attributes from Csource to Cdestination. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] RFC: copy-attributes command
On Fri, Jan 10, 2014 at 01:33:38PM +, Richard W.M. Jones wrote: The API is now pretty confusing. Each OBool flag is really a tristate. It can either be true, false or not specified. Therefore I think it should be: xattributes:true# copies only xattrs and nothing else all:true# copies everything all:true xattributes:false # copies everything except xattrs In other words, 'all' changes the default (ie. not specified) state of the other flags. To be clearer, the four OBool parameters would be: [OBool all; OBool mode; OBool ownership; OBool xattributes] So looking at your v2 patch a bit more, I think this is what you already did, except that skipmode is backwards from the other flags. I think we're in agreement, except I think skipmode should just become mode and not have negated meaning compared to the other flags. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH] daemon: xattr: move the listxattrs code in an own function
Move in an own function the code that does the (l)listxattrs allocating the buffer of the right legth, as it will be useful later. No functional changes, just code motion. --- daemon/xattr.c | 64 -- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/daemon/xattr.c b/daemon/xattr.c index b84cf3d..e01e9e2 100644 --- a/daemon/xattr.c +++ b/daemon/xattr.c @@ -54,6 +54,7 @@ optgroup_linuxxattrs_available (void) static guestfs_int_xattr_list *getxattrs (const char *path, ssize_t (*listxattr) (const char *path, char *list, size_t size), ssize_t (*getxattr) (const char *path, const char *name, void *value, size_t size)); static int _setxattr (const char *xattr, const char *val, int vallen, const char *path, int (*setxattr) (const char *path, const char *name, const void *value, size_t size, int flags)); static int _removexattr (const char *xattr, const char *path, int (*removexattr) (const char *path, const char *name)); +static char *_listxattrs (const char *path, ssize_t (*listxattr) (const char *path, char *list, size_t size), ssize_t *size); guestfs_int_xattr_list * do_getxattrs (const char *path) @@ -111,27 +112,10 @@ getxattrs (const char *path, size_t i, j; guestfs_int_xattr_list *r = NULL; - CHROOT_IN; - len = listxattr (path, NULL, 0); - CHROOT_OUT; - if (len == -1) { -reply_with_perror (listxattr: %s, path); + buf = _listxattrs (path, listxattr, len); + if (buf == NULL) +/* _listxattrs issues reply_with_perror already. */ goto error; - } - - buf = malloc (len); - if (buf == NULL) { -reply_with_perror (malloc); -goto error; - } - - CHROOT_IN; - len = listxattr (path, buf, len); - CHROOT_OUT; - if (len == -1) { -reply_with_perror (listxattr: %s, path); -goto error; - } r = calloc (1, sizeof (*r)); if (r == NULL) { @@ -252,6 +236,46 @@ _removexattr (const char *xattr, const char *path, return 0; } +static char * +_listxattrs (const char *path, + ssize_t (*listxattr) (const char *path, char *list, size_t size), + ssize_t *size) +{ + int r; + char *buf = NULL; + ssize_t len; + + CHROOT_IN; + len = listxattr (path, NULL, 0); + CHROOT_OUT; + if (len == -1) { +reply_with_perror (listxattr: %s, path); +goto error; + } + + buf = malloc (len); + if (buf == NULL) { +reply_with_perror (malloc); +goto error; + } + + CHROOT_IN; + len = listxattr (path, buf, len); + CHROOT_OUT; + if (len == -1) { +reply_with_perror (listxattr: %s, path); +goto error; + } + + if (size) +*size = len; + return buf; + + error: + free (buf); + return NULL; +} + guestfs_int_xattr_list * do_internal_lxattrlist (const char *path, char *const *names) { -- 1.8.3.1 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] RFC: copy-attributes command
On Friday 10 January 2014 13:33:38 Richard W.M. Jones wrote: On Fri, Jan 10, 2014 at 02:17:48PM +0100, Pino Toscano wrote: This code looks as if it will copy the xattrs, but it won't remove any which don't exist in the source. eg: source xattrs before: user.foo = 1 dest xattrs before: user.bar = 2 dest xattrs after: user.foo = 1 user.bar = 2 That may or may not be what we want, but I would say it's a bit unexpected. Yes, the current behaviour is done on purpose; my thought that, given the command is copy attributes, it would just copy what specified from the source to the destination. I see reasons for both the behaviours, so I'm not totally sure which one pick. On the basis that most users will be creating a new file (which will have no xattrs except in some very odd corner cases), just leave your implementation for now, but don't specify it in the documentation so we could change it later. After all, the documentation says that it just copies the xattrs from the source to the destination, but it does not explicitly mention what is done with the xattrs in the destination not in the source ... :-) On Friday 10 January 2014 13:36:06 Richard W.M. Jones wrote: On Fri, Jan 10, 2014 at 01:33:38PM +, Richard W.M. Jones wrote: The API is now pretty confusing. Each OBool flag is really a tristate. It can either be true, false or not specified. I see, I did not pay much attention to the use of optargs_bitmask outside the auto-generated RPC stuff the daemon code. Therefore I think it should be: xattributes:true# copies only xattrs and nothing else all:true# copies everything all:true xattributes:false # copies everything except xattrs In other words, 'all' changes the default (ie. not specified) state of the other flags. Given the above, this indeed becomes straightforward to have. To be clearer, the four OBool parameters would be: [OBool all; OBool mode; OBool ownership; OBool xattributes] So looking at your v2 patch a bit more, I think this is what you already did, except that skipmode is backwards from the other flags. I think we're in agreement, except I think skipmode should just become mode and not have negated meaning compared to the other flags. OK, I will turn it back as it was before (into mode), but making use of the tristate information to have it true by default. We're allowed to extend the API later by adding optional flags (see Note about extending functions in generator/README for the complicated rules about extending APIs while preserving binary compatibility). Yes, I read it earlier, that's why I'm not that concerned about adding all the potential attributes now. Attached there is the v3 of the patch. -- Pino Toscanodiff --git a/daemon/daemon.h b/daemon/daemon.h index b77d764..6535658 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -231,6 +231,9 @@ extern void journal_finalize (void); /*-- in proto.c --*/ extern void main_loop (int sock) __attribute__((noreturn)); +/*-- in xattr.c --*/ +extern int copy_xattrs (const char *src, const char *dest); + /* ordinary daemon functions use these to indicate errors * NB: you don't need to prefix the string with the current command, * it is added automatically by the client-side RPC stubs. diff --git a/daemon/file.c b/daemon/file.c index f348f87..34ec95a 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -28,6 +28,7 @@ #include guestfs_protocol.h #include daemon.h #include actions.h +#include optgroups.h GUESTFSD_EXT_CMD(str_file, file); GUESTFSD_EXT_CMD(str_zcat, zcat); @@ -584,3 +585,79 @@ do_filesize (const char *path) return buf.st_size; } + +int +do_copy_attributes (const char *src, const char *dest, int all, int mode, int xattributes, int ownership) +{ + int r; + struct stat srcstat, deststat; + + static const unsigned int file_mask = 0; + + /* If it was specified to copy everything, manually enable all the flags + * not manually specified to avoid checking for flag || all everytime. + */ + if (all) { +if (!(optargs_bitmask GUESTFS_COPY_ATTRIBUTES_MODE_BITMASK)) + mode = 1; +if (!(optargs_bitmask GUESTFS_COPY_ATTRIBUTES_XATTRIBUTES_BITMASK)) + xattributes = 1; +if (!(optargs_bitmask GUESTFS_COPY_ATTRIBUTES_OWNERSHIP_BITMASK)) + ownership = 1; + } else if ((!(optargs_bitmask GUESTFS_COPY_ATTRIBUTES_ALL_BITMASK)) + (!(optargs_bitmask GUESTFS_COPY_ATTRIBUTES_MODE_BITMASK))) { +/* Neither all nor mode were specified, so make mode on by default. + */ +mode = 1; + } + + CHROOT_IN; + r = stat (src, srcstat); + CHROOT_OUT; + + if (r == -1) { +reply_with_perror (stat: %s, src); +return -1; + } + + CHROOT_IN; + r = stat (dest, deststat); + CHROOT_OUT; + + if (r == -1) { +reply_with_perror (stat: %s, dest); +return -1; + } + + if (mode +
Re: [Libguestfs] RFC: copy-attributes command
On Fri, Jan 10, 2014 at 05:36:39PM +0100, Pino Toscano wrote: [..] This still isn't quite what I meant. My meaning was that mode would be disabled by default (unless all:true). How about: int copy_mode, copy_xattributes, copy_ownership; /* Set defaults. */ if (all) copy_mode = copy_xattributes = copy_ownership = 1; else copy_mode = copy_xattributes = copy_ownership = 0; /* If set in the original struct, copy those settings overriding * the defaults. */ if ((optargs_bitmask GUESTFS_COPY_ATTRIBUTES_MODE_BITMASK)) copy_mode = mode; if ((optargs_bitmask GUESTFS_COPY_ATTRIBUTES_XATTRIBUTES_BITMASK)) copy_xattributes = xattributes; if ((optargs_bitmask GUESTFS_COPY_ATTRIBUTES_OWNERSHIP_BITMASK)) copy_ownership = ownership; if (!copy_mode !copy_xattributes !copy_ownership) { /* Short-circuit the code, but this *isn't* an error. */ return 0; } [...] if (copy_mode) // chmod etc. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 0/3] Timezone and keyboard layout settings in virt-builder and virt-sysprep.
Setting timezone is easy. It turns out to be almost impossible to set keyboard layout in virt-builder sanely, so I have added some examples instead. Coming up next, setting languages in virt-builder (clue: very very very hard). Rich. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 2/3] builder: docs: Remove confusing reference to timezone.
--- builder/virt-builder.pod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod index a703346..6db3dd9 100644 --- a/builder/virt-builder.pod +++ b/builder/virt-builder.pod @@ -1233,8 +1233,8 @@ least one character of whitespace (even on blank lines): notes=This image was prepared using the following kickstart script: -- one space at beginning of line - timezone Europe/London part /boot --fstype ext3 + ... =item Chidden=true -- 1.8.4.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 3/3] builder: Document how to change keyboard layout.
This is too complex to implement directly in virt-builder. Instead we just document how to do it for some common Linux distros using --run-command, --edit etc. --- builder/virt-builder.pod | 40 1 file changed, 40 insertions(+) diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod index 6db3dd9..f81c556 100644 --- a/builder/virt-builder.pod +++ b/builder/virt-builder.pod @@ -779,6 +779,46 @@ The above command will create an Crjones account with no password, and force the user to set a password when they first log in. There are other ways to manage passwords, see Luseradd(8) for details. +=head2 KEYBOARD LAYOUT + +Because there are so many different ways to set the keyboard layout in +Linux distributions, virt-builder does not yet attempt to have a +simple command line option. This section describes how to set the +keyboard for some common Linux distributions. + +=head3 Keyboard layout with systemd + +For distros that use systemd Clocalectl, use a command like this: + + virt-builder fedora-20 \ + --firstboot-command 'localectl set-keymap uk' + +See Llocalectl(1) and +Lhttps://www.happyassassin.net/2013/11/23/keyboard-layouts-in-fedora-20-and-previously/ +for more details. + +=head3 Keyboard layout using C/etc/sysconfig/keyboard + +For RHEL Ele 6, Fedora Ele 18 and similar, upload or modify the +keyboard configuration file using the I--upload, I--write or +I--edit options. For example: + + virt-builder centos-6 \ + --edit '/etc/sysconfig/keyboard: s/^KEYTABLE=.*/KEYTABLE=uk/' + +The format of this file can be found documented in many places online. + +=head3 Keyboard layout with Debian-derived distros + +For Debian-derived distros using C/etc/default/keyboard, upload or +modify the keyboard file using the I--upload, I--write or +I--edit options. For example: + + virt-builder debian-7 \ + --edit '/etc/default/keyboard: s/^XKBLAYOUT=.*/XKBLAYOUT=gb/' + +See Lhttps://wiki.debian.org/Keyboard. + =head2 LOG FILE Scripts and package installation that runs at build time (I--run, -- 1.8.4.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 2/7] lib: Use vk-len for string conversion
--- lib/value.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/value.c b/lib/value.c index 65404d7..e700c84 100644 --- a/lib/value.c +++ b/lib/value.c @@ -207,14 +207,8 @@ hivex_value_key (hive_h *h, hive_value_h value) struct ntreg_vk_record *vk = (struct ntreg_vk_record *) ((char *) h-addr + value); - /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is - * necessary. However we do need to nul-terminate the string. - */ - errno = 0; - size_t len = hivex_value_key_len (h, value); - if (len == 0 errno != 0) -return NULL; size_t flags = le16toh (vk-flags); + size_t len = le16toh (vk-name_len); if (flags 0x01) { return _hivex_windows_latin1_to_utf8 (vk-name, len); } else { -- 1.8.5.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 4/7] python: Add test for special keys and values
--- python/t/130-special.py | 28 1 file changed, 28 insertions(+) create mode 100755 python/t/130-special.py diff --git a/python/t/130-special.py b/python/t/130-special.py new file mode 100755 index 000..7adb9d5 --- /dev/null +++ b/python/t/130-special.py @@ -0,0 +1,28 @@ +# coding: utf-8 + +import os +import hivex + +srcdir = os.environ[srcdir] +if not srcdir: +srcdir = . + +h = hivex.Hivex (%s/../images/special % srcdir) +assert h + +root = h.root () +assert root + +ns = [ n for n in h.node_children (root) if h.node_name(n) == uabcd_äöüß ] +assert len (ns) == 1 +vs = [ v for v in h.node_values (ns[0]) if h.value_key(v) == uabcd_äöüß ] +assert len (vs) == 1 +ns = [ n for n in h.node_children (root) if h.node_name(n) == uzero\0key ] +assert len (ns) == 1 +vs = [ v for v in h.node_values (ns[0]) if h.value_key(v) == uzero\0val ] +assert len (vs) == 1 +ns = [ n for n in h.node_children (root) if h.node_name(n) == uweird™ ] +assert len (ns) == 1 +vs = [ v for v in h.node_values (ns[0]) if h.value_key(v) == usymbols $£₤₧€ ] +assert len (vs) == 1 + -- 1.8.5.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 1/7] Add a minimal hive with special keys and values
--- images/README | 14 images/mkzero/Makefile | 9 images/mkzero/mkzero.c | 59 + images/special | Bin 0 - 8192 bytes 4 files changed, 82 insertions(+) create mode 100644 images/mkzero/Makefile create mode 100644 images/mkzero/mkzero.c create mode 100644 images/special diff --git a/images/README b/images/README index 2131885..b01e5a2 100644 --- a/images/README +++ b/images/README @@ -11,3 +11,17 @@ hand-crafted binary blob. tests. - Richard W.M. Jones 2010-02-24. + +'special' was created by importing 'minimal' into a VM running Windows +XP, loading it into HKEY_LOCAL_MACHINE\minimal using regedit.exe +(File/Load Hive...), and running 'mkzero.exe'. + +'mkzero.exe' creates the following keys and values: + +- A key 'zero\0key' containing a REG_DWORD value 'zero\0val' (\0 = zero + character) +- A key 'asdf_äöüß' containing a REG_DWORD value 'asdf_äöüß' +- A key 'weird™' containing a REG_DWORD value 'symbols $£₤₧€' (SMALL + DOLLAR SIGN, FULLWIDTH POUND SIGN, PESETA SIGN, EURO SIGN) + +- Hilko Bengen 2014-01-10. diff --git a/images/mkzero/Makefile b/images/mkzero/Makefile new file mode 100644 index 000..affe52b --- /dev/null +++ b/images/mkzero/Makefile @@ -0,0 +1,9 @@ +CROSS=i686-w64-mingw32- +CFLAGS=--std=c99 +all: mkzero.exe +clean: + rm -f *.exe *.o +mkzero.exe: mkzero.o + $(CROSS)gcc -o $@ $ -lntdll +%.o: %.c + $(CROSS)gcc $(CFLAGS) -Wpedantic -Wall -o $@ -c $ diff --git a/images/mkzero/mkzero.c b/images/mkzero/mkzero.c new file mode 100644 index 000..a95794a --- /dev/null +++ b/images/mkzero/mkzero.c @@ -0,0 +1,59 @@ +/* use the NT native API to create registry key and value that contain + a zero character */ + +#include ntdef.h +#include stdio.h +#include ddk/wdm.h +#include windef.h + +void create_key_value (PHANDLE handle, WCHAR* key, int key_len, WCHAR* val, int val_len) +{ + UNICODE_STRING key_name = { key_len, key_len, key }; + UNICODE_STRING value_name = { val_len, val_len, val }; + OBJECT_ATTRIBUTES key_obj; + InitializeObjectAttributes (key_obj, key_name, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + *handle, NULL); + HANDLE key_handle; + NTSTATUS rc; + rc = ZwCreateKey (key_handle, KEY_ALL_ACCESS, key_obj, +0, NULL, REG_OPTION_NON_VOLATILE, NULL); + if (!NT_SUCCESS (rc)) { +wprintf(Lerror: CreateKey %s: 0x%08x\n, key, rc); +exit(1); + } + DWORD value = 0; + rc = ZwSetValueKey (key_handle, value_name, 0, + REG_DWORD, value, sizeof(value)); + if (!NT_SUCCESS (rc)) { +wprintf(Lerror: SetValueKey %s: 0x%08x\n, val, rc); +exit(1); + } +} + +int main (int argc, char **argv) +{ + UNICODE_STRING root_key_name; + RtlInitUnicodeString(root_key_name, L\\Registry\\Machine\\minimal); + OBJECT_ATTRIBUTES root_key_obj; + InitializeObjectAttributes (root_key_obj, root_key_name, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + NULL, NULL); + HANDLE minimal_key_handle; + NTSTATUS rc = ZwCreateKey (minimal_key_handle, KEY_ALL_ACCESS, root_key_obj, +0, NULL, REG_OPTION_NON_VOLATILE, NULL); + if (!NT_SUCCESS (rc)) { +wprintf(Lerror: CreateKey HKLM\\minimal: 0x%08x\n, rc); +exit(1); + } + WCHAR k1[] = Lzero\0key; + WCHAR v1[] = Lzero\0val; + create_key_value (minimal_key_handle, k1, sizeof (k1)-2, v1, sizeof (v1)-2); + WCHAR k2[] = Labcd_äöüß; + WCHAR v2[] = Labcd_äöüß; + create_key_value (minimal_key_handle, k2, sizeof (k2)-2, v2, sizeof (v2)-2); + WCHAR k3[] = Lweird™; + WCHAR v3[] = Lsymbols $£₤₧€; + create_key_value (minimal_key_handle, k3, sizeof (k3)-2, v3, sizeof (v3)-2); + return 0; +} diff --git a/images/special b/images/special new file mode 100644 index ..8a5ff5f34f32f0e56c1e1e9abf49bd3a8857c5e7 GIT binary patch literal 8192 zcmeHLziU%b6h28CZ9~EDAeHa+P=XdxC$;R6s%K4L=cN5X`%@)O-drwio+ZH@elY1 z1T2`rMJE?Ghc2Q^L|k-m(@8`sh|ll4H6SLm(oQjat_k?mh3^bH4X|uYulX`TDgz zDG`p7(@(o+_rFeIDH#kJ*De1UAJUGPYj?r7CrdmfVo06fig77i3n-i1}u}f_;? zjGP+lsO=gC@|UkX+cjVmh%%rICDrXGN2471ImChpbRJj%D_Kmpi-XO#}RYA6aw{ zzoOm!@8fB{JkG9c{jk=AfNT);Y`B1j3jrVo1lAOn3ifxYK=P%4(oIgHy?h+qw z{0hUCkL!iB9c*wEQ%Xi3^76qk9Yqcyo|Z3?sq4rBiN;I29|L#Ov!_#3aE$JRyH( zNWO_9|CAhv)p!5qJ6r3UIMA7Vi#223Jxj!Zzcn_rZYYO+utKz2fTypy6?txaoMqF z)PlzLZB!(`+(*wTH5K*hWU26*$}_H*6!MAjUy3vnTR?oPlTv+vWW7F#44ACPu zM301g!+S!$i6cKz51T)zhm)X3F2=Fd$nk7ld)bvajCbvvcw4^n+1odxa5E1yT;F1 zZMMlz4SCknQ#PT23*zbDz-2a^~b11fNu2s?5!TFgOk$bZx`$RPU7pz4=YDHfcE zP+Tf4e)|6NgNg7jN~BgvO9yAKb|1WY4iGQCdhg#EeB%T7`p;W@vZL?uRsy~p`bYTq zJ8={Dh*jJumSlR05Q(E!8To^64$0m1`;7=Eb7g|Z!U(H@s_ONF0zPQ${NLc=AZr k-N)_|mrtRG{b8{ios|J)Kp9X5lmTTx8Bhk4fY|-#+)~(*OVf literal 0 HcmV?d1 -- 1.8.5.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 3/7] perl: Add test for special keys and values
--- perl/t/130-special.t | 34 ++ 1 file changed, 34 insertions(+) create mode 100644 perl/t/130-special.t diff --git a/perl/t/130-special.t b/perl/t/130-special.t new file mode 100644 index 000..c25af7e --- /dev/null +++ b/perl/t/130-special.t @@ -0,0 +1,34 @@ +# hivex Perl bindings -*- perl -*- + +use strict; +use warnings; +use utf8::all; # so the strings in this file are interpreted correctly. +use Test::More; + +use Win::Hivex; + +my $srcdir = $ENV{srcdir} || .; +my $h = Win::Hivex-open ($srcdir/../images/special); +ok $h, 'hive opened correctly'; +my $root = $h-root; +ok $root, 'root node found'; +my ($node, $value); + +my @nodes = $h-node_children( $root ); + +($node) = grep { $h-node_name($_) eq 'abcd_äöüß' } @nodes; +ok $node, q'abcd_äöüß' (node) has been found; +($value) = grep { $h-value_key($_) eq 'abcd_äöüß' } $h-node_values($node); +ok $value, q'abcd_äöüß\abcd_äöüß' (value) has been found; + +($node) = grep { $h-node_name($_) eq zero\0key } @nodes; +ok $node, 'key has been found'; +($value) = grep { $h-value_key($_) eq zero\0val } $h-node_values($node); +ok $value, 'value has been found'; + +($node) = grep { $h-node_name($_) eq 'weird™' } @nodes; +ok $node, q'weird™' (node) has been found; +($value) = grep { $h-value_key($_) eq 'symbols $£₤₧€' } $h-node_values($node); +ok $value, q'weird™\symbols $£₤₧€' (value) has been found; + +done_testing; -- 1.8.5.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 5/7] perl: Properly decode node names, value keys from UTF-8
--- generator/generator.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/generator.ml b/generator/generator.ml index 6b1eef7..4119b04 100755 --- a/generator/generator.ml +++ b/generator/generator.ml @@ -2648,7 +2648,7 @@ DESTROY (h) pr croak (\%%s: %%s\, \%s\, strerror (errno));\n name; if f_len_exists name then - pr RETVAL = newSVpvn (r, hivex_%s_len (%s));\n + pr RETVAL = newSVpvn_utf8 (r, hivex_%s_len (%s), 1);\n name (String.concat , c_params) else pr RETVAL = newSVpv (r, 0);\n; -- 1.8.5.2 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs