[PATCH] hivex: Fix Ruby bindings for 1.9; let the user explicitly choose ruby, rake
by Hilko Bengen
---
configure.ac | 15 +++++++++++++--
generator/generator.ml | 12 ++++++++++--
ruby/Makefile.am | 11 ++++++-----
ruby/Rakefile.in | 2 +-
ruby/run-ruby-tests | 4 ++--
5 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/configure.ac b/configure.ac
index 8651c7b..33c09db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -312,8 +312,19 @@ AM_CONDITIONAL([HAVE_PYTHON],
[test "x$PYTHON" != "xno" && test "x$PYTHON_INCLUDEDIR" != "x" && test "x$PYTHON_INSTALLDIR" != "x"])
dnl Check for Ruby and rake (optional, for Ruby bindings).
-AC_CHECK_LIB([ruby],[ruby_init],[HAVE_LIBRUBY=1],[HAVE_LIBRUBY=0])
-AC_CHECK_PROG([RAKE],[rake],[rake],[no])
+AC_ARG_ENABLE([ruby],
+ AS_HELP_STRING([--disable-ruby], [Disable Ruby language bindings]),
+ [],
+ [enable_ruby=yes])
+AS_IF([test "x$enable_ruby" != "xno"],
+ [
+ AC_CHECK_PROG([RUBY],[ruby],[ruby],[no])
+ AC_CHECK_PROG([RAKE],[rake],[rake],[no])
+ AC_CHECK_LIB([ruby],[ruby_init],[HAVE_LIBRUBY=1],[HAVE_LIBRUBY=0])
+ AC_SUBST(RAKE)
+ ])
+AM_CONDITIONAL([HAVE_RUBY],
+ [test "x$RAKE" != "xno" && test -n "$HAVE_LIBRUBY"])
AM_CONDITIONAL([HAVE_RUBY],
[test "x$RAKE" != "xno" && test -n "$HAVE_LIBRUBY"])
diff --git a/generator/generator.ml b/generator/generator.ml
index 065c25d..dd13d6a 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -3265,6 +3265,14 @@ and generate_ruby_c () =
#define RARRAY_LEN(r) (RARRAY((r))->len)
#endif
+#ifndef RSTRING_LEN
+#define RSTRING_LEN(r) (RSTRING((r))->len)
+#endif
+
+#ifndef RSTRING_PTR
+#define RSTRING_PTR(r) (RSTRING((r))->ptr)
+#endif
+
static VALUE m_hivex; /* hivex module */
static VALUE c_hivex; /* hive_h handle */
static VALUE e_Error; /* used for all errors */
@@ -3287,8 +3295,8 @@ get_value (VALUE valv, hive_set_value *val)
val->key = StringValueCStr (key);
val->t = NUM2ULL (type);
- val->len = RSTRING (value)->len;
- val->value = RSTRING (value)->ptr;
+ val->len = RSTRING_LEN (value);
+ val->value = RSTRING_PTR (value);
}
static hive_set_value *
diff --git a/ruby/Makefile.am b/ruby/Makefile.am
index b323d7e..efc2211 100644
--- a/ruby/Makefile.am
+++ b/ruby/Makefile.am
@@ -40,14 +40,15 @@ if HAVE_RUBY
TESTS = run-ruby-tests
TESTS_ENVIRONMENT = \
- LD_LIBRARY_PATH=$(top_builddir)/src/.libs
+ LD_LIBRARY_PATH=$(top_builddir)/src/.libs \
+ RUBY=$(RUBY) RAKE=$(RAKE)
all:
- rake build
- rake rdoc
+ $(RAKE) build
+ $(RAKE) rdoc
-RUBY_SITELIB := $(shell ruby -rrbconfig -e "puts Config::CONFIG['sitelibdir']")
-RUBY_SITEARCH := $(shell ruby -rrbconfig -e "puts Config::CONFIG['sitearchdir']")
+RUBY_SITELIB := $(shell $(RUBY) -rrbconfig -e "puts Config::CONFIG['sitelibdir']")
+RUBY_SITEARCH := $(shell $(RUBY) -rrbconfig -e "puts Config::CONFIG['sitearchdir']")
install:
$(MKDIR_P) $(DESTDIR)$(RUBY_SITELIB)
diff --git a/ruby/Rakefile.in b/ruby/Rakefile.in
index 2587476..4cb2d67 100644
--- a/ruby/Rakefile.in
+++ b/ruby/Rakefile.in
@@ -38,7 +38,7 @@ CLOBBER.include [ "@builddir(a)/config.save", "@builddir(a)/ext/**/mkmf.log",
# Build locally
file MAKEFILE => EXT_CONF do |t|
- unless sh "top_srcdir=$(pwd)/@top_srcdir@; top_builddir=$(pwd)/@top_builddir@; export ARCHFLAGS=\"-arch $(uname -m)\"; mkdir -p @builddir@/ext/hivex; cd @builddir@/ext/hivex; ruby #{EXT_CONF} --with-_hivex-include=$top_srcdir/lib --with-_hivex-lib=$top_builddir/lib/.libs"
+ unless sh "top_srcdir=$(pwd)/@top_srcdir@; top_builddir=$(pwd)/@top_builddir@; export ARCHFLAGS=\"-arch $(uname -m)\"; mkdir -p @builddir@/ext/hivex; cd @builddir@/ext/hivex; @RUBY@ #{EXT_CONF} --with-_hivex-include=$top_srcdir/lib --with-_hivex-lib=$top_builddir/lib/.libs"
$stderr.puts "Failed to run extconf"
break
end
diff --git a/ruby/run-ruby-tests b/ruby/run-ruby-tests
index 1596c87..74afb9f 100755
--- a/ruby/run-ruby-tests
+++ b/ruby/run-ruby-tests
@@ -24,6 +24,6 @@ export LD_LIBRARY_PATH=../lib/.libs
# is bound to fail because they all use a single test image file).
for f in tests/tc_*.rb; do
- echo rake test "$@" TEST="$f"
- rake test "$@" TEST="$f"
+ echo $RAKE test "$@" TEST="$f"
+ $RAKE test "$@" TEST="$f"
done
--
1.7.7.3
12 years, 11 months
guestmount failing to mount a qcow image
by Pádraig Brady
I've been able to mount this image with qemu-nbd on Fedora 15 with:
mkdir pb.test
cd pb.test
wget http://www.pixelbeat.org/guestfs/annoying.qcow2.gz
wget http://www.pixelbeat.org/guestfs/77de68daecd823babbb58edb1c8e14d7106e83bb...
gzip -d *.gz
mkdir -p /var/lib/nova/instances/_base/
mv 77* /var/lib/nova/instances/_base/
modprobe nbd
qemu-nbd -c /dev/nbd1 annoying.qcow2
mkdir t
mount /dev/nbd1 t
ls t
umount t
qemu-nbd -d /dev/nbd1
However guestmount on RHEL6.2 and Fedora 15 does this:
# guestmount --rw -a /tmp/disk -i /tmp/tmplFlBCc
libguestfs: error: mount_options: mount_options_stub: /dev/root: No such file or directory
guestmount: some filesystems could not be mounted (ignored)
# echo $?
0
# ls -lrt /tmp
ls: cannot access /tmp/tmplFlBCc: Input/output error
d?????????? ? ? ? ? ? tmplFlBCc
I've attached the debug output from the above run on RHEL6.2
cheers,
Pádraig.
12 years, 11 months
failure converting Linux ESX guest to KVM hypervisor
by John Kienle
Hi,
I am experiencing a failure running virt-v2v to convert a Linux guest
on an ESX host to a RedHat KVM hypervisor. The output with the failure
follows. Any help/guidance is appreciated.
[root@storage-024 ~]# virt-v2v -ic esx://<ip address>/?no_verify=1 -op
transferimages --bridge br0 dev-03 > /tmp/virt-v2v.output
error from Term::ReadKey::GetTerminalSize(): Unable to get Terminal Size.
The TIOCGWINSZ ioctl didn't work. The COLUMNS and LINES environment
variables didn't work. The resize program didn't work.
at /usr/lib64/perl5/vendor_perl/Term/ReadKey.pm line 362.
guessing terminal width 50
dev-03_dev-03: 100% [==================]D 0h24m34s
libguestfs: trace: add_drive_opts "/local/transferimages/dev-03_dev-03"
"iface:ide"
libguestfs: trace: add_drive_opts = 0
libguestfs: trace: add_drive_ro_with_if "/var/lib/virt-v2v/transfer.iso"
"ide"
libguestfs: trace: add_drive_ro_with_if = 0
libguestfs: trace: set_network true
libguestfs: trace: set_network = 0
libguestfs: trace: launch
Using CPU model "cpu64-rhel6"
libguestfs: trace: launch = 0
libguestfs: trace: set_autosync true
libguestfs: trace: set_autosync = 0
libguestfs: trace: list_devices
libguestfs: trace: list_devices = ["/dev/sda", "/dev/sdb"]
libguestfs: trace: mount_ro "/dev/sda" "/"
libguestfs: trace: mount_ro = -1 (error)
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
libguestfs: trace: mount_ro "/dev/sdb" "/"
libguestfs: trace: mount_ro = 0
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
libguestfs: trace: list_partitions
libguestfs: trace: list_partitions = ["/dev/sda1", "/dev/sda2",
"/dev/sda3"]
libguestfs: trace: pvs
libguestfs: trace: pvs = [""]
libguestfs: trace: available "lvm2"
libguestfs: trace: available = 0
libguestfs: trace: lvs
libguestfs: trace: lvs = [""]
libguestfs: trace: file "/dev/sda1"
libguestfs: trace: file = "Linux rev 1.0 ext3 filesystem data"
libguestfs: trace: get_e2uuid "/dev/sda1"
libguestfs: trace: get_e2uuid = "1a90f551-5635-4d8d-af60-810b82a45cda"
libguestfs: trace: get_e2label "/dev/sda1"
libguestfs: trace: get_e2label = "/boot"
libguestfs: trace: mount_ro "/dev/sda1" "/"
libguestfs: trace: mount_ro = 0
libguestfs: trace: is_file "/grub/menu.lst"
libguestfs: trace: is_file = 0
libguestfs: trace: is_file "/grub/grub.conf"
libguestfs: trace: is_file = 1
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
libguestfs: trace: file "/dev/sda2"
libguestfs: trace: file = "Linux/i386 swap file (new style) 1 (4K pages)
size 1024142 pages Label SWAP-sda2"
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
libguestfs: trace: file "/dev/sda3"
libguestfs: trace: file = "Linux rev 1.0 ext3 filesystem data (large
files)"
libguestfs: trace: get_e2uuid "/dev/sda3"
libguestfs: trace: get_e2uuid = "6c19c312-8cd2-44e7-acea-236758464c81"
libguestfs: trace: get_e2label "/dev/sda3"
libguestfs: trace: get_e2label = "/"
libguestfs: trace: mount_ro "/dev/sda3" "/"
libguestfs: trace: mount_ro = 0
libguestfs: trace: is_file "/grub/menu.lst"
libguestfs: trace: is_file = 0
libguestfs: trace: is_file "/grub/grub.conf"
libguestfs: trace: is_file = 0
libguestfs: trace: is_dir "/etc"
libguestfs: trace: is_dir = 1
libguestfs: trace: is_dir "/bin"
libguestfs: trace: is_dir = 1
libguestfs: trace: is_file "/etc/fstab"
libguestfs: trace: is_file = 1
libguestfs: trace: exists "/etc/redhat-release"
libguestfs: trace: exists = 1
libguestfs: trace: cat "/etc/redhat-release"
libguestfs: trace: cat = "Red Hat Enterprise Linux Server release 5.4
(Tikanga)
"
libguestfs: trace: cat "/etc/fstab"
libguestfs: trace: cat = "LABEL=/ /
ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-sda2 swap swap defaults 0 0
"
libguestfs: trace: is_file "/bin/bash"
libguestfs: trace: is_file = 1
libguestfs: trace: file_architecture "/bin/bash"
libguestfs: trace: file "/bin/bash"
libguestfs: trace: file = "ELF 32-bit LSB executable, Intel 80386, version
1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9,
stripped"
libguestfs: trace: file_architecture = "i386"
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
libguestfs: trace: file "/dev/sdb"
libguestfs: trace: file = "ISO 9660 CD-ROM filesystem data
'__virt-v2v_transfer__ '"
libguestfs: trace: mount_ro "/dev/sdb" "/"
libguestfs: trace: mount_ro = 0
libguestfs: trace: is_file "/grub/menu.lst"
libguestfs: trace: is_file = 0
libguestfs: trace: is_file "/grub/grub.conf"
libguestfs: trace: is_file = 0
libguestfs: trace: is_dir "/etc"
libguestfs: trace: is_dir = 0
libguestfs: trace: is_dir "/etc"
libguestfs: trace: is_dir = 0
libguestfs: trace: is_dir "/etc"
libguestfs: trace: is_dir = 0
libguestfs: trace: is_file "/AUTOEXEC.BAT"
libguestfs: trace: is_file = 0
libguestfs: trace: is_file "/autoexec.bat"
libguestfs: trace: is_file = 0
libguestfs: trace: is_dir "/Program Files"
libguestfs: trace: is_dir = 0
libguestfs: trace: is_dir "/WINDOWS"
libguestfs: trace: is_dir = 0
libguestfs: trace: is_file "/boot.ini"
libguestfs: trace: is_file = 0
libguestfs: trace: is_file "/ntldr"
libguestfs: trace: is_file = 0
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
unknown filesystem label SWAP-sda2
libguestfs: trace: mount_options "" "/dev/sda1" "/"
libguestfs: trace: mount_options = 0
libguestfs: trace: is_dir "/boot"
libguestfs: trace: is_dir = 0
libguestfs: trace: command_lines "rpm -q -a --qf %{name} %{epoch}
%{version} %{release} %{arch}
"
libguestfs: trace: command_lines = NULL (error)
Error running rpm -qa: command_lines: command_lines: rpm: No such file or
directory at /usr/share/perl5/vendor_perl/Sys/VirtV2V/GuestfsHandle.pm line
188.
at /usr/lib64/perl5/vendor_perl/Sys/Guestfs/Lib.pm line 1022
libguestfs: trace: available "augeas"
libguestfs: trace: available = 0
libguestfs: trace: aug_init "/" 16
libguestfs: trace: aug_init = 0
libguestfs: trace: aug_match "/files//etc/grub.conf/title"
libguestfs: trace: aug_match = [""]
libguestfs: trace: aug_get "/files//etc/grub.conf/default"
libguestfs: trace: aug_get = NULL (error)
libguestfs: trace: aug_init "/" 16
libguestfs: trace: aug_init = 0
libguestfs: trace: aug_match "/files/etc/conf.modules/alias"
libguestfs: trace: aug_match = [""]
libguestfs: trace: aug_match "/files/etc/modules.conf/alias"
libguestfs: trace: aug_match = [""]
libguestfs: trace: aug_match "/files/etc/modprobe.conf/alias"
libguestfs: trace: aug_match = [""]
libguestfs: trace: aug_match "/files/etc/modprobe.d/*/alias"
libguestfs: trace: aug_match = [""]
libguestfs: trace: exists "/usr/sbin/load_policy"
libguestfs: trace: exists = 0
libguestfs: trace: aug_close
libguestfs: trace: aug_close = 0
libguestfs: trace: aug_init "/" 1
libguestfs: trace: aug_init = 0
libguestfs: trace: aug_match "/augeas/load/Grub/incl"
libguestfs: trace: aug_match = ["/augeas/load/Grub/incl[1]",
"/augeas/load/Grub/incl[2]"]
libguestfs: trace: aug_get "/augeas/load/Grub/incl[1]"
libguestfs: trace: aug_get = "/etc/grub.conf"
libguestfs: trace: aug_get "/augeas/load/Grub/incl[2]"
libguestfs: trace: aug_get = "/boot/grub/menu.lst"
libguestfs: trace: aug_load
libguestfs: trace: aug_load = 0
libguestfs: trace: exists "/etc/conf.modules"
libguestfs: trace: exists = 0
libguestfs: trace: exists "/etc/modules.conf"
libguestfs: trace: exists = 0
libguestfs: trace: exists "/etc/modprobe.conf"
libguestfs: trace: exists = 0
libguestfs: trace: exists "/etc/modprobe.d"
libguestfs: trace: exists = 0
libguestfs: trace: umount_all
libguestfs: trace: umount_all = 0
libguestfs: trace: sync
libguestfs: trace: sync = 0
libguestfs: trace: kill_subprocess
libguestfs: trace: kill_subprocess = 0
virt-v2v: Unable to find any valid modprobe configuration
Regards,
John Kienle
Emerging Technologies Solutions Development
IBM T.J. Watson Research
12 years, 11 months
[hivex] [PATCH 7/8] ruby: Add unit test for new RLenValue type
by Alex Nelson
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
ruby/tests/tc_120_rlenvalue.rb | 46 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 46 insertions(+), 0 deletions(-)
create mode 100644 ruby/tests/tc_120_rlenvalue.rb
diff --git a/ruby/tests/tc_120_rlenvalue.rb b/ruby/tests/tc_120_rlenvalue.rb
new file mode 100644
index 0000000..ff920af
--- /dev/null
+++ b/ruby/tests/tc_120_rlenvalue.rb
@@ -0,0 +1,46 @@
+# hivex Ruby bindings -*- ruby -*-
+# Copyright (C) 2009-2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Demonstrate value_data_cell_offset by looking at the value data at
+# "\$$$PROTO.HIV\ModerateValueParent\33Bytes", verified to be at file
+# offset 8680 (0x21e8) of the hive rlenvalue_test_hive. The returned
+# length and offset for this value cell should be 37 bytes, position
+# 8712.
+
+require 'test/unit'
+$:.unshift(File::join(File::dirname(__FILE__), "..", "lib"))
+$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "hivex"))
+require 'hivex'
+
+class TestRLenValue < Test::Unit::TestCase
+ def test_RLenValue
+ h = Hivex::open("../images/rlenvalue_test_hive", {})
+ assert_not_nil (h)
+
+ root = h.root ()
+ assert_not_nil (root)
+
+ moderate_value_node = h.node_get_child (root, "ModerateValueParent")
+ assert_not_nil (moderate_value_node)
+
+ moderate_value_value = h.node_get_value (moderate_value_node, "33Bytes")
+
+ r = h.value_data_cell_offset (moderate_value_value)
+ assert_equal (r[:len], 37)
+ assert_equal (r[:off], 8712)
+ end
+end
--
1.7.6.4
12 years, 11 months
[hivex] [PATCH 6/8] python: Add unit test for new RLenValue type
by Alex Nelson
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
python/t/120-rlenvalue.py | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
create mode 100644 python/t/120-rlenvalue.py
diff --git a/python/t/120-rlenvalue.py b/python/t/120-rlenvalue.py
new file mode 100644
index 0000000..ebc48f5
--- /dev/null
+++ b/python/t/120-rlenvalue.py
@@ -0,0 +1,42 @@
+# hivex Python bindings
+# Copyright (C) 2010 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Demonstrate value_data_cell_offset by looking at the value data at
+# "\$$$PROTO.HIV\ModerateValueParent\33Bytes", verified to be at file
+# offset 8680 (0x21e8) of the hive rlenvalue_test_hive. The returned
+# length and offset for this value cell should be 37 bytes, position
+# 8712.
+
+import os
+import hivex
+
+srcdir = os.environ["srcdir"]
+if not srcdir:
+ srcdir = "."
+
+h = hivex.Hivex ("%s/../images/rlenvalue_test_hive" % srcdir)
+assert h
+
+root = h.root ()
+
+moderate_value_node = h.node_get_child (root, "ModerateValueParent")
+
+moderate_value_value = h.node_get_value (moderate_value_node, "33Bytes")
+
+r = h.value_data_cell_offset (moderate_value_value)
+assert r[0] == 37L
+assert r[1] == 8712L
--
1.7.6.4
12 years, 11 months
[hivex] [PATCH 5/8] perl: Add unit test for new RLenValue type
by Alex Nelson
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
perl/t/120-rlenvalue.t | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 46 insertions(+), 0 deletions(-)
create mode 100644 perl/t/120-rlenvalue.t
diff --git a/perl/t/120-rlenvalue.t b/perl/t/120-rlenvalue.t
new file mode 100644
index 0000000..70e9060
--- /dev/null
+++ b/perl/t/120-rlenvalue.t
@@ -0,0 +1,46 @@
+# hivex Perl bindings -*- perl -*-
+# Copyright (C) 2010 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Demonstrate value_data_cell_offset by looking at the value data at
+# "\$$$PROTO.HIV\ModerateValueParent\33Bytes", verified to be at file
+# offset 8680 (0x21e8) of the hive rlenvalue_test_hive. The returned
+# length and offset for this value cell should be 37 bytes, position
+# 8712.
+
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+use Win::Hivex;
+
+my $srcdir = $ENV{srcdir} || ".";
+
+my $h = Win::Hivex->open ("$srcdir/../images/rlenvalue_test_hive");
+ok ($h);
+
+my $root = $h->root ();
+ok ($root);
+
+my $moderate_value_node = $h->node_get_child ($root, "ModerateValueParent");
+
+my $moderate_value_value = $h->node_get_value ($moderate_value_node, "33Bytes");
+
+my ($off, $len) = $h->value_data_cell_offset ($moderate_value_value);
+ok ($off == 37);
+ok ($len == 8712);
+
+ok (1);
--
1.7.6.4
12 years, 11 months
[hivex] [PATCH 4/8] ocaml: Add unit test for new RLenValue type
by Alex Nelson
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
.gitignore | 1 +
ocaml/Makefile.am | 1 +
ocaml/t/hivex_120_rlenvalue.ml | 43 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 0 deletions(-)
create mode 100644 ocaml/t/hivex_120_rlenvalue.ml
diff --git a/.gitignore b/.gitignore
index 820130e..13351e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,7 @@ ocaml/t/hivex_010_open
ocaml/t/hivex_020_root
ocaml/t/hivex_100_errors
ocaml/t/hivex_110_gc_handle
+ocaml/t/hivex_120_rlenvalue
ocaml/t/hivex_200_write
ocaml/t/hivex_300_fold
perl/blib
diff --git a/ocaml/Makefile.am b/ocaml/Makefile.am
index ca4c111..eb49431 100644
--- a/ocaml/Makefile.am
+++ b/ocaml/Makefile.am
@@ -59,6 +59,7 @@ TESTS = \
t/hivex_020_root \
t/hivex_100_errors \
t/hivex_110_gc_handle \
+ t/hivex_120_rlenvalue \
t/hivex_200_write \
t/hivex_300_fold
noinst_DATA += $(TESTS)
diff --git a/ocaml/t/hivex_120_rlenvalue.ml b/ocaml/t/hivex_120_rlenvalue.ml
new file mode 100644
index 0000000..63c4cb2
--- /dev/null
+++ b/ocaml/t/hivex_120_rlenvalue.ml
@@ -0,0 +1,43 @@
+(* hivex OCaml bindings
+ * Copyright (C) 2009-2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
+
+(* Demonstrate value_data_cell_offset by looking at the value data at
+ * "\$$$PROTO.HIV\ModerateValueParent\33Bytes", verified to be at file
+ * offset 8680 (0x21e8) of the hive rlenvalue_test_hive. The returned
+ * length and offset for this value cell should be 37 bytes, position
+ * 8712.
+ *)
+
+open Unix
+open Printf
+let (//) = Filename.concat
+
+let () =
+ let h = Hivex.open_file "../images/rlenvalue_test_hive" [] in
+ let root = Hivex.root h in
+ let moderate_value_node = Hivex.node_get_child h root "ModerateValueParent" in
+ let moderate_value_value = Hivex.node_get_value h moderate_value_node "33Bytes" in
+ let (data_len, data_off) = Hivex.value_data_cell_offset h moderate_value_value in
+ assert ( (data_off == (Obj.magic 8712:Hivex.value)) && (data_len == 37) );
+
+ Hivex.close h;
+
+ (* Gc.compact is a good way to ensure we don't have
+ * heap corruption or double-freeing.
+ *)
+ Gc.compact ()
--
1.7.6.4
12 years, 11 months
[hivex] [PATCH 3/8] hivex: Add offset-&-length function for long value data
by Alex Nelson
This patch adds value_data_cell_offset to the hivex ABI, to report the
hive space used for long (>4 bytes) value data.
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
generator/generator.ml | 12 +++++++++
lib/hivex.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/generator/generator.ml b/generator/generator.ml
index 85d1863..f8d9c9b 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -273,6 +273,18 @@ Return the length of the node data structure.";
"\
Return the length of the value data structure.";
+ "value_data_cell_offset", (RLenValue, [AHive; AValue "val"]),
+ "return the offset and length of a value data cell",
+ "\
+Return the offset and length of the value's data cell, not value cell.
+E.g. if the value data were \"foobar\" then the cell length would be 10,
+and the offset would be to a value data cell, which houses the data
+prefixed with 4 bytes describing the size. If the data length is not
+greater than 4, then 0 is returned as offset and length, as the data
+are inline in the value.
+
+Returns 0 and sets errno on error.";
+
"value_value", (RLenTypeVal, [AHive; AValue "val"]),
"return data length, data type and data of a value",
"\
diff --git a/lib/hivex.c b/lib/hivex.c
index bf1a860..df313bf 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -1257,6 +1257,66 @@ hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
return 0;
}
+hive_value_h
+hivex_value_data_cell_offset (hive_h *h, hive_value_h value, size_t *len)
+{
+ if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_data_cell_offset: value=0x%zx\n", value);
+ struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
+
+ size_t data_len;
+ int is_inline;
+
+ data_len = le32toh (vk->data_len);
+ is_inline = !!(data_len & 0x80000000);
+ data_len &= 0x7fffffff;
+
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_data_cell_offset: is_inline=%d\n", is_inline);
+
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_data_cell_offset: data_len=%zx\n", data_len);
+
+ if (is_inline && data_len > 4) {
+ errno = ENOTSUP;
+ return 0;
+ }
+
+ if (is_inline) {
+ /* There is no other location for the value data. */
+ if (len)
+ *len = 0;
+ return 0;
+ } else {
+ if (len)
+ *len = data_len + 4; /* Include 4 header length bytes */
+ }
+
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_data_cell_offset: Proceeding with indirect data.\n");
+
+ size_t data_offset = le32toh (vk->data_offset);
+ data_offset += 0x1000; /* Add 0x1000 because everything's off by 4KiB */
+ if (!IS_VALID_BLOCK (h, data_offset)) {
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_data_cell_offset: returning EFAULT because data "
+ "offset is not a valid block (0x%zx)\n",
+ data_offset);
+ errno = EFAULT;
+ return 0;
+ }
+
+ if (h->msglvl >= 2)
+ fprintf (stderr, "hivex_value_data_cell_offset: data_offset=%zx\n", data_offset);
+
+ return data_offset;
+}
+
char *
hivex_value_value (hive_h *h, hive_value_h value,
hive_type *t_rtn, size_t *len_rtn)
--
1.7.6.4
12 years, 11 months
[hivex] [PATCH 2/8] generator: Add new return type to ABI: RLenValue
by Alex Nelson
RLenValue is similar to RLenType, though with one less argument. This
required adding additional conversion functions for several languages'
bindings.
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
generator/generator.ml | 78 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/generator/generator.ml b/generator/generator.ml
index 065c25d..85d1863 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -51,6 +51,7 @@ and ret =
| RNodeList (* Returns hive_node_h* or NULL. *)
| RValue (* Returns hive_value_h or 0. *)
| RValueList (* Returns hive_value_h* or NULL. *)
+ | RLenValue (* Returns offset and length of value. *)
| RString (* Returns char* or NULL. *)
| RStringList (* Returns char** or NULL. *)
| RLenType (* See hivex_value_type. *)
@@ -888,6 +889,7 @@ and generate_c_prototype ?(extern = false) name style =
| RValueList -> pr "hive_value_h *"
| RString -> pr "char *"
| RStringList -> pr "char **"
+ | RLenValue -> pr "hive_value_h "
| RLenType -> pr "int "
| RLenTypeVal -> pr "char *"
| RInt32 -> pr "int32_t "
@@ -909,6 +911,7 @@ and generate_c_prototype ?(extern = false) name style =
) (snd style);
(match fst style with
| RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len"
+ | RLenValue -> pr ", size_t *len"
| _ -> ()
);
pr ");\n"
@@ -1111,6 +1114,10 @@ On error this returns NULL and sets errno.\n\n"
pr "\
Returns 0 on success.
On error this returns -1 and sets errno.\n\n"
+ | RLenValue ->
+ pr "\
+Returns a value handle.
+On error this returns 0 and sets errno.\n\n"
| RLenTypeVal ->
pr "\
The value is returned as an array of bytes (of length C<len>).
@@ -1622,6 +1629,7 @@ and generate_ocaml_prototype ?(is_external = false) name style =
| RString -> pr "string"
| RStringList -> pr "string array"
| RLenType -> pr "hive_type * int"
+ | RLenValue -> pr "int * value"
| RLenTypeVal -> pr "hive_type * string"
| RInt32 -> pr "int32"
| RInt64 -> pr "int64"
@@ -1685,6 +1693,7 @@ static hive_type HiveType_val (value);
static value Val_hive_type (hive_type);
static value copy_int_array (size_t *);
static value copy_type_len (size_t, hive_type);
+static value copy_len_value (size_t, hive_value_h);
static value copy_type_value (const char *, size_t, hive_type);
static void raise_error (const char *) Noreturn;
static void raise_closed (const char *) Noreturn;
@@ -1707,6 +1716,7 @@ static void raise_closed (const char *) Noreturn;
let c_params =
match fst style with
| RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]]
+ | RLenValue -> c_params @ [["&len"]]
| _ -> c_params in
let c_params = List.concat c_params in
@@ -1779,6 +1789,11 @@ static void raise_closed (const char *) Noreturn;
pr " size_t len;\n";
pr " hive_type t;\n";
"-1"
+ | RLenValue ->
+ pr " errno = 0;";
+ pr " hive_value_h r;\n";
+ pr " size_t len;\n";
+ "0 && errno != 0"
| RLenTypeVal ->
pr " char *r;\n";
pr " size_t len;\n";
@@ -1859,6 +1874,7 @@ static void raise_closed (const char *) Noreturn;
pr " for (int i = 0; r[i] != NULL; ++i) free (r[i]);\n";
pr " free (r);\n"
| RLenType -> pr " rv = copy_type_len (len, t);\n"
+ | RLenValue -> pr " rv = copy_len_value (len, r);\n"
| RLenTypeVal ->
pr " rv = copy_type_value (r, len, t);\n";
pr " free (r);\n"
@@ -1981,6 +1997,20 @@ copy_type_len (size_t len, hive_type t)
}
static value
+copy_len_value (size_t len, hive_value_h r)
+{
+ CAMLparam0 ();
+ CAMLlocal2 (v, rv);
+
+ rv = caml_alloc (2, 0);
+ v = Val_int (len);
+ Store_field (rv, 0, v);
+ v = Val_int (r);
+ Store_field (rv, 1, v);
+ CAMLreturn (rv);
+}
+
+static value
copy_type_value (const char *r, size_t len, hive_type t)
{
CAMLparam0 ();
@@ -2170,6 +2200,7 @@ sub open {
| RString
| RStringList
| RLenType
+ | RLenValue
| RLenTypeVal
| RInt32
| RInt64 -> ()
@@ -2244,6 +2275,7 @@ and generate_perl_prototype name style =
| RString -> pr "$string = "
| RStringList -> pr "@strings = "
| RLenType -> pr "($type, $len) = "
+ | RLenValue -> pr "($len, $value) = "
| RLenTypeVal -> pr "($type, $data) = "
| RInt32 -> pr "$int32 = "
| RInt64 -> pr "$int64 = "
@@ -2467,6 +2499,7 @@ DESTROY (h)
| RValueList
| RStringList
| RLenType
+ | RLenValue
| RLenTypeVal -> pr "void\n"
| RInt32 -> pr "SV *\n"
| RInt64 -> pr "SV *\n"
@@ -2639,6 +2672,22 @@ DESTROY (h)
pr " PUSHs (sv_2mortal (newSViv (type)));\n";
pr " PUSHs (sv_2mortal (newSViv (len)));\n";
+ | RLenValue ->
+ pr "PREINIT:\n";
+ pr " hive_value_h r;\n";
+ pr " size_t len;\n";
+ pr " PPCODE:\n";
+ pr " errno = 0;\n";
+ pr " r = hivex_%s (%s, &len);\n"
+ name (String.concat ", " c_params);
+ free_args ();
+ pr " if (r == 0 && errno)\n";
+ pr " croak (\"%%s: \", \"%s\", strerror (errno));\n"
+ name;
+ pr " EXTEND (SP, 2);\n";
+ pr " PUSHs (sv_2mortal (newSViv (len)));\n";
+ pr " PUSHs (sv_2mortal (newSViv (r)));\n";
+
| RLenTypeVal ->
pr "PREINIT:\n";
pr " char *r;\n";
@@ -2886,6 +2935,15 @@ put_len_type (size_t len, hive_type t)
}
static PyObject *
+put_len_val (size_t len, hive_value_h value)
+{
+ PyObject *r = PyTuple_New (2);
+ PyTuple_SetItem (r, 0, PyLong_FromLongLong ((long) len));
+ PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) value));
+ return r;
+}
+
+static PyObject *
put_val_type (char *val, size_t len, hive_type t)
{
PyObject *r = PyTuple_New (2);
@@ -2929,6 +2987,11 @@ put_val_type (char *val, size_t len, hive_type t)
pr " size_t len;\n";
pr " hive_type t;\n";
"-1"
+ | RLenValue ->
+ pr " errno = 0;\n";
+ pr " int r;\n";
+ pr " size_t len;\n";
+ "0 && errno != 0"
| RLenTypeVal ->
pr " char *r;\n";
pr " size_t len;\n";
@@ -2953,6 +3016,7 @@ put_val_type (char *val, size_t len, hive_type t)
let c_params =
match fst style with
| RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"]
+ | RLenValue -> c_params @ ["&len"]
| _ -> c_params in
List.iter (
@@ -3101,6 +3165,8 @@ put_val_type (char *val, size_t len, hive_type t)
pr " free_strings (r);\n"
| RLenType ->
pr " py_r = put_len_type (len, t);\n"
+ | RLenValue ->
+ pr " py_r = put_len_val (len, r);\n"
| RLenTypeVal ->
pr " py_r = put_val_type (r, len, t);\n";
pr " free (r);\n"
@@ -3343,6 +3409,7 @@ get_values (VALUE valuesv, size_t *nr_values)
| RString -> "string"
| RStringList -> "list"
| RLenType -> "hash"
+ | RLenValue -> "integer"
| RLenTypeVal -> "hash"
| RInt32 -> "integer"
| RInt64 -> "integer" in
@@ -3441,6 +3508,11 @@ get_values (VALUE valuesv, size_t *nr_values)
pr " size_t len;\n";
pr " hive_type t;\n";
"-1"
+ | RLenValue ->
+ pr " errno = 0;\n";
+ pr " hive_value_h r;\n";
+ pr " size_t len;\n";
+ "0 && errno != 0"
| RLenTypeVal ->
pr " char *r;\n";
pr " size_t len;\n";
@@ -3465,6 +3537,7 @@ get_values (VALUE valuesv, size_t *nr_values)
let c_params =
match ret with
| RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]]
+ | RLenValue -> c_params @ [["&len"]]
| _ -> c_params in
let c_params = List.concat c_params in
@@ -3546,6 +3619,11 @@ get_values (VALUE valuesv, size_t *nr_values)
pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n";
pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"type\")), INT2NUM (t));\n";
pr " return rv;\n"
+ | RLenValue ->
+ pr " VALUE rv = rb_hash_new ();\n";
+ pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n";
+ pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"off\")), ULL2NUM (r));\n";
+ pr " return rv;\n"
| RLenTypeVal ->
pr " VALUE rv = rb_hash_new ();\n";
pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n";
--
1.7.6.4
12 years, 11 months
[hivex] [PATCH 1/8] Add test hive and generator script
by Alex Nelson
Signed-off-by: Alex Nelson <ajnelson(a)cs.ucsc.edu>
---
images/mkrlenvalue_test_hive.py | 37 +++++++++++++++++++++++++++++++++++++
images/rlenvalue_test_hive | Bin 0 -> 12288 bytes
2 files changed, 37 insertions(+), 0 deletions(-)
create mode 100755 images/mkrlenvalue_test_hive.py
create mode 100644 images/rlenvalue_test_hive
diff --git a/images/mkrlenvalue_test_hive.py b/images/mkrlenvalue_test_hive.py
new file mode 100755
index 0000000..827667e
--- /dev/null
+++ b/images/mkrlenvalue_test_hive.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+import os
+import hivex
+
+srcdir = os.environ.get("srcdir")
+if not srcdir:
+ srcdir = "."
+
+h = hivex.Hivex ("%s/../images/minimal" % srcdir,
+ write = True)
+assert h
+
+root = h.root ()
+assert root
+
+h.node_add_child (root, "ModerateValueParent")
+
+mvp = h.node_get_child (root, "ModerateValueParent")
+assert mvp
+
+moderate_value = "0123456789ABCDEF"
+
+values = [
+ { "key": "3Bytes", "t": 3, "value": moderate_value[:3] },
+ { "key": "16Bytes", "t": 3, "value": moderate_value },
+ { "key": "30Bytes", "t": 3, "value": (moderate_value*2)[:30] },
+ { "key": "31Bytes", "t": 3, "value": (moderate_value*2)[:31] },
+ { "key": "32Bytes", "t": 3, "value": moderate_value*2 },
+ { "key": "33Bytes", "t": 3, "value": (moderate_value*3)[:33] },
+]
+h.node_set_values (mvp, values)
+
+new_moderate_value = h.node_get_value (mvp, "16Bytes")
+
+assert h.value_value (new_moderate_value)[1] == moderate_value
+
+h.commit ("%s/../images/rlenvalue_test_hive" % srcdir)
diff --git a/images/rlenvalue_test_hive b/images/rlenvalue_test_hive
new file mode 100644
index 0000000000000000000000000000000000000000..87cbec5d93f39f2f3821e631b6bc2d41ae885a72
GIT binary patch
literal 12288
zcmeI2zfV(96vw|+q1uSn9|I;vAF<KJn3gKyL@2buM1>e64lGrl(iE#H)#&y{{s0FY
zOc?wl++-w9jEsy74o=26`23#RKKmX*?BD>&_mXq(x%Zy)z4v`Oog13|v!|&PV79fq
z@nPWO7jw}^vu3_$4m<PbF~+}nJit9naBQK88XlwW{O5SdaS~-zFwU4en6+HBeM#VR
zZS?29yqGQ}0wN#+A|L`HAOa#F0wN#+BJke{EIg_;oM^Ty9lZnC%4!&fjrvu1S4!{g
zZNS#n((ShZ^Ou>&kkEV^gU)!_7Iw7boab`6nfueT)7PeM&)N3+uP|Jy0|9-rL$vce
zC50pJ?7<=HP6W=ny|2h{1O{=Aktqx2Q-#NF$o$M8I|P5N?-GA$k9fDv_%WPJ=zHDx
zY+T>1^L8%2eb>Izc8iSNnAeZ5?WvoHJ#2|P&q(S3QztA+O$0<h1VlgtL_h>YKm<fU
z1VlgtdL!WKf2;jt^?y8bg*APn?j`DfFBV`mzqNj@txzN2X!9t<%G9CG<P68VFP`|#
zYRjLiF23?-s!hMqa=YJ{v$&9gM~(IGm1A3+f1<xh%bo%r(pG8PG;6m1y50{K%R#;{
zY@_@CgktG!%U_E2)9$l=P$SwejI;x`na{l9^&2BMM{kXnCML_3u5KC^ILY&@D6g1r
z=WXtim(($p?)ew#zlrM<detc>bUe=1;yS}U>m<I*ev6}gp!oA$9bo_du5u;M+>HTt
aY9b&4A|L`HAOa#F0wN#+A|L_>j=*muug%l|
literal 0
HcmV?d00001
--
1.7.6.4
12 years, 11 months