Fwd: hivex: patch for read support of "li"-records from "ri" intermediate
by Richard W.M. Jones
[The bug which this fixes is:
https://bugzilla.redhat.com/show_bug.cgi?id=717583 ]
----- Forwarded message from Peter Fokker <peter(a)berestijn.nl> -----
Date: Thu, 8 Mar 2012 11:37:06 +0100 (CET)
From: Peter Fokker <peter(a)berestijn.nl>
To: rjones(a)redhat.com
Cc: Peter Fokker <peter(a)berestijn.nl>
Subject: hivex: patch for read support of "li"-records from "ri"
intermediate
User-Agent: SquirrelMail/1.4.9a
Richard,
Thank you for creating the hivex-library. Studying your source code helped
me a great deal to better understand the internals of the Windows Registry.
However, while I was browsing a real-world SOFTWARE-hive (XP, SP3) I
could not browse to the '\Classes' key. Instead I got this (debug)-message:
get_children: returning ENOTSUP because ri-record offset does not
point to lf/lh (0x49020)
I tracked this issue down and I discovered that the intermediate
"ri"-record may not only contain offsets to "lf" and "lh" but to
"li"-records too.
Attached is a patch against hivex.c v1.3.3 that recognises
"li"-records referenced from "ri"-records. For me this fixed the issue
with browsing the '\Classes' key.
Note that I have not fixed the related problem of rewriting
"li"-records when inserting a new subkey or deleting an
existing one. This sure would cause problems when I were to
add/delete a subkey to/from '\Classes'.
I would very much appreciate it if would be so kind to take a look at
my patch, allthough I cannot blame you if you immediately dump this
unsollicited message+patch from some random stranger from The Netherlands.
Kind regards,
--Peter Fokker
--
Peter Fokker <peter(a)berestijn.nl>
Ingenieursbureau PSD +31 35 695 29 99 / +31 644 238 568
Stargardlaan 7 1404 BC Bussum, The Netherlands
----- End forwarded message -----
--
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
11 years, 12 months
[PATCH v6] hivexml: Add byte run reporting functions
by Alex Nelson
This patch adds value_byte_runs and node_byte_runs. Each byte run
represents the offset and length of a data structure within the hive,
one per node, and one or two per value depending on the length of the
value data.
These byte run functions also add additional data sanity checks as a
hive is being parsed, mainly checking that a node address actually
points to a node, and similarly for values.
---
xml/hivexml.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 96 insertions(+), 9 deletions(-)
diff --git a/xml/hivexml.c b/xml/hivexml.c
index 54d9049..a4bc7eb 100644
--- a/xml/hivexml.c
+++ b/xml/hivexml.c
@@ -210,11 +210,40 @@ filetime_to_8601 (int64_t windows_ticks)
return ret;
}
+#define BYTE_RUN_BUF_LEN 32
+
+static int
+node_byte_runs (hive_h *h, void *writer_v, hive_node_h node)
+{
+ xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ char buf[1+BYTE_RUN_BUF_LEN];
+ errno = 0;
+ size_t node_struct_length = hivex_node_struct_length (h, node);
+ if (errno) {
+ if (errno == EINVAL) {
+ fprintf (stderr, "node_byte_runs: Invoked on what does not seem to be a node (%zu).\n", node);
+ }
+ return -1;
+ }
+ /* A node has one byte run. */
+ XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_runs"));
+ XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_run"));
+ memset (buf, 0, 1+BYTE_RUN_BUF_LEN);
+ snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%zu", node);
+ XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "file_offset", BAD_CAST buf));
+ snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%zu", node_struct_length);
+ XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "len", BAD_CAST buf));
+ XML_CHECK (xmlTextWriterEndElement, (writer));
+ XML_CHECK (xmlTextWriterEndElement, (writer));
+ return 0;
+}
+
static int
node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name)
{
int64_t last_modified;
char *timebuf;
+ int ret = 0;
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "node"));
@@ -235,7 +264,8 @@ node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name)
}
}
- return 0;
+ ret = node_byte_runs (h, writer_v, node);
+ return ret;
}
static int
@@ -267,11 +297,53 @@ end_value (xmlTextWriterPtr writer)
}
static int
+value_byte_runs (hive_h *h, void *writer_v, hive_value_h value) {
+ xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ char buf[1+BYTE_RUN_BUF_LEN];
+ size_t value_data_cell_length;
+ errno = 0;
+ size_t value_data_structure_length = hivex_value_struct_length (h, value);
+ if (errno != 0) {
+ if (errno == EINVAL) {
+ fprintf (stderr, "value_byte_runs: Invoked on what does not seem to be a value (%zu).\n", value);
+ }
+ return -1;
+ }
+ hive_value_h value_data_cell_offset = hivex_value_data_cell_offset (h, value, &value_data_cell_length);
+ if (errno != 0)
+ return -1;
+
+ XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_runs"));
+ memset (buf, 0, 1+BYTE_RUN_BUF_LEN);
+
+ /* Write first byte run for data structure */
+ XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_run"));
+ snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%zu", value);
+ XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "file_offset", BAD_CAST buf));
+ snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%zu", value_data_structure_length);
+ XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "len", BAD_CAST buf));
+ XML_CHECK (xmlTextWriterEndElement, (writer));
+
+ /* Write second byte run for longer values */
+ if (value_data_cell_length > 4) {
+ XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "byte_run"));
+ snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%zu", value_data_cell_offset);
+ XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "file_offset", BAD_CAST buf));
+ snprintf (buf, 1+BYTE_RUN_BUF_LEN, "%zu", value_data_cell_length);
+ XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "len", BAD_CAST buf));
+ XML_CHECK (xmlTextWriterEndElement, (writer));
+ }
+ XML_CHECK (xmlTextWriterEndElement, (writer));
+ return 0;
+}
+
+static int
value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
hive_type t, size_t len, const char *key, const char *str)
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
const char *type;
+ int ret = 0;
switch (t) {
case hive_t_string: type = "string"; break;
@@ -297,8 +369,9 @@ value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST str));
XML_CHECK (xmlTextWriterEndAttribute, (writer));
+ ret = value_byte_runs (h, writer_v, value);
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -307,6 +380,7 @@ value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node,
const char *key, char **argv)
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ int ret = 0;
start_value (writer, key, "string-list", NULL);
size_t i;
@@ -316,8 +390,9 @@ value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node,
XML_CHECK (xmlTextWriterEndElement, (writer));
}
+ ret = value_byte_runs (h, writer_v, value);
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -328,6 +403,7 @@ value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node,
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
const char *type;
+ int ret = 0;
switch (t) {
case hive_t_string: type = "bad-string"; break;
@@ -353,9 +429,10 @@ value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node,
XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
XML_CHECK (xmlTextWriterWriteBase64, (writer, str, 0, len));
XML_CHECK (xmlTextWriterEndAttribute, (writer));
+ ret = value_byte_runs (h, writer_v, value);
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -363,10 +440,12 @@ value_dword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
hive_type t, size_t len, const char *key, int32_t v)
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ int ret = 0;
start_value (writer, key, "int32", NULL);
XML_CHECK (xmlTextWriterWriteFormatAttribute, (writer, BAD_CAST "value", "%" PRIi32, v));
+ ret = value_byte_runs (h, writer_v, value);
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -374,10 +453,12 @@ value_qword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
hive_type t, size_t len, const char *key, int64_t v)
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ int ret = 0;
start_value (writer, key, "int64", NULL);
XML_CHECK (xmlTextWriterWriteFormatAttribute, (writer, BAD_CAST "value", "%" PRIi64, v));
+ ret = value_byte_runs (h, writer_v, value);
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -385,12 +466,14 @@ value_binary (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
hive_type t, size_t len, const char *key, const char *v)
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ int ret = 0;
start_value (writer, key, "binary", "base64");
XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
XML_CHECK (xmlTextWriterEndAttribute, (writer));
+ ret = value_byte_runs (h, writer_v, value);
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -398,14 +481,16 @@ value_none (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
hive_type t, size_t len, const char *key, const char *v)
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
+ int ret = 0;
start_value (writer, key, "none", "base64");
if (len > 0) {
XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
XML_CHECK (xmlTextWriterEndAttribute, (writer));
+ ret = value_byte_runs (h, writer_v, value);
}
end_value (writer);
- return 0;
+ return ret;
}
static int
@@ -414,6 +499,7 @@ value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
{
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
const char *type;
+ int ret = 0;
switch (t) {
case hive_t_none:
@@ -440,8 +526,9 @@ value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
XML_CHECK (xmlTextWriterEndAttribute, (writer));
+ ret = value_byte_runs (h, writer_v, value);
}
end_value (writer);
- return 0;
+ return ret;
}
--
1.7.4.4
12 years, 4 months
Problem with backporting libguestfs 1.16.5 to squeeze
by Nikita A Menkovich
Hello
I am trying to backport package from debian sid to squeeze.
I backport some needed packages(some dependencies to qemu-kvm, libvirt, etc)
Before building I disable gobject in debian/{control,rules}
--- debian/rules 2012-02-13 22:51:18.000000000 +0400
+++ ../libguestfs-1.16.5_new/debian/rules 2012-02-28 23:53:50.307471412 +0400
@@ -11,7 +11,8 @@
--disable-appliance \
--with-readline \
--disable-haskell \
- --disable-php
+ --disable-php \
+ --disable-gobject
BARE_CONFIG_FLAGS = \
$(DEFAULT_CONFIG_FLAGS) \
@@ -136,4 +138,4 @@
%:
dh $@ \
--without=python-support \
- --with=autotools-dev,ocaml,python2,python3,bash-completion,ruby,gir
+ --with=autotools-dev,ocaml,python2,python3,bash-completion,ruby
When I try to build libguestfs I receive an error(full log attached):
cat: ../podfiles: No such file or directory
make[6]: Entering directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default/po-docs/ja'
make[7]: Entering directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default'
make[7]: Leaving directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default'
/bin/mkdir -p /home/lib/projects/libguestfs-1.16.5/debian/tmp/usr/share/man/ja/man1
/usr/bin/install -c -m 0644 guestfish.1
/home/lib/projects/libguestfs-1.16.5/debian/tmp/usr/share/man/ja/man1
/usr/bin/install: cannot stat `guestfish.1': No such file or directory
make[6]: *** [install-data-hook] Error 1
make[6]: Leaving directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default/po-docs/ja'
make[5]: *** [install-data-am] Error 2
make[5]: Leaving directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default/po-docs/ja'
make[4]: *** [install-am] Error 2
make[4]: Leaving directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default/po-docs/ja'
make[3]: *** [install-recursive] Error 1
make[3]: Leaving directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default/po-docs'
make[2]: *** [install-recursive] Ошибка 1
make[2]: Leaving directory
`/home/lib/projects/libguestfs-1.16.5/debian/build-default'
dh_auto_install: make -j1 install
DESTDIR=/home/lib/projects/libguestfs-1.16.5/debian/tmp returned exit
code 2
make[1]: *** [override_dh_auto_install] Ошибка 29
--
Nikita A Menkovich
http://libc6.org/
JID: menkovich(a)gmail.com
12 years, 5 months
[PATCH (incomplete)] Rewrite virt-sysprep in OCaml.
by Richard W.M. Jones
This patch is incomplete but it illustrates the idea. virt-sysprep is
rewritten as a modular tool in OCaml.
Only the 'utmp' and 'hostname' operations are implemented at the
moment.
Rich.
12 years, 6 months
Re: [Libguestfs] modifying open_guest function (copy_over.c)
by THO HUYNH
It works, but I should delete
if (guestfs_umount_all (destg) == -1)
exit (EXIT_FAILURE);
inmain() function and
/* Clean up. */
if (guestfs_umount_all (srcg) == -1) {
pthread_cancel (threaddata->mainthread);
exit (EXIT_FAILURE);
}
in the start_scrthread() function or it will return an error after the program finish:
libguestfs: error: umount_all: umount: /sys/fs/cgroup/systemd: umount: /sys/fs/cgroup/systemd: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
12 years, 6 months
gobject header files
by Richard W.M. Jones
Matt, I don't know if it worries you or not, but the new scheme does
create rather a lot of header files directly in /usr/include:
/usr/include/guestfs-gobject-optargs-add_domain.h
/usr/include/guestfs-gobject-optargs-add_drive_opts.h
/usr/include/guestfs-gobject-optargs-btrfs_filesystem_resize.h
/usr/include/guestfs-gobject-optargs-compress_device_out.h
/usr/include/guestfs-gobject-optargs-compress_out.h
/usr/include/guestfs-gobject-optargs-copy_device_to_device.h
/usr/include/guestfs-gobject-optargs-copy_device_to_file.h
/usr/include/guestfs-gobject-optargs-copy_file_to_device.h
/usr/include/guestfs-gobject-optargs-copy_file_to_file.h
/usr/include/guestfs-gobject-optargs-e2fsck.h
/usr/include/guestfs-gobject-optargs-inspect_get_icon.h
/usr/include/guestfs-gobject-optargs-md_create.h
/usr/include/guestfs-gobject-optargs-mkfs_opts.h
/usr/include/guestfs-gobject-optargs-mount_9p.h
/usr/include/guestfs-gobject-optargs-mount_local.h
/usr/include/guestfs-gobject-optargs-ntfsclone_out.h
/usr/include/guestfs-gobject-optargs-ntfsfix.h
/usr/include/guestfs-gobject-optargs-ntfsresize_opts.h
/usr/include/guestfs-gobject-optargs-test0.h
/usr/include/guestfs-gobject-optargs-tune2fs.h
/usr/include/guestfs-gobject-optargs-umount_local.h
/usr/include/guestfs-gobject-session.h
/usr/include/guestfs-gobject-struct-application.h
/usr/include/guestfs-gobject-struct-dirent.h
/usr/include/guestfs-gobject-struct-inotify_event.h
/usr/include/guestfs-gobject-struct-int_bool.h
/usr/include/guestfs-gobject-struct-isoinfo.h
/usr/include/guestfs-gobject-struct-lvm_lv.h
/usr/include/guestfs-gobject-struct-lvm_pv.h
/usr/include/guestfs-gobject-struct-lvm_vg.h
/usr/include/guestfs-gobject-struct-mdstat.h
/usr/include/guestfs-gobject-struct-partition.h
/usr/include/guestfs-gobject-struct-stat.h
/usr/include/guestfs-gobject-struct-statvfs.h
/usr/include/guestfs-gobject-struct-version.h
/usr/include/guestfs-gobject-struct-xattr.h
/usr/include/guestfs-gobject-tristate.h
Perhaps we should put these in a subdir and have a single
/usr/include/guestfs-gobject.h (generated, of course) which includes
the others?
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
12 years, 6 months
Re: [Libguestfs] modifying open_guest function (copy_over.c)
by Richard W.M. Jones
[Please keep questions on the mailing list]
On Fri, Mar 30, 2012 at 07:39:41AM -0700, THO HUYNH wrote:
> This is open_guest function that I modified.
> Could you take a look to check if anything wrong :)
> I only modified this function, the rest of the copy_over.c still remain.
>
> Thanks.
>
>
> static int
>
> open_guest (guestfs_h *g, const char *dom, int readonly)
> {
> /* Use libvirt to find the guest disks and add them to the handle. */
> if (guestfs_add_domain (g, dom,
> GUESTFS_ADD_DOMAIN_LIVE, 1,
> -1) == -1)
> return -1;
>
> if (guestfs_launch (g) == -1)
> return -1;
>
> /* Everything ready, no error. */
> return 0;
> }
Seems reasonable. Does it work?
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://et.redhat.com/~rjones/virt-df/
12 years, 6 months
[PATCH v3] New APIs: mount-local, mount-local-run and umount-local using FUSE
by Richard W.M. Jones
This changes the proposed API slightly.
Previously 'mount-local' generating a 'mounted' event when the
filesystem was ready, and from the 'mounted' event you had to
effectively do a fork.
Now, 'mount-local' just initializes the mountpoint and you have to
call 'mount-local-run' to enter the FUSE main loop. Between these
calls you can do a fork or whatever other work is needed.
Rich.
12 years, 6 months
[PATCH 01/16] generator: Fix unescaped '<' and '>' in api descriptions
by Matthew Booth
---
generator/generator_actions.ml | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 68a7bf6..fcf363f 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -4664,7 +4664,7 @@ This creates an ext2/3/4 filesystem on C<device> with
an external journal on C<journal>. It is equivalent
to the command:
- mke2fs -t fstype -b blocksize -J device=<journal> <device>
+ mke2fs -t fstype -b blocksize -J device=E<lt>journalE<gt> E<lt>deviceE<gt>
See also C<guestfs_mke2journal>.");
@@ -5330,7 +5330,7 @@ For example, in guestfish you could use the following command
to examine the boot script (usually called C</init>)
contained in a Linux initrd or initramfs image:
- initrd-cat /boot/initrd-<version>.img init
+ initrd-cat /boot/initrd-E<lt>versionE<gt>.img init
See also C<guestfs_initrd_list>.");
@@ -6560,8 +6560,9 @@ List all Linux md devices.");
[],
"obtain metadata for an MD device",
"\
-This command exposes the output of 'mdadm -DY <md>'. The following fields are
-usually present in the returned hash. Other fields may also be present.
+This command exposes the output of 'mdadm -DY E<lt>mdE<gt>'. The following
+fields are usually present in the returned hash. Other fields may also be
+present.
=over
--
1.7.7.6
12 years, 6 months