diff --git a/trunk/hivex/.gitmodules b/trunk/hivex/.gitmodules deleted file mode 100644 index 579ec64..0000000 --- a/trunk/hivex/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule ".gnulib"] - path = .gnulib - url = git://git.sv.gnu.org/gnulib.git diff --git a/trunk/hivex/.tx/config b/trunk/hivex/.tx/config deleted file mode 100644 index 705e760..0000000 --- a/trunk/hivex/.tx/config +++ /dev/null @@ -1,7 +0,0 @@ -[main] -host = https://www.transifex.net - -[hivex.hivexpot] -file_filter = po/.po -source_file = po/hivex.pot -source_lang = en diff --git a/trunk/hivex/.x-sc_prohibit_magic_number_exit b/trunk/hivex/.x-sc_prohibit_magic_number_exit deleted file mode 100644 index 5a3f685..0000000 --- a/trunk/hivex/.x-sc_prohibit_magic_number_exit +++ /dev/null @@ -1,2 +0,0 @@ -^.*\.java$ -^.*\.pl$ diff --git a/trunk/hivex/LICENSE b/trunk/hivex/LICENSE deleted file mode 100644 index 38dec6d..0000000 --- a/trunk/hivex/LICENSE +++ /dev/null @@ -1,506 +0,0 @@ -This is the license for the hivex library. - ----------------------------------------------------------------------- - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/trunk/hivex/Makefile.am b/trunk/hivex/Makefile.am deleted file mode 100644 index 80ea8cb..0000000 --- a/trunk/hivex/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -# hivex -# 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. - -ACLOCAL_AMFLAGS = -I m4 - -# Work around broken libtool. -export to_tool_file_cmd=func_convert_file_noop - -SUBDIRS = gnulib/lib generator lib images gnulib/tests xml po - -if HAVE_HIVEXSH -SUBDIRS += sh -endif - -if HAVE_OCAML -SUBDIRS += ocaml -endif - -if HAVE_PERL -SUBDIRS += perl regedit -endif - -if HAVE_PYTHON -SUBDIRS += python -endif - -if HAVE_RUBY -SUBDIRS += ruby -endif - -EXTRA_DIST = hivex.pc hivex.pc.in LICENSE README tx-pull.sh - -# Generate the ChangeLog automatically from the gitlog. -dist-hook: - $(top_srcdir)/build-aux/gitlog-to-changelog > ChangeLog - cp ChangeLog $(distdir)/ChangeLog - -# Pkgconfig. -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = hivex.pc - -# Maintainer website update. -HTMLFILES = \ - html/hivex.3.html \ - html/hivexget.1.html \ - html/hivexml.1.html \ - html/hivexregedit.1.html \ - html/hivexsh.1.html - -WEBSITEDIR = $(HOME)/d/redhat/websites/libguestfs - -website: $(HTMLFILES) - cp $(HTMLFILES) $(WEBSITEDIR) - -CLEANFILES = $(HTMLFILES) pod2*.tmp diff --git a/trunk/hivex/README b/trunk/hivex/README deleted file mode 100644 index ae3d159..0000000 --- a/trunk/hivex/README +++ /dev/null @@ -1,106 +0,0 @@ -hivex - by Richard W.M. Jones, rjones@redhat.com -Copyright (C) 2009-2010 Red Hat Inc. ----------------------------------------------------------------------- - -This is a self-contained library for reading and writing Windows -Registry "hive" binary files. - -Unlike many other tools in this area, it doesn't use the textual .REG -format for output, because parsing that is as much trouble as parsing -the original binary format. Instead it makes the file available -through a C API, or there is a separate program to export the hive as -XML. - -This library was derived from several sources: - - . NTREG registry reader/writer library by Petter Nordahl-Hagen - (LGPL v2.1 licensed library and program) - . http://pogostick.net/~pnh/ntpasswd/WinReg.txt - . dumphive (a BSD-licensed Pascal program by Markus Stephany) - . http://www.sentinelchicken.com/data/TheWindowsNTRegistryFileFormat.pdf - . editreg program from Samba - this program was removed in later - versions of Samba, so you have to go back in the source repository - to find it (GPLv2+) - . http://amnesia.gtisc.gatech.edu/~moyix/suzibandit.ltd.uk/MSc/ - . reverse engineering the format (see lib/tools/visualizer.ml) - -Like NTREG, this library only attempts to read Windows NT registry -files (ie. not Windows 3.1 or Windows 95/98/ME). See the link above -for documentation on the older formats if you wish to read them. - -Unlike NTREG, this code is much more careful about handling error -cases, corrupt and malicious registry files, and endianness. - -License -------- - -The license for this library is LGPL v2.1, but not later versions. -For full details, see the file LICENSE in this directory. - -Dependencies ------------- - -To just build the library, the dependencies are quite minimal. You -only need the following: - -- An ISO C compiler. - -- Perl tools 'pod2man' and 'pod2text'. - -These dependencies are needed for the tools: - -- Readline library (optional, to add command-line editing to hivexsh). - -- libxml2 (optional, for hivexml). - -If you want to make the generated files or change the API, then you -will need the OCaml interpreter (/usr/bin/ocaml). - -To build the language bindings, you will need various extra packages. -See the configure output for more details. - -Directories and tools ---------------------- - -generator/ - - Generator used to write a lot of boilerplate code for - header files, documentation, language bindings etc. - The API for hivex is specified in the generator. - -images/ - - Test hive files. See images/README. - -lib/ - - The C library. - -ocaml/ - - OCaml bindings and tests. The bindings are generated by - 'generator/generator.ml'. - -perl/ - - Perl bindings and tests. The bindings are generated by - 'generator/generator.ml'. - -python/ - - NOTE: Python bindings are not yet written. Your patches - are welcome (please modify generator/generator.ml to - add them). - -regedit/ - Regedit-like registry merging tool. - -sh/ - - Interactive shell. This also contains the old 'hivexget' - tool (originally written in C, now replaced by a hivexsh - shell script). - -xml/ - - hivexml program which converts hive files to XML. diff --git a/trunk/hivex/TODO b/trunk/hivex/TODO deleted file mode 100644 index e2c688c..0000000 --- a/trunk/hivex/TODO +++ /dev/null @@ -1,2 +0,0 @@ -Add a command to hivexsh to allow updating a single value -(ie. implement a shell equivalent of hivex_node_set_value). diff --git a/trunk/hivex/autogen.sh b/trunk/hivex/autogen.sh deleted file mode 100755 index 4017d32..0000000 --- a/trunk/hivex/autogen.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# hivex -# 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. -# -# Rebuild the autotools environment. - -set -e -set -v - -# Ensure that whenever we pull in a gnulib update or otherwise change to a -# different version (i.e., when switching branches), we also rerun ./bootstrap. -curr_status=.git-module-status -t=$(git submodule status) -if test "$t" = "$(cat $curr_status 2>/dev/null)"; then - : # good, it's up to date -else - echo running bootstrap... - ./bootstrap && echo "$t" > $curr_status -fi - -CONFIGUREDIR=. - -# Run configure in BUILDDIR if it's set -if [ ! -z "$BUILDDIR" ]; then - mkdir -p $BUILDDIR - cd $BUILDDIR - - CONFIGUREDIR=.. -fi - -# Rerun the generator (requires OCaml interpreter). This is *not* for -# anything that is required at configure-time when configure is run -# from a distribution tarball. From those, nothing ocaml-related is -# required. -mkdir -p perl/lib/Win -./generator/generator.ml - -# If no arguments were specified and configure has run before, use the previous -# arguments -if test $# = 0 && test -x ./config.status; then - ./config.status --recheck -else - $CONFIGUREDIR/configure "$@" -fi diff --git a/trunk/hivex/bootstrap b/trunk/hivex/bootstrap deleted file mode 100755 index b2960c1..0000000 --- a/trunk/hivex/bootstrap +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/sh - -usage() { - echo >&2 "\ -Usage: $0 [OPTION]... -Bootstrap this package from the checked-out sources. -" -} - -for option -do - case $option in - --help) - usage - exit;; - *) - echo >&2 "$0: $option: unknown option" - exit 1;; - esac -done - -# Get gnulib files. - -echo "$0: getting gnulib files..." -git submodule init || exit $? -git submodule update || exit $? -GNULIB_SRCDIR=.gnulib - -ls po/*.po 2>/dev/null | sed 's|.*/||; s|\.po$||' > po/LINGUAS - -# Run autopoint, to get po/Makevars.template: -# Also, released autopoint has the tendency to install macros that have -# been obsoleted in current gnulib, so run this before gnulib-tool. -autopoint --force - -# Autoreconf runs aclocal before libtoolize, which causes spurious -# warnings if the initial aclocal is confused by the libtoolized -# (or worse out-of-date) macro directory. -libtoolize --copy --install || glibtoolize --copy --install - -# Create gettext configuration. -echo "$0: Creating po/Makevars from po/Makevars.template ..." -rm -f po/Makevars -sed ' - /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/ - /^MSGID_BUGS_ADDRESS *=/s/=.*/= '"$MSGID_BUGS_ADDRESS"'/ - /^XGETTEXT_OPTIONS *=/{ - s/$/ \\/ - a\ - '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+} - } -' po/Makevars.template >po/Makevars - -gnulib_tool=$GNULIB_SRCDIR/gnulib-tool -<$gnulib_tool || exit - -modules=' -byteswap -c-ctype -fcntl -full-read -full-write -gitlog-to-changelog -gnu-make -gnumakefile -ignore-value -inttypes -maintainer-makefile -manywarnings -progname -strndup -vasprintf -vc-list-files -warnings -xstrtol -xstrtoll -' - -$gnulib_tool \ - --libtool \ - --avoid=dummy \ - --with-tests \ - --m4-base=m4 \ - --source-base=gnulib/lib \ - --tests-base=gnulib/tests \ - --import $modules - -# Disable autopoint and libtoolize, since they were already done above. -AUTOPOINT=true LIBTOOLIZE=true autoreconf --verbose --install diff --git a/trunk/hivex/cfg.mk b/trunk/hivex/cfg.mk deleted file mode 100644 index 528f722..0000000 --- a/trunk/hivex/cfg.mk +++ /dev/null @@ -1,24 +0,0 @@ -# Tests not to run as part of "make distcheck". -local-checks-to-skip = \ - sc_prohibit_strcmp \ - sc_two_space_separator_in_usage \ - sc_prohibit_magic_number_exit \ - sc_file_system \ - sc_GPL_version \ - sc_bindtextdomain \ - sc_makefile_path_separator_check \ - sc_program_name - -gnulib_dir = .gnulib - -exclude_file_name_regexp--sc_trailing_blank = \ - ^sh/hivexsh\.pod$$ - -_img_regexp = ^images/(minimal|rlenvalue_test_hive)$$ -exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = $(_img_regexp) -exclude_file_name_regexp--sc_trailing_blank = $(_img_regexp) - -exclude_file_name_regexp--sc_useless_cpp_parens = \ - ^lib/gettext\.h$$ - -config_h_header ?= ["<](hivex|config)\.h[>"] diff --git a/trunk/hivex/configure.ac b/trunk/hivex/configure.ac deleted file mode 100644 index ce42785..0000000 --- a/trunk/hivex/configure.ac +++ /dev/null @@ -1,597 +0,0 @@ -# hivex -# 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. - -# major/minor/release must be numbers -m4_define([hivex_major], [1]) -m4_define([hivex_minor], [3]) -m4_define([hivex_release], [7]) -# extra can be any string -m4_define([hivex_extra], []) - -AC_INIT([hivex],hivex_major.hivex_minor.hivex_release[]hivex_extra) -AC_CONFIG_AUX_DIR([build-aux]) -AM_INIT_AUTOMAKE([foreign]) - -m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])]) -AM_SILENT_RULES([yes]) # make --enable-silent-rules the default. - -AC_CONFIG_MACRO_DIR([m4]) - -dnl Split up the version string. -AC_DEFINE([PACKAGE_VERSION_MAJOR],[hivex_major],[Major version number]) -AC_DEFINE([PACKAGE_VERSION_MINOR],[hivex_minor],[Minor version number]) -AC_DEFINE([PACKAGE_VERSION_RELEASE],[hivex_release],[Release number]) -AC_DEFINE([PACKAGE_VERSION_EXTRA],["hivex_extra"],[Extra version string]) - -gl_EARLY -gl_INIT - -AM_PROG_LIBTOOL - -dnl Define $(SED). -m4_ifdef([AC_PROG_SED],[ - AC_PROG_SED -],[ - dnl ... else hope for the best - AC_SUBST([SED], "sed") -]) - -dnl Check for basic C environment. -AC_PROG_CC_STDC -AC_PROG_INSTALL -AC_PROG_CPP - -AC_ARG_ENABLE([gcc-warnings], - [AS_HELP_STRING([--enable-gcc-warnings], - [turn on lots of GCC warnings (for developers)])], - [case $enableval in - yes|no) ;; - *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;; - esac - gl_gcc_warnings=$enableval], - [gl_gcc_warnings=no] -) - -if test "$gl_gcc_warnings" = yes; then - gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) - AC_SUBST([WERROR_CFLAGS]) - - nw= - # This, $nw, is the list of warnings we disable. - nw="$nw -Wdeclaration-after-statement" # too useful to forbid - nw="$nw -Waggregate-return" # anachronistic - nw="$nw -Wc++-compat" # We don't care about C++ compilers - nw="$nw -Wundef" # Warns on '#if GNULIB_FOO' etc in gnulib - nw="$nw -Wtraditional" # Warns on #elif which we use often - nw="$nw -Wcast-qual" # Too many warnings for now - nw="$nw -Wconversion" # Too many warnings for now - nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings - nw="$nw -Wsign-conversion" # Too many warnings for now - nw="$nw -Wtraditional-conversion" # Too many warnings for now - nw="$nw -Wunreachable-code" # Too many warnings for now - nw="$nw -Wpadded" # Our structs are not padded - nw="$nw -Wredundant-decls" # openat.h declares e.g., mkdirat - nw="$nw -Wlogical-op" # any use of fwrite provokes this - nw="$nw -Wvla" # two warnings in mount.c - # things I might fix soon: - nw="$nw -Wmissing-format-attribute" # daemon.h's asprintf_nowarn - nw="$nw -Winline" # daemon.h's asprintf_nowarn - nw="$nw -Wshadow" # numerous, plus we're not unanimous - # ?? -Wstrict-overflow - nw="$nw -Wunsafe-loop-optimizations" # just a warning that an optimization - # was not possible, safe to ignore - nw="$nw -Wpacked" # Allow attribute((packed)) on structs - nw="$nw -Wlong-long" # Allow long long since it's required - # by xstrtoll. - nw="$nw -Wsuggest-attribute=pure" # Don't suggest pure functions. -# nw="$nw -Wsuggest-attribute=const" # Don't suggest const functions. -# nw="$nw -Wunsuffixed-float-constants" # Don't care about these. - - gl_MANYWARN_ALL_GCC([ws]) - gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw]) - for w in $ws; do - gl_WARN_ADD([$w]) - done - - # Unused parameters are not a bug in C. - gl_WARN_ADD([-Wno-unused-parameter]) - - # Missing field initializers is not a bug in C. - gl_WARN_ADD([-Wno-missing-field-initializers]) - - # In spite of excluding -Wlogical-op above, it is enabled, as of - # gcc 4.5.0 20090517, and it provokes warnings in cat.c, dd.c, truncate.c - gl_WARN_ADD([-Wno-logical-op]) - - gl_WARN_ADD([-fdiagnostics-show-option]) - - AC_SUBST([WARN_CFLAGS]) - - AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.]) - AC_DEFINE([_FORTIFY_SOURCE], [2], - [enable compile-time and run-time bounds-checking, and some warnings]) - AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) -fi - -AC_C_PROTOTYPES -test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant]) - -AM_PROG_CC_C_O - -dnl Work out how to specify the linker script to the linker. -VERSION_SCRIPT_FLAGS=-Wl,--version-script= -`/usr/bin/ld --help 2>&1 | grep -- --version-script >/dev/null` || \ - VERSION_SCRIPT_FLAGS="-Wl,-M -Wl," -AC_SUBST(VERSION_SCRIPT_FLAGS) - -dnl Check support for 64 bit file offsets. -AC_SYS_LARGEFILE - -dnl Check sizeof long. -AC_CHECK_SIZEOF([long]) - -dnl Headers. -AC_CHECK_HEADERS([byteswap.h endian.h libintl.h]) - -dnl Check for mmap -AC_REPLACE_FUNCS([mmap]) - -dnl Functions. -AC_CHECK_FUNCS([bindtextdomain]) - -dnl Check for pod2man and pod2text. -AC_CHECK_PROG([POD2MAN],[pod2man],[pod2man],[no]) -test "x$POD2MAN" = "xno" && - AC_MSG_ERROR([pod2man must be installed]) -AC_CHECK_PROG([POD2TEXT],[pod2text],[pod2text],[no]) -test "x$POD2TEXT" = "xno" && - AC_MSG_ERROR([pod2text must be installed]) - -dnl Readline. -AC_ARG_WITH([readline], - [AS_HELP_STRING([--with-readline], - [support fancy command line editing @<:@default=check@:>@])], - [], - [with_readline=check]) - -LIBREADLINE= -AS_IF([test "x$with_readline" != xno], - [AC_CHECK_LIB([readline], [main], - [AC_SUBST([LIBREADLINE], ["-lreadline"]) - AC_DEFINE([HAVE_LIBREADLINE], [1], - [Define if you have libreadline]) - ], - [if test "x$with_readline" != xcheck; then - AC_MSG_FAILURE( - [--with-readline was given, but test for readline failed]) - fi - ])]) - -dnl For i18n. -AM_GNU_GETTEXT([external]) -AM_GNU_GETTEXT_VERSION([0.17]) -AM_ICONV - -dnl libxml2. -PKG_CHECK_MODULES([LIBXML2], [libxml-2.0]) -AC_SUBST([LIBXML2_CFLAGS]) -AC_SUBST([LIBXML2_LIBS]) - -dnl hivexsh depends on open_memstream, which is absent on OS X. -AC_CHECK_FUNC([open_memstream]) -AM_CONDITIONAL([HAVE_HIVEXSH],[test "x$ac_cv_func_open_memstream" = "xyes"]) - -dnl Check for OCaml (optional, for OCaml bindings). -OCAMLC=no -OCAMLFIND=no -AC_ARG_ENABLE([ocaml], - AS_HELP_STRING([--disable-ocaml], [Disable OCaml language bindings]), - [], - [enable_ocaml=yes]) -AS_IF([test "x$enable_ocaml" != "xno"], - [dnl OCAMLC and OCAMLFIND have to be unset first, otherwise - dnl AC_CHECK_TOOL (inside AC_PROG_OCAML) will not look. - OCAMLC= - OCAMLFIND= - AC_PROG_OCAML - AC_PROG_FINDLIB - ]) -AM_CONDITIONAL([HAVE_OCAML], - [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno"]) -AM_CONDITIONAL([HAVE_OCAMLOPT], - [test "x$OCAMLOPT" != "xno" && test "x$OCAMLFIND" != "xno"]) - -if test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno"; then - dnl Check if we have caml/unixsupport.h header (OCaml bindings only). - old_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -I$OCAMLLIB" - AC_CHECK_HEADERS([caml/unixsupport.h],[],[], - [ - #include - #include - ]) - CFLAGS="$old_CFLAGS" - - dnl Do we have function caml_raise_with_args? - f=caml_raise_with_args - AC_MSG_CHECKING([for function $f]) - echo "char $f (); char foo() { return $f (); }" > conftest.c - rm -f conftest_ml.ml - touch conftest_ml.ml - if $OCAMLC -c conftest.c >&AS_MESSAGE_LOG_FD 2>&1 && \ - $OCAMLC -c conftest_ml.ml >&AS_MESSAGE_LOG_FD 2>&1 && \ - $OCAMLC -custom conftest.o conftest_ml.cmo -o conftest >&AS_MESSAGE_LOG_FD 2>&1 ; then - AC_DEFINE([HAVE_CAML_RAISE_WITH_ARGS],[1], - [Defined if function caml_raise_with_args exists.]) - AC_MSG_RESULT([found]) - else - AC_MSG_RESULT([not found]) - fi - rm -f conftest conftest.* conftest_ml.* -fi - -dnl Check for Perl (optional, for Perl bindings and Perl tools). -AC_CHECK_PROG([PERL],[perl],[perl],[no]) - -AC_ARG_ENABLE([perl], - AS_HELP_STRING([--disable-perl], [Disable Perl language bindings]), - [], - [enable_perl=yes]) -AS_IF([test "x$enable_perl" != "xno"],[ - dnl Check for Perl modules that must be present to compile and - dnl test the Perl bindings. - missing_perl_modules=no - for pm in Test::More ExtUtils::MakeMaker IO::Stringy; do - AC_MSG_CHECKING([for $pm]) - if ! $PERL -M$pm -e1 >/dev/null 2>&1; then - AC_MSG_RESULT([no]) - missing_perl_modules=yes - else - AC_MSG_RESULT([yes]) - fi - done - if test "x$missing_perl_modules" = "xyes"; then - AC_MSG_WARN([some Perl modules required to compile or test the Perl bindings are missing]) - fi - ]) -AM_CONDITIONAL([HAVE_PERL], - [test "x$enable_perl" != "xno" && test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) - -dnl Check for Python (optional, for Python bindings). -PYTHON_PREFIX= -PYTHON_VERSION= -PYTHON_CFLAGS= -PYTHON_INSTALLDIR= - -AC_ARG_ENABLE([python], - AS_HELP_STRING([--disable-python], [Disable Python language bindings]), - [], - [enable_python=yes]) -AS_IF([test "x$enable_python" != "xno"], - [ - AC_CHECK_PROG([PYTHON],[python],[python],[no]) - - if test "x$PYTHON" != "xno"; then - AC_MSG_CHECKING([Python prefix]) - PYTHON_PREFIX=`$PYTHON -c "import sys; print (sys.prefix)"` - AC_MSG_RESULT([$PYTHON_PREFIX]) - - AC_MSG_CHECKING([Python version]) - PYTHON_VERSION_MAJOR=`$PYTHON -c "import sys; print (sys.version_info@<:@0@:>@)"` - PYTHON_VERSION_MINOR=`$PYTHON -c "import sys; print (sys.version_info@<:@1@:>@)"` - PYTHON_VERSION="$PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR" - AC_MSG_RESULT([$PYTHON_VERSION]) - - AC_MSG_CHECKING([for Python include path]) - if test -z "$PYTHON_CFLAGS"; then - python_path=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_python_inc ());"` - python_platpath=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_python_inc (plat_specific=1));"` - if test "$python_path" = "$python_platpath"; then - PYTHON_CFLAGS=-I$python_path - else - PYTHON_CFLAGS="-I$python_path -I$python_platpath" - fi - fi - AC_MSG_RESULT([$PYTHON_CFLAGS]) - - AC_ARG_WITH([python-installdir], - [AS_HELP_STRING([--with-python-installdir], - [directory to install python modules @<:@default=check@:>@])], - [PYTHON_INSTALLDIR="$withval" - AC_MSG_NOTICE([Python install dir $PYTHON_INSTALLDIR])], - [PYTHON_INSTALLDIR=check]) - - if test "x$PYTHON_INSTALLDIR" = "xcheck"; then - PYTHON_INSTALLDIR= - AC_MSG_CHECKING([for Python site-packages path]) - if test -z "$PYTHON_INSTALLDIR"; then - PYTHON_INSTALLDIR=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_python_lib(1,0));"` - fi - AC_MSG_RESULT([$PYTHON_INSTALLDIR]) - fi - - AC_MSG_CHECKING([for Python extension suffix (PEP-3149)]) - if test -z "$PYTHON_EXT_SUFFIX"; then - python_ext_suffix=`$PYTHON -c "import sysconfig; \ - print (sysconfig.get_config_var('EXT_SUFFIX') or sysconfig.get_config_var('SO'))"` - PYTHON_EXT_SUFFIX=$python_ext_suffix - fi - AC_MSG_RESULT([$PYTHON_EXT_SUFFIX]) - - dnl Look for some optional symbols in libpython. - old_LIBS="$LIBS" - - PYTHON_BLDLIBRARY=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_config_var('BLDLIBRARY'))"` - AC_CHECK_LIB([c],[PyCapsule_New], - [AC_DEFINE([HAVE_PYCAPSULE_NEW],1, - [Found PyCapsule_New in libpython])], - [],[$PYTHON_BLDLIBRARY]) - AC_CHECK_LIB([c],[PyString_AsString], - [AC_DEFINE([HAVE_PYSTRING_ASSTRING],1, - [Found PyString_AsString in libpython])], - [],[$PYTHON_BLDLIBRARY]) - - LIBS="$old_LIBS" - fi - - AC_SUBST(PYTHON_PREFIX) - AC_SUBST(PYTHON_VERSION) - AC_SUBST(PYTHON_CFLAGS) - AC_SUBST(PYTHON_INSTALLDIR) - AC_SUBST(PYTHON_EXT_SUFFIX) - ]) -AM_CONDITIONAL([HAVE_PYTHON], - [test "x$PYTHON" != "xno" && test "x$PYTHON_CFLAGS" != "x" && test "x$PYTHON_INSTALLDIR" != "x"]) - -dnl Check for Ruby and rake (optional, for Ruby bindings). -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]) - - AS_IF([test -n "$RUBY" && test -n "$RAKE"],[ - dnl Find the library. Note on Debian it's not -lruby. - AC_MSG_CHECKING([for C library for Ruby extensions]) - ruby_cmd='puts RbConfig::CONFIG@<:@"RUBY_SO_NAME"@:>@' - echo running: $RUBY -rrbconfig -e \'$ruby_cmd\' >&AS_MESSAGE_LOG_FD - $RUBY -rrbconfig -e "$ruby_cmd" >conftest 2>&AS_MESSAGE_LOG_FD - libruby="$(cat conftest)" - rm conftest - AS_IF([test -n "$libruby"],[ - AC_MSG_RESULT([-l$libruby]) - AC_CHECK_LIB([$libruby],[ruby_init], - [have_libruby=1],[have_libruby=]) - - dnl Symbols that we substitute when missing. - AS_IF([test -n "$have_libruby"],[ - old_LIBS="$LIBS" - LIBS="$LIBS -l$libruby" - AC_CHECK_FUNCS([rb_hash_lookup]) - LIBS="$old_LIBS" - ]) - ],[ - AC_MSG_RESULT([not found]) - ]) - ]) -]) -AM_CONDITIONAL([HAVE_RUBY], - [test -n "$RUBY" && test -n "$RAKE" && test -n "$have_libruby"]) - -dnl dnl Check for Java. -dnl AC_ARG_WITH(java_home, -dnl [AS_HELP_STRING([--with-java-home], -dnl [specify path to JDK directory @<:@default=check@:>@])], -dnl [], -dnl [with_java_home=check]) - -dnl if test "x$with_java_home" != "xno"; then -dnl if test "x$with_java_home" != "xyes" && test "x$with_java_home" != "xcheck" -dnl then -dnl # Reject unsafe characters in $JAVA_HOME -dnl jh_lf=' -dnl ' -dnl case $JAVA_HOME in -dnl *[\\\"\#\$\&\'\`$jh_lf\ \ ]*) -dnl AC_MSG_FAILURE([unsafe \$JAVA_HOME directory (use --with-java-home=no to disable Java support)]);; -dnl esac -dnl if test -d "$with_java_home"; then -dnl JAVA_HOME="$with_java_home" -dnl else -dnl AC_MSG_FAILURE([$with_java_home is not a directory (use --with-java-home=no to disable Java support)]) -dnl fi -dnl fi - -dnl if test "x$JAVA_HOME" = "x"; then -dnl # Look for Java in some likely locations. -dnl for d in \ -dnl /usr/lib/jvm/java \ -dnl /usr/lib/jvm/java-6-openjdk -dnl do -dnl if test -d $d && test -f $d/bin/java; then -dnl JAVA_HOME=$d -dnl break -dnl fi -dnl done -dnl fi - -dnl if test "x$JAVA_HOME" != "x"; then -dnl AC_MSG_CHECKING(for JDK in $JAVA_HOME) -dnl if test ! -x "$JAVA_HOME/bin/java"; then -dnl AC_MSG_ERROR([missing $JAVA_HOME/bin/java binary (use --with-java-home=no to disable Java support)]) -dnl else -dnl JAVA="$JAVA_HOME/bin/java" -dnl fi -dnl if test ! -x "$JAVA_HOME/bin/javac"; then -dnl AC_MSG_ERROR([missing $JAVA_HOME/bin/javac binary]) -dnl else -dnl JAVAC="$JAVA_HOME/bin/javac" -dnl fi -dnl if test ! -x "$JAVA_HOME/bin/javah"; then -dnl AC_MSG_ERROR([missing $JAVA_HOME/bin/javah binary]) -dnl else -dnl JAVAH="$JAVA_HOME/bin/javah" -dnl fi -dnl if test ! -x "$JAVA_HOME/bin/javadoc"; then -dnl AC_MSG_ERROR([missing $JAVA_HOME/bin/javadoc binary]) -dnl else -dnl JAVADOC="$JAVA_HOME/bin/javadoc" -dnl fi -dnl if test ! -x "$JAVA_HOME/bin/jar"; then -dnl AC_MSG_ERROR([missing $JAVA_HOME/bin/jar binary]) -dnl else -dnl JAR="$JAVA_HOME/bin/jar" -dnl fi -dnl java_version=`$JAVA -version 2>&1 | grep "java version"` -dnl AC_MSG_RESULT(found $java_version in $JAVA_HOME) - -dnl dnl Find jni.h. -dnl AC_MSG_CHECKING([for jni.h]) -dnl if test -f "$JAVA_HOME/include/jni.h"; then -dnl JNI_CFLAGS="-I$JAVA_HOME/include" -dnl else -dnl if test "`find $JAVA_HOME -name jni.h`" != ""; then -dnl head=`find $JAVA_HOME -name jni.h | tail -1` -dnl dir=`dirname "$head"` -dnl JNI_CFLAGS="-I$dir" -dnl else -dnl AC_MSG_FAILURE([missing jni.h header file]) -dnl fi -dnl fi -dnl AC_MSG_RESULT([$JNI_CFLAGS]) - -dnl dnl Find jni_md.h. -dnl AC_MSG_CHECKING([for jni_md.h]) -dnl case "$build_os" in -dnl *linux*) system="linux" ;; -dnl *SunOS*) system="solaris" ;; -dnl *cygwin*) system="win32" ;; -dnl *) system="$build_os" ;; -dnl esac -dnl if test -f "$JAVA_HOME/include/$system/jni_md.h"; then -dnl JNI_CFLAGS="$JNI_CFLAGS -I$JAVA_HOME/include/$system" -dnl else -dnl if test "`find $JAVA_HOME -name jni_md.h`" != ""; then -dnl head=`find $JAVA_HOME -name jni_md.h | tail -1` -dnl dir=`dirname "$head"` -dnl JNI_CFLAGS="$JNI_CFLAGS -I$dir" -dnl else -dnl AC_MSG_FAILURE([missing jni_md.h header file]) -dnl fi -dnl fi -dnl AC_MSG_RESULT([$JNI_CFLAGS]) - -dnl dnl Need extra version flag? -dnl AC_MSG_CHECKING([extra javac flags]) -dnl JAVAC_FLAGS= -dnl javac_version=`$JAVAC -version 2>&1` -dnl case "$javac_version" in -dnl *Eclipse*) -dnl JAVAC_FLAGS="-source 1.5" ;; -dnl esac -dnl AC_MSG_RESULT([$JAVAC_FLAGS]) - -dnl dnl Where to install jarfiles. -dnl dnl XXX How to make it configurable? -dnl JAR_INSTALL_DIR=\${prefix}/share/java -dnl JNI_INSTALL_DIR=\${libdir} - -dnl dnl JNI version. -dnl jni_major_version=`echo "$VERSION" | awk -F. '{print $1}'` -dnl jni_minor_version=`echo "$VERSION" | awk -F. '{print $2}'` -dnl jni_micro_version=`echo "$VERSION" | awk -F. '{print $3}'` -dnl JNI_VERSION_INFO=`expr "$jni_major_version" + "$jni_minor_version"`":$jni_micro_version:$jni_minor_version" -dnl fi -dnl fi - -dnl AC_SUBST(JAVA_HOME) -dnl AC_SUBST(JAVA) -dnl AC_SUBST(JAVAC) -dnl AC_SUBST(JAVAH) -dnl AC_SUBST(JAVADOC) -dnl AC_SUBST(JAR) -dnl AC_SUBST(JNI_CFLAGS) -dnl AC_SUBST(JAVAC_FLAGS) -dnl AC_SUBST(JAR_INSTALL_DIR) -dnl AC_SUBST(JNI_INSTALL_DIR) -dnl AC_SUBST(JNI_VERSION_INFO) - -dnl AM_CONDITIONAL([HAVE_JAVA],[test -n "$JAVAC"]) - -dnl dnl Check for Haskell (GHC). -dnl AC_CHECK_PROG([GHC],[ghc],[ghc],[no]) - -dnl AM_CONDITIONAL([HAVE_HASKELL], -dnl [test "x$GHC" != "xno"]) - -dnl Produce output files. -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([Makefile - generator/Makefile - gnulib/lib/Makefile - gnulib/tests/Makefile - hivex.pc - images/Makefile - lib/Makefile - lib/tools/Makefile - ocaml/Makefile ocaml/META - perl/Makefile perl/Makefile.PL - python/Makefile - po/Makefile.in - regedit/Makefile - ruby/Makefile ruby/Rakefile - sh/Makefile - xml/Makefile]) -AC_CONFIG_FILES([python/run-python-tests], [chmod +x python/run-python-tests]) -AC_OUTPUT - -dnl Produce summary. -echo -echo -echo "------------------------------------------------------------" -echo "Thank you for downloading $PACKAGE_STRING" -echo -echo "This is how we have configured the optional components for you today:" -echo -echo -n "OCaml bindings ...................... " -if test "x$HAVE_OCAML_TRUE" = "x"; then echo "yes"; else echo "no"; fi -echo -n "Perl bindings ....................... " -if test "x$HAVE_PERL_TRUE" = "x"; then echo "yes"; else echo "no"; fi -echo -n "Python bindings ..................... " -if test "x$HAVE_PYTHON_TRUE" = "x"; then echo "yes"; else echo "no"; fi -echo -n "Ruby bindings ....................... " -if test "x$HAVE_RUBY_TRUE" = "x"; then echo "yes"; else echo "no"; fi -dnl echo -n "Java bindings ....................... " -dnl if test "x$HAVE_JAVA_TRUE" = "x"; then echo "yes"; else echo "no"; fi -dnl echo -n "Haskell bindings .................... " -dnl if test "x$HAVE_HASKELL" = "x"; then echo "yes"; else echo "no"; fi -echo -echo "If any optional component is configured 'no' when you expected 'yes'" -echo "then you should check the preceeding messages." -echo -echo "Please report bugs back to the mailing list:" -echo "http://www.redhat.com/mailman/listinfo/libguestfs" -echo -echo "Next you should type 'make' to build the package," -echo "then 'make check' to run the tests." -echo "------------------------------------------------------------" diff --git a/trunk/hivex/generator/Makefile.am b/trunk/hivex/generator/Makefile.am deleted file mode 100644 index 514e1d0..0000000 --- a/trunk/hivex/generator/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# hivex -# 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. - -EXTRA_DIST = generator.ml - -CLEANFILES = stamp-generator diff --git a/trunk/hivex/generator/generator.ml b/trunk/hivex/generator/generator.ml deleted file mode 100755 index 54e5f0f..0000000 --- a/trunk/hivex/generator/generator.ml +++ /dev/null @@ -1,3776 +0,0 @@ -#!/usr/bin/env ocaml -(* hivex - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *) - -(* This script generates language bindings and some documentation for - * hivex. - * - * After editing this file, run it (./generator/generator.ml) to - * regenerate all the output files. 'make' will rerun this - * automatically when necessary. Note that if you are using a separate - * build directory you must run generator.ml from the _source_ - * directory. - * - * IMPORTANT: This script should NOT print any warnings. If it prints - * warnings, you should treat them as errors. - * - * OCaml tips: (1) In emacs, install tuareg-mode to display and format - * OCaml code correctly. 'vim' comes with a good OCaml editing mode by - * default. (2) Read the resources at http://ocaml-tutorial.org/ - *) - -#load "unix.cma";; -#load "str.cma";; - -open Unix -open Printf - -type style = ret * args -and ret = - | RErr (* 0 = ok, -1 = error *) - | RErrDispose (* Disposes handle, see hivex_close. *) - | RHive (* Returns a hive_h or NULL. *) - | RSize (* Returns size_t or 0. *) - | RNode (* Returns hive_node_h or 0. *) - | RNodeNotFound (* See hivex_node_get_child. *) - | 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. *) - | RLenTypeVal (* See hivex_value_value. *) - | RInt32 (* Returns int32. *) - | RInt64 (* Returns int64. *) - -and args = argt list (* List of parameters. *) - -and argt = (* Note, cannot be NULL/0 unless it - says so explicitly below. *) - | AHive (* hive_h* *) - | ANode of string (* hive_node_h *) - | AValue of string (* hive_value_h *) - | AString of string (* char* *) - | AStringNullable of string (* char* (can be NULL) *) - | AOpenFlags (* HIVEX_OPEN_* flags list. *) - | AUnusedFlags (* Flags arg that is always 0 *) - | ASetValues (* See hivex_node_set_values. *) - | ASetValue (* See hivex_node_set_value. *) - -(* Hive types, from: - * https://secure.wikimedia.org/wikipedia/en/wiki/Windows_Registry#Keys_and_values - * - * It's unfortunate that in our original C binding we strayed away from - * the names that Windows uses (eg. REG_SZ for strings). We include - * both our names and the Windows names. - *) -let hive_types = [ - 0, "none", "NONE", - "Just a key without a value"; - 1, "string", "SZ", - "A Windows string (encoding is unknown, but often UTF16-LE)"; - 2, "expand_string", "EXPAND_SZ", - "A Windows string that contains %env% (environment variable expansion)"; - 3, "binary", "BINARY", - "A blob of binary"; - 4, "dword", "DWORD", - "DWORD (32 bit integer), little endian"; - 5, "dword_be", "DWORD_BIG_ENDIAN", - "DWORD (32 bit integer), big endian"; - 6, "link", "LINK", - "Symbolic link to another part of the registry tree"; - 7, "multiple_strings", "MULTI_SZ", - "Multiple Windows strings. See http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx"; - 8, "resource_list", "RESOURCE_LIST", - "Resource list"; - 9, "full_resource_description", "FULL_RESOURCE_DESCRIPTOR", - "Resource descriptor"; - 10, "resource_requirements_list", "RESOURCE_REQUIREMENTS_LIST", - "Resouce requirements list"; - 11, "qword", "QWORD", - "QWORD (64 bit integer), unspecified endianness but usually little endian" -] -let max_hive_type = 11 - -(* Open flags (bitmask passed to AOpenFlags) *) -let open_flags = [ - 1, "VERBOSE", "Verbose messages"; - 2, "DEBUG", "Debug messages"; - 4, "WRITE", "Enable writes to the hive"; -] - -(* The API calls. *) -let functions = [ - "open", (RHive, [AString "filename"; AOpenFlags]), - "open a hive file", - "\ -Opens the hive named C for reading. - -Flags is an ORed list of the open flags (or C<0> if you don't -want to pass any flags). These flags are defined: - -=over 4 - -=item HIVEX_OPEN_VERBOSE - -Verbose messages. - -=item HIVEX_OPEN_DEBUG - -Very verbose messages, suitable for debugging problems in the library -itself. - -This is also selected if the C environment variable -is set to 1. - -=item HIVEX_OPEN_WRITE - -Open the hive for writing. If omitted, the hive is read-only. - -See L. - -=back"; - - "close", (RErrDispose, [AHive]), - "close a hive handle", - "\ -Close a hive handle and free all associated resources. - -Note that any uncommitted writes are I committed by this call, -but instead are lost. See L."; - - "root", (RNode, [AHive]), - "return the root node of the hive", - "\ -Return root node of the hive. All valid hives must contain a root node."; - - "last_modified", (RInt64, [AHive]), - "return the modification time from the header of the hive", - "\ -Return the modification time from the header of the hive. - -The returned value is a Windows filetime. -To convert this to a Unix C see: -L"; - - "node_name", (RString, [AHive; ANode "node"]), - "return the name of the node", - "\ -Return the name of the node. - -Note that the name of the root node is a dummy, such as -C<$$$PROTO.HIV> (other names are possible: it seems to depend on the -tool or program that created the hive in the first place). You can -only know the \"real\" name of the root node by knowing which registry -file this hive originally comes from, which is knowledge that is -outside the scope of this library."; - - "node_timestamp", (RInt64, [AHive; ANode "node"]), - "return the modification time of the node", - "\ -Return the modification time of the node. - -The returned value is a Windows filetime. -To convert this to a Unix C see: -L"; - - "node_children", (RNodeList, [AHive; ANode "node"]), - "return children of node", - "\ -Return an array of nodes which are the subkeys -(children) of C."; - - "node_get_child", (RNodeNotFound, [AHive; ANode "node"; AString "name"]), - "return named child of node", - "\ -Return the child of node with the name C, if it exists. - -The name is matched case insensitively."; - - "node_parent", (RNode, [AHive; ANode "node"]), - "return the parent of node", - "\ -Return the parent of C. - -The parent pointer of the root node in registry files that we -have examined seems to be invalid, and so this function will -return an error if called on the root node."; - - "node_values", (RValueList, [AHive; ANode "node"]), - "return (key, value) pairs attached to a node", - "\ -Return the array of (key, value) pairs attached to this node."; - - "node_get_value", (RValue, [AHive; ANode "node"; AString "key"]), - "return named key at node", - "\ -Return the value attached to this node which has the name C, -if it exists. - -The key name is matched case insensitively. - -Note that to get the default key, you should pass the empty -string C<\"\"> here. The default key is often written C<\"@\">, but -inside hives that has no meaning and won't give you the -default key."; - - "value_key_len", (RSize, [AHive; AValue "val"]), - "return the length of a value's key", - "\ -Return the length of the key (name) of a (key, value) pair. The -length can legitimately be 0, so errno is the necesary mechanism -to check for errors. - -In the context of Windows Registries, a zero-length name means -that this value is the default key for this node in the tree. -This is usually written as C<\"@\">."; - - "value_key", (RString, [AHive; AValue "val"]), - "return the key of a (key, value) pair", - "\ -Return the key (name) of a (key, value) pair. The name -is reencoded as UTF-8 and returned as a string. - -The string should be freed by the caller when it is no longer needed. - -Note that this function can return a zero-length string. In the -context of Windows Registries, this means that this value is the -default key for this node in the tree. This is usually written -as C<\"@\">."; - - "value_type", (RLenType, [AHive; AValue "val"]), - "return data length and data type of a value", - "\ -Return the data length and data type of the value in this (key, value) -pair. See also C which returns all this -information, and the value itself. Also, C functions -below which can be used to return the value in a more useful form when -you know the type in advance."; - - "node_struct_length", (RSize, [AHive; ANode "node"]), - "return the length of a node", - "\ -Return the length of the node data structure."; - - "value_struct_length", (RSize, [AHive; AValue "val"]), - "return the length of a value 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. - -The data cell is a registry structure that contains the length -(a 4 byte, little endian integer) followed by the data. - -If the length of the value is less than or equal to 4 bytes -then the offset and length returned by this function is zero -as the data is inlined 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", - "\ -Return the value of this (key, value) pair. The value should -be interpreted according to its type (see C)."; - - "value_string", (RString, [AHive; AValue "val"]), - "return value as a string", - "\ -If this value is a string, return the string reencoded as UTF-8 -(as a C string). This only works for values which have type -C, C or C."; - - "value_multiple_strings", (RStringList, [AHive; AValue "val"]), - "return value as multiple strings", - "\ -If this value is a multiple-string, return the strings reencoded -as UTF-8 (in C, as a NULL-terminated array of C strings, in other -language bindings, as a list of strings). This only -works for values which have type C."; - - "value_dword", (RInt32, [AHive; AValue "val"]), - "return value as a DWORD", - "\ -If this value is a DWORD (Windows int32), return it. This only works -for values which have type C or C."; - - "value_qword", (RInt64, [AHive; AValue "val"]), - "return value as a QWORD", - "\ -If this value is a QWORD (Windows int64), return it. This only -works for values which have type C."; - - "commit", (RErr, [AHive; AStringNullable "filename"; AUnusedFlags]), - "commit (write) changes to file", - "\ -Commit (write) any changes which have been made. - -C is the new file to write. If C is null/undefined -then we overwrite the original file (ie. the file name that was passed to -C). - -Note this does not close the hive handle. You can perform further -operations on the hive after committing, including making more -modifications. If you no longer wish to use the hive, then you -should close the handle after committing."; - - "node_add_child", (RNode, [AHive; ANode "parent"; AString "name"]), - "add child node", - "\ -Add a new child node named C to the existing node C. -The new child initially has no subnodes and contains no keys or -values. The sk-record (security descriptor) is inherited from -the parent. - -The parent must not have an existing child called C, so if you -want to overwrite an existing child, call C -first."; - - "node_delete_child", (RErr, [AHive; ANode "node"]), - "delete child node", - "\ -Delete the node C. All values at the node and all subnodes are -deleted (recursively). The C handle and the handles of all -subnodes become invalid. You cannot delete the root node."; - - "node_set_values", (RErr, [AHive; ANode "node"; ASetValues; AUnusedFlags]), - "set (key, value) pairs at a node", - "\ -This call can be used to set all the (key, value) pairs -stored in C. - -C is the node to modify."; - - "node_set_value", (RErr, [AHive; ANode "node"; ASetValue; AUnusedFlags]), - "set a single (key, value) pair at a given node", - "\ -This call can be used to replace a single C<(key, value)> pair -stored in C. If the key does not already exist, then a -new key is added. Key matching is case insensitive. - -C is the node to modify."; -] - -(* Useful functions. - * Note we don't want to use any external OCaml libraries which - * makes this a bit harder than it should be. - *) -module StringMap = Map.Make (String) - -let failwithf fs = ksprintf failwith fs - -let unique = let i = ref 0 in fun () -> incr i; !i - -let replace_char s c1 c2 = - let s2 = String.copy s in - let r = ref false in - for i = 0 to String.length s2 - 1 do - if String.unsafe_get s2 i = c1 then ( - String.unsafe_set s2 i c2; - r := true - ) - done; - if not !r then s else s2 - -let isspace c = - c = ' ' - (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *) - -let triml ?(test = isspace) str = - let i = ref 0 in - let n = ref (String.length str) in - while !n > 0 && test str.[!i]; do - decr n; - incr i - done; - if !i = 0 then str - else String.sub str !i !n - -let trimr ?(test = isspace) str = - let n = ref (String.length str) in - while !n > 0 && test str.[!n-1]; do - decr n - done; - if !n = String.length str then str - else String.sub str 0 !n - -let trim ?(test = isspace) str = - trimr ~test (triml ~test str) - -(* Used to memoize the result of pod2text. *) -let pod2text_memo_filename = "generator/.pod2text.data.version.2" -let pod2text_memo : ((int option * bool * bool * string * string), string list) Hashtbl.t = - try - let chan = open_in pod2text_memo_filename in - let v = input_value chan in - close_in chan; - v - with - _ -> Hashtbl.create 13 -let pod2text_memo_updated () = - let chan = open_out pod2text_memo_filename in - output_value chan pod2text_memo; - close_out chan - -(* Useful if you need the longdesc POD text as plain text. Returns a - * list of lines. - * - * Because this is very slow (the slowest part of autogeneration), - * we memoize the results. - *) -let pod2text ?width ?(trim = true) ?(discard = true) name longdesc = - let key = width, trim, discard, name, longdesc in - try Hashtbl.find pod2text_memo key - with Not_found -> - let filename, chan = Filename.open_temp_file "gen" ".tmp" in - fprintf chan "=head1 %s\n\n%s\n" name longdesc; - close_out chan; - let cmd = - match width with - | Some width -> - sprintf "pod2text -w %d %s" width (Filename.quote filename) - | None -> - sprintf "pod2text %s" (Filename.quote filename) in - let chan = open_process_in cmd in - let lines = ref [] in - let rec loop i = - let line = input_line chan in - if i = 1 && discard then (* discard the first line of output *) - loop (i+1) - else ( - let line = if trim then triml line else line in - lines := line :: !lines; - loop (i+1) - ) in - let lines = try loop 1 with End_of_file -> List.rev !lines in - unlink filename; - (match close_process_in chan with - | WEXITED 0 -> () - | WEXITED i -> - failwithf "pod2text: process exited with non-zero status (%d)" i - | WSIGNALED i | WSTOPPED i -> - failwithf "pod2text: process signalled or stopped by signal %d" i - ); - Hashtbl.add pod2text_memo key lines; - pod2text_memo_updated (); - lines - -let rec find s sub = - let len = String.length s in - let sublen = String.length sub in - let rec loop i = - if i <= len-sublen then ( - let rec loop2 j = - if j < sublen then ( - if s.[i+j] = sub.[j] then loop2 (j+1) - else -1 - ) else - i (* found *) - in - let r = loop2 0 in - if r = -1 then loop (i+1) else r - ) else - -1 (* not found *) - in - loop 0 - -let rec replace_str s s1 s2 = - let len = String.length s in - let sublen = String.length s1 in - let i = find s s1 in - if i = -1 then s - else ( - let s' = String.sub s 0 i in - let s'' = String.sub s (i+sublen) (len-i-sublen) in - s' ^ s2 ^ replace_str s'' s1 s2 - ) - -let rec string_split sep str = - let len = String.length str in - let seplen = String.length sep in - let i = find str sep in - if i = -1 then [str] - else ( - let s' = String.sub str 0 i in - let s'' = String.sub str (i+seplen) (len-i-seplen) in - s' :: string_split sep s'' - ) - -let files_equal n1 n2 = - let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in - match Sys.command cmd with - | 0 -> true - | 1 -> false - | i -> failwithf "%s: failed with error code %d" cmd i - -let rec filter_map f = function - | [] -> [] - | x :: xs -> - match f x with - | Some y -> y :: filter_map f xs - | None -> filter_map f xs - -let rec find_map f = function - | [] -> raise Not_found - | x :: xs -> - match f x with - | Some y -> y - | None -> find_map f xs - -let iteri f xs = - let rec loop i = function - | [] -> () - | x :: xs -> f i x; loop (i+1) xs - in - loop 0 xs - -let mapi f xs = - let rec loop i = function - | [] -> [] - | x :: xs -> let r = f i x in r :: loop (i+1) xs - in - loop 0 xs - -let count_chars c str = - let count = ref 0 in - for i = 0 to String.length str - 1 do - if c = String.unsafe_get str i then incr count - done; - !count - -let name_of_argt = function - | AHive -> "h" - | ANode n | AValue n | AString n | AStringNullable n -> n - | AOpenFlags | AUnusedFlags -> "flags" - | ASetValues -> "values" - | ASetValue -> "val" - -(* Check function names etc. for consistency. *) -let check_functions () = - let contains_uppercase str = - let len = String.length str in - let rec loop i = - if i >= len then false - else ( - let c = str.[i] in - if c >= 'A' && c <= 'Z' then true - else loop (i+1) - ) - in - loop 0 - in - - (* Check function names. *) - List.iter ( - fun (name, _, _, _) -> - if String.length name >= 7 && String.sub name 0 7 = "hivex" then - failwithf "function name %s does not need 'hivex' prefix" name; - if name = "" then - failwithf "function name is empty"; - if name.[0] < 'a' || name.[0] > 'z' then - failwithf "function name %s must start with lowercase a-z" name; - if String.contains name '-' then - failwithf "function name %s should not contain '-', use '_' instead." - name - ) functions; - - (* Check function parameter/return names. *) - List.iter ( - fun (name, style, _, _) -> - let check_arg_ret_name n = - if contains_uppercase n then - failwithf "%s param/ret %s should not contain uppercase chars" - name n; - if String.contains n '-' || String.contains n '_' then - failwithf "%s param/ret %s should not contain '-' or '_'" - name n; - if n = "value" then - failwithf "%s has a param/ret called 'value', which causes conflicts in the OCaml bindings, use something like 'val' or a more descriptive name" name; - if n = "int" || n = "char" || n = "short" || n = "long" then - failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name; - if n = "i" || n = "n" then - failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name; - if n = "argv" || n = "args" then - failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name; - - (* List Haskell, OCaml and C keywords here. - * http://www.haskell.org/haskellwiki/Keywords - * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char - * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords - * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \ - * |perl -pe 's/(.+)/"$1";/'|fmt -70 - * Omitting _-containing words, since they're handled above. - * Omitting the OCaml reserved word, "val", is ok, - * and saves us from renaming several parameters. - *) - let reserved = [ - "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case"; - "char"; "class"; "const"; "constraint"; "continue"; "data"; - "default"; "deriving"; "do"; "done"; "double"; "downto"; "else"; - "end"; "enum"; "exception"; "extern"; "external"; "false"; "float"; - "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto"; - "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl"; - "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int"; - "interface"; - "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor"; - "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new"; - "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified"; - "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed"; - "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try"; - "type"; "typedef"; "union"; "unsigned"; "virtual"; "void"; - "volatile"; "when"; "where"; "while"; - ] in - if List.mem n reserved then - failwithf "%s has param/ret using reserved word %s" name n; - in - - List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style) - ) functions; - - (* Check short descriptions. *) - List.iter ( - fun (name, _, shortdesc, _) -> - if shortdesc.[0] <> Char.lowercase shortdesc.[0] then - failwithf "short description of %s should begin with lowercase." name; - let c = shortdesc.[String.length shortdesc-1] in - if c = '\n' || c = '.' then - failwithf "short description of %s should not end with . or \\n." name - ) functions; - - (* Check long dscriptions. *) - List.iter ( - fun (name, _, _, longdesc) -> - if longdesc.[String.length longdesc-1] = '\n' then - failwithf "long description of %s should not end with \\n." name - ) functions - -(* 'pr' prints to the current output file. *) -let chan = ref Pervasives.stdout -let lines = ref 0 -let pr fs = - ksprintf - (fun str -> - let i = count_chars '\n' str in - lines := !lines + i; - output_string !chan str - ) fs - -let copyright_years = - let this_year = 1900 + (localtime (time ())).tm_year in - if this_year > 2009 then sprintf "2009-%04d" this_year else "2009" - -(* Generate a header block in a number of standard styles. *) -type comment_style = - | CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle - | PODCommentStyle -type license = GPLv2plus | LGPLv2plus | GPLv2 | LGPLv2 - -let generate_header ?(extra_inputs = []) comment license = - let inputs = "generator/generator.ml" :: extra_inputs in - let c = match comment with - | CStyle -> pr "/* "; " *" - | CPlusPlusStyle -> pr "// "; "//" - | HashStyle -> pr "# "; "#" - | OCamlStyle -> pr "(* "; " *" - | HaskellStyle -> pr "{- "; " " - | PODCommentStyle -> pr "=begin comment\n\n "; "" in - pr "hivex generated file\n"; - pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c; - List.iter (pr "%s %s\n" c) inputs; - pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c; - pr "%s\n" c; - pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years; - pr "%s Derived from code by Petter Nordahl-Hagen under a compatible license:\n" c; - pr "%s Copyright (c) 1997-2007 Petter Nordahl-Hagen.\n" c; - pr "%s Derived from code by Markus Stephany under a compatible license:\n" c; - pr "%s Copyright (c)2000-2004, Markus Stephany.\n" c; - pr "%s\n" c; - (match license with - | GPLv2plus -> - pr "%s This program is free software; you can redistribute it and/or modify\n" c; - pr "%s it under the terms of the GNU General Public License as published by\n" c; - pr "%s the Free Software Foundation; either version 2 of the License, or\n" c; - pr "%s (at your option) any later version.\n" c; - pr "%s\n" c; - pr "%s This program is distributed in the hope that it will be useful,\n" c; - pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c; - pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c; - pr "%s GNU General Public License for more details.\n" c; - pr "%s\n" c; - pr "%s You should have received a copy of the GNU General Public License along\n" c; - pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c; - pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c; - - | LGPLv2plus -> - pr "%s This library is free software; you can redistribute it and/or\n" c; - pr "%s modify it under the terms of the GNU Lesser General Public\n" c; - pr "%s License as published by the Free Software Foundation; either\n" c; - pr "%s version 2 of the License, or (at your option) any later version.\n" c; - pr "%s\n" c; - pr "%s This library is distributed in the hope that it will be useful,\n" c; - pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c; - pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c; - pr "%s Lesser General Public License for more details.\n" c; - pr "%s\n" c; - pr "%s You should have received a copy of the GNU Lesser General Public\n" c; - pr "%s License along with this library; if not, write to the Free Software\n" c; - pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c; - - | GPLv2 -> - pr "%s This program is free software; you can redistribute it and/or modify\n" c; - pr "%s it under the terms of the GNU General Public License as published by\n" c; - pr "%s the Free Software Foundation; version 2 of the License only.\n" c; - pr "%s\n" c; - pr "%s This program is distributed in the hope that it will be useful,\n" c; - pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c; - pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c; - pr "%s GNU General Public License for more details.\n" c; - pr "%s\n" c; - pr "%s You should have received a copy of the GNU General Public License along\n" c; - pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c; - pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c; - - | LGPLv2 -> - pr "%s This library is free software; you can redistribute it and/or\n" c; - pr "%s modify it under the terms of the GNU Lesser General Public\n" c; - pr "%s License as published by the Free Software Foundation;\n" c; - pr "%s version 2.1 of the License only.\n" c; - pr "%s\n" c; - pr "%s This library is distributed in the hope that it will be useful,\n" c; - pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c; - pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c; - pr "%s Lesser General Public License for more details.\n" c; - pr "%s\n" c; - pr "%s You should have received a copy of the GNU Lesser General Public\n" c; - pr "%s License along with this library; if not, write to the Free Software\n" c; - pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c; - ); - (match comment with - | CStyle -> pr " */\n" - | CPlusPlusStyle - | HashStyle -> () - | OCamlStyle -> pr " *)\n" - | HaskellStyle -> pr "-}\n" - | PODCommentStyle -> pr "\n=end comment\n" - ); - pr "\n" - -(* Start of main code generation functions below this line. *) - -let rec generate_c_header () = - generate_header CStyle LGPLv2; - - pr "\ -#ifndef HIVEX_H_ -#define HIVEX_H_ - -#include -#include - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* NOTE: This API is documented in the man page hivex(3). */ - -/* Hive handle. */ -typedef struct hive_h hive_h; - -/* Nodes and values. */ -typedef size_t hive_node_h; -typedef size_t hive_value_h; - -#include -#ifdef ENOKEY -# define HIVEX_NO_KEY ENOKEY -#else -# define HIVEX_NO_KEY ENOENT -#endif - -/* Pre-defined types. */ -enum hive_type { -"; - List.iter ( - fun (t, old_style, new_style, description) -> - pr " /* %s */\n" description; - pr " hive_t_REG_%s,\n" new_style; - pr "#define hive_t_%s hive_t_REG_%s\n" old_style new_style; - pr "\n" - ) hive_types; - pr "\ -}; - -typedef enum hive_type hive_type; - -/* Bitmask of flags passed to hivex_open. */ -"; - List.iter ( - fun (v, flag, description) -> - pr " /* %s */\n" description; - pr "#define HIVEX_OPEN_%-10s %d\n" flag v; - ) open_flags; - pr "\n"; - - pr "\ -/* Array of (key, value) pairs passed to hivex_node_set_values. */ -struct hive_set_value { - char *key; - hive_type t; - size_t len; - char *value; -}; -typedef struct hive_set_value hive_set_value; - -"; - - pr "/* Functions. */\n"; - - (* Function declarations. *) - List.iter ( - fun (shortname, style, _, _) -> - let name = "hivex_" ^ shortname in - generate_c_prototype ~extern:true name style - ) functions; - - (* The visitor pattern. *) - pr " -/* Visit all nodes. This is specific to the C API and is not made - * available to other languages. This is because of the complexity - * of binding callbacks in other languages, but also because other - * languages make it much simpler to iterate over a tree. - */ -struct hivex_visitor { - int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name); - int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name); - int (*value_string) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *str); - int (*value_multiple_strings) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, char **argv); - int (*value_string_invalid_utf16) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *str); - int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t); - int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t); - int (*value_binary) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); - int (*value_none) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); - int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); - int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); -}; - -#define HIVEX_VISIT_SKIP_BAD 1 - -extern int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags); -extern int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags); - -"; - - (* Finish the header file. *) - pr "\ -#ifdef __cplusplus -} -#endif - -#endif /* HIVEX_H_ */ -" - -and generate_c_prototype ?(extern = false) name style = - if extern then pr "extern "; - (match fst style with - | RErr -> pr "int " - | RErrDispose -> pr "int " - | RHive -> pr "hive_h *" - | RSize -> pr "size_t " - | RNode -> pr "hive_node_h " - | RNodeNotFound -> pr "hive_node_h " - | RNodeList -> pr "hive_node_h *" - | RValue -> pr "hive_value_h " - | 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 " - | RInt64 -> pr "int64_t " - ); - pr "%s (" name; - let comma = ref false in - List.iter ( - fun arg -> - if !comma then pr ", "; comma := true; - match arg with - | AHive -> pr "hive_h *h" - | ANode n -> pr "hive_node_h %s" n - | AValue n -> pr "hive_value_h %s" n - | AString n | AStringNullable n -> pr "const char *%s" n - | AOpenFlags | AUnusedFlags -> pr "int flags" - | ASetValues -> pr "size_t nr_values, const hive_set_value *values" - | ASetValue -> pr "const hive_set_value *val" - ) (snd style); - (match fst style with - | RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len" - | RLenValue -> pr ", size_t *len" - | _ -> () - ); - pr ");\n" - -and generate_c_pod () = - generate_header PODCommentStyle GPLv2; - - pr "\ - =encoding utf8 - -=head1 NAME - -hivex - Windows Registry \"hive\" extraction library - -=head1 SYNOPSIS - - #include - -"; - List.iter ( - fun (shortname, style, _, _) -> - let name = "hivex_" ^ shortname in - pr " "; - generate_c_prototype ~extern:false name style; - ) functions; - - pr "\ - -Link with I<-lhivex>. - -=head1 DESCRIPTION - -Hivex is a library for extracting the contents of Windows Registry -\"hive\" files. It is designed to be secure against buggy or malicious -registry files. - -Unlike other tools in this area, it doesn't use the textual .REG -format, because parsing that is as much trouble as parsing the -original binary format. Instead it makes the file available -through a C API, and then wraps this API in higher level scripting -and GUI tools. - -There is a separate program to export the hive as XML -(see L), or to navigate the file (see L). -There is also a Perl script to export and merge the -file as a textual .REG (regedit) file, see L. - -If you just want to export or modify the Registry of a Windows -virtual machine, you should look at L. - -Hivex is also comes with language bindings for -OCaml, Perl, Python and Ruby. - -=head1 TYPES - -=head2 C - -This handle describes an open hive file. - -=head2 C - -This is a node handle, an integer but opaque outside the library. -Valid node handles cannot be 0. The library returns 0 in some -situations to indicate an error. - -=head2 C - -The enum below describes the possible types for the value(s) -stored at each node. Note that you should not trust the -type field in a Windows Registry, as it very often has no -relationship to reality. Some applications use their own -types. The encoding of strings is not specified. Some -programs store everything (including strings) in binary blobs. - - enum hive_type { -"; - List.iter ( - fun (t, _, new_style, description) -> - pr " /* %s */\n" description; - pr " hive_t_REG_%s = %d,\n" new_style t - ) hive_types; - pr "\ - }; - -=head2 C - -This is a value handle, an integer but opaque outside the library. -Valid value handles cannot be 0. The library returns 0 in some -situations to indicate an error. - -=head2 C - -The typedef C is used in conjunction with the -C call described below. - - struct hive_set_value { - char *key; /* key - a UTF-8 encoded ASCIIZ string */ - hive_type t; /* type of value field */ - size_t len; /* length of value field in bytes */ - char *value; /* value field */ - }; - typedef struct hive_set_value hive_set_value; - -To set the default value for a node, you have to pass C. - -Note that the C field is just treated as a list of bytes, and -is stored directly in the hive. The caller has to ensure correct -encoding and endianness, for example converting dwords to little -endian. - -The correct type and encoding for values depends on the node and key -in the registry, the version of Windows, and sometimes even changes -between versions of Windows for the same key. We don't document it -here. Often it's not documented at all. - -=head1 FUNCTIONS - -"; - List.iter ( - fun (shortname, style, _, longdesc) -> - let name = "hivex_" ^ shortname in - pr "=head2 %s\n" name; - pr "\n "; - generate_c_prototype ~extern:false name style; - pr "\n"; - pr "%s\n" longdesc; - pr "\n"; - - if List.mem AUnusedFlags (snd style) then - pr "The flags parameter is unused. Always pass 0.\n\n"; - - if List.mem ASetValues (snd style) then - pr "C is an array of (key, value) pairs. There -should be C elements in this array. - -Any existing values stored at the node are discarded, and their -C handles become invalid. Thus you can remove all -values stored at C by passing C.\n\n"; - - if List.mem ASetValue (snd style) then - pr "C is a single (key, value) pair. - -Existing C handles become invalid.\n\n"; - - (match fst style with - | RErr -> - pr "\ -Returns 0 on success. -On error this returns -1 and sets errno.\n\n" - | RErrDispose -> - pr "\ -Returns 0 on success. -On error this returns -1 and sets errno. - -This function frees the hive handle (even if it returns an error). -The hive handle must not be used again after calling this function.\n\n" - | RHive -> - pr "\ -Returns a new hive handle. -On error this returns NULL and sets errno.\n\n" - | RSize -> - pr "\ -Returns a size. -On error this returns 0 and sets errno.\n\n" - | RNode -> - pr "\ -Returns a node handle. -On error this returns 0 and sets errno.\n\n" - | RNodeNotFound -> - pr "\ -Returns a node handle. -If the node was not found, this returns 0 without setting errno. -On error this returns 0 and sets errno.\n\n" - | RNodeList -> - pr "\ -Returns a 0-terminated array of nodes. -The array must be freed by the caller when it is no longer needed. -On error this returns NULL and sets errno.\n\n" - | RValue -> - pr "\ -Returns a value handle. -On error this returns 0 and sets errno.\n\n" - | RValueList -> - pr "\ -Returns a 0-terminated array of values. -The array must be freed by the caller when it is no longer needed. -On error this returns NULL and sets errno.\n\n" - | RString -> - pr "\ -Returns a string. -The string must be freed by the caller when it is no longer needed. -On error this returns NULL and sets errno.\n\n" - | RStringList -> - pr "\ -Returns a NULL-terminated array of C strings. -The strings and the array must all be freed by the caller when -they are no longer needed. -On error this returns NULL and sets errno.\n\n" - | RLenType -> - 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). -The value must be freed by the caller when it is no longer needed. -On error this returns NULL and sets errno.\n\n" - | RInt32 | RInt64 -> () - ); - ) functions; - - pr "\ -=head1 WRITING TO HIVE FILES - -The hivex library supports making limited modifications to hive files. -We have tried to implement this very conservatively in order to reduce -the chance of corrupting your registry. However you should be careful -and take back-ups, since Microsoft has never documented the hive -format, and so it is possible there are nuances in the -reverse-engineered format that we do not understand. - -To be able to modify a hive, you must pass the C -flag to C, otherwise any write operation will return with -errno C. - -The write operations shown below do not modify the on-disk file -immediately. You must call C in order to write the -changes to disk. If you call C without committing then -any writes are discarded. - -Hive files internally consist of a \"memory dump\" of binary blocks -(like the C heap), and some of these blocks can be unused. The hivex -library never reuses these unused blocks. Instead, to ensure -robustness in the face of the partially understood on-disk format, -hivex only allocates new blocks after the end of the file, and makes -minimal modifications to existing structures in the file to point to -these new blocks. This makes hivex slightly less disk-efficient than -it could be, but disk is cheap, and registry modifications tend to be -very small. - -When deleting nodes, it is possible that this library may leave -unreachable live blocks in the hive. This is because certain parts of -the hive disk format such as security (sk) records and big data (db) -records and classname fields are not well understood (and not -documented at all) and we play it safe by not attempting to modify -them. Apart from wasting a little bit of disk space, it is not -thought that unreachable blocks are a problem. - -=head2 WRITE OPERATIONS WHICH ARE NOT SUPPORTED - -=over 4 - -=item * - -Changing the root node. - -=item * - -Creating a new hive file from scratch. This is impossible at present -because not all fields in the header are understood. In the hivex -source tree is a file called C which could be used as -the basis for a new hive (but I). - -=item * - -Modifying or deleting single values at a node. - -=item * - -Modifying security key (sk) records or classnames. -Previously we did not understand these records. However now they -are well-understood and we could add support if it was required -(but nothing much really uses them). - -=back - -=head1 VISITING ALL NODES - -The visitor pattern is useful if you want to visit all nodes -in the tree or all nodes below a certain point in the tree. - -First you set up your own C with your -callback functions. - -Each of these callback functions should return 0 on success or -1 -on error. If any callback returns -1, then the entire visit -terminates immediately. If you don't need a callback function at -all, set the function pointer to NULL. - - struct hivex_visitor { - int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name); - int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name); - int (*value_string) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, const char *str); - int (*value_multiple_strings) (hive_h *, void *opaque, hive_node_h, - hive_value_h, hive_type t, size_t len, const char *key, char **argv); - int (*value_string_invalid_utf16) (hive_h *, void *opaque, hive_node_h, - hive_value_h, hive_type t, size_t len, const char *key, - const char *str); - int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, int32_t); - int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, int64_t); - int (*value_binary) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, const char *value); - int (*value_none) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, const char *value); - int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, const char *value); - /* If value_any callback is not NULL, then the other value_* - * callbacks are not used, and value_any is called on all values. - */ - int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h, - hive_type t, size_t len, const char *key, const char *value); - }; - -=over 4 - -=item hivex_visit - - int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags); - -Visit all the nodes recursively in the hive C. - -C should be a C structure with callback -fields filled in as required (unwanted callbacks can be set to -NULL). C must be the length of the 'visitor' struct (you -should pass C for this). - -This returns 0 if the whole recursive visit was completed -successfully. On error this returns -1. If one of the callback -functions returned an error than we don't touch errno. If the -error was generated internally then we set errno. - -You can skip bad registry entries by setting C to -C. If this flag is not set, then a bad registry -causes the function to return an error immediately. - -This function is robust if the registry contains cycles or -pointers which are invalid or outside the registry. It detects -these cases and returns an error. - -=item hivex_visit_node - - int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque); - -Same as C but instead of starting out at the root, this -starts at C. - -=back - -=head1 THE STRUCTURE OF THE WINDOWS REGISTRY - -Note: To understand the relationship between hives and the common -Windows Registry keys (like C) please see the -Wikipedia page on the Windows Registry. - -The Windows Registry is split across various binary files, each -file being known as a \"hive\". This library only handles a single -hive file at a time. - -Hives are n-ary trees with a single root. Each node in the tree -has a name. - -Each node in the tree (including non-leaf nodes) may have an -arbitrary list of (key, value) pairs attached to it. It may -be the case that one of these pairs has an empty key. This -is referred to as the default key for the node. - -The (key, value) pairs are the place where the useful data is -stored in the registry. The key is always a string (possibly the -empty string for the default key). The value is a typed object -(eg. string, int32, binary, etc.). - -=head2 RELATIONSHIP TO .REG FILES - -The hivex C library does not care about or deal with Windows .REG -files. Instead we push this complexity up to the Perl -L library and the Perl programs -L and L. -Nevertheless it is useful to look at the relationship between the -Registry and .REG files because they are so common. - -A .REG file is a textual representation of the registry, or part of the -registry. The actual registry hives that Windows uses are binary -files. There are a number of Windows and Linux tools that let you -generate .REG files, or merge .REG files back into the registry hives. -Notable amongst them is Microsoft's REGEDIT program (formerly known as -REGEDT32). - -A typical .REG file will contain many sections looking like this: - - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack] - \"@\"=\"Generic Stack\" - \"TileInfo\"=\"prop:System.FileCount\" - \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\" - \"ThumbnailCutoff\"=dword:00000000 - \"FriendlyTypeName\"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,\\ - 6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,\\ - 33,00,32,00,5c,00,73,00,65,00,61,00,72,00,63,00,68,00,66,00,\\ - 6f,00,6c,00,64,00,65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,\\ - 2d,00,39,00,30,00,32,00,38,00,00,00,d8 - -Taking this one piece at a time: - - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack] - -This is the path to this node in the registry tree. The first part, -C means that this comes from a hive -file called C. -C<\\Classes\\Stack> is the real path part, -starting at the root node of the C hive. - -Below the node name is a list of zero or more key-value pairs. Any -interior or leaf node in the registry may have key-value pairs -attached. - - \"@\"=\"Generic Stack\" - -This is the \"default key\". In reality (ie. inside the binary hive) -the key string is the empty string. In .REG files this is written as -C<@> but this has no meaning either in the hives themselves or in this -library. The value is a string (type 1 - see C -above). - - \"TileInfo\"=\"prop:System.FileCount\" - -This is a regular (key, value) pair, with the value being a type 1 -string. Note that inside the binary file the string is likely to be -UTF-16LE encoded. This library converts to and from UTF-8 strings -transparently in some cases. - - \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\" - -The value in this case has type 2 (expanded string) meaning that some -%%...%% variables get expanded by Windows. (This library doesn't know -or care about variable expansion). - - \"ThumbnailCutoff\"=dword:00000000 - -The value in this case is a dword (type 4). - - \"FriendlyTypeName\"=hex(2):40,00,.... - -This value is an expanded string (type 2) represented in the .REG file -as a series of hex bytes. In this case the string appears to be a -UTF-16LE string. - -=head1 NOTE ON THE USE OF ERRNO - -Many functions in this library set errno to indicate errors. These -are the values of errno you may encounter (this list is not -exhaustive): - -=over 4 - -=item ENOTSUP - -Corrupt or unsupported Registry file format. - -=item HIVEX_NO_KEY - -Missing root key. - -=item EINVAL - -Passed an invalid argument to the function. - -=item EFAULT - -Followed a Registry pointer which goes outside -the registry or outside a registry block. - -=item ELOOP - -Registry contains cycles. - -=item ERANGE - -Field in the registry out of range. - -=item EEXIST - -Registry key already exists. - -=item EROFS - -Tried to write to a registry which is not opened for writing. - -=back - -=head1 ENVIRONMENT VARIABLES - -=over 4 - -=item HIVEX_DEBUG - -Setting HIVEX_DEBUG=1 will enable very verbose messages. This is -useful for debugging problems with the library itself. - -=back - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L, -L, -L, -L, -L. - -=head1 AUTHORS - -Richard W.M. Jones (C) - -=head1 COPYRIGHT - -Copyright (C) 2009-2010 Red Hat Inc. - -Derived from code by Petter Nordahl-Hagen under a compatible license: -Copyright (C) 1997-2007 Petter Nordahl-Hagen. - -Derived from code by Markus Stephany under a compatible license: -Copyright (C) 2000-2004 Markus Stephany. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library 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 -Lesser General Public License for more details. -" - -(* Generate the linker script which controls the visibility of - * symbols in the public ABI and ensures no other symbols get - * exported accidentally. - *) -and generate_linker_script () = - generate_header HashStyle GPLv2plus; - - let globals = [ - "hivex_visit"; - "hivex_visit_node" - ] in - - let functions = - List.map (fun (name, _, _, _) -> "hivex_" ^ name) - functions in - let globals = List.sort compare (globals @ functions) in - - pr "{\n"; - pr " global:\n"; - List.iter (pr " %s;\n") globals; - pr "\n"; - - pr " local:\n"; - pr " *;\n"; - pr "};\n" - -and generate_ocaml_interface () = - generate_header OCamlStyle LGPLv2plus; - - pr "\ -type t -(** A [hive_h] hive file handle. *) - -type node -type value -(** Nodes and values. *) - -exception Error of string * Unix.error * string -(** Error raised by a function. - - The first parameter is the name of the function which raised the error. - The second parameter is the errno (see the [Unix] module). The third - parameter is a human-readable string corresponding to the errno. - - See hivex(3) for a partial list of interesting errno values that - can be generated by the library. *) -exception Handle_closed of string -(** This exception is raised if you call a function on a closed handle. *) - -type hive_type = -"; - iteri ( - fun i -> - fun (t, _, new_style, description) -> - assert (i = t); - pr " | REG_%s (** %s *)\n" new_style description - ) hive_types; - - pr "\ - | REG_UNKNOWN of int32 (** unknown type *) -(** Hive type field. *) - -type open_flag = -"; - iteri ( - fun i -> - fun (v, flag, description) -> - assert (1 lsl i = v); - pr " | OPEN_%s (** %s *)\n" flag description - ) open_flags; - - pr "\ -(** Open flags for {!open_file} call. *) - -type set_value = { - key : string; - t : hive_type; - value : string; -} -(** (key, value) pair passed (as an array) to {!node_set_values}. *) -"; - - List.iter ( - fun (name, style, shortdesc, _) -> - pr "\n"; - generate_ocaml_prototype name style; - pr "(** %s *)\n" shortdesc - ) functions - -and generate_ocaml_implementation () = - generate_header OCamlStyle LGPLv2plus; - - pr "\ -type t -type node = int -type value = int - -exception Error of string * Unix.error * string -exception Handle_closed of string - -(* Give the exceptions names, so they can be raised from the C code. *) -let () = - Callback.register_exception \"ocaml_hivex_error\" - (Error (\"\", Unix.EUNKNOWNERR 0, \"\")); - Callback.register_exception \"ocaml_hivex_closed\" (Handle_closed \"\") - -type hive_type = -"; - iteri ( - fun i -> - fun (t, _, new_style, _) -> - assert (i = t); - pr " | REG_%s\n" new_style - ) hive_types; - - pr "\ - | REG_UNKNOWN of int32 - -type open_flag = -"; - iteri ( - fun i -> - fun (v, flag, description) -> - assert (1 lsl i = v); - pr " | OPEN_%s (** %s *)\n" flag description - ) open_flags; - - pr "\ - -type set_value = { - key : string; - t : hive_type; - value : string; -} - -"; - - List.iter ( - fun (name, style, _, _) -> - generate_ocaml_prototype ~is_external:true name style - ) functions - -and generate_ocaml_prototype ?(is_external = false) name style = - let ocaml_name = if name = "open" then "open_file" else name in - - if is_external then pr "external " else pr "val "; - pr "%s : " ocaml_name; - List.iter ( - function - | AHive -> pr "t -> " - | ANode _ -> pr "node -> " - | AValue _ -> pr "value -> " - | AString _ -> pr "string -> " - | AStringNullable _ -> pr "string option -> " - | AOpenFlags -> pr "open_flag list -> " - | AUnusedFlags -> () - | ASetValues -> pr "set_value array -> " - | ASetValue -> pr "set_value -> " - ) (snd style); - (match fst style with - | RErr -> pr "unit" (* all errors are turned into exceptions *) - | RErrDispose -> pr "unit" - | RHive -> pr "t" - | RSize -> pr "int64" - | RNode -> pr "node" - | RNodeNotFound -> pr "node" - | RNodeList -> pr "node array" - | RValue -> pr "value" - | RValueList -> pr "value array" - | 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" - ); - if is_external then - pr " = \"ocaml_hivex_%s\"" name; - pr "\n" - -and generate_ocaml_c () = - generate_header CStyle LGPLv2plus; - - pr "\ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_CAML_UNIXSUPPORT_H -#include -#else -extern value unix_error_of_code (int errcode); -#endif - -#ifndef HAVE_CAML_RAISE_WITH_ARGS -static void -caml_raise_with_args (value tag, int nargs, value args[]) -{ - CAMLparam1 (tag); - CAMLxparamN (args, nargs); - value bucket; - int i; - - bucket = caml_alloc_small (1 + nargs, 0); - Field(bucket, 0) = tag; - for (i = 0; i < nargs; i++) Field(bucket, 1 + i) = args[i]; - caml_raise(bucket); - CAMLnoreturn; -} -#endif - -#include - -#define Hiveh_val(v) (*((hive_h **)Data_custom_val(v))) -static value Val_hiveh (hive_h *); -static int HiveOpenFlags_val (value); -static hive_set_value *HiveSetValue_val (value); -static hive_set_value *HiveSetValues_val (value); -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; - -"; - - (* The wrappers. *) - List.iter ( - fun (name, style, _, _) -> - pr "/* Automatically generated wrapper for function\n"; - pr " * "; generate_ocaml_prototype name style; - pr " */\n"; - pr "\n"; - - let c_params = - List.map (function - | ASetValues -> ["nrvalues"; "values"] - | AUnusedFlags -> ["0"] - | arg -> [name_of_argt arg]) (snd style) in - 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 - - let params = - filter_map (function - | AUnusedFlags -> None - | arg -> Some (name_of_argt arg ^ "v")) (snd style) in - - pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n"; - pr "CAMLprim value ocaml_hivex_%s (value %s" name (List.hd params); - List.iter (pr ", value %s") (List.tl params); pr ");\n"; - pr "\n"; - - pr "CAMLprim value\n"; - pr "ocaml_hivex_%s (value %s" name (List.hd params); - List.iter (pr ", value %s") (List.tl params); - pr ")\n"; - pr "{\n"; - - pr " CAMLparam%d (%s);\n" - (List.length params) (String.concat ", " params); - pr " CAMLlocal1 (rv);\n"; - pr "\n"; - - List.iter ( - function - | AHive -> - pr " hive_h *h = Hiveh_val (hv);\n"; - pr " if (h == NULL)\n"; - pr " raise_closed (\"%s\");\n" name - | ANode n -> - pr " hive_node_h %s = Int_val (%sv);\n" n n - | AValue n -> - pr " hive_value_h %s = Int_val (%sv);\n" n n - | AString n -> - pr " const char *%s = String_val (%sv);\n" n n - | AStringNullable n -> - pr " const char *%s =\n" n; - pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n" - n n - | AOpenFlags -> - pr " int flags = HiveOpenFlags_val (flagsv);\n" - | AUnusedFlags -> () - | ASetValues -> - pr " int nrvalues = Wosize_val (valuesv);\n"; - pr " hive_set_value *values = HiveSetValues_val (valuesv);\n" - | ASetValue -> - pr " hive_set_value *val = HiveSetValue_val (valv);\n" - ) (snd style); - pr "\n"; - - let error_code = - match fst style with - | RErr -> pr " int r;\n"; "-1" - | RErrDispose -> pr " int r;\n"; "-1" - | RHive -> pr " hive_h *r;\n"; "NULL" - | RSize -> pr " size_t r;\n"; "0" - | RNode -> pr " hive_node_h r;\n"; "0" - | RNodeNotFound -> - pr " errno = 0;\n"; - pr " hive_node_h r;\n"; - "0 && errno != 0" - | RNodeList -> pr " hive_node_h *r;\n"; "NULL" - | RValue -> pr " hive_value_h r;\n"; "0" - | RValueList -> pr " hive_value_h *r;\n"; "NULL" - | RString -> pr " char *r;\n"; "NULL" - | RStringList -> pr " char **r;\n"; "NULL" - | RLenType -> - pr " int r;\n"; - 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"; - pr " hive_type t;\n"; - "NULL" - | RInt32 -> - pr " errno = 0;\n"; - pr " int32_t r;\n"; - "-1 && errno != 0" - | RInt64 -> - pr " errno = 0;\n"; - pr " int64_t r;\n"; - "-1 && errno != 0" in - - (* The libguestfs OCaml bindings call enter_blocking_section - * here. However I don't think that is safe, because we are - * holding pointers to caml strings during the call, and these - * could be moved or freed by other threads. In any case, there - * is very little reason to enter_blocking_section for any hivex - * call, so don't do it. XXX - *) - (*pr " caml_enter_blocking_section ();\n";*) - pr " r = hivex_%s (%s" name (List.hd c_params); - List.iter (pr ", %s") (List.tl c_params); - pr ");\n"; - (*pr " caml_leave_blocking_section ();\n";*) - pr "\n"; - - (* Dispose of the hive handle (even if hivex_close returns error). *) - (match fst style with - | RErrDispose -> - pr " /* So we don't double-free in the finalizer. */\n"; - pr " Hiveh_val (hv) = NULL;\n"; - pr "\n"; - | _ -> () - ); - - List.iter ( - function - | AHive | ANode _ | AValue _ | AString _ | AStringNullable _ - | AOpenFlags | AUnusedFlags -> () - | ASetValues -> - pr " free (values);\n"; - pr "\n"; - | ASetValue -> - pr " free (val);\n"; - pr "\n"; - ) (snd style); - - (* Check for errors. *) - pr " if (r == %s)\n" error_code; - pr " raise_error (\"%s\");\n" name; - pr "\n"; - - (match fst style with - | RErr -> pr " rv = Val_unit;\n" - | RErrDispose -> pr " rv = Val_unit;\n" - | RHive -> pr " rv = Val_hiveh (r);\n" - | RSize -> pr " rv = caml_copy_int64 (r);\n" - | RNode -> pr " rv = Val_int (r);\n" - | RNodeNotFound -> - pr " if (r == 0)\n"; - pr " caml_raise_not_found ();\n"; - pr "\n"; - pr " rv = Val_int (r);\n" - | RNodeList -> - pr " rv = copy_int_array (r);\n"; - pr " free (r);\n" - | RValue -> pr " rv = Val_int (r);\n" - | RValueList -> - pr " rv = copy_int_array (r);\n"; - pr " free (r);\n" - | RString -> - pr " rv = caml_copy_string (r);\n"; - pr " free (r);\n" - | RStringList -> - pr " rv = caml_copy_string_array ((const char **) r);\n"; - pr " int i;\n"; - pr " for (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" - | RInt32 -> pr " rv = caml_copy_int32 (r);\n" - | RInt64 -> pr " rv = caml_copy_int64 (r);\n" - ); - - pr " CAMLreturn (rv);\n"; - pr "}\n"; - pr "\n"; - - ) functions; - - pr "\ -static int -HiveOpenFlags_val (value v) -{ - int flags = 0; - value v2; - - while (v != Val_int (0)) { - v2 = Field (v, 0); - flags |= 1 << Int_val (v2); - v = Field (v, 1); - } - - return flags; -} - -static hive_set_value * -HiveSetValue_val (value v) -{ - hive_set_value *val = malloc (sizeof (hive_set_value)); - - val->key = String_val (Field (v, 0)); - val->t = HiveType_val (Field (v, 1)); - val->len = caml_string_length (Field (v, 2)); - val->value = String_val (Field (v, 2)); - - return val; -} - -static hive_set_value * -HiveSetValues_val (value v) -{ - size_t nr_values = Wosize_val (v); - hive_set_value *values = malloc (nr_values * sizeof (hive_set_value)); - size_t i; - value v2; - - for (i = 0; i < nr_values; ++i) { - v2 = Field (v, i); - values[i].key = String_val (Field (v2, 0)); - values[i].t = HiveType_val (Field (v2, 1)); - values[i].len = caml_string_length (Field (v2, 2)); - values[i].value = String_val (Field (v2, 2)); - } - - return values; -} - -static hive_type -HiveType_val (value v) -{ - if (Is_long (v)) - return Int_val (v); /* REG_NONE etc. */ - else - return Int32_val (Field (v, 0)); /* REG_UNKNOWN of int32 */ -} - -static value -Val_hive_type (hive_type t) -{ - CAMLparam0 (); - CAMLlocal2 (rv, v); - - if (t <= %d) - CAMLreturn (Val_int (t)); - else { - rv = caml_alloc (1, 0); /* REG_UNKNOWN of int32 */ - v = caml_copy_int32 (t); - caml_modify (&Field (rv, 0), v); - CAMLreturn (rv); - } -} - -static value -copy_int_array (size_t *xs) -{ - CAMLparam0 (); - CAMLlocal2 (v, rv); - size_t nr, i; - - for (nr = 0; xs[nr] != 0; ++nr) - ; - if (nr == 0) - CAMLreturn (Atom (0)); - else { - rv = caml_alloc (nr, 0); - for (i = 0; i < nr; ++i) { - v = Val_int (xs[i]); - Store_field (rv, i, v); /* Safe because v is not a block. */ - } - CAMLreturn (rv); - } -} - -static value -copy_type_len (size_t len, hive_type t) -{ - CAMLparam0 (); - CAMLlocal2 (v, rv); - - rv = caml_alloc (2, 0); - v = Val_hive_type (t); - Store_field (rv, 0, v); - v = Val_int (len); - Store_field (rv, 1, v); - CAMLreturn (rv); -} - -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 (); - CAMLlocal2 (v, rv); - - rv = caml_alloc (2, 0); - v = Val_hive_type (t); - Store_field (rv, 0, v); - v = caml_alloc_string (len); - memcpy (String_val (v), r, len); - caml_modify (&Field (rv, 1), v); - CAMLreturn (rv); -} - -/* Raise exceptions. */ -static void -raise_error (const char *function) -{ - /* Save errno early in case it gets trashed. */ - int err = errno; - - CAMLparam0 (); - CAMLlocal3 (v1, v2, v3); - - v1 = caml_copy_string (function); - v2 = unix_error_of_code (err); - v3 = caml_copy_string (strerror (err)); - value vvv[] = { v1, v2, v3 }; - caml_raise_with_args (*caml_named_value (\"ocaml_hivex_error\"), 3, vvv); - - CAMLnoreturn; -} - -static void -raise_closed (const char *function) -{ - CAMLparam0 (); - CAMLlocal1 (v); - - v = caml_copy_string (function); - caml_raise_with_arg (*caml_named_value (\"ocaml_hivex_closed\"), v); - - CAMLnoreturn; -} - -/* Allocate handles and deal with finalization. */ -static void -hivex_finalize (value hv) -{ - hive_h *h = Hiveh_val (hv); - if (h) hivex_close (h); -} - -static struct custom_operations hivex_custom_operations = { - (char *) \"hivex_custom_operations\", - hivex_finalize, - custom_compare_default, - custom_hash_default, - custom_serialize_default, - custom_deserialize_default -}; - -static value -Val_hiveh (hive_h *h) -{ - CAMLparam0 (); - CAMLlocal1 (rv); - - rv = caml_alloc_custom (&hivex_custom_operations, - sizeof (hive_h *), 0, 1); - Hiveh_val (rv) = h; - - CAMLreturn (rv); -} -" max_hive_type - -and generate_perl_pm () = - generate_header HashStyle LGPLv2plus; - - pr "\ -=pod - -=head1 NAME - -Win::Hivex - Perl bindings for reading and writing Windows Registry hive files - -=head1 SYNOPSIS - - use Win::Hivex; - - $h = Win::Hivex->open ('SOFTWARE'); - $root_node = $h->root (); - print $h->node_name ($root_node); - -=head1 DESCRIPTION - -The C module provides a Perl XS binding to the -L API for reading and writing Windows Registry binary -hive files. - -=head1 ERRORS - -All errors turn into calls to C (see L). - -=head1 METHODS - -=over 4 - -=cut - -package Win::Hivex; - -use strict; -use warnings; - -require XSLoader; -XSLoader::load ('Win::Hivex'); - -=item open - - $h = Win::Hivex->open ($filename,"; - - List.iter ( - fun (_, flag, _) -> - pr "\n [%s => 1,]" (String.lowercase flag) - ) open_flags; - - pr ") - -Open a Windows Registry binary hive file. - -The C and C flags enable different levels of -debugging messages. - -The C flag is required if you will be modifying the -hive file (see L). - -This function returns a hive handle. The hive handle is -closed automatically when its reference count drops to 0. - -=cut - -sub open { - my $proto = shift; - my $class = ref ($proto) || $proto; - my $filename = shift; - my %%flags = @_; - my $flags = 0; - -"; - - List.iter ( - fun (n, flag, description) -> - pr " # %s\n" description; - pr " $flags += %d if $flags{%s};\n" n (String.lowercase flag) - ) open_flags; - - pr "\ - - my $self = Win::Hivex::_open ($filename, $flags); - bless $self, $class; - return $self; -} - -"; - - List.iter ( - fun (name, style, _, longdesc) -> - (* The close call isn't explicit in Perl: handles are closed - * when their reference count drops to 0. - * - * The open call is coded specially in Perl. - * - * Therefore we don't generate prototypes for these two calls: - *) - if fst style <> RErrDispose && List.hd (snd style) = AHive then ( - let longdesc = replace_str longdesc "C () - | RSize -> - pr "\ -This returns a size.\n\n" - | RNode -> - pr "\ -This returns a node handle.\n\n" - | RNodeNotFound -> - pr "\ -This returns a node handle, or C if the node was not found.\n\n" - | RNodeList -> - pr "\ -This returns a list of node handles.\n\n" - | RValue -> - pr "\ -This returns a value handle.\n\n" - | RValueList -> - pr "\ -This returns a list of value handles.\n\n" - ); - - if List.mem ASetValues (snd style) then - pr "C<@values> is an array of (keys, value) pairs. -Each element should be a hashref containing C, C (type) -and C. - -Any existing values stored at the node are discarded, and their -C handles become invalid. Thus you can remove all -values stored at C by passing C<@values = []>.\n\n" - ) - ) functions; - - pr "\ -=cut - -1; - -=back - -=head1 COPYRIGHT - -Copyright (C) %s Red Hat Inc. - -=head1 LICENSE - -Please see the file COPYING.LIB for the full license. - -=head1 SEE ALSO - -L, -L, -L, -L. - -=cut -" copyright_years - -and generate_perl_prototype name style = - (* Return type. *) - (match fst style with - | RErr - | RErrDispose -> () - | RHive -> pr "$h = " - | RSize -> pr "$size = " - | RNode - | RNodeNotFound -> pr "$node = " - | RNodeList -> pr "@nodes = " - | RValue -> pr "$value = " - | RValueList -> pr "@values = " - | RString -> pr "$string = " - | RStringList -> pr "@strings = " - | RLenType -> pr "($type, $len) = " - | RLenValue -> pr "($len, $value) = " - | RLenTypeVal -> pr "($type, $data) = " - | RInt32 -> pr "$int32 = " - | RInt64 -> pr "$int64 = " - ); - - let args = List.tl (snd style) in - - (* AUnusedFlags is dropped in the bindings. *) - let args = List.filter ((<>) AUnusedFlags) args in - - pr "$h->%s (" name; - - let comma = ref false in - List.iter ( - fun arg -> - if !comma then pr ", "; comma := true; - match arg with - | AHive -> pr "$h" - | ANode n - | AValue n - | AString n -> pr "$%s" n - | AStringNullable n -> pr "[$%s|undef]" n - | AOpenFlags -> pr "[flags]" - | AUnusedFlags -> assert false - | ASetValues -> pr "\\@values" - | ASetValue -> pr "$val" - ) args; - - pr ")" - -and generate_perl_xs () = - generate_header CStyle LGPLv2plus; - - pr "\ -#include \"EXTERN.h\" -#include \"perl.h\" -#include \"XSUB.h\" - -#include -#include -#include - -static SV * -my_newSVll(long long val) { -#ifdef USE_64_BIT_ALL - return newSViv(val); -#else - char buf[100]; - int len; - len = snprintf(buf, 100, \"%%\" PRId64, val); - return newSVpv(buf, len); -#endif -} - -#if 0 -static SV * -my_newSVull(unsigned long long val) { -#ifdef USE_64_BIT_ALL - return newSVuv(val); -#else - char buf[100]; - int len; - len = snprintf(buf, 100, \"%%\" PRIu64, val); - return newSVpv(buf, len); -#endif -} -#endif - -#if 0 -/* http://www.perlmonks.org/?node_id=680842 */ -static char ** -XS_unpack_charPtrPtr (SV *arg) { - char **ret; - AV *av; - I32 i; - - if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV) - croak (\"array reference expected\"); - - av = (AV *)SvRV (arg); - ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *)); - if (!ret) - croak (\"malloc failed\"); - - for (i = 0; i <= av_len (av); i++) { - SV **elem = av_fetch (av, i, 0); - - if (!elem || !*elem) - croak (\"missing element in list\"); - - ret[i] = SvPV_nolen (*elem); - } - - ret[i] = NULL; - - return ret; -} -#endif - -/* Handle set_values parameter. */ -typedef struct pl_set_values { - size_t nr_values; - hive_set_value *values; -} pl_set_values; - -static pl_set_values -unpack_pl_set_values (SV *sv) -{ - pl_set_values ret; - AV *av; - I32 i; - - if (!sv || !SvOK (sv) || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV) - croak (\"array reference expected\"); - - av = (AV *)SvRV(sv); - ret.nr_values = av_len (av) + 1; - ret.values = malloc (ret.nr_values * sizeof (hive_set_value)); - if (!ret.values) - croak (\"malloc failed\"); - - for (i = 0; i <= av_len (av); i++) { - SV **hvp = av_fetch (av, i, 0); - - if (!hvp || !*hvp || !SvROK (*hvp) || SvTYPE (SvRV (*hvp)) != SVt_PVHV) - croak (\"missing element in list or not a hash ref\"); - - HV *hv = (HV *)SvRV(*hvp); - - SV **svp; - svp = hv_fetch (hv, \"key\", 3, 0); - if (!svp || !*svp) - croak (\"missing 'key' in hash\"); - ret.values[i].key = SvPV_nolen (*svp); - - svp = hv_fetch (hv, \"t\", 1, 0); - if (!svp || !*svp) - croak (\"missing 't' in hash\"); - ret.values[i].t = SvIV (*svp); - - svp = hv_fetch (hv, \"value\", 5, 0); - if (!svp || !*svp) - croak (\"missing 'value' in hash\"); - ret.values[i].value = SvPV (*svp, ret.values[i].len); - } - - return ret; -} - -static hive_set_value * -unpack_set_value (SV *sv) -{ - hive_set_value *ret; - - if (!sv || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVHV) - croak (\"not a hash ref\"); - - ret = malloc (sizeof (hive_set_value)); - if (ret == NULL) - croak (\"malloc failed\"); - - HV *hv = (HV *)SvRV(sv); - - SV **svp; - svp = hv_fetch (hv, \"key\", 3, 0); - if (!svp || !*svp) - croak (\"missing 'key' in hash\"); - ret->key = SvPV_nolen (*svp); - - svp = hv_fetch (hv, \"t\", 1, 0); - if (!svp || !*svp) - croak (\"missing 't' in hash\"); - ret->t = SvIV (*svp); - - svp = hv_fetch (hv, \"value\", 5, 0); - if (!svp || !*svp) - croak (\"missing 'value' in hash\"); - ret->value = SvPV (*svp, ret->len); - - return ret; -} - -MODULE = Win::Hivex PACKAGE = Win::Hivex - -PROTOTYPES: ENABLE - -hive_h * -_open (filename, flags) - char *filename; - int flags; - CODE: - RETVAL = hivex_open (filename, flags); - if (!RETVAL) - croak (\"hivex_open: %%s: %%s\", filename, strerror (errno)); - OUTPUT: - RETVAL - -void -DESTROY (h) - hive_h *h; - PPCODE: - if (hivex_close (h) == -1) - croak (\"hivex_close: %%s\", strerror (errno)); - -"; - - List.iter ( - fun (name, style, _, longdesc) -> - (* The close and open calls are handled specially above. *) - if fst style <> RErrDispose && List.hd (snd style) = AHive then ( - (match fst style with - | RErr -> pr "void\n" - | RErrDispose -> failwith "perl bindings cannot handle a call which disposes of the handle" - | RHive -> failwith "perl bindings cannot handle a call which returns a handle" - | RSize - | RNode - | RNodeNotFound - | RValue - | RString -> pr "SV *\n" - | RNodeList - | RValueList - | RStringList - | RLenType - | RLenValue - | RLenTypeVal -> pr "void\n" - | RInt32 -> pr "SV *\n" - | RInt64 -> pr "SV *\n" - ); - - (* Call and arguments. *) - let perl_params = - filter_map (function - | AUnusedFlags -> None - | arg -> Some (name_of_argt arg)) (snd style) in - - let c_params = - List.map (function - | AUnusedFlags -> "0" - | ASetValues -> "values.nr_values, values.values" - | arg -> name_of_argt arg) (snd style) in - - pr "%s (%s)\n" name (String.concat ", " perl_params); - iteri ( - fun i -> - function - | AHive -> - pr " hive_h *h;\n" - | ANode n - | AValue n -> - pr " int %s;\n" n - | AString n -> - pr " char *%s;\n" n - | AStringNullable n -> - (* http://www.perlmonks.org/?node_id=554277 *) - pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n i i - | AOpenFlags -> - pr " int flags;\n" - | AUnusedFlags -> () - | ASetValues -> - pr " pl_set_values values = unpack_pl_set_values (ST(%d));\n" i - | ASetValue -> - pr " hive_set_value *val = unpack_set_value (ST(%d));\n" i - ) (snd style); - - let free_args () = - List.iter ( - function - | ASetValues -> - pr " free (values.values);\n" - | ASetValue -> - pr " free (val);\n" - | AHive | ANode _ | AValue _ | AString _ | AStringNullable _ - | AOpenFlags | AUnusedFlags -> () - ) (snd style) - in - - (* Code. *) - (match fst style with - | RErr -> - pr "PREINIT:\n"; - pr " int r;\n"; - pr " PPCODE:\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == -1)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - - | RErrDispose -> assert false - | RHive -> assert false - - | RSize - | RNode - | RValue -> - pr "PREINIT:\n"; - pr " /* hive_node_h = hive_value_h = size_t so we cheat\n"; - pr " here to simplify the generator */\n"; - pr " size_t r;\n"; - pr " CODE:\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == 0)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " RETVAL = newSViv (r);\n"; - pr " OUTPUT:\n"; - pr " RETVAL\n" - - | RNodeNotFound -> - pr "PREINIT:\n"; - pr " hive_node_h r;\n"; - pr " CODE:\n"; - pr " errno = 0;\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == 0 && errno != 0)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " if (r == 0)\n"; - pr " RETVAL = &PL_sv_undef;\n"; - pr " else\n"; - pr " RETVAL = newSViv (r);\n"; - pr " OUTPUT:\n"; - pr " RETVAL\n" - - | RString -> - pr "PREINIT:\n"; - pr " char *r;\n"; - pr " CODE:\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == NULL)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " RETVAL = newSVpv (r, 0);\n"; - pr " free (r);\n"; - pr " OUTPUT:\n"; - pr " RETVAL\n" - - | RNodeList - | RValueList -> - pr "PREINIT:\n"; - pr " size_t *r;\n"; - pr " int i, n;\n"; - pr " PPCODE:\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == NULL)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " for (n = 0; r[n] != 0; ++n) /**/;\n"; - pr " EXTEND (SP, n);\n"; - pr " for (i = 0; i < n; ++i)\n"; - pr " PUSHs (sv_2mortal (newSViv (r[i])));\n"; - pr " free (r);\n"; - - | RStringList -> - pr "PREINIT:\n"; - pr " char **r;\n"; - pr " int i, n;\n"; - pr " PPCODE:\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == NULL)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " for (n = 0; r[n] != NULL; ++n) /**/;\n"; - pr " EXTEND (SP, n);\n"; - pr " for (i = 0; i < n; ++i) {\n"; - pr " PUSHs (sv_2mortal (newSVpv (r[i], 0)));\n"; - pr " free (r[i]);\n"; - pr " }\n"; - pr " free (r);\n"; - - | RLenType -> - pr "PREINIT:\n"; - pr " int r;\n"; - pr " size_t len;\n"; - pr " hive_type type;\n"; - pr " PPCODE:\n"; - pr " r = hivex_%s (%s, &type, &len);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == -1)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " EXTEND (SP, 2);\n"; - 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"; - pr " size_t len;\n"; - pr " hive_type type;\n"; - pr " PPCODE:\n"; - pr " r = hivex_%s (%s, &type, &len);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == NULL)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " EXTEND (SP, 2);\n"; - pr " PUSHs (sv_2mortal (newSViv (type)));\n"; - pr " PUSHs (sv_2mortal (newSVpvn (r, len)));\n"; - pr " free (r);\n"; - - | RInt32 -> - pr "PREINIT:\n"; - pr " int32_t r;\n"; - pr " CODE:\n"; - pr " errno = 0;\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == -1 && errno != 0)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " RETVAL = newSViv (r);\n"; - pr " OUTPUT:\n"; - pr " RETVAL\n" - - | RInt64 -> - pr "PREINIT:\n"; - pr " int64_t r;\n"; - pr " CODE:\n"; - pr " errno = 0;\n"; - pr " r = hivex_%s (%s);\n" - name (String.concat ", " c_params); - free_args (); - pr " if (r == -1 && errno != 0)\n"; - pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n" - name; - pr " RETVAL = my_newSVll (r);\n"; - pr " OUTPUT:\n"; - pr " RETVAL\n" - ); - pr "\n" - ) - ) functions - -and generate_python_c () = - generate_header CStyle LGPLv2plus; - - pr "\ -#include - -#define PY_SSIZE_T_CLEAN 1 -#include - -#if PY_VERSION_HEX < 0x02050000 -typedef int Py_ssize_t; -#define PY_SSIZE_T_MAX INT_MAX -#define PY_SSIZE_T_MIN INT_MIN -#endif - -#include -#include -#include - -#include \"hivex.h\" - -#ifndef HAVE_PYCAPSULE_NEW -typedef struct { - PyObject_HEAD - hive_h *h; -} Pyhivex_Object; -#endif - -static hive_h * -get_handle (PyObject *obj) -{ - assert (obj); - assert (obj != Py_None); -#ifndef HAVE_PYCAPSULE_NEW - return ((Pyhivex_Object *) obj)->h; -#else - return (hive_h *) PyCapsule_GetPointer(obj, \"hive_h\"); -#endif -} - -static PyObject * -put_handle (hive_h *h) -{ - assert (h); -#ifndef HAVE_PYCAPSULE_NEW - return - PyCObject_FromVoidPtrAndDesc ((void *) h, (char *) \"hive_h\", NULL); -#else - return PyCapsule_New ((void *) h, \"hive_h\", NULL); -#endif -} - -/* This returns pointers into the Python objects, which should - * not be freed. - */ -static int -get_value (PyObject *v, hive_set_value *ret) -{ - PyObject *obj; -#ifndef HAVE_PYSTRING_ASSTRING - PyObject *bytes; -#endif - - obj = PyDict_GetItemString (v, \"key\"); - if (!obj) { - PyErr_SetString (PyExc_RuntimeError, \"no 'key' element in dictionary\"); - return -1; - } -#ifdef HAVE_PYSTRING_ASSTRING - ret->key = PyString_AsString (obj); -#else - bytes = PyUnicode_AsUTF8String (obj); - ret->key = PyBytes_AS_STRING (bytes); -#endif - - obj = PyDict_GetItemString (v, \"t\"); - if (!obj) { - PyErr_SetString (PyExc_RuntimeError, \"no 't' element in dictionary\"); - return -1; - } - ret->t = PyLong_AsLong (obj); - - obj = PyDict_GetItemString (v, \"value\"); - if (!obj) { - PyErr_SetString (PyExc_RuntimeError, \"no 'value' element in dictionary\"); - return -1; - } -#ifdef HAVE_PYSTRING_ASSTRING - ret->value = PyString_AsString (obj); - ret->len = PyString_Size (obj); -#else - bytes = PyUnicode_AsUTF8String (obj); - ret->value = PyBytes_AS_STRING (bytes); - ret->len = PyBytes_GET_SIZE (bytes); -#endif - - return 0; -} - -typedef struct py_set_values { - size_t nr_values; - hive_set_value *values; -} py_set_values; - -static int -get_values (PyObject *v, py_set_values *ret) -{ - Py_ssize_t slen; - size_t len, i; - - if (!PyList_Check (v)) { - PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\"); - return -1; - } - - slen = PyList_Size (v); - if (slen < 0) { - PyErr_SetString (PyExc_RuntimeError, \"get_string_list: PyList_Size failure\"); - return -1; - } - len = (size_t) slen; - ret->nr_values = len; - ret->values = malloc (len * sizeof (hive_set_value)); - if (!ret->values) { - PyErr_SetString (PyExc_RuntimeError, strerror (errno)); - return -1; - } - - for (i = 0; i < len; ++i) { - if (get_value (PyList_GetItem (v, i), &(ret->values[i])) == -1) { - free (ret->values); - return -1; - } - } - - return 0; -} - -static PyObject * -put_string_list (char * const * const argv) -{ - PyObject *list; - size_t argc, i; - - for (argc = 0; argv[argc] != NULL; ++argc) - ; - - list = PyList_New (argc); - for (i = 0; i < argc; ++i) { -#ifdef HAVE_PYSTRING_ASSTRING - PyList_SetItem (list, i, PyString_FromString (argv[i])); -#else - PyList_SetItem (list, i, PyUnicode_FromString (argv[i])); -#endif - } - - return list; -} - -static void -free_strings (char **argv) -{ - size_t argc; - - for (argc = 0; argv[argc] != NULL; ++argc) - free (argv[argc]); - free (argv); -} - -/* Since hive_node_t is the same as hive_value_t this also works for values. */ -static PyObject * -put_node_list (hive_node_h *nodes) -{ - PyObject *list; - size_t argc, i; - - for (argc = 0; nodes[argc] != 0; ++argc) - ; - - list = PyList_New (argc); - for (i = 0; i < argc; ++i) - PyList_SetItem (list, i, PyLong_FromLongLong ((long) nodes[i])); - - return list; -} - -static PyObject * -put_len_type (size_t len, hive_type t) -{ - PyObject *r = PyTuple_New (2); - PyTuple_SetItem (r, 0, PyLong_FromLong ((long) t)); - PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) len)); - return r; -} - -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); - PyTuple_SetItem (r, 0, PyLong_FromLong ((long) t)); -#ifdef HAVE_PYSTRING_ASSTRING - PyTuple_SetItem (r, 1, PyString_FromStringAndSize (val, len)); -#else - PyTuple_SetItem (r, 1, PyBytes_FromStringAndSize (val, len)); -#endif - return r; -} - -"; - - (* Generate functions. *) - List.iter ( - fun (name, style, _, longdesc) -> - pr "static PyObject *\n"; - pr "py_hivex_%s (PyObject *self, PyObject *args)\n" name; - pr "{\n"; - pr " PyObject *py_r;\n"; - - let error_code = - match fst style with - | RErr -> pr " int r;\n"; "-1" - | RErrDispose -> pr " int r;\n"; "-1" - | RHive -> pr " hive_h *r;\n"; "NULL" - | RSize -> pr " size_t r;\n"; "0" - | RNode -> pr " hive_node_h r;\n"; "0" - | RNodeNotFound -> - pr " errno = 0;\n"; - pr " hive_node_h r;\n"; - "0 && errno != 0" - | RNodeList -> pr " hive_node_h *r;\n"; "NULL" - | RValue -> pr " hive_value_h r;\n"; "0" - | RValueList -> pr " hive_value_h *r;\n"; "NULL" - | RString -> pr " char *r;\n"; "NULL" - | RStringList -> pr " char **r;\n"; "NULL" - | RLenType -> - pr " int r;\n"; - 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"; - pr " hive_type t;\n"; - "NULL" - | RInt32 -> - pr " errno = 0;\n"; - pr " int32_t r;\n"; - "-1 && errno != 0" - | RInt64 -> - pr " errno = 0;\n"; - pr " int64_t r;\n"; - "-1 && errno != 0" in - - (* Call and arguments. *) - let c_params = - List.map (function - | AUnusedFlags -> "0" - | ASetValues -> "values.nr_values, values.values" - | ASetValue -> "&val" - | arg -> name_of_argt arg) (snd style) in - let c_params = - match fst style with - | RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"] - | RLenValue -> c_params @ ["&len"] - | _ -> c_params in - - List.iter ( - function - | AHive -> - pr " hive_h *h;\n"; - pr " PyObject *py_h;\n" - | ANode n - | AValue n -> - pr " long %s;\n" n - | AString n - | AStringNullable n -> - pr " char *%s;\n" n - | AOpenFlags -> - pr " int flags;\n" - | AUnusedFlags -> () - | ASetValues -> - pr " py_set_values values;\n"; - pr " PyObject *py_values;\n" - | ASetValue -> - pr " hive_set_value val;\n"; - pr " PyObject *py_val;\n" - ) (snd style); - - pr "\n"; - - (* Convert the required parameters. *) - pr " if (!PyArg_ParseTuple (args, (char *) \""; - List.iter ( - function - | AHive -> - pr "O" - | ANode n - | AValue n -> - pr "l" - | AString n -> - pr "s" - | AStringNullable n -> - pr "z" - | AOpenFlags -> - pr "i" - | AUnusedFlags -> () - | ASetValues - | ASetValue -> - pr "O" - ) (snd style); - - pr ":hivex_%s\"" name; - - List.iter ( - function - | AHive -> - pr ", &py_h" - | ANode n - | AValue n -> - pr ", &%s" n - | AString n - | AStringNullable n -> - pr ", &%s" n - | AOpenFlags -> - pr ", &flags" - | AUnusedFlags -> () - | ASetValues -> - pr ", &py_values" - | ASetValue -> - pr ", &py_val" - ) (snd style); - - pr "))\n"; - pr " return NULL;\n"; - - (* Convert some Python argument types to C. *) - List.iter ( - function - | AHive -> - pr " h = get_handle (py_h);\n" - | ANode _ - | AValue _ - | AString _ - | AStringNullable _ - | AOpenFlags - | AUnusedFlags -> () - | ASetValues -> - pr " if (get_values (py_values, &values) == -1)\n"; - pr " return NULL;\n" - | ASetValue -> - pr " if (get_value (py_val, &val) == -1)\n"; - pr " return NULL;\n" - ) (snd style); - - (* Call the C function. *) - pr " r = hivex_%s (%s);\n" name (String.concat ", " c_params); - - (* Free up arguments. *) - List.iter ( - function - | AHive | ANode _ | AValue _ - | AString _ | AStringNullable _ - | AOpenFlags | AUnusedFlags -> () - | ASetValues -> - pr " free (values.values);\n" - | ASetValue -> () - ) (snd style); - - (* Check for errors from C library. *) - pr " if (r == %s) {\n" error_code; - pr " PyErr_SetString (PyExc_RuntimeError,\n"; - pr " strerror (errno));\n"; - pr " return NULL;\n"; - pr " }\n"; - pr "\n"; - - (* Convert return value to Python. *) - (match fst style with - | RErr - | RErrDispose -> - pr " Py_INCREF (Py_None);\n"; - pr " py_r = Py_None;\n" - | RHive -> - pr " py_r = put_handle (r);\n" - | RSize - | RNode -> - pr " py_r = PyLong_FromLongLong (r);\n" - | RNodeNotFound -> - pr " if (r)\n"; - pr " py_r = PyLong_FromLongLong (r);\n"; - pr " else {\n"; - pr " Py_INCREF (Py_None);\n"; - pr " py_r = Py_None;\n"; - pr " }\n"; - | RNodeList - | RValueList -> - pr " py_r = put_node_list (r);\n"; - pr " free (r);\n" - | RValue -> - pr " py_r = PyLong_FromLongLong (r);\n" - | RString -> - pr "#ifdef HAVE_PYSTRING_ASSTRING\n"; - pr " py_r = PyString_FromString (r);\n"; - pr "#else\n"; - pr " py_r = PyUnicode_FromString (r);\n"; - pr "#endif\n"; - pr " free (r);" - | RStringList -> - pr " py_r = put_string_list (r);\n"; - 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" - | RInt32 -> - pr " py_r = PyLong_FromLong ((long) r);\n" - | RInt64 -> - pr " py_r = PyLong_FromLongLong (r);\n" - ); - pr " return py_r;\n"; - pr "}\n"; - pr "\n" - ) functions; - - (* Table of functions. *) - pr "static PyMethodDef methods[] = {\n"; - List.iter ( - fun (name, _, _, _) -> - pr " { (char *) \"%s\", py_hivex_%s, METH_VARARGS, NULL },\n" - name name - ) functions; - pr " { NULL, NULL, 0, NULL }\n"; - pr "};\n"; - pr "\n"; - - (* Init function. *) - pr "\ -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - \"libhivexmod\", /* m_name */ - \"hivex module\", /* m_doc */ - -1, /* m_size */ - methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; -#endif - -static PyObject * -moduleinit (void) -{ - PyObject *m; - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create (&moduledef); -#else - m = Py_InitModule ((char *) \"libhivexmod\", methods); -#endif - - return m; /* m might be NULL if module init failed */ -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC -PyInit_libhivexmod (void) -{ - return moduleinit (); -} -#else -void -initlibhivexmod (void) -{ - (void) moduleinit (); -} -#endif -" - -and generate_python_py () = - generate_header HashStyle LGPLv2plus; - - pr "\ -\"\"\"Python bindings for hivex - -import hivex -h = hivex.Hivex (filename) - -The hivex module provides Python bindings to the hivex API for -examining and modifying Windows Registry 'hive' files. - -Read the hivex(3) man page to find out how to use the API. -\"\"\" - -import libhivexmod - -class Hivex(object): - \"\"\"Instances of this class are hivex API handles.\"\"\" - - def __init__ (self, filename"; - - List.iter ( - fun (_, flag, _) -> pr ", %s = False" (String.lowercase flag) - ) open_flags; - - pr "): - \"\"\"Create a new hivex handle.\"\"\" - flags = 0 -"; - - List.iter ( - fun (n, flag, description) -> - pr " # %s\n" description; - pr " if %s: flags += %d\n" (String.lowercase flag) n - ) open_flags; - - pr " self._o = libhivexmod.open (filename, flags) - - def __del__ (self): - libhivexmod.close (self._o) - -"; - - List.iter ( - fun (name, style, shortdesc, _) -> - (* The close and open calls are handled specially above. *) - if fst style <> RErrDispose && List.hd (snd style) = AHive then ( - let args = List.tl (snd style) in - let args = List.filter ( - function AOpenFlags | AUnusedFlags -> false - | _ -> true - ) args in - - pr " def %s (self" name; - List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args; - pr "):\n"; - pr " \"\"\"%s\"\"\"\n" shortdesc; - pr " return libhivexmod.%s (self._o" name; - List.iter ( - fun arg -> - pr ", "; - match arg with - | AHive -> assert false - | ANode n | AValue n - | AString n | AStringNullable n -> pr "%s" n - | AOpenFlags - | AUnusedFlags -> assert false - | ASetValues -> pr "values" - | ASetValue -> pr "val" - ) args; - pr ")\n"; - pr "\n" - ) - ) functions - -and generate_ruby_c () = - generate_header CStyle LGPLv2plus; - - pr "\ -#include -#include -#include - -#include - -#include \"hivex.h\" - -#include \"extconf.h\" - -/* For Ruby < 1.9 */ -#ifndef RARRAY_LEN -#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 */ - -static void -ruby_hivex_free (void *hvp) -{ - hive_h *h = hvp; - - if (h) - hivex_close (h); -} - -static void -get_value (VALUE valv, hive_set_value *val) -{ - VALUE key = rb_hash_lookup (valv, ID2SYM (rb_intern (\"key\"))); - VALUE type = rb_hash_lookup (valv, ID2SYM (rb_intern (\"type\"))); - VALUE value = rb_hash_lookup (valv, ID2SYM (rb_intern (\"value\"))); - - val->key = StringValueCStr (key); - val->t = NUM2ULL (type); - val->len = RSTRING_LEN (value); - val->value = RSTRING_PTR (value); -} - -static hive_set_value * -get_values (VALUE valuesv, size_t *nr_values) -{ - size_t i; - hive_set_value *ret; - - *nr_values = RARRAY_LEN (valuesv); - ret = malloc (sizeof (*ret) * *nr_values); - if (ret == NULL) - abort (); - - for (i = 0; i < *nr_values; ++i) { - VALUE v = rb_ary_entry (valuesv, i); - get_value (v, &ret[i]); - } - - return ret; -} - -"; - - List.iter ( - fun (name, (ret, args), shortdesc, longdesc) -> - let () = - (* Generate rdoc. *) - let doc = replace_str longdesc "C "h." ^ name, args - | args -> "Hivex::" ^ name, args in - let args = filter_map ( - function - | AUnusedFlags -> None - | args -> Some (name_of_argt args) - ) args in - let args = String.concat ", " args in - - let ret = - match ret with - | RErr | RErrDispose -> "nil" - | RHive -> "Hivex::Hivex" - | RSize | RNode | RNodeNotFound -> "integer" - | RNodeList -> "list" - | RValue -> "integer" - | RValueList -> "list" - | RString -> "string" - | RStringList -> "list" - | RLenType -> "hash" - | RLenValue -> "integer" - | RLenTypeVal -> "hash" - | RInt32 -> "integer" - | RInt64 -> "integer" in - - pr "\ -/* - * call-seq: - * %s(%s) -> %s - * - * %s - * - * %s - * - * (For the C API documentation for this function, see - * +hivex_%s+[http://libguestfs.org/hivex.3.html#hivex_%s]). - */ -" call args ret shortdesc doc name name in - - (* Generate the function. *) - pr "static VALUE\n"; - pr "ruby_hivex_%s (" name; - - let () = - (* If the first argument is not AHive, then this is a module-level - * function, and Ruby passes an implicit module argument which we - * must ignore. Otherwise the first argument is the hive handle. - *) - let args = - match args with - | AHive :: args -> pr "VALUE hv"; args - | args -> pr "VALUE modulev"; args in - List.iter ( - function - | AUnusedFlags -> () - | arg -> - pr ", VALUE %sv" (name_of_argt arg) - ) args; - pr ")\n" in - - pr "{\n"; - - List.iter ( - function - | AHive -> - pr " hive_h *h;\n"; - pr " Data_Get_Struct (hv, hive_h, h);\n"; - pr " if (!h)\n"; - pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\",\n"; - pr " \"%s\");\n" name; - | ANode n -> - pr " hive_node_h %s = NUM2ULL (%sv);\n" n n - | AValue n -> - pr " hive_value_h %s = NUM2ULL (%sv);\n" n n - | AString n -> - pr " const char *%s = StringValueCStr (%sv);\n" n n; - | AStringNullable n -> - pr " const char *%s =\n" n; - pr " !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n - | AOpenFlags -> - pr " int flags = 0;\n"; - List.iter ( - fun (n, flag, _) -> - pr " if (RTEST (rb_hash_lookup (flagsv, ID2SYM (rb_intern (\"%s\")))))\n" - (String.lowercase flag); - pr " flags += %d;\n" n - ) open_flags - | AUnusedFlags -> () - | ASetValues -> - pr " size_t nr_values;\n"; - pr " hive_set_value *values;\n"; - pr " values = get_values (valuesv, &nr_values);\n" - | ASetValue -> - pr " hive_set_value val;\n"; - pr " get_value (valv, &val);\n" - ) args; - pr "\n"; - - let error_code = - match ret with - | RErr -> pr " int r;\n"; "-1" - | RErrDispose -> pr " int r;\n"; "-1" - | RHive -> pr " hive_h *r;\n"; "NULL" - | RSize -> pr " size_t r;\n"; "0" - | RNode -> pr " hive_node_h r;\n"; "0" - | RNodeNotFound -> - pr " errno = 0;\n"; - pr " hive_node_h r;\n"; - "0 && errno != 0" - | RNodeList -> pr " hive_node_h *r;\n"; "NULL" - | RValue -> pr " hive_value_h r;\n"; "0" - | RValueList -> pr " hive_value_h *r;\n"; "NULL" - | RString -> pr " char *r;\n"; "NULL" - | RStringList -> pr " char **r;\n"; "NULL" - | RLenType -> - pr " int r;\n"; - 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"; - pr " hive_type t;\n"; - "NULL" - | RInt32 -> - pr " errno = 0;\n"; - pr " int32_t r;\n"; - "-1 && errno != 0" - | RInt64 -> - pr " errno = 0;\n"; - pr " int64_t r;\n"; - "-1 && errno != 0" in - pr "\n"; - - let c_params = - List.map (function - | ASetValues -> ["nr_values"; "values"] - | ASetValue -> ["&val"] - | AUnusedFlags -> ["0"] - | arg -> [name_of_argt arg]) args in - 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 - - pr " r = hivex_%s (%s" name (List.hd c_params); - List.iter (pr ", %s") (List.tl c_params); - pr ");\n"; - pr "\n"; - - (* Dispose of the hive handle (even if hivex_close returns error). *) - (match ret with - | RErrDispose -> - pr " /* So we don't double-free in the finalizer. */\n"; - pr " DATA_PTR (hv) = NULL;\n"; - pr "\n"; - | _ -> () - ); - - List.iter ( - function - | AHive - | ANode _ - | AValue _ - | AString _ - | AStringNullable _ - | AOpenFlags - | AUnusedFlags -> () - | ASetValues -> - pr " free (values);\n" - | ASetValue -> () - ) args; - - (* Check for errors from C library. *) - pr " if (r == %s)\n" error_code; - pr " rb_raise (e_Error, \"%%s\", strerror (errno));\n"; - pr "\n"; - - (match ret with - | RErr | RErrDispose -> - pr " return Qnil;\n" - | RHive -> - pr " return Data_Wrap_Struct (c_hivex, NULL, ruby_hivex_free, r);\n" - | RSize - | RNode - | RValue - | RInt64 -> - pr " return ULL2NUM (r);\n" - | RInt32 -> - pr " return INT2NUM (r);\n" - | RNodeNotFound -> - pr " if (r)\n"; - pr " return ULL2NUM (r);\n"; - pr " else\n"; - pr " return Qnil;\n" - | RNodeList - | RValueList -> - pr " size_t i, len = 0;\n"; - pr " for (i = 0; r[i] != 0; ++i) len++;\n"; - pr " VALUE rv = rb_ary_new2 (len);\n"; - pr " for (i = 0; r[i] != 0; ++i)\n"; - pr " rb_ary_push (rv, ULL2NUM (r[i]));\n"; - pr " free (r);\n"; - pr " return rv;\n" - | RString -> - pr " VALUE rv = rb_str_new2 (r);\n"; - pr " free (r);\n"; - pr " return rv;\n" - | RStringList -> - pr " size_t i, len = 0;\n"; - pr " for (i = 0; r[i] != NULL; ++i) len++;\n"; - pr " VALUE rv = rb_ary_new2 (len);\n"; - pr " for (i = 0; r[i] != NULL; ++i) {\n"; - pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n"; - pr " free (r[i]);\n"; - pr " }\n"; - pr " free (r);\n"; - pr " return rv;\n" - | RLenType -> - 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 (\"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"; - pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"type\")), INT2NUM (t));\n"; - pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"value\")), rb_str_new (r, len));\n"; - pr " free (r);\n"; - pr " return rv;\n" - ); - - pr "}\n"; - pr "\n" - ) functions; - - pr "\ -/* Initialize the module. */ -void Init__hivex () -{ - m_hivex = rb_define_module (\"Hivex\"); - c_hivex = rb_define_class_under (m_hivex, \"Hivex\", rb_cObject); - e_Error = rb_define_class_under (m_hivex, \"Error\", rb_eStandardError); - - /* XXX How to pass arguments? */ -#if 0 -#ifdef HAVE_RB_DEFINE_ALLOC_FUNC - rb_define_alloc_func (c_hivex, ruby_hivex_open); -#endif -#endif - -"; - - (* Methods. *) - List.iter ( - fun (name, (_, args), _, _) -> - let args = List.filter ( - function - | AUnusedFlags -> false - | _ -> true - ) args in - let nr_args = List.length args in - match args with - | AHive :: _ -> - pr " rb_define_method (c_hivex, \"%s\",\n" name; - pr " ruby_hivex_%s, %d);\n" name (nr_args-1) - | args -> (* class function *) - pr " rb_define_module_function (m_hivex, \"%s\",\n" name; - pr " ruby_hivex_%s, %d);\n" name nr_args - ) functions; - - pr "}\n" - -let output_to filename k = - let filename_new = filename ^ ".new" in - chan := open_out filename_new; - k (); - close_out !chan; - chan := Pervasives.stdout; - - (* Is the new file different from the current file? *) - if Sys.file_exists filename && files_equal filename filename_new then - unlink filename_new (* same, so skip it *) - else ( - (* different, overwrite old one *) - (try chmod filename 0o644 with Unix_error _ -> ()); - rename filename_new filename; - chmod filename 0o444; - printf "written %s\n%!" filename; - ) - -let perror msg = function - | Unix_error (err, _, _) -> - eprintf "%s: %s\n" msg (error_message err) - | exn -> - eprintf "%s: %s\n" msg (Printexc.to_string exn) - -(* Main program. *) -let () = - let lock_fd = - try openfile "configure.ac" [O_RDWR] 0 - with - | Unix_error (ENOENT, _, _) -> - eprintf "\ -You are probably running this from the wrong directory. -Run it from the top source directory using the command - generator/generator.ml -"; - exit 1 - | exn -> - perror "open: configure.ac" exn; - exit 1 in - - (* Acquire a lock so parallel builds won't try to run the generator - * twice at the same time. Subsequent builds will wait for the first - * one to finish. Note the lock is released implicitly when the - * program exits. - *) - (try lockf lock_fd F_LOCK 1 - with exn -> - perror "lock: configure.ac" exn; - exit 1); - - check_functions (); - - output_to "lib/hivex.h" generate_c_header; - output_to "lib/hivex.pod" generate_c_pod; - - output_to "lib/hivex.syms" generate_linker_script; - - output_to "ocaml/hivex.mli" generate_ocaml_interface; - output_to "ocaml/hivex.ml" generate_ocaml_implementation; - output_to "ocaml/hivex_c.c" generate_ocaml_c; - - output_to "perl/lib/Win/Hivex.pm" generate_perl_pm; - output_to "perl/Hivex.xs" generate_perl_xs; - - output_to "python/hivex.py" generate_python_py; - output_to "python/hivex-py.c" generate_python_c; - - output_to "ruby/ext/hivex/_hivex.c" generate_ruby_c; - - (* Always generate this file last, and unconditionally. It's used - * by the Makefile to know when we must re-run the generator. - *) - let chan = open_out "generator/stamp-generator" in - fprintf chan "1\n"; - close_out chan; - - printf "generated %d lines of code\n" !lines diff --git a/trunk/hivex/hivex.pc.in b/trunk/hivex/hivex.pc.in deleted file mode 100644 index c5f594a..0000000 --- a/trunk/hivex/hivex.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: hivex -Version: @VERSION@ -Description: Read and write Windows Registry Hive files. -Requires: -Cflags: -Libs: -lhivex @LIBS@ diff --git a/trunk/hivex/html/pod.css b/trunk/hivex/html/pod.css deleted file mode 100644 index 9a0b4b5..0000000 --- a/trunk/hivex/html/pod.css +++ /dev/null @@ -1,24 +0,0 @@ -/* CSS to make pod2html files look a little bit better. */ -@import url("http://et.redhat.com/~rjones/css/standard.css"); - -/* Put the index on the right hand side in a floating box. */ -div[name="index"] { - float: right; - width: 24em; - background-color: white; - margin-right: 2em; -} - -/* Get rid of those horrible
's :-( */ -hr { display: none; } - -/* Demote

's. */ -h1 { - font-size: 100%; - border-bottom: none; -} - -h2 { - font-size: 120%; - border-bottom: none; -} diff --git a/trunk/hivex/images/Makefile.am b/trunk/hivex/images/Makefile.am deleted file mode 100644 index b0087f3..0000000 --- a/trunk/hivex/images/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -# hivex -# 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. - -# Old RHEL 5 autoconf doesn't have builddir. -builddir ?= $(top_builddir)/images - -EXTRA_DIST = minimal rlenvalue_test_hive - -# 'large' is a large hive used for testing purposes. It is generated -# by the mklarge C program, to avoid having to distribute this large -# binary blob. -noinst_PROGRAMS = mklarge -mklarge_SOURCES = mklarge.c -mklarge_CFLAGS = \ - -I$(srcdir)/../lib \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) -mklarge_LDADD = ../lib/libhivex.la - -noinst_DATA = large - -large: minimal mklarge - cmp -s $(srcdir)/minimal $(builddir)/minimal || \ - cp $(srcdir)/minimal $(builddir)/minimal - ./mklarge $(builddir)/minimal $(builddir)/large - -CLEANFILES = $(noinst_DATA) diff --git a/trunk/hivex/images/README b/trunk/hivex/images/README deleted file mode 100644 index 2131885..0000000 --- a/trunk/hivex/images/README +++ /dev/null @@ -1,13 +0,0 @@ -This directory contains test images for the hivex library. - -'minimal' is a valid registry containing a single root nk (with -associated sk) which was created by chopping out everything possible -from a Windows 2003 software hive and then doing lots of hand edits on -the result. There is no "source" for it as such, it is just a -hand-crafted binary blob. - -'large' is a procedurally generated, large hive. The program -'mklarge.c' is used to make this during the build. It is used during -tests. - -- Richard W.M. Jones 2010-02-24. diff --git a/trunk/hivex/images/minimal b/trunk/hivex/images/minimal deleted file mode 100755 index 3f4ee58..0000000 Binary files a/trunk/hivex/images/minimal and /dev/null differ diff --git a/trunk/hivex/images/mklarge.c b/trunk/hivex/images/mklarge.c deleted file mode 100644 index c818df8..0000000 --- a/trunk/hivex/images/mklarge.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mklarge - Make a large hive for testing purposes. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include - -#include - -static int degrees[] = { 3, 1, 4, 1, 5, 9, 2 }; /* ~1000 nodes */ -static const int nr_degrees = sizeof degrees / sizeof degrees[0]; -static const char *strings[][10] = { - { "The", "A", "Another" }, /* level 0 */ - { "giant" }, - { "mongoose", "goat", "zebra", "elephant" }, - { "was" }, - { "found in", "seen in", "spotted over", "sent to", "fired at" }, - { "Paris", "London", "Rome", "Oslo", "Madrid", "Nicosia", "Amsterdam", - "Moscow", "Riga" }, - { "today", "yesterday" } /* level 6 */ -}; -static hive_set_value values[] = { - /* char* casts are needed to work around a stupidity of C */ - { (char *) "A", hive_t_REG_SZ, 4, (char *) "a\0\0\0" }, - { (char *) "B", hive_t_REG_DWORD, 4, (char *) "\x78\x56\x34\x12" }, - { (char *) "C", hive_t_REG_EXPAND_SZ, 6, (char *) "c\0c\0\0\0" }, - { (char *) "D", hive_t_REG_SZ, 8, (char *) "d\0d\0d\0\0\0" }, - { (char *) "E", hive_t_REG_QWORD, 8, (char *) "\xf0\xde\xbc\x9a\x78\x56\x34\x12" }, - { (char *) "F", hive_t_REG_SZ, 4, (char *) "f\0\0\0" }, - { (char *) "G", hive_t_REG_EXPAND_SZ, 4, (char *) "g\0\0\0" } -}; - -static void -iter (hive_h *h, int depth, int posn, hive_node_h parent, char *name) -{ - if (depth < nr_degrees) { - int degree = degrees[depth]; - int i, len; - hive_node_h node; - - len = strlen (name); - if (len > 0) name[len++] = ' '; - - for (i = 0; i < degree; ++i) { - strcpy (&name[len], strings[depth][i]); - node = hivex_node_add_child (h, parent, name); - if (node == 0) { - perror ("mklarge: hivex_node_add_child"); - exit (1); - } - iter (h, depth+1, i, node, name); - } - - if (hivex_node_set_values (h, parent, depth, values, 0) == -1) { - perror ("mklarge: hivex_node_set_values"); - exit (1); - } - } -} - -int -main (int argc, char *argv[]) -{ - hive_h *h; - char name[4096] = { '\0' }; - - h = hivex_open (argv[1], HIVEX_OPEN_WRITE); - if (h == NULL) { - perror (argv[1]); - exit (1); - } - - iter (h, 0, 0, hivex_root (h), name); - - if (hivex_commit (h, argv[2], 0) == -1) { - perror (argv[2]); - exit (1); - } - - if (hivex_close (h) == -1) { - perror ("mklarge: close"); - exit (1); - } - - exit (0); -} diff --git a/trunk/hivex/images/mkrlenvalue_test_hive.py b/trunk/hivex/images/mkrlenvalue_test_hive.py deleted file mode 100755 index 827667e..0000000 --- a/trunk/hivex/images/mkrlenvalue_test_hive.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/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/trunk/hivex/images/rlenvalue_test_hive b/trunk/hivex/images/rlenvalue_test_hive deleted file mode 100644 index 87cbec5..0000000 Binary files a/trunk/hivex/images/rlenvalue_test_hive and /dev/null differ diff --git a/trunk/hivex/lib/Makefile.am b/trunk/hivex/lib/Makefile.am deleted file mode 100644 index 8d7ff69..0000000 --- a/trunk/hivex/lib/Makefile.am +++ /dev/null @@ -1,84 +0,0 @@ -# hivex -# 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. - -SUBDIRS = tools - -EXTRA_DIST = \ - hivex.pod \ - hivex.syms - -lib_LTLIBRARIES = libhivex.la - -libhivex_la_SOURCES = \ - hivex.c \ - hivex.h \ - hivex-internal.h \ - byte_conversions.h \ - gettext.h \ - mmap.h \ - hivex.syms - -libhivex_la_LIBADD = ../gnulib/lib/libgnu.la $(LTLIBOBJS) -libhivex_la_LDFLAGS = \ - -version-info 0:0:0 \ - $(VERSION_SCRIPT_FLAGS)$(srcdir)/hivex.syms \ - $(LTLIBICONV) \ - $(LTLIBINTL) \ - $(LTLIBTHREAD) -libhivex_la_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) -libhivex_la_CPPFLAGS = \ - -I$(top_srcdir)/gnulib/lib \ - -I$(top_builddir)/gnulib/lib \ - -I$(srcdir) - -include_HEADERS = hivex.h - -man_MANS = hivex.3 - -hivex.3: hivex.pod - $(POD2MAN) \ - --section 3 \ - -c "Windows Registry" \ - --name "hivex" \ - --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ - $< > $@-t; mv $@-t $@ - -noinst_DATA = \ - $(top_builddir)/html/hivex.3.html - -$(top_builddir)/html/hivex.3.html: hivex.pod - mkdir -p $(top_builddir)/html - pod2html \ - --css pod.css \ - --htmldir $(top_builddir)/html \ - --outfile $(top_builddir)/html/hivex.3.html \ - $< - -CLEANFILES = $(man_MANS) - -# Tests. - -check_PROGRAMS = test-just-header - -TESTS = test-just-header - -test_just_header_SOURCES = test-just-header.c -test_just_header_CFLAGS = \ - -I$(top_srcdir)/lib -I$(top_builddir)/lib \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) -test_just_header_LDADD = \ - $(top_builddir)/lib/libhivex.la diff --git a/trunk/hivex/lib/byte_conversions.h b/trunk/hivex/lib/byte_conversions.h deleted file mode 100644 index 2e4cafe..0000000 --- a/trunk/hivex/lib/byte_conversions.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Useful byte conversion macros, not available on all platforms. - * Copyright (C) 2009-2010 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License. - * - * This library 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 - * Lesser General Public License for more details. - */ - -#ifndef hivex_byteorder_h -#define hivex_byteorder_h - -#ifdef HAVE_ENDIAN_H -#include -#endif -#include - -#if __BYTE_ORDER == __LITTLE_ENDIAN -#ifndef be32toh -#define be32toh(x) bswap_32 (x) -#endif -#ifndef htobe32 -#define htobe32(x) bswap_32 (x) -#endif -#ifndef be64toh -#define be64toh(x) bswap_64 (x) -#endif -#ifndef htobe64 -#define htobe64(x) bswap_64 (x) -#endif -#ifndef le16toh -#define le16toh(x) (x) -#endif -#ifndef htole16 -#define htole16(x) (x) -#endif -#ifndef le32toh -#define le32toh(x) (x) -#endif -#ifndef htole32 -#define htole32(x) (x) -#endif -#ifndef le64toh -#define le64toh(x) (x) -#endif -#ifndef htole64 -#define htole64(x) (x) -#endif -#else /* __BYTE_ORDER == __BIG_ENDIAN */ -#ifndef be32toh -#define be32toh(x) (x) -#endif -#ifndef htobe32 -#define htobe32(x) (x) -#endif -#ifndef be64toh -#define be64toh(x) (x) -#endif -#ifndef htobe64 -#define htobe64(x) (x) -#endif -#ifndef le16toh -#define le16toh(x) bswap_16 (x) -#endif -#ifndef htole16 -#define htole16(x) bswap_16 (x) -#endif -#ifndef le32toh -#define le32toh(x) bswap_32 (x) -#endif -#ifndef htole32 -#define htole32(x) bswap_32 (x) -#endif -#ifndef le64toh -#define le64toh(x) bswap_64 (x) -#endif -#ifndef htole64 -#define htole64(x) bswap_64 (x) -#endif -#endif /* __BYTE_ORDER == __BIG_ENDIAN */ - -#endif /* hivex_byteorder_h */ diff --git a/trunk/hivex/lib/gettext.h b/trunk/hivex/lib/gettext.h deleted file mode 100644 index 93f32e5..0000000 --- a/trunk/hivex/lib/gettext.h +++ /dev/null @@ -1,271 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, 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, 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 - Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by - the gettext() and ngettext() macros. This is an alternative to calling - textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Many header files from the libstdc++ coming with g++ 3.3 or newer include - , which chokes if dcgettext is defined as a macro. So include - it now, to make later inclusions of a NOP. */ -#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) - -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -/* The separator between msgctxt and msgid in a .mo file. */ -#define GETTEXT_CONTEXT_GLUE "\004" - -/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a - MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be - short and rarely need to change. - The letter 'p' stands for 'particular' or 'special'. */ -#ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) -#ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); - if (translation == msg_ctxt_id) - return msgid; - else - return translation; -} - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - if (translation == msg_ctxt_id || translation == msgid_plural) - return (n == 1 ? msgid : msgid_plural); - else - return translation; -} - -/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID - can be arbitrary expressions. But for string literals these macros are - less efficient than those above. */ - -#include - -#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ - (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) - -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS -#include -#endif - -#define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) -#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (translation != msg_ctxt_id) - return translation; - } - return msgid; -} - -#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; - } - return (n == 1 ? msgid : msgid_plural); -} - -#endif /* _LIBGETTEXT_H */ diff --git a/trunk/hivex/lib/hivex-internal.h b/trunk/hivex/lib/hivex-internal.h deleted file mode 100644 index b053850..0000000 --- a/trunk/hivex/lib/hivex-internal.h +++ /dev/null @@ -1,79 +0,0 @@ -/* hivex internal header - * Copyright (C) 2009-2011 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef HIVEX_INTERNAL_H_ -#define HIVEX_INTERNAL_H_ - -#include - -struct hive_h { - char *filename; - int fd; - size_t size; - int msglvl; - int writable; - - /* Registry file, memory mapped if read-only, or malloc'd if writing. */ - union { - void *addr; - struct ntreg_header *hdr; - }; - - /* Use a bitmap to store which file offsets are valid (point to a - * used block). We only need to store 1 bit per 32 bits of the file - * (because blocks are 4-byte aligned). We found that the average - * block size in a registry file is ~50 bytes. So roughly 1 in 12 - * bits in the bitmap will be set, making it likely a more efficient - * structure than a hash table. - */ - char *bitmap; -#define BITMAP_SET(bitmap,off) (bitmap[(off)>>5] |= 1 << (((off)>>2)&7)) -#define BITMAP_CLR(bitmap,off) (bitmap[(off)>>5] &= ~ (1 << (((off)>>2)&7))) -#define BITMAP_TST(bitmap,off) (bitmap[(off)>>5] & (1 << (((off)>>2)&7))) -#define IS_VALID_BLOCK(h,off) \ - (((off) & 3) == 0 && \ - (off) >= 0x1000 && \ - (off) < (h)->size && \ - BITMAP_TST((h)->bitmap,(off))) - - /* Fields from the header, extracted from little-endianness hell. */ - size_t rootoffs; /* Root key offset (always an nk-block). */ - size_t endpages; /* Offset of end of pages. */ - int64_t last_modified; /* mtime of base block. */ - - /* For writing. */ - size_t endblocks; /* Offset to next block allocation (0 - if not allocated anything yet). */ - -#ifndef HAVE_MMAP - /* Internal data for mmap replacement */ - void *p_winmap; -#endif -}; - -#define STREQ(a,b) (strcmp((a),(b)) == 0) -#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0) -#define STRNEQ(a,b) (strcmp((a),(b)) != 0) -#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0) -#define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0) -#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0) -#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0) -#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0) -#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0) - -#endif /* HIVEX_INTERNAL_H_ */ diff --git a/trunk/hivex/lib/hivex.c b/trunk/hivex/lib/hivex.c deleted file mode 100644 index a2bd43b..0000000 --- a/trunk/hivex/lib/hivex.c +++ /dev/null @@ -1,2931 +0,0 @@ -/* hivex - Windows Registry "hive" extraction library. - * Copyright (C) 2009-2011 Red Hat Inc. - * Derived from code by Petter Nordahl-Hagen under a compatible license: - * Copyright (c) 1997-2007 Petter Nordahl-Hagen. - * Derived from code by Markus Stephany under a compatible license: - * Copyright (c) 2000-2004, Markus Stephany. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License. - * - * This library 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 - * Lesser General Public License for more details. - * - * See file LICENSE for the full license. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_MMAP -#include -#else -/* On systems without mmap (and munmap), use a replacement function. */ -#include "mmap.h" -#endif - -#include "c-ctype.h" -#include "full-read.h" -#include "full-write.h" - -#include "hivex.h" -#include "hivex-internal.h" -#include "byte_conversions.h" - -/* These limits are in place to stop really stupid stuff and/or exploits. */ -#define HIVEX_MAX_SUBKEYS 15000 -#define HIVEX_MAX_VALUES 10000 -#define HIVEX_MAX_VALUE_LEN 1000000 -#define HIVEX_MAX_ALLOCATION 1000000 - -static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len); -static size_t utf16_string_len_in_bytes_max (const char *str, size_t len); - -/* NB. All fields are little endian. */ -struct ntreg_header { - char magic[4]; /* "regf" */ - uint32_t sequence1; - uint32_t sequence2; - int64_t last_modified; - uint32_t major_ver; /* 1 */ - uint32_t minor_ver; /* 3 */ - uint32_t unknown5; /* 0 */ - uint32_t unknown6; /* 1 */ - uint32_t offset; /* offset of root key record - 4KB */ - uint32_t blocks; /* pointer AFTER last hbin in file - 4KB */ - uint32_t unknown7; /* 1 */ - /* 0x30 */ - char name[64]; /* original file name of hive */ - char unknown_guid1[16]; - char unknown_guid2[16]; - /* 0x90 */ - uint32_t unknown8; - char unknown_guid3[16]; - uint32_t unknown9; - /* 0xa8 */ - char unknown10[340]; - /* 0x1fc */ - uint32_t csum; /* checksum: xor of dwords 0-0x1fb. */ - /* 0x200 */ - char unknown11[3528]; - /* 0xfc8 */ - char unknown_guid4[16]; - char unknown_guid5[16]; - char unknown_guid6[16]; - uint32_t unknown12; - uint32_t unknown13; - /* 0x1000 */ -} __attribute__((__packed__)); - -struct ntreg_hbin_page { - char magic[4]; /* "hbin" */ - uint32_t offset_first; /* offset from 1st block */ - uint32_t page_size; /* size of this page (multiple of 4KB) */ - char unknown[20]; - /* Linked list of blocks follows here. */ -} __attribute__((__packed__)); - -struct ntreg_hbin_block { - int32_t seg_len; /* length of this block (-ve for used block) */ - char id[2]; /* the block type (eg. "nk" for nk record) */ - /* Block data follows here. */ -} __attribute__((__packed__)); - -#define BLOCK_ID_EQ(h,offs,eqid) \ - (STREQLEN (((struct ntreg_hbin_block *)((h)->addr + (offs)))->id, (eqid), 2)) - -static size_t -block_len (hive_h *h, size_t blkoff, int *used) -{ - struct ntreg_hbin_block *block; - block = (struct ntreg_hbin_block *) ((char *) h->addr + blkoff); - - int32_t len = le32toh (block->seg_len); - if (len < 0) { - if (used) *used = 1; - len = -len; - } else { - if (used) *used = 0; - } - - return (size_t) len; -} - -struct ntreg_nk_record { - int32_t seg_len; /* length (always -ve because used) */ - char id[2]; /* "nk" */ - uint16_t flags; - int64_t timestamp; - uint32_t unknown1; - uint32_t parent; /* offset of owner/parent */ - uint32_t nr_subkeys; /* number of subkeys */ - uint32_t nr_subkeys_volatile; - uint32_t subkey_lf; /* lf record containing list of subkeys */ - uint32_t subkey_lf_volatile; - uint32_t nr_values; /* number of values */ - uint32_t vallist; /* value-list record */ - uint32_t sk; /* offset of sk-record */ - uint32_t classname; /* offset of classname record */ - uint16_t max_subkey_name_len; /* maximum length of a subkey name in bytes - if the subkey was reencoded as UTF-16LE */ - uint16_t unknown2; - uint32_t unknown3; - uint32_t max_vk_name_len; /* maximum length of any vk name in bytes - if the name was reencoded as UTF-16LE */ - uint32_t max_vk_data_len; /* maximum length of any vk data in bytes */ - uint32_t unknown6; - uint16_t name_len; /* length of name */ - uint16_t classname_len; /* length of classname */ - char name[1]; /* name follows here */ -} __attribute__((__packed__)); - -struct ntreg_lf_record { - int32_t seg_len; - char id[2]; /* "lf"|"lh" */ - uint16_t nr_keys; /* number of keys in this record */ - struct { - uint32_t offset; /* offset of nk-record for this subkey */ - char hash[4]; /* hash of subkey name */ - } keys[1]; -} __attribute__((__packed__)); - -struct ntreg_ri_record { - int32_t seg_len; - char id[2]; /* "ri"|"li" */ - uint16_t nr_offsets; /* number of pointers to lf/lh/li records */ - uint32_t offset[1]; /* list of pointers to lf/lh/li records */ -} __attribute__((__packed__)); - -/* This has no ID header. */ -struct ntreg_value_list { - int32_t seg_len; - uint32_t offset[1]; /* list of pointers to vk records */ -} __attribute__((__packed__)); - -struct ntreg_vk_record { - int32_t seg_len; /* length (always -ve because used) */ - char id[2]; /* "vk" */ - uint16_t name_len; /* length of name */ - /* length of the data: - * If data_len is <= 4, then it's stored inline. - * Top bit is set to indicate inline. - */ - uint32_t data_len; - uint32_t data_offset; /* pointer to the data (or data if inline) */ - uint32_t data_type; /* type of the data */ - uint16_t flags; /* bit 0 set => key name ASCII, - bit 0 clr => key name UTF-16. - Only seen ASCII here in the wild. - NB: this is CLEAR for default key. */ - uint16_t unknown2; - char name[1]; /* key name follows here */ -} __attribute__((__packed__)); - -struct ntreg_sk_record { - int32_t seg_len; /* length (always -ve because used) */ - char id[2]; /* "sk" */ - uint16_t unknown1; - uint32_t sk_next; /* linked into a circular list */ - uint32_t sk_prev; - uint32_t refcount; /* reference count */ - uint32_t sec_len; /* length of security info */ - char sec_desc[1]; /* security info follows */ -} __attribute__((__packed__)); - -static uint32_t -header_checksum (const hive_h *h) -{ - uint32_t *daddr = (uint32_t *) h->addr; - size_t i; - uint32_t sum = 0; - - for (i = 0; i < 0x1fc / 4; ++i) { - sum ^= le32toh (*daddr); - daddr++; - } - - return sum; -} - -#define HIVEX_OPEN_MSGLVL_MASK (HIVEX_OPEN_VERBOSE|HIVEX_OPEN_DEBUG) - -hive_h * -hivex_open (const char *filename, int flags) -{ - hive_h *h = NULL; - - assert (sizeof (struct ntreg_header) == 0x1000); - assert (offsetof (struct ntreg_header, csum) == 0x1fc); - - h = calloc (1, sizeof *h); - if (h == NULL) - goto error; - - h->msglvl = flags & HIVEX_OPEN_MSGLVL_MASK; - - const char *debug = getenv ("HIVEX_DEBUG"); - if (debug && STREQ (debug, "1")) - h->msglvl = 2; - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_open: created handle %p\n", h); - - h->writable = !!(flags & HIVEX_OPEN_WRITE); - h->filename = strdup (filename); - if (h->filename == NULL) - goto error; - -#ifdef O_CLOEXEC - h->fd = open (filename, O_RDONLY | O_CLOEXEC); -#else - h->fd = open (filename, O_RDONLY); -#endif - if (h->fd == -1) - goto error; -#ifndef O_CLOEXEC - fcntl (h->fd, F_SETFD, FD_CLOEXEC); -#endif - - struct stat statbuf; - if (fstat (h->fd, &statbuf) == -1) - goto error; - - h->size = statbuf.st_size; - - if (!h->writable) { - h->addr = mmap (NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0); - if (h->addr == MAP_FAILED) - goto error; - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_open: mapped file at %p\n", h->addr); - } else { - h->addr = malloc (h->size); - if (h->addr == NULL) - goto error; - - if (full_read (h->fd, h->addr, h->size) < h->size) - goto error; - - /* We don't need the file descriptor along this path, since we - * have read all the data. - */ - if (close (h->fd) == -1) - goto error; - h->fd = -1; - } - - /* Check header. */ - if (h->hdr->magic[0] != 'r' || - h->hdr->magic[1] != 'e' || - h->hdr->magic[2] != 'g' || - h->hdr->magic[3] != 'f') { - fprintf (stderr, "hivex: %s: not a Windows NT Registry hive file\n", - filename); - errno = ENOTSUP; - goto error; - } - - /* Check major version. */ - uint32_t major_ver = le32toh (h->hdr->major_ver); - if (major_ver != 1) { - fprintf (stderr, - "hivex: %s: hive file major version %" PRIu32 " (expected 1)\n", - filename, major_ver); - errno = ENOTSUP; - goto error; - } - - h->bitmap = calloc (1 + h->size / 32, 1); - if (h->bitmap == NULL) - goto error; - - /* Header checksum. */ - uint32_t sum = header_checksum (h); - if (sum != le32toh (h->hdr->csum)) { - fprintf (stderr, "hivex: %s: bad checksum in hive header\n", filename); - errno = EINVAL; - goto error; - } - - /* Last modified time. */ - h->last_modified = le64toh ((int64_t) h->hdr->last_modified); - - if (h->msglvl >= 2) { - char *name = windows_utf16_to_utf8 (h->hdr->name, 64); - - fprintf (stderr, - "hivex_open: header fields:\n" - " file version %" PRIu32 ".%" PRIu32 "\n" - " sequence nos %" PRIu32 " %" PRIu32 "\n" - " (sequences nos should match if hive was synched at shutdown)\n" - " last modified %" PRIu64 "\n" - " (Windows filetime, x 100 ns since 1601-01-01)\n" - " original file name %s\n" - " (only 32 chars are stored, name is probably truncated)\n" - " root offset 0x%x + 0x1000\n" - " end of last page 0x%x + 0x1000 (total file size 0x%zx)\n" - " checksum 0x%x (calculated 0x%x)\n", - major_ver, le32toh (h->hdr->minor_ver), - le32toh (h->hdr->sequence1), le32toh (h->hdr->sequence2), - h->last_modified, - name ? name : "(conversion failed)", - le32toh (h->hdr->offset), - le32toh (h->hdr->blocks), h->size, - le32toh (h->hdr->csum), sum); - free (name); - } - - h->rootoffs = le32toh (h->hdr->offset) + 0x1000; - h->endpages = le32toh (h->hdr->blocks) + 0x1000; - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_open: root offset = 0x%zx\n", h->rootoffs); - - /* We'll set this flag when we see a block with the root offset (ie. - * the root block). - */ - int seen_root_block = 0, bad_root_block = 0; - - /* Collect some stats. */ - size_t pages = 0; /* Number of hbin pages read. */ - size_t smallest_page = SIZE_MAX, largest_page = 0; - size_t blocks = 0; /* Total number of blocks found. */ - size_t smallest_block = SIZE_MAX, largest_block = 0, blocks_bytes = 0; - size_t used_blocks = 0; /* Total number of used blocks found. */ - size_t used_size = 0; /* Total size (bytes) of used blocks. */ - - /* Read the pages and blocks. The aim here is to be robust against - * corrupt or malicious registries. So we make sure the loops - * always make forward progress. We add the address of each block - * we read to a hash table so pointers will only reference the start - * of valid blocks. - */ - size_t off; - struct ntreg_hbin_page *page; - for (off = 0x1000; off < h->size; off += le32toh (page->page_size)) { - if (off >= h->endpages) - break; - - page = (struct ntreg_hbin_page *) ((char *) h->addr + off); - if (page->magic[0] != 'h' || - page->magic[1] != 'b' || - page->magic[2] != 'i' || - page->magic[3] != 'n') { - fprintf (stderr, "hivex: %s: trailing garbage at end of file " - "(at 0x%zx, after %zu pages)\n", - filename, off, pages); - errno = ENOTSUP; - goto error; - } - - size_t page_size = le32toh (page->page_size); - if (h->msglvl >= 2) - fprintf (stderr, "hivex_open: page at 0x%zx, size %zu\n", off, page_size); - pages++; - if (page_size < smallest_page) smallest_page = page_size; - if (page_size > largest_page) largest_page = page_size; - - if (page_size <= sizeof (struct ntreg_hbin_page) || - (page_size & 0x0fff) != 0) { - fprintf (stderr, "hivex: %s: page size %zu at 0x%zx, bad registry\n", - filename, page_size, off); - errno = ENOTSUP; - goto error; - } - - /* Read the blocks in this page. */ - size_t blkoff; - struct ntreg_hbin_block *block; - size_t seg_len; - for (blkoff = off + 0x20; - blkoff < off + page_size; - blkoff += seg_len) { - blocks++; - - int is_root = blkoff == h->rootoffs; - if (is_root) - seen_root_block = 1; - - block = (struct ntreg_hbin_block *) ((char *) h->addr + blkoff); - int used; - seg_len = block_len (h, blkoff, &used); - if (seg_len <= 4 || (seg_len & 3) != 0) { - fprintf (stderr, "hivex: %s: block size %" PRIu32 " at 0x%zx," - " bad registry\n", - filename, le32toh (block->seg_len), blkoff); - errno = ENOTSUP; - goto error; - } - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_open: %s block id %d,%d at 0x%zx size %zu%s\n", - used ? "used" : "free", block->id[0], block->id[1], blkoff, - seg_len, is_root ? " (root)" : ""); - - blocks_bytes += seg_len; - if (seg_len < smallest_block) smallest_block = seg_len; - if (seg_len > largest_block) largest_block = seg_len; - - if (is_root && !used) - bad_root_block = 1; - - if (used) { - used_blocks++; - used_size += seg_len; - - /* Root block must be an nk-block. */ - if (is_root && (block->id[0] != 'n' || block->id[1] != 'k')) - bad_root_block = 1; - - /* Note this blkoff is a valid address. */ - BITMAP_SET (h->bitmap, blkoff); - } - } - } - - if (!seen_root_block) { - fprintf (stderr, "hivex: %s: no root block found\n", filename); - errno = ENOTSUP; - goto error; - } - - if (bad_root_block) { - fprintf (stderr, "hivex: %s: bad root block (free or not nk)\n", filename); - errno = ENOTSUP; - goto error; - } - - if (h->msglvl >= 1) - fprintf (stderr, - "hivex_open: successfully read Windows Registry hive file:\n" - " pages: %zu [sml: %zu, lge: %zu]\n" - " blocks: %zu [sml: %zu, avg: %zu, lge: %zu]\n" - " blocks used: %zu\n" - " bytes used: %zu\n", - pages, smallest_page, largest_page, - blocks, smallest_block, blocks_bytes / blocks, largest_block, - used_blocks, used_size); - - return h; - - error:; - int err = errno; - if (h) { - free (h->bitmap); - if (h->addr && h->size && h->addr != MAP_FAILED) { - if (!h->writable) - munmap (h->addr, h->size); - else - free (h->addr); - } - if (h->fd >= 0) - close (h->fd); - free (h->filename); - free (h); - } - errno = err; - return NULL; -} - -int -hivex_close (hive_h *h) -{ - int r; - - if (h->msglvl >= 1) - fprintf (stderr, "hivex_close\n"); - - free (h->bitmap); - if (!h->writable) - munmap (h->addr, h->size); - else - free (h->addr); - if (h->fd >= 0) - r = close (h->fd); - else - r = 0; - free (h->filename); - free (h); - - return r; -} - -/*---------------------------------------------------------------------- - * Reading. - */ - -hive_node_h -hivex_root (hive_h *h) -{ - hive_node_h ret = h->rootoffs; - if (!IS_VALID_BLOCK (h, ret)) { - errno = HIVEX_NO_KEY; - return 0; - } - return ret; -} - -size_t -hivex_node_struct_length (hive_h *h, hive_node_h node) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return 0; - } - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - size_t name_len = le16toh (nk->name_len); - /* -1 to avoid double-counting the first name character */ - size_t ret = name_len + sizeof (struct ntreg_nk_record) - 1; - int used; - size_t seg_len = block_len (h, node, &used); - if (ret > seg_len) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_struct_length: returning EFAULT because" - " node name is too long (%zu, %zu)\n", name_len, seg_len); - errno = EFAULT; - return 0; - } - return ret; -} - -char * -hivex_node_name (hive_h *h, hive_node_h node) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return NULL; - } - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - - /* AFAIK the node name is always plain ASCII, so no conversion - * to UTF-8 is necessary. However we do need to nul-terminate - * the string. - */ - - /* nk->name_len is unsigned, 16 bit, so this is safe ... However - * we have to make sure the length doesn't exceed the block length. - */ - size_t len = le16toh (nk->name_len); - size_t seg_len = block_len (h, node, NULL); - if (sizeof (struct ntreg_nk_record) + len - 1 > seg_len) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_name: returning EFAULT because node name" - " is too long (%zu, %zu)\n", - len, seg_len); - errno = EFAULT; - return NULL; - } - - char *ret = malloc (len + 1); - if (ret == NULL) - return NULL; - memcpy (ret, nk->name, len); - ret[len] = '\0'; - return ret; -} - -static int64_t -timestamp_check (hive_h *h, hive_node_h node, int64_t timestamp) -{ - if (timestamp < 0) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex: timestamp_check: " - "negative time reported at %zu: %" PRIi64 "\n", - node, timestamp); - errno = EINVAL; - return -1; - } - - return timestamp; -} - -int64_t -hivex_last_modified (hive_h *h) -{ - return timestamp_check (h, 0, h->last_modified); -} - -int64_t -hivex_node_timestamp (hive_h *h, hive_node_h node) -{ - int64_t ret; - - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return -1; - } - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - - ret = le64toh (nk->timestamp); - return timestamp_check (h, node, ret); -} - -#if 0 -/* I think the documentation for the sk and classname fields in the nk - * record is wrong, or else the offset field is in the wrong place. - * Otherwise this makes no sense. Disabled this for now -- it's not - * useful for reading the registry anyway. - */ - -hive_security_h -hivex_node_security (hive_h *h, hive_node_h node) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return 0; - } - - struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node); - - hive_node_h ret = le32toh (nk->sk); - ret += 0x1000; - if (!IS_VALID_BLOCK (h, ret)) { - errno = EFAULT; - return 0; - } - return ret; -} - -hive_classname_h -hivex_node_classname (hive_h *h, hive_node_h node) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return 0; - } - - struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node); - - hive_node_h ret = le32toh (nk->classname); - ret += 0x1000; - if (!IS_VALID_BLOCK (h, ret)) { - errno = EFAULT; - return 0; - } - return ret; -} -#endif - -/* Structure for returning 0-terminated lists of offsets (nodes, - * values, etc). - */ -struct offset_list { - size_t *offsets; - size_t len; - size_t alloc; -}; - -static void -init_offset_list (struct offset_list *list) -{ - list->len = 0; - list->alloc = 0; - list->offsets = NULL; -} - -#define INIT_OFFSET_LIST(name) \ - struct offset_list name; \ - init_offset_list (&name) - -/* Preallocates the offset_list, but doesn't make the contents longer. */ -static int -grow_offset_list (struct offset_list *list, size_t alloc) -{ - assert (alloc >= list->len); - size_t *p = realloc (list->offsets, alloc * sizeof (size_t)); - if (p == NULL) - return -1; - list->offsets = p; - list->alloc = alloc; - return 0; -} - -static int -add_to_offset_list (struct offset_list *list, size_t offset) -{ - if (list->len >= list->alloc) { - if (grow_offset_list (list, list->alloc ? list->alloc * 2 : 4) == -1) - return -1; - } - list->offsets[list->len] = offset; - list->len++; - return 0; -} - -static void -free_offset_list (struct offset_list *list) -{ - free (list->offsets); -} - -static size_t * -return_offset_list (struct offset_list *list) -{ - if (add_to_offset_list (list, 0) == -1) - return NULL; - return list->offsets; /* caller frees */ -} - -/* Iterate over children, returning child nodes and intermediate blocks. */ -#define GET_CHILDREN_NO_CHECK_NK 1 - -static int -get_children (hive_h *h, hive_node_h node, - hive_node_h **children_ret, size_t **blocks_ret, - int flags) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return -1; - } - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - - size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys); - - INIT_OFFSET_LIST (children); - INIT_OFFSET_LIST (blocks); - - /* Deal with the common "no subkeys" case quickly. */ - if (nr_subkeys_in_nk == 0) - goto ok; - - /* Arbitrarily limit the number of subkeys we will ever deal with. */ - if (nr_subkeys_in_nk > HIVEX_MAX_SUBKEYS) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex: get_children: returning ERANGE because " - "nr_subkeys_in_nk > HIVEX_MAX_SUBKEYS (%zu > %d)\n", - nr_subkeys_in_nk, HIVEX_MAX_SUBKEYS); - errno = ERANGE; - goto error; - } - - /* Preallocate space for the children. */ - if (grow_offset_list (&children, nr_subkeys_in_nk) == -1) - goto error; - - /* The subkey_lf field can point either to an lf-record, which is - * the common case, or if there are lots of subkeys, to an - * ri-record. - */ - size_t subkey_lf = le32toh (nk->subkey_lf); - subkey_lf += 0x1000; - if (!IS_VALID_BLOCK (h, subkey_lf)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT" - " because subkey_lf is not a valid block (0x%zx)\n", - subkey_lf); - errno = EFAULT; - goto error; - } - - if (add_to_offset_list (&blocks, subkey_lf) == -1) - goto error; - - struct ntreg_hbin_block *block = - (struct ntreg_hbin_block *) ((char *) h->addr + subkey_lf); - - /* Points to lf-record? (Note, also "lh" but that is basically the - * same as "lf" as far as we are concerned here). - */ - if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) { - struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block; - - /* Check number of subkeys in the nk-record matches number of subkeys - * in the lf-record. - */ - size_t nr_subkeys_in_lf = le16toh (lf->nr_keys); - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu," - " nr_subkeys_in_lf = %zu\n", - nr_subkeys_in_nk, nr_subkeys_in_lf); - - if (nr_subkeys_in_nk != nr_subkeys_in_lf) { - errno = ENOTSUP; - goto error; - } - - size_t len = block_len (h, subkey_lf, NULL); - if (8 + nr_subkeys_in_lf * 8 > len) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT" - " because too many subkeys (%zu, %zu)\n", - nr_subkeys_in_lf, len); - errno = EFAULT; - goto error; - } - - size_t i; - for (i = 0; i < nr_subkeys_in_lf; ++i) { - hive_node_h subkey = le32toh (lf->keys[i].offset); - subkey += 0x1000; - if (!(flags & GET_CHILDREN_NO_CHECK_NK)) { - if (!IS_VALID_BLOCK (h, subkey)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT" - " because subkey is not a valid block (0x%zx)\n", - subkey); - errno = EFAULT; - goto error; - } - } - if (add_to_offset_list (&children, subkey) == -1) - goto error; - } - goto ok; - } - /* Points to ri-record? */ - else if (block->id[0] == 'r' && block->id[1] == 'i') { - struct ntreg_ri_record *ri = (struct ntreg_ri_record *) block; - - size_t nr_offsets = le16toh (ri->nr_offsets); - - /* Count total number of children. */ - size_t i, count = 0; - for (i = 0; i < nr_offsets; ++i) { - hive_node_h offset = le32toh (ri->offset[i]); - offset += 0x1000; - if (!IS_VALID_BLOCK (h, offset)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT" - " because ri-offset is not a valid block (0x%zx)\n", - offset); - errno = EFAULT; - goto error; - } - if (!BLOCK_ID_EQ (h, offset, "lf") && - !BLOCK_ID_EQ (h, offset, "lh") && - !BLOCK_ID_EQ (h, offset, "li")) { - if (h->msglvl >= 2) - fprintf (stderr, "get_children: returning ENOTSUP because" - " ri-record offset does not point to lf/lh/li (0x%zx)\n", - offset); - errno = ENOTSUP; - goto error; - } - - if (add_to_offset_list (&blocks, offset) == -1) - goto error; - - struct ntreg_lf_record *lf = - (struct ntreg_lf_record *) ((char *) h->addr + offset); - - count += le16toh (lf->nr_keys); - } - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: nr_subkeys_in_nk = %zu," - " counted = %zu\n", - nr_subkeys_in_nk, count); - - if (nr_subkeys_in_nk != count) { - errno = ENOTSUP; - goto error; - } - - /* Copy list of children. Note nr_subkeys_in_nk is limited to - * something reasonable above. - */ - for (i = 0; i < nr_offsets; ++i) { - hive_node_h offset = le32toh (ri->offset[i]); - offset += 0x1000; - if (!IS_VALID_BLOCK (h, offset)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT" - " because ri-offset is not a valid block (0x%zx)\n", - offset); - errno = EFAULT; - goto error; - } - if (BLOCK_ID_EQ (h, offset, "li")) { - /* "ri" and "li" are basically the same */ - struct ntreg_ri_record *li = - (struct ntreg_ri_record *) ((char *) h->addr + offset); - - size_t j; - for (j = 0; j < le16toh (li->nr_offsets); ++j) { - hive_node_h subkey = le32toh (li->offset[j]); - subkey += 0x1000; - if (!(flags & GET_CHILDREN_NO_CHECK_NK)) { - if (!IS_VALID_BLOCK (h, subkey)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT because" - " li indirect subkey is not a valid block (0x%zx)\n", - subkey); - errno = EFAULT; - goto error; - } - } - if (add_to_offset_list (&children, subkey) == -1) - goto error; - } - } else { /* "lf" or "lh" block */ - struct ntreg_lf_record *lf = - (struct ntreg_lf_record *) ((char *) h->addr + offset); - - size_t j; - for (j = 0; j < le16toh (lf->nr_keys); ++j) { - hive_node_h subkey = le32toh (lf->keys[j].offset); - subkey += 0x1000; - if (!(flags & GET_CHILDREN_NO_CHECK_NK)) { - if (!IS_VALID_BLOCK (h, subkey)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_children: returning EFAULT because" - " lf/lh indirect subkey is not a valid block (0x%zx)\n", - subkey); - errno = EFAULT; - goto error; - } - } - if (add_to_offset_list (&children, subkey) == -1) - goto error; - } - } - } - goto ok; - } - /* else not supported, set errno and fall through */ - if (h->msglvl >= 2) - fprintf (stderr, "get_children: returning ENOTSUP" - " because subkey block is not lf/lh/li/ri (0x%zx, %d, %d)\n", - subkey_lf, block->id[0], block->id[1]); - errno = ENOTSUP; - error: - free_offset_list (&children); - free_offset_list (&blocks); - return -1; - - ok: - *children_ret = return_offset_list (&children); - *blocks_ret = return_offset_list (&blocks); - if (!*children_ret || !*blocks_ret) - goto error; - return 0; -} - -hive_node_h * -hivex_node_children (hive_h *h, hive_node_h node) -{ - hive_node_h *children; - size_t *blocks; - - if (get_children (h, node, &children, &blocks, 0) == -1) - return NULL; - - free (blocks); - return children; -} - -/* Very inefficient, but at least having a separate API call - * allows us to make it more efficient in future. - */ -hive_node_h -hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname) -{ - hive_node_h *children = NULL; - char *name = NULL; - hive_node_h ret = 0; - - children = hivex_node_children (h, node); - if (!children) goto error; - - size_t i; - for (i = 0; children[i] != 0; ++i) { - name = hivex_node_name (h, children[i]); - if (!name) goto error; - if (STRCASEEQ (name, nname)) { - ret = children[i]; - break; - } - free (name); name = NULL; - } - - error: - free (children); - free (name); - return ret; -} - -hive_node_h -hivex_node_parent (hive_h *h, hive_node_h node) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return 0; - } - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - - hive_node_h ret = le32toh (nk->parent); - ret += 0x1000; - if (!IS_VALID_BLOCK (h, ret)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_parent: returning EFAULT" - " because parent is not a valid block (0x%zx)\n", - ret); - errno = EFAULT; - return 0; - } - return ret; -} - -static int -get_values (hive_h *h, hive_node_h node, - hive_value_h **values_ret, size_t **blocks_ret) -{ - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return -1; - } - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - - size_t nr_values = le32toh (nk->nr_values); - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values); - - INIT_OFFSET_LIST (values); - INIT_OFFSET_LIST (blocks); - - /* Deal with the common "no values" case quickly. */ - if (nr_values == 0) - goto ok; - - /* Arbitrarily limit the number of values we will ever deal with. */ - if (nr_values > HIVEX_MAX_VALUES) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex: get_values: returning ERANGE" - " because nr_values > HIVEX_MAX_VALUES (%zu > %d)\n", - nr_values, HIVEX_MAX_VALUES); - errno = ERANGE; - goto error; - } - - /* Preallocate space for the values. */ - if (grow_offset_list (&values, nr_values) == -1) - goto error; - - /* Get the value list and check it looks reasonable. */ - size_t vlist_offset = le32toh (nk->vallist); - vlist_offset += 0x1000; - if (!IS_VALID_BLOCK (h, vlist_offset)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_values: returning EFAULT" - " because value list is not a valid block (0x%zx)\n", - vlist_offset); - errno = EFAULT; - goto error; - } - - if (add_to_offset_list (&blocks, vlist_offset) == -1) - goto error; - - struct ntreg_value_list *vlist = - (struct ntreg_value_list *) ((char *) h->addr + vlist_offset); - - size_t len = block_len (h, vlist_offset, NULL); - if (4 + nr_values * 4 > len) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_values: returning EFAULT" - " because value list is too long (%zu, %zu)\n", - nr_values, len); - errno = EFAULT; - goto error; - } - - size_t i; - for (i = 0; i < nr_values; ++i) { - hive_node_h value = le32toh (vlist->offset[i]); - value += 0x1000; - if (!IS_VALID_BLOCK (h, value)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_values: returning EFAULT" - " because value is not a valid block (0x%zx)\n", - value); - errno = EFAULT; - goto error; - } - if (add_to_offset_list (&values, value) == -1) - goto error; - } - - ok: - *values_ret = return_offset_list (&values); - *blocks_ret = return_offset_list (&blocks); - if (!*values_ret || !*blocks_ret) - goto error; - return 0; - - error: - free_offset_list (&values); - free_offset_list (&blocks); - return -1; -} - -hive_value_h * -hivex_node_values (hive_h *h, hive_node_h node) -{ - hive_value_h *values; - size_t *blocks; - - if (get_values (h, node, &values, &blocks) == -1) - return NULL; - - free (blocks); - return values; -} - -/* Very inefficient, but at least having a separate API call - * allows us to make it more efficient in future. - */ -hive_value_h -hivex_node_get_value (hive_h *h, hive_node_h node, const char *key) -{ - hive_value_h *values = NULL; - char *name = NULL; - hive_value_h ret = 0; - - values = hivex_node_values (h, node); - if (!values) goto error; - - size_t i; - for (i = 0; values[i] != 0; ++i) { - name = hivex_value_key (h, values[i]); - if (!name) goto error; - if (STRCASEEQ (name, key)) { - ret = values[i]; - break; - } - free (name); name = NULL; - } - - error: - free (values); - free (name); - return ret; -} - -size_t -hivex_value_struct_length (hive_h *h, hive_value_h value) -{ - size_t key_len; - - errno = 0; - key_len = hivex_value_key_len (h, value); - if (key_len == 0 && errno != 0) - return 0; - - /* -1 to avoid double-counting the first name character */ - return key_len + sizeof (struct ntreg_vk_record) - 1; -} - -size_t -hivex_value_key_len (hive_h *h, hive_value_h value) -{ - if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) { - errno = EINVAL; - return 0; - } - - struct ntreg_vk_record *vk = - (struct ntreg_vk_record *) ((char *) h->addr + value); - - /* vk->name_len is unsigned, 16 bit, so this is safe ... However - * we have to make sure the length doesn't exceed the block length. - */ - size_t ret = le16toh (vk->name_len); - size_t seg_len = block_len (h, value, NULL); - if (sizeof (struct ntreg_vk_record) + ret - 1 > seg_len) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_value_key_len: returning EFAULT" - " because key length is too long (%zu, %zu)\n", - ret, seg_len); - errno = EFAULT; - return 0; - } - return ret; -} - -char * -hivex_value_key (hive_h *h, hive_value_h value) -{ - if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) { - errno = EINVAL; - return 0; - } - - 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; - - char *ret = malloc (len + 1); - if (ret == NULL) - return NULL; - memcpy (ret, vk->name, len); - ret[len] = '\0'; - return ret; -} - -int -hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len) -{ - if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) { - errno = EINVAL; - return -1; - } - - struct ntreg_vk_record *vk = - (struct ntreg_vk_record *) ((char *) h->addr + value); - - if (t) - *t = le32toh (vk->data_type); - - if (len) { - *len = le32toh (vk->data_len); - *len &= 0x7fffffff; /* top bit indicates if data is stored inline */ - } - - 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 *) ((char *) 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) -{ - if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) { - errno = EINVAL; - return NULL; - } - - struct ntreg_vk_record *vk = - (struct ntreg_vk_record *) ((char *) h->addr + value); - - hive_type t; - size_t len; - int is_inline; - - t = le32toh (vk->data_type); - - len = le32toh (vk->data_len); - is_inline = !!(len & 0x80000000); - len &= 0x7fffffff; - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_value_value: value=0x%zx, t=%d, len=%zu, inline=%d\n", - value, t, len, is_inline); - - if (t_rtn) - *t_rtn = t; - if (len_rtn) - *len_rtn = len; - - if (is_inline && len > 4) { - errno = ENOTSUP; - return NULL; - } - - /* Arbitrarily limit the length that we will read. */ - if (len > HIVEX_MAX_VALUE_LEN) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_value_value: returning ERANGE because data " - "length > HIVEX_MAX_VALUE_LEN (%zu > %d)\n", - len, HIVEX_MAX_SUBKEYS); - errno = ERANGE; - return NULL; - } - - char *ret = malloc (len); - if (ret == NULL) - return NULL; - - if (is_inline) { - memcpy (ret, (char *) &vk->data_offset, len); - return ret; - } - - size_t data_offset = le32toh (vk->data_offset); - data_offset += 0x1000; - if (!IS_VALID_BLOCK (h, data_offset)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_value_value: returning EFAULT because data " - "offset is not a valid block (0x%zx)\n", - data_offset); - errno = EFAULT; - free (ret); - return NULL; - } - - /* Check that the declared size isn't larger than the block its in. - * - * XXX Some apparently valid registries are seen to have this, - * so turn this into a warning and substitute the smaller length - * instead. - */ - size_t blen = block_len (h, data_offset, NULL); - if (len > blen - 4 /* subtract 4 for block header */) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_value_value: warning: declared data length " - "is longer than the block it is in " - "(data 0x%zx, data len %zu, block len %zu)\n", - data_offset, len, blen); - len = blen - 4; - - /* Return the smaller length to the caller too. */ - if (len_rtn) - *len_rtn = len; - } - - char *data = (char *) h->addr + data_offset + 4; - memcpy (ret, data, len); - return ret; -} - -static char * -windows_utf16_to_utf8 (/* const */ char *input, size_t len) -{ - iconv_t ic = iconv_open ("UTF-8", "UTF-16"); - if (ic == (iconv_t) -1) - return NULL; - - /* iconv(3) has an insane interface ... */ - - /* Mostly UTF-8 will be smaller, so this is a good initial guess. */ - size_t outalloc = len; - - again:; - size_t inlen = len; - size_t outlen = outalloc; - char *out = malloc (outlen + 1); - if (out == NULL) { - int err = errno; - iconv_close (ic); - errno = err; - return NULL; - } - char *inp = input; - char *outp = out; - - size_t r = iconv (ic, &inp, &inlen, &outp, &outlen); - if (r == (size_t) -1) { - if (errno == E2BIG) { - int err = errno; - size_t prev = outalloc; - /* Try again with a larger output buffer. */ - free (out); - outalloc *= 2; - if (outalloc < prev) { - iconv_close (ic); - errno = err; - return NULL; - } - goto again; - } - else { - /* Else some conversion failure, eg. EILSEQ, EINVAL. */ - int err = errno; - iconv_close (ic); - free (out); - errno = err; - return NULL; - } - } - - *outp = '\0'; - iconv_close (ic); - - return out; -} - -char * -hivex_value_string (hive_h *h, hive_value_h value) -{ - hive_type t; - size_t len; - char *data = hivex_value_value (h, value, &t, &len); - - if (data == NULL) - return NULL; - - if (t != hive_t_string && t != hive_t_expand_string && t != hive_t_link) { - free (data); - errno = EINVAL; - return NULL; - } - - /* Deal with the case where Windows has allocated a large buffer - * full of random junk, and only the first few bytes of the buffer - * contain a genuine UTF-16 string. - * - * In this case, iconv would try to process the junk bytes as UTF-16 - * and inevitably find an illegal sequence (EILSEQ). Instead, stop - * after we find the first \0\0. - * - * (Found by Hilko Bengen in a fresh Windows XP SOFTWARE hive). - */ - size_t slen = utf16_string_len_in_bytes_max (data, len); - if (slen < len) - len = slen; - - char *ret = windows_utf16_to_utf8 (data, len); - free (data); - if (ret == NULL) - return NULL; - - return ret; -} - -static void -free_strings (char **argv) -{ - if (argv) { - size_t i; - - for (i = 0; argv[i] != NULL; ++i) - free (argv[i]); - free (argv); - } -} - -/* Get the length of a UTF-16 format string. Handle the string as - * pairs of bytes, looking for the first \0\0 pair. Only read up to - * 'len' maximum bytes. - */ -static size_t -utf16_string_len_in_bytes_max (const char *str, size_t len) -{ - size_t ret = 0; - - while (len >= 2 && (str[0] || str[1])) { - str += 2; - ret += 2; - len -= 2; - } - - return ret; -} - -/* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */ -char ** -hivex_value_multiple_strings (hive_h *h, hive_value_h value) -{ - hive_type t; - size_t len; - char *data = hivex_value_value (h, value, &t, &len); - - if (data == NULL) - return NULL; - - if (t != hive_t_multiple_strings) { - free (data); - errno = EINVAL; - return NULL; - } - - size_t nr_strings = 0; - char **ret = malloc ((1 + nr_strings) * sizeof (char *)); - if (ret == NULL) { - free (data); - return NULL; - } - ret[0] = NULL; - - char *p = data; - size_t plen; - - while (p < data + len && - (plen = utf16_string_len_in_bytes_max (p, data + len - p)) > 0) { - nr_strings++; - char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *)); - if (ret2 == NULL) { - free_strings (ret); - free (data); - return NULL; - } - ret = ret2; - - ret[nr_strings-1] = windows_utf16_to_utf8 (p, plen); - ret[nr_strings] = NULL; - if (ret[nr_strings-1] == NULL) { - free_strings (ret); - free (data); - return NULL; - } - - p += plen + 2 /* skip over UTF-16 \0\0 at the end of this string */; - } - - free (data); - return ret; -} - -int32_t -hivex_value_dword (hive_h *h, hive_value_h value) -{ - hive_type t; - size_t len; - void *data = hivex_value_value (h, value, &t, &len); - - if (data == NULL) - return -1; - - if ((t != hive_t_dword && t != hive_t_dword_be) || len != 4) { - free (data); - errno = EINVAL; - return -1; - } - - int32_t ret = * (int32_t *) data; - free (data); - if (t == hive_t_dword) /* little endian */ - ret = le32toh (ret); - else - ret = be32toh (ret); - - return ret; -} - -int64_t -hivex_value_qword (hive_h *h, hive_value_h value) -{ - hive_type t; - size_t len; - void *data = hivex_value_value (h, value, &t, &len); - - if (data == NULL) - return -1; - - if (t != hive_t_qword || len != 8) { - free (data); - errno = EINVAL; - return -1; - } - - int64_t ret = * (int64_t *) data; - free (data); - ret = le64toh (ret); /* always little endian */ - - return ret; -} - -/*---------------------------------------------------------------------- - * Visiting. - */ - -int -hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, - void *opaque, int flags) -{ - return hivex_visit_node (h, hivex_root (h), visitor, len, opaque, flags); -} - -static int hivex__visit_node (hive_h *h, hive_node_h node, - const struct hivex_visitor *vtor, - char *unvisited, void *opaque, int flags); - -int -hivex_visit_node (hive_h *h, hive_node_h node, - const struct hivex_visitor *visitor, size_t len, void *opaque, - int flags) -{ - struct hivex_visitor vtor; - memset (&vtor, 0, sizeof vtor); - - /* Note that len might be larger *or smaller* than the expected size. */ - size_t copysize = len <= sizeof vtor ? len : sizeof vtor; - memcpy (&vtor, visitor, copysize); - - /* This bitmap records unvisited nodes, so we don't loop if the - * registry contains cycles. - */ - char *unvisited = malloc (1 + h->size / 32); - if (unvisited == NULL) - return -1; - memcpy (unvisited, h->bitmap, 1 + h->size / 32); - - int r = hivex__visit_node (h, node, &vtor, unvisited, opaque, flags); - free (unvisited); - return r; -} - -static int -hivex__visit_node (hive_h *h, hive_node_h node, - const struct hivex_visitor *vtor, char *unvisited, - void *opaque, int flags) -{ - int skip_bad = flags & HIVEX_VISIT_SKIP_BAD; - char *name = NULL; - hive_value_h *values = NULL; - hive_node_h *children = NULL; - char *key = NULL; - char *str = NULL; - char **strs = NULL; - int i; - - /* Return -1 on all callback errors. However on internal errors, - * check if skip_bad is set and suppress those errors if so. - */ - int ret = -1; - - if (!BITMAP_TST (unvisited, node)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex__visit_node: contains cycle:" - " visited node 0x%zx already\n", - node); - - errno = ELOOP; - return skip_bad ? 0 : -1; - } - BITMAP_CLR (unvisited, node); - - name = hivex_node_name (h, node); - if (!name) return skip_bad ? 0 : -1; - if (vtor->node_start && vtor->node_start (h, opaque, node, name) == -1) - goto error; - - values = hivex_node_values (h, node); - if (!values) { - ret = skip_bad ? 0 : -1; - goto error; - } - - for (i = 0; values[i] != 0; ++i) { - hive_type t; - size_t len; - - if (hivex_value_type (h, values[i], &t, &len) == -1) { - ret = skip_bad ? 0 : -1; - goto error; - } - - key = hivex_value_key (h, values[i]); - if (key == NULL) { - ret = skip_bad ? 0 : -1; - goto error; - } - - if (vtor->value_any) { - str = hivex_value_value (h, values[i], &t, &len); - if (str == NULL) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1) - goto error; - free (str); str = NULL; - } - else { - switch (t) { - case hive_t_none: - str = hivex_value_value (h, values[i], &t, &len); - if (str == NULL) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (t != hive_t_none) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (vtor->value_none && - vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1) - goto error; - free (str); str = NULL; - break; - - case hive_t_string: - case hive_t_expand_string: - case hive_t_link: - str = hivex_value_string (h, values[i]); - if (str == NULL) { - if (errno != EILSEQ && errno != EINVAL) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (vtor->value_string_invalid_utf16) { - str = hivex_value_value (h, values[i], &t, &len); - if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], - t, len, key, str) == -1) - goto error; - free (str); str = NULL; - } - break; - } - if (vtor->value_string && - vtor->value_string (h, opaque, node, values[i], - t, len, key, str) == -1) - goto error; - free (str); str = NULL; - break; - - case hive_t_dword: - case hive_t_dword_be: { - int32_t i32 = hivex_value_dword (h, values[i]); - if (vtor->value_dword && - vtor->value_dword (h, opaque, node, values[i], - t, len, key, i32) == -1) - goto error; - break; - } - - case hive_t_qword: { - int64_t i64 = hivex_value_qword (h, values[i]); - if (vtor->value_qword && - vtor->value_qword (h, opaque, node, values[i], - t, len, key, i64) == -1) - goto error; - break; - } - - case hive_t_binary: - str = hivex_value_value (h, values[i], &t, &len); - if (str == NULL) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (t != hive_t_binary) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (vtor->value_binary && - vtor->value_binary (h, opaque, node, values[i], - t, len, key, str) == -1) - goto error; - free (str); str = NULL; - break; - - case hive_t_multiple_strings: - strs = hivex_value_multiple_strings (h, values[i]); - if (strs == NULL) { - if (errno != EILSEQ && errno != EINVAL) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (vtor->value_string_invalid_utf16) { - str = hivex_value_value (h, values[i], &t, &len); - if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], - t, len, key, str) == -1) - goto error; - free (str); str = NULL; - } - break; - } - if (vtor->value_multiple_strings && - vtor->value_multiple_strings (h, opaque, node, values[i], - t, len, key, strs) == -1) - goto error; - free_strings (strs); strs = NULL; - break; - - case hive_t_resource_list: - case hive_t_full_resource_description: - case hive_t_resource_requirements_list: - default: - str = hivex_value_value (h, values[i], &t, &len); - if (str == NULL) { - ret = skip_bad ? 0 : -1; - goto error; - } - if (vtor->value_other && - vtor->value_other (h, opaque, node, values[i], - t, len, key, str) == -1) - goto error; - free (str); str = NULL; - break; - } - } - - free (key); key = NULL; - } - - children = hivex_node_children (h, node); - if (children == NULL) { - ret = skip_bad ? 0 : -1; - goto error; - } - - for (i = 0; children[i] != 0; ++i) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex__visit_node: %s: visiting subkey %d (0x%zx)\n", - name, i, children[i]); - - if (hivex__visit_node (h, children[i], vtor, unvisited, opaque, flags) == -1) - goto error; - } - - if (vtor->node_end && vtor->node_end (h, opaque, node, name) == -1) - goto error; - - ret = 0; - - error: - free (name); - free (values); - free (children); - free (key); - free (str); - free_strings (strs); - return ret; -} - -/*---------------------------------------------------------------------- - * Writing. - */ - -/* Allocate an hbin (page), extending the malloc'd space if necessary, - * and updating the hive handle fields (but NOT the hive disk header - * -- the hive disk header is updated when we commit). This function - * also extends the bitmap if necessary. - * - * 'allocation_hint' is the size of the block allocation we would like - * to make. Normally registry blocks are very small (avg 50 bytes) - * and are contained in standard-sized pages (4KB), but the registry - * can support blocks which are larger than a standard page, in which - * case it creates a page of 8KB, 12KB etc. - * - * Returns: - * > 0 : offset of first usable byte of new page (after page header) - * 0 : error (errno set) - */ -static size_t -allocate_page (hive_h *h, size_t allocation_hint) -{ - /* In almost all cases this will be 1. */ - size_t nr_4k_pages = - 1 + (allocation_hint + sizeof (struct ntreg_hbin_page) - 1) / 4096; - assert (nr_4k_pages >= 1); - - /* 'extend' is the number of bytes to extend the file by. Note that - * hives found in the wild often contain slack between 'endpages' - * and the actual end of the file, so we don't always need to make - * the file larger. - */ - ssize_t extend = h->endpages + nr_4k_pages * 4096 - h->size; - - if (h->msglvl >= 2) { - fprintf (stderr, "allocate_page: current endpages = 0x%zx," - " current size = 0x%zx\n", - h->endpages, h->size); - fprintf (stderr, "allocate_page: extending file by %zd bytes" - " (<= 0 if no extension)\n", - extend); - } - - if (extend > 0) { - size_t oldsize = h->size; - size_t newsize = h->size + extend; - char *newaddr = realloc (h->addr, newsize); - if (newaddr == NULL) - return 0; - - size_t oldbitmapsize = 1 + oldsize / 32; - size_t newbitmapsize = 1 + newsize / 32; - char *newbitmap = realloc (h->bitmap, newbitmapsize); - if (newbitmap == NULL) { - free (newaddr); - return 0; - } - - h->addr = newaddr; - h->size = newsize; - h->bitmap = newbitmap; - - memset ((char *) h->addr + oldsize, 0, newsize - oldsize); - memset (h->bitmap + oldbitmapsize, 0, newbitmapsize - oldbitmapsize); - } - - size_t offset = h->endpages; - h->endpages += nr_4k_pages * 4096; - - if (h->msglvl >= 2) - fprintf (stderr, "allocate_page: new endpages = 0x%zx, new size = 0x%zx\n", - h->endpages, h->size); - - /* Write the hbin header. */ - struct ntreg_hbin_page *page = - (struct ntreg_hbin_page *) ((char *) h->addr + offset); - page->magic[0] = 'h'; - page->magic[1] = 'b'; - page->magic[2] = 'i'; - page->magic[3] = 'n'; - page->offset_first = htole32 (offset - 0x1000); - page->page_size = htole32 (nr_4k_pages * 4096); - memset (page->unknown, 0, sizeof (page->unknown)); - - if (h->msglvl >= 2) - fprintf (stderr, "allocate_page: new page at 0x%zx\n", offset); - - /* Offset of first usable byte after the header. */ - return offset + sizeof (struct ntreg_hbin_page); -} - -/* Allocate a single block, first allocating an hbin (page) at the end - * of the current file if necessary. NB. To keep the implementation - * simple and more likely to be correct, we do not reuse existing free - * blocks. - * - * seg_len is the size of the block (this INCLUDES the block header). - * The header of the block is initialized to -seg_len (negative to - * indicate used). id[2] is the block ID (type), eg. "nk" for nk- - * record. The block bitmap is updated to show this block as valid. - * The rest of the contents of the block will be zero. - * - * **NB** Because allocate_block may reallocate the memory, all - * pointers into the memory become potentially invalid. I really - * love writing in C, can't you tell? - * - * Returns: - * > 0 : offset of new block - * 0 : error (errno set) - */ -static size_t -allocate_block (hive_h *h, size_t seg_len, const char id[2]) -{ - if (!h->writable) { - errno = EROFS; - return 0; - } - - if (seg_len < 4) { - /* The caller probably forgot to include the header. Note that - * value lists have no ID field, so seg_len == 4 would be possible - * for them, albeit unusual. - */ - if (h->msglvl >= 2) - fprintf (stderr, "allocate_block: refusing too small allocation (%zu)," - " returning ERANGE\n", seg_len); - errno = ERANGE; - return 0; - } - - /* Refuse really large allocations. */ - if (seg_len > HIVEX_MAX_ALLOCATION) { - if (h->msglvl >= 2) - fprintf (stderr, "allocate_block: refusing large allocation (%zu)," - " returning ERANGE\n", seg_len); - errno = ERANGE; - return 0; - } - - /* Round up allocation to multiple of 8 bytes. All blocks must be - * on an 8 byte boundary. - */ - seg_len = (seg_len + 7) & ~7; - - /* Allocate a new page if necessary. */ - if (h->endblocks == 0 || h->endblocks + seg_len > h->endpages) { - size_t newendblocks = allocate_page (h, seg_len); - if (newendblocks == 0) - return 0; - h->endblocks = newendblocks; - } - - size_t offset = h->endblocks; - - if (h->msglvl >= 2) - fprintf (stderr, "allocate_block: new block at 0x%zx, size %zu\n", - offset, seg_len); - - struct ntreg_hbin_block *blockhdr = - (struct ntreg_hbin_block *) ((char *) h->addr + offset); - - memset (blockhdr, 0, seg_len); - - blockhdr->seg_len = htole32 (- (int32_t) seg_len); - if (id[0] && id[1] && seg_len >= sizeof (struct ntreg_hbin_block)) { - blockhdr->id[0] = id[0]; - blockhdr->id[1] = id[1]; - } - - BITMAP_SET (h->bitmap, offset); - - h->endblocks += seg_len; - - /* If there is space after the last block in the last page, then we - * have to put a dummy free block header here to mark the rest of - * the page as free. - */ - ssize_t rem = h->endpages - h->endblocks; - if (rem > 0) { - if (h->msglvl >= 2) - fprintf (stderr, "allocate_block: marking remainder of page free" - " starting at 0x%zx, size %zd\n", h->endblocks, rem); - - assert (rem >= 4); - - blockhdr = (struct ntreg_hbin_block *) ((char *) h->addr + h->endblocks); - blockhdr->seg_len = htole32 ((int32_t) rem); - } - - return offset; -} - -/* 'offset' must point to a valid, used block. This function marks - * the block unused (by updating the seg_len field) and invalidates - * the bitmap. It does NOT do this recursively, so to avoid creating - * unreachable used blocks, callers may have to recurse over the hive - * structures. Also callers must ensure there are no references to - * this block from other parts of the hive. - */ -static void -mark_block_unused (hive_h *h, size_t offset) -{ - assert (h->writable); - assert (IS_VALID_BLOCK (h, offset)); - - if (h->msglvl >= 2) - fprintf (stderr, "mark_block_unused: marking 0x%zx unused\n", offset); - - struct ntreg_hbin_block *blockhdr = - (struct ntreg_hbin_block *) ((char *) h->addr + offset); - - size_t seg_len = block_len (h, offset, NULL); - blockhdr->seg_len = htole32 (seg_len); - - BITMAP_CLR (h->bitmap, offset); -} - -/* Delete all existing values at this node. */ -static int -delete_values (hive_h *h, hive_node_h node) -{ - assert (h->writable); - - hive_value_h *values; - size_t *blocks; - if (get_values (h, node, &values, &blocks) == -1) - return -1; - - size_t i; - for (i = 0; blocks[i] != 0; ++i) - mark_block_unused (h, blocks[i]); - - free (blocks); - - for (i = 0; values[i] != 0; ++i) { - struct ntreg_vk_record *vk = - (struct ntreg_vk_record *) ((char *) h->addr + values[i]); - - size_t len; - int is_inline; - len = le32toh (vk->data_len); - is_inline = !!(len & 0x80000000); /* top bit indicates is inline */ - len &= 0x7fffffff; - - if (!is_inline) { /* non-inline, so remove data block */ - size_t data_offset = le32toh (vk->data_offset); - data_offset += 0x1000; - mark_block_unused (h, data_offset); - } - - /* remove vk record */ - mark_block_unused (h, values[i]); - } - - free (values); - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - nk->nr_values = htole32 (0); - nk->vallist = htole32 (0xffffffff); - - return 0; -} - -int -hivex_commit (hive_h *h, const char *filename, int flags) -{ - if (flags != 0) { - errno = EINVAL; - return -1; - } - - if (!h->writable) { - errno = EROFS; - return -1; - } - - filename = filename ? : h->filename; - int fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666); - if (fd == -1) - return -1; - - /* Update the header fields. */ - uint32_t sequence = le32toh (h->hdr->sequence1); - sequence++; - h->hdr->sequence1 = htole32 (sequence); - h->hdr->sequence2 = htole32 (sequence); - /* XXX Ought to update h->hdr->last_modified. */ - h->hdr->blocks = htole32 (h->endpages - 0x1000); - - /* Recompute header checksum. */ - uint32_t sum = header_checksum (h); - h->hdr->csum = htole32 (sum); - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_commit: new header checksum: 0x%x\n", sum); - - if (full_write (fd, h->addr, h->size) != h->size) { - int err = errno; - close (fd); - errno = err; - return -1; - } - - if (close (fd) == -1) - return -1; - - return 0; -} - -/* Calculate the hash for a lf or lh record offset. - */ -static void -calc_hash (const char *type, const char *name, void *ret) -{ - size_t len = strlen (name); - - if (STRPREFIX (type, "lf")) - /* Old-style, not used in current registries. */ - memcpy (ret, name, len < 4 ? len : 4); - else { - /* New-style for lh-records. */ - size_t i, c; - uint32_t h = 0; - for (i = 0; i < len; ++i) { - c = c_toupper (name[i]); - h *= 37; - h += c; - } - *((uint32_t *) ret) = htole32 (h); - } -} - -/* Create a completely new lh-record containing just the single node. */ -static size_t -new_lh_record (hive_h *h, const char *name, hive_node_h node) -{ - static const char id[2] = { 'l', 'h' }; - size_t seg_len = sizeof (struct ntreg_lf_record); - size_t offset = allocate_block (h, seg_len, id); - if (offset == 0) - return 0; - - struct ntreg_lf_record *lh = - (struct ntreg_lf_record *) ((char *) h->addr + offset); - lh->nr_keys = htole16 (1); - lh->keys[0].offset = htole32 (node - 0x1000); - calc_hash ("lh", name, lh->keys[0].hash); - - return offset; -} - -/* Insert node into existing lf/lh-record at position. - * This allocates a new record and marks the old one as unused. - */ -static size_t -insert_lf_record (hive_h *h, size_t old_offs, size_t posn, - const char *name, hive_node_h node) -{ - assert (IS_VALID_BLOCK (h, old_offs)); - - /* Work around C stupidity. - * http://www.redhat.com/archives/libguestfs/2010-February/msg00056.html - */ - int test = BLOCK_ID_EQ (h, old_offs, "lf") || BLOCK_ID_EQ (h, old_offs, "lh"); - assert (test); - - struct ntreg_lf_record *old_lf = - (struct ntreg_lf_record *) ((char *) h->addr + old_offs); - size_t nr_keys = le16toh (old_lf->nr_keys); - - nr_keys++; /* in new record ... */ - - size_t seg_len = sizeof (struct ntreg_lf_record) + (nr_keys-1) * 8; - - /* Copy the old_lf->id in case it moves during allocate_block. */ - char id[2]; - memcpy (id, old_lf->id, sizeof id); - - size_t new_offs = allocate_block (h, seg_len, id); - if (new_offs == 0) - return 0; - - /* old_lf could have been invalidated by allocate_block. */ - old_lf = (struct ntreg_lf_record *) ((char *) h->addr + old_offs); - - struct ntreg_lf_record *new_lf = - (struct ntreg_lf_record *) ((char *) h->addr + new_offs); - new_lf->nr_keys = htole16 (nr_keys); - - /* Copy the keys until we reach posn, insert the new key there, then - * copy the remaining keys. - */ - size_t i; - for (i = 0; i < posn; ++i) - new_lf->keys[i] = old_lf->keys[i]; - - new_lf->keys[i].offset = htole32 (node - 0x1000); - calc_hash (new_lf->id, name, new_lf->keys[i].hash); - - for (i = posn+1; i < nr_keys; ++i) - new_lf->keys[i] = old_lf->keys[i-1]; - - /* Old block is unused, return new block. */ - mark_block_unused (h, old_offs); - return new_offs; -} - -/* Compare name with name in nk-record. */ -static int -compare_name_with_nk_name (hive_h *h, const char *name, hive_node_h nk_offs) -{ - assert (IS_VALID_BLOCK (h, nk_offs)); - assert (BLOCK_ID_EQ (h, nk_offs, "nk")); - - /* Name in nk is not necessarily nul-terminated. */ - char *nname = hivex_node_name (h, nk_offs); - - /* Unfortunately we don't have a way to return errors here. */ - if (!nname) { - perror ("compare_name_with_nk_name"); - return 0; - } - - int r = strcasecmp (name, nname); - free (nname); - - return r; -} - -hive_node_h -hivex_node_add_child (hive_h *h, hive_node_h parent, const char *name) -{ - if (!h->writable) { - errno = EROFS; - return 0; - } - - if (!IS_VALID_BLOCK (h, parent) || !BLOCK_ID_EQ (h, parent, "nk")) { - errno = EINVAL; - return 0; - } - - if (name == NULL || strlen (name) == 0) { - errno = EINVAL; - return 0; - } - - if (hivex_node_get_child (h, parent, name) != 0) { - errno = EEXIST; - return 0; - } - - /* Create the new nk-record. */ - static const char nk_id[2] = { 'n', 'k' }; - size_t seg_len = sizeof (struct ntreg_nk_record) + strlen (name); - hive_node_h node = allocate_block (h, seg_len, nk_id); - if (node == 0) - return 0; - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_add_child: allocated new nk-record" - " for child at 0x%zx\n", node); - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - nk->flags = htole16 (0x0020); /* key is ASCII. */ - nk->parent = htole32 (parent - 0x1000); - nk->subkey_lf = htole32 (0xffffffff); - nk->subkey_lf_volatile = htole32 (0xffffffff); - nk->vallist = htole32 (0xffffffff); - nk->classname = htole32 (0xffffffff); - nk->name_len = htole16 (strlen (name)); - strcpy (nk->name, name); - - /* Inherit parent sk. */ - struct ntreg_nk_record *parent_nk = - (struct ntreg_nk_record *) ((char *) h->addr + parent); - size_t parent_sk_offset = le32toh (parent_nk->sk); - parent_sk_offset += 0x1000; - if (!IS_VALID_BLOCK (h, parent_sk_offset) || - !BLOCK_ID_EQ (h, parent_sk_offset, "sk")) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_add_child: returning EFAULT" - " because parent sk is not a valid block (%zu)\n", - parent_sk_offset); - errno = EFAULT; - return 0; - } - struct ntreg_sk_record *sk = - (struct ntreg_sk_record *) ((char *) h->addr + parent_sk_offset); - sk->refcount = htole32 (le32toh (sk->refcount) + 1); - nk->sk = htole32 (parent_sk_offset - 0x1000); - - /* Inherit parent timestamp. */ - nk->timestamp = parent_nk->timestamp; - - /* What I found out the hard way (not documented anywhere): the - * subkeys in lh-records must be kept sorted. If you just add a - * subkey in a non-sorted position (eg. just add it at the end) then - * Windows won't see the subkey _and_ Windows will corrupt the hive - * itself when it modifies or saves it. - * - * So use get_children() to get a list of intermediate - * lf/lh-records. get_children() returns these in reading order - * (which is sorted), so we look for the lf/lh-records in sequence - * until we find the key name just after the one we are inserting, - * and we insert the subkey just before it. - * - * The only other case is the no-subkeys case, where we have to - * create a brand new lh-record. - */ - hive_node_h *unused; - size_t *blocks; - - if (get_children (h, parent, &unused, &blocks, 0) == -1) - return 0; - free (unused); - - size_t i, j; - size_t nr_subkeys_in_parent_nk = le32toh (parent_nk->nr_subkeys); - if (nr_subkeys_in_parent_nk == 0) { /* No subkeys case. */ - /* Free up any existing intermediate blocks. */ - for (i = 0; blocks[i] != 0; ++i) - mark_block_unused (h, blocks[i]); - size_t lh_offs = new_lh_record (h, name, node); - if (lh_offs == 0) { - free (blocks); - return 0; - } - - /* Recalculate pointers that could have been invalidated by - * previous call to allocate_block (via new_lh_record). - */ - nk = (struct ntreg_nk_record *) ((char *) h->addr + node); - parent_nk = (struct ntreg_nk_record *) ((char *) h->addr + parent); - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_add_child: no keys, allocated new" - " lh-record at 0x%zx\n", lh_offs); - - parent_nk->subkey_lf = htole32 (lh_offs - 0x1000); - } - else { /* Insert subkeys case. */ - size_t old_offs = 0, new_offs = 0; - struct ntreg_lf_record *old_lf = NULL; - - /* Find lf/lh key name just after the one we are inserting. */ - for (i = 0; blocks[i] != 0; ++i) { - if (BLOCK_ID_EQ (h, blocks[i], "lf") || - BLOCK_ID_EQ (h, blocks[i], "lh")) { - old_offs = blocks[i]; - old_lf = (struct ntreg_lf_record *) ((char *) h->addr + old_offs); - for (j = 0; j < le16toh (old_lf->nr_keys); ++j) { - hive_node_h nk_offs = le32toh (old_lf->keys[j].offset); - nk_offs += 0x1000; - if (compare_name_with_nk_name (h, name, nk_offs) < 0) - goto insert_it; - } - } - } - - /* Insert it at the end. - * old_offs points to the last lf record, set j. - */ - assert (old_offs != 0); /* should never happen if nr_subkeys > 0 */ - j = le16toh (old_lf->nr_keys); - - /* Insert it. */ - insert_it: - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_add_child: insert key in existing" - " lh-record at 0x%zx, posn %zu\n", old_offs, j); - - new_offs = insert_lf_record (h, old_offs, j, name, node); - if (new_offs == 0) { - free (blocks); - return 0; - } - - /* Recalculate pointers that could have been invalidated by - * previous call to allocate_block (via insert_lf_record). - */ - nk = (struct ntreg_nk_record *) ((char *) h->addr + node); - parent_nk = (struct ntreg_nk_record *) ((char *) h->addr + parent); - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_add_child: new lh-record at 0x%zx\n", - new_offs); - - /* If the lf/lh-record was directly referenced by the parent nk, - * then update the parent nk. - */ - if (le32toh (parent_nk->subkey_lf) + 0x1000 == old_offs) - parent_nk->subkey_lf = htole32 (new_offs - 0x1000); - /* Else we have to look for the intermediate ri-record and update - * that in-place. - */ - else { - for (i = 0; blocks[i] != 0; ++i) { - if (BLOCK_ID_EQ (h, blocks[i], "ri")) { - struct ntreg_ri_record *ri = - (struct ntreg_ri_record *) ((char *) h->addr + blocks[i]); - for (j = 0; j < le16toh (ri->nr_offsets); ++j) - if (le32toh (ri->offset[j] + 0x1000) == old_offs) { - ri->offset[j] = htole32 (new_offs - 0x1000); - goto found_it; - } - } - } - - /* Not found .. This is an internal error. */ - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_add_child: returning ENOTSUP" - " because could not find ri->lf link\n"); - errno = ENOTSUP; - free (blocks); - return 0; - - found_it: - ; - } - } - - free (blocks); - - /* Update nr_subkeys in parent nk. */ - nr_subkeys_in_parent_nk++; - parent_nk->nr_subkeys = htole32 (nr_subkeys_in_parent_nk); - - /* Update max_subkey_name_len in parent nk. */ - uint16_t max = le16toh (parent_nk->max_subkey_name_len); - if (max < strlen (name) * 2) /* *2 because "recoded" in UTF16-LE. */ - parent_nk->max_subkey_name_len = htole16 (strlen (name) * 2); - - return node; -} - -/* Decrement the refcount of an sk-record, and if it reaches zero, - * unlink it from the chain and delete it. - */ -static int -delete_sk (hive_h *h, size_t sk_offset) -{ - if (!IS_VALID_BLOCK (h, sk_offset) || !BLOCK_ID_EQ (h, sk_offset, "sk")) { - if (h->msglvl >= 2) - fprintf (stderr, "delete_sk: not an sk record: 0x%zx\n", sk_offset); - errno = EFAULT; - return -1; - } - - struct ntreg_sk_record *sk = - (struct ntreg_sk_record *) ((char *) h->addr + sk_offset); - - if (sk->refcount == 0) { - if (h->msglvl >= 2) - fprintf (stderr, "delete_sk: sk record already has refcount 0: 0x%zx\n", - sk_offset); - errno = EINVAL; - return -1; - } - - sk->refcount--; - - if (sk->refcount == 0) { - size_t sk_prev_offset = sk->sk_prev; - sk_prev_offset += 0x1000; - - size_t sk_next_offset = sk->sk_next; - sk_next_offset += 0x1000; - - /* Update sk_prev/sk_next SKs, unless they both point back to this - * cell in which case we are deleting the last SK. - */ - if (sk_prev_offset != sk_offset && sk_next_offset != sk_offset) { - struct ntreg_sk_record *sk_prev = - (struct ntreg_sk_record *) ((char *) h->addr + sk_prev_offset); - struct ntreg_sk_record *sk_next = - (struct ntreg_sk_record *) ((char *) h->addr + sk_next_offset); - - sk_prev->sk_next = htole32 (sk_next_offset - 0x1000); - sk_next->sk_prev = htole32 (sk_prev_offset - 0x1000); - } - - /* Refcount is zero so really delete this block. */ - mark_block_unused (h, sk_offset); - } - - return 0; -} - -/* Callback from hivex_node_delete_child which is called to delete a - * node AFTER its subnodes have been visited. The subnodes have been - * deleted but we still have to delete any lf/lh/li/ri records and the - * value list block and values, followed by deleting the node itself. - */ -static int -delete_node (hive_h *h, void *opaque, hive_node_h node, const char *name) -{ - /* Get the intermediate blocks. The subkeys have already been - * deleted by this point, so tell get_children() not to check for - * validity of the nk-records. - */ - hive_node_h *unused; - size_t *blocks; - if (get_children (h, node, &unused, &blocks, GET_CHILDREN_NO_CHECK_NK) == -1) - return -1; - free (unused); - - /* We don't care what's in these intermediate blocks, so we can just - * delete them unconditionally. - */ - size_t i; - for (i = 0; blocks[i] != 0; ++i) - mark_block_unused (h, blocks[i]); - - free (blocks); - - /* Delete the values in the node. */ - if (delete_values (h, node) == -1) - return -1; - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - - /* If the NK references an SK, delete it. */ - size_t sk_offs = le32toh (nk->sk); - if (sk_offs != 0xffffffff) { - sk_offs += 0x1000; - if (delete_sk (h, sk_offs) == -1) - return -1; - nk->sk = htole32 (0xffffffff); - } - - /* If the NK references a classname, delete it. */ - size_t cl_offs = le32toh (nk->classname); - if (cl_offs != 0xffffffff) { - cl_offs += 0x1000; - mark_block_unused (h, cl_offs); - nk->classname = htole32 (0xffffffff); - } - - /* Delete the node itself. */ - mark_block_unused (h, node); - - return 0; -} - -int -hivex_node_delete_child (hive_h *h, hive_node_h node) -{ - if (!h->writable) { - errno = EROFS; - return -1; - } - - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return -1; - } - - if (node == hivex_root (h)) { - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_delete_child: cannot delete root node\n"); - errno = EINVAL; - return -1; - } - - hive_node_h parent = hivex_node_parent (h, node); - if (parent == 0) - return -1; - - /* Delete node and all its children and values recursively. */ - static const struct hivex_visitor visitor = { .node_end = delete_node }; - if (hivex_visit_node (h, node, &visitor, sizeof visitor, NULL, 0) == -1) - return -1; - - /* Delete the link from parent to child. We need to find the lf/lh - * record which contains the offset and remove the offset from that - * record, then decrement the element count in that record, and - * decrement the overall number of subkeys stored in the parent - * node. - */ - hive_node_h *unused; - size_t *blocks; - if (get_children (h, parent, &unused, &blocks, GET_CHILDREN_NO_CHECK_NK)== -1) - return -1; - free (unused); - - size_t i, j; - for (i = 0; blocks[i] != 0; ++i) { - struct ntreg_hbin_block *block = - (struct ntreg_hbin_block *) ((char *) h->addr + blocks[i]); - - if (block->id[0] == 'l' && (block->id[1] == 'f' || block->id[1] == 'h')) { - struct ntreg_lf_record *lf = (struct ntreg_lf_record *) block; - - size_t nr_subkeys_in_lf = le16toh (lf->nr_keys); - - for (j = 0; j < nr_subkeys_in_lf; ++j) - if (le32toh (lf->keys[j].offset) + 0x1000 == node) { - for (; j < nr_subkeys_in_lf - 1; ++j) - memcpy (&lf->keys[j], &lf->keys[j+1], sizeof (lf->keys[j])); - lf->nr_keys = htole16 (nr_subkeys_in_lf - 1); - goto found; - } - } - } - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_delete_child: could not find parent" - " to child link\n"); - errno = ENOTSUP; - return -1; - - found:; - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + parent); - size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys); - nk->nr_subkeys = htole32 (nr_subkeys_in_nk - 1); - - if (h->msglvl >= 2) - fprintf (stderr, "hivex_node_delete_child: updating nr_subkeys" - " in parent 0x%zx to %zu\n", parent, nr_subkeys_in_nk); - - return 0; -} - -int -hivex_node_set_values (hive_h *h, hive_node_h node, - size_t nr_values, const hive_set_value *values, - int flags) -{ - if (!h->writable) { - errno = EROFS; - return -1; - } - - if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) { - errno = EINVAL; - return -1; - } - - /* Delete all existing values. */ - if (delete_values (h, node) == -1) - return -1; - - if (nr_values == 0) - return 0; - - /* Allocate value list node. Value lists have no id field. */ - static const char nul_id[2] = { 0, 0 }; - size_t seg_len = - sizeof (struct ntreg_value_list) + (nr_values - 1) * sizeof (uint32_t); - size_t vallist_offs = allocate_block (h, seg_len, nul_id); - if (vallist_offs == 0) - return -1; - - struct ntreg_nk_record *nk = - (struct ntreg_nk_record *) ((char *) h->addr + node); - nk->nr_values = htole32 (nr_values); - nk->vallist = htole32 (vallist_offs - 0x1000); - - struct ntreg_value_list *vallist = - (struct ntreg_value_list *) ((char *) h->addr + vallist_offs); - - size_t i; - for (i = 0; i < nr_values; ++i) { - /* Allocate vk record to store this (key, value) pair. */ - static const char vk_id[2] = { 'v', 'k' }; - seg_len = sizeof (struct ntreg_vk_record) + strlen (values[i].key); - size_t vk_offs = allocate_block (h, seg_len, vk_id); - if (vk_offs == 0) - return -1; - - /* Recalculate pointers that could have been invalidated by - * previous call to allocate_block. - */ - nk = (struct ntreg_nk_record *) ((char *) h->addr + node); - vallist = (struct ntreg_value_list *) ((char *) h->addr + vallist_offs); - - vallist->offset[i] = htole32 (vk_offs - 0x1000); - - struct ntreg_vk_record *vk = - (struct ntreg_vk_record *) ((char *) h->addr + vk_offs); - size_t name_len = strlen (values[i].key); - vk->name_len = htole16 (name_len); - strcpy (vk->name, values[i].key); - vk->data_type = htole32 (values[i].t); - uint32_t len = values[i].len; - if (len <= 4) /* store it inline => set MSB flag */ - len |= 0x80000000; - vk->data_len = htole32 (len); - vk->flags = name_len == 0 ? 0 : 1; - - if (values[i].len <= 4) /* store it inline */ - memcpy (&vk->data_offset, values[i].value, values[i].len); - else { - size_t offs = allocate_block (h, values[i].len + 4, nul_id); - if (offs == 0) - return -1; - - /* Recalculate pointers that could have been invalidated by - * previous call to allocate_block. - */ - nk = (struct ntreg_nk_record *) ((char *) h->addr + node); - vallist = (struct ntreg_value_list *) ((char *) h->addr + vallist_offs); - vk = (struct ntreg_vk_record *) ((char *) h->addr + vk_offs); - - memcpy ((char *) h->addr + offs + 4, values[i].value, values[i].len); - vk->data_offset = htole32 (offs - 0x1000); - } - - if (name_len * 2 > le32toh (nk->max_vk_name_len)) - /* * 2 for UTF16-LE "reencoding" */ - nk->max_vk_name_len = htole32 (name_len * 2); - if (values[i].len > le32toh (nk->max_vk_data_len)) - nk->max_vk_data_len = htole32 (values[i].len); - } - - return 0; -} - -int -hivex_node_set_value (hive_h *h, hive_node_h node, - const hive_set_value *val, int flags) -{ - int retval = -1; - hive_value_h *prev_values; - hive_set_value *new_values; - size_t nr_values; - size_t i; - ssize_t idx_of_val; - - prev_values = hivex_node_values (h, node); - if (prev_values == NULL) - return -1; - - /* Count number of existing values in this node. */ - nr_values = 0; - for (i = 0; prev_values[i] != 0; i++) - nr_values++; - - /* Allocate a new hive_set_value list, with space for all existing - * values, plus 1 (for the new key if we're not replacing an - * existing key). - */ - new_values = calloc (nr_values + 1, sizeof (hive_set_value)); - if (new_values == NULL) - goto out1; - - /* Copy the old values to the new values. If we find the key along - * the way, note its index in 'idx_of_val'. - */ - idx_of_val = -1; - for (i = 0; prev_values[i] != 0; i++) { - size_t len; - hive_type t; - char *valkey, *valval; - - valval = hivex_value_value (h, prev_values[i], &t, &len); - if (valval == NULL) goto out2; - - new_values[i].value = valval; - new_values[i].t = t; - new_values[i].len = len; - - valkey = hivex_value_key (h, prev_values[i]); - if (valkey == NULL) goto out2; - - new_values[i].key = valkey; - - if (STRCASEEQ (valkey, val->key)) - idx_of_val = i; - } - - if (idx_of_val > -1) { - free (new_values[idx_of_val].key); - free (new_values[idx_of_val].value); - } else { /* insert it at the end */ - idx_of_val = nr_values; - nr_values++; - } - - new_values[idx_of_val].key = strdup (val->key); - new_values[idx_of_val].value = malloc (val->len); - new_values[idx_of_val].len = val->len; - new_values[idx_of_val].t = val->t; - - if (new_values[idx_of_val].key == NULL || - new_values[idx_of_val].value == NULL) - goto out2; - memcpy (new_values[idx_of_val].value, val->value, val->len); - - retval = hivex_node_set_values (h, node, nr_values, new_values, 0); - - out2: - for (i = 0; i < nr_values; ++i) { - free (new_values[i].key); - free (new_values[i].value); - } - free (new_values); - - out1: - free (prev_values); - - return retval; -} diff --git a/trunk/hivex/lib/mmap.c b/trunk/hivex/lib/mmap.c deleted file mode 100644 index c68ec32..0000000 --- a/trunk/hivex/lib/mmap.c +++ /dev/null @@ -1,69 +0,0 @@ -/* mmap replacement for mingw. - * - * Copyright (C) 2011 by Daniel Gillen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License. - * - * This library 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 - * Lesser General Public License for more details. - */ - -#include "hivex.h" -#include "hivex-internal.h" -#include "mmap.h" - -#include -#include - -void * -hivex__rpl_mmap (hive_h *h, - void *p_addr, size_t len, int prot, int flags, int fd, off_t offset) -{ - void *p_map; - - // Check parameters for unsupported values - if (p_addr != NULL) - return MAP_FAILED; - if (prot != PROT_READ) - return MAP_FAILED; - if (flags != MAP_SHARED) - return MAP_FAILED; - - // Create file mapping - h->p_winmap = CreateFileMapping ((HANDLE)_get_osfhandle(fd), - NULL, PAGE_READONLY, 0, 0, NULL); - if (h->p_winmap == NULL) - return MAP_FAILED; - - // Create map view - p_map = MapViewOfFile (h->p_winmap, FILE_MAP_READ, 0, 0, len); - if (p_map == NULL) { - CloseHandle (h->p_winmap); - return MAP_FAILED; - } - - return p_map; -} - -int -hivex__rpl_munmap (hive_h *h, void *p_addr, size_t len) -{ - if (p_addr == NULL || h->p_winmap == NULL) - return -1; - - // Close map view - if (UnmapViewOfFile (p_addr) == 0) - return -1; - - // Close file mapping - if (CloseHandle (h->p_winmap) == 0) - return -1; - - h->p_winmap = NULL; - return 0; -} diff --git a/trunk/hivex/lib/mmap.h b/trunk/hivex/lib/mmap.h deleted file mode 100644 index 0a693f3..0000000 --- a/trunk/hivex/lib/mmap.h +++ /dev/null @@ -1,74 +0,0 @@ -/* mmap replacement for mingw. - * - * Copyright (C) 2011 by Daniel Gillen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License. - * - * This library 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 - * Lesser General Public License for more details. - */ - -#ifndef HIVEX_MMAP_H_ -#define HIVEX_MMAP_H_ - -#include -#include - -#include "hivex.h" -#include "hivex-internal.h" - -/* Hack to pass the hive handle to the replacement mmap and munmap - * functions. XXX - */ -#define mmap(a,b,c,d,e,f) hivex__rpl_mmap(h,(a),(b),(c),(d),(e),(f)) -#define munmap(a,b) hivex__rpl_munmap(h,(a),(b)) - -// Supported map protections. -#define PROT_READ 0x1 /* Page can be read. */ - -// Supported sharing types (must choose one and only one of these). -#define MAP_SHARED 0x01 /* Share changes. */ - -// Value that is returned when mapping failed -#define MAP_FAILED NULL - -/* - * hivex replacement mmap - * - * Parameters: - * h : Hive handle - * void *p_addr : Preferred starting address for the mapping. Unsupported - * and must be NULL. - * size_t len : Mapping length (From offset to offset+len-1). - * int prot : Flags that control what kind of access is permitted. - * Must be PROT_READ. - * int flags : Flags that control the nature of the map. Must be - * MAP_SHARED. - * int fd : File descriptor of file to be mapped. - * off_t offset : Mapping offset. - * - * Returns: - * Map address on success or MAP_FAILED on error. - */ -extern void *hivex__rpl_mmap (hive_h *h, void *p_addr, size_t len, int prot, int flags, int fd, off_t offset); - -/* - * hivex replacement munmap - * - * Parameters: - * h : Hive handle - * void *p_addr : Startaddress of mapping created with mmap - * size_t len : Lenght of mapping to be unmapped. Unsupported. The whole - * mapping will always be unmapped. - * - * Returns: - * 0 on success or -1 on error. - */ -extern int hivex__rpl_munmap (hive_h *h, void *p_addr, size_t len); - -#endif /* HIVEX_MMAP_H_ */ diff --git a/trunk/hivex/lib/test-just-header.c b/trunk/hivex/lib/test-just-header.c deleted file mode 100644 index 5b8129f..0000000 --- a/trunk/hivex/lib/test-just-header.c +++ /dev/null @@ -1,30 +0,0 @@ -/* hivex - * Copyright (C) 2010-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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* Check that just including the header and nothing else works, ie. - * that there are no implicit dependencies in the header file. - */ - -#include "hivex.h" - -int -main (int argc, char *argv[]) -{ - hive_h *h = hivex_open ("../images/minimal", 0); - return h == h ? 0 : 1; -} diff --git a/trunk/hivex/lib/tools/Makefile.am b/trunk/hivex/lib/tools/Makefile.am deleted file mode 100644 index bd8e986..0000000 --- a/trunk/hivex/lib/tools/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -# libguestfs -# Copyright (C) 2009 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. - -# OCaml Windows Registry visualizer. This was used while reverse -# engineering the hive format, and is not normally compiled. If you -# do with to compile it, you'll need ocaml-bitstring-devel and -# ocaml-extlib-devel. Also you'll need a collection of hive files -# from Windows machines to experiment with. -# -# We use '-w y' (disable unused variable warnings) because these -# warnings aren't very reliable with heavily preprocessed code like -# that produced by bitstring. - -EXTRA_DIST = \ - visualizer.ml \ - visualizer_utils.ml \ - visualizer_NT_time.ml \ - clearheaderfields.ml \ - fillemptyhbins.ml \ - truncatefile.ml \ - counter.mli \ - counter.ml - -visualizer.opt: counter.mli counter.ml visualizer_utils.ml visualizer_NT_time.ml visualizer.ml - ocamlfind ocamlopt -w y \ - -package bitstring,bitstring.syntax,extlib \ - -syntax camlp4 -linkpkg $^ -o $@ - -fillemptyhbins.opt: fillemptyhbins.ml - ocamlfind ocamlopt -w y \ - -package bitstring,bitstring.syntax,extlib \ - -syntax camlp4 -linkpkg $^ -o $@ - -clearheaderfields.opt: visualizer_utils.ml clearheaderfields.ml - ocamlfind ocamlopt -w y \ - -package bitstring,bitstring.syntax,extlib \ - -syntax camlp4 -linkpkg $^ -o $@ - -truncatefile.opt: visualizer_utils.ml truncatefile.ml - ocamlfind ocamlopt -w y \ - -package bitstring,bitstring.syntax,extlib \ - -syntax camlp4 -linkpkg $^ -o $@ diff --git a/trunk/hivex/lib/tools/clearheaderfields.ml b/trunk/hivex/lib/tools/clearheaderfields.ml deleted file mode 100644 index d055553..0000000 --- a/trunk/hivex/lib/tools/clearheaderfields.ml +++ /dev/null @@ -1,112 +0,0 @@ -(* Windows Registry reverse-engineering tool. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - -open Bitstring -open ExtString -open Printf -open Visualizer_utils - -let () = - if Array.length Sys.argv <> 2 then ( - eprintf "Error: missing argument. -Usage: %s hivefile -" Sys.executable_name; - exit 1 - ) - -let filename = Sys.argv.(1) - -(* Load the file. *) -let bits = bitstring_of_file filename - -(* Split into header + data at the 4KB boundary. *) -let header, data = takebits (4096 * 8) bits, dropbits (4096 * 8) bits - -(* Read the header fields. *) -let seq, last_modified, major, minor, unknown1, unknown2, - root_key, end_pages, unknown3, fname = - bitmatch header with - | { "regf" : 4*8 : string; - seq1 : 4*8 : littleendian; - seq2 : 4*8 : littleendian; - last_modified : 64 : bitstring; - major : 4*8 : littleendian; - minor : 4*8 : littleendian; - unknown1 : 4*8 : littleendian; - unknown2 : 4*8 : littleendian; - root_key : 4*8 : littleendian; - end_pages : 4*8 : littleendian; - unknown3 : 4*8 : littleendian; - fname : 64*8 : string; - unknownguid1 : 16*8 : bitstring; - unknownguid2 : 16*8 : bitstring; - unknown4 : 4*8 : littleendian; - unknownguid3 : 16*8 : bitstring; - unknown5 : 4*8 : string; - unknown6 : 340*8 : bitstring; - csum : 4*8 - : littleendian, save_offset_to (crc_offset), - check (assert (crc_offset = 0x1fc * 8); true); - unknown7 : (0x1000-0x200)*8 : bitstring } -> - seq1, last_modified, major, minor, unknown1, unknown2, - root_key, end_pages, unknown3, fname - | {_} -> assert false - -(* Create a new header, but with unknown fields cleared. Do it in - * two parts, first creating everything up to the checksum, then - * calculating the checksum and appending checksum and the final - * field. - *) -let header = - let zeroguid = zeroes_bitstring (16*8) in - let before_csum = - BITSTRING { - "regf" : 4*8 : string; - seq : 4*8 : littleendian; - seq : 4*8 : littleendian; - last_modified : 64 : bitstring; - major : 4*8 : littleendian; - minor : 4*8 : littleendian; - unknown1 : 4*8 : littleendian; - unknown2 : 4*8 : littleendian; - root_key : 4*8 : littleendian; - end_pages : 4*8 : littleendian; - unknown3 : 4*8 : littleendian; - fname : 64*8 : string; - zeroguid : 16*8 : bitstring; - zeroguid : 16*8 : bitstring; - 0_l : 4*8 : littleendian; - zeroguid : 16*8 : bitstring; - 0_l : 4*8 : littleendian; - zeroes_bitstring (340*8) : 340*8 : bitstring - } in - assert (bitstring_length before_csum = 0x1fc * 8); - let csum = bitstring_fold_left_int32_le Int32.logxor 0_l before_csum in - let csum_and_after = - BITSTRING { - csum : 4*8 : littleendian; - zeroes_bitstring ((0x1000-0x200)*8) : (0x1000-0x200)*8 : bitstring - } in - let new_header = concat [before_csum; csum_and_after] in - assert (bitstring_length header = bitstring_length new_header); - new_header - -(* Write it. *) -let () = - let file = concat [header; data] in - bitstring_to_file file filename diff --git a/trunk/hivex/lib/tools/counter.ml b/trunk/hivex/lib/tools/counter.ml deleted file mode 100644 index 2e44c65..0000000 --- a/trunk/hivex/lib/tools/counter.ml +++ /dev/null @@ -1,86 +0,0 @@ -(* Basic counting module. - - Copyright (C) 2006 Merjis Ltd. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*) - -type 'a t = ('a, int ref) Hashtbl.t - -let create () = - Hashtbl.create 13 - -let get_ref counter thing = - try - Hashtbl.find counter thing - with - Not_found -> - let r = ref 0 in - Hashtbl.add counter thing r; - r - -let incr counter thing = - let r = get_ref counter thing in - incr r - -let decr counter thing = - let r = get_ref counter thing in - decr r - -let add counter thing n = - let r = get_ref counter thing in - r := !r + n - -let sub counter thing n = - let r = get_ref counter thing in - r := !r - n - -let set counter thing n = - let r = get_ref counter thing in - r := n - -(* Don't use get_ref, to avoid unnecessarily creating 'ref 0's. *) -let get counter thing = - try - !(Hashtbl.find counter thing) - with - Not_found -> 0 - -(* This is a common pair of operations, worth optimising. *) -let incr_get counter thing = - let r = get_ref counter thing in - Pervasives.incr r; - !r - -let zero = Hashtbl.remove - -let read counter = - let counts = - Hashtbl.fold ( - fun thing r xs -> - let r = !r in - if r <> 0 then (r, thing) :: xs - else xs - ) counter [] in - List.sort (fun (a, _) (b, _) -> compare (b : int) (a : int)) counts - -let length = Hashtbl.length - -let total counter = - let total = ref 0 in - Hashtbl.iter (fun _ r -> total := !total + !r) counter; - !total - -let clear = Hashtbl.clear diff --git a/trunk/hivex/lib/tools/counter.mli b/trunk/hivex/lib/tools/counter.mli deleted file mode 100644 index 87610b5..0000000 --- a/trunk/hivex/lib/tools/counter.mli +++ /dev/null @@ -1,69 +0,0 @@ -(** Basic counting module. - - Copyright (C) 2006 Merjis Ltd. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*) - -type 'a t -(** Count items of type ['a]. *) - -val create : unit -> 'a t -(** Create a new counter. *) - -val incr : 'a t -> 'a -> unit -(** [incr counter thing] adds one to the count of [thing]s in [counter]. *) - -val decr : 'a t -> 'a -> unit -(** [decr counter thing] subtracts one to the count of [thing]s in [counter]. *) - -val add : 'a t -> 'a -> int -> unit -(** [add counter thing n] adds [n] to the count of [thing]s in [counter]. *) - -val sub : 'a t -> 'a -> int -> unit -(** [sub counter thing n] subtracts [n] to the count of [thing]s in [counter]. *) - -val set : 'a t -> 'a -> int -> unit -(** [set counter thing n] sets the count of [thing]s to [n]. *) - -val get : 'a t -> 'a -> int -(** [get counter thing] returns the count of [thing]s. (Returns 0 for - * [thing]s which have not been added. - *) - -val incr_get : 'a t -> 'a -> int -(** Faster form of {!Counter.incr} followed by {!Counter.get}. *) - -val zero : 'a t -> 'a -> unit -(** [zero counter thing] sets the count of [thing]s to 0. - * See also {!Counter.clear}. - *) - -val read : 'a t -> (int * 'a) list -(** [read counter] reads the frequency of each thing. They are sorted - * with the thing appearing most frequently first. Only things occurring - * non-zero times are returned. - *) - -val length : 'a t -> int -(** Return the number of distinct things. See also {!Counter.total} *) - -val total : 'a t -> int -(** Return the number of things counted (the total number of counts). - * See also {!Counter.length} - *) - -val clear : 'a t -> unit -(** [clear counter] zeroes all counts. *) diff --git a/trunk/hivex/lib/tools/fillemptyhbins.ml b/trunk/hivex/lib/tools/fillemptyhbins.ml deleted file mode 100644 index 14eae96..0000000 --- a/trunk/hivex/lib/tools/fillemptyhbins.ml +++ /dev/null @@ -1,74 +0,0 @@ -(* Windows Registry reverse-engineering tool. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - -open Bitstring -open ExtString -open Printf - -let () = - if Array.length Sys.argv <> 3 then ( - eprintf "Error: missing argument. -Usage: %s hivefile startoffset -" Sys.executable_name; - exit 1 - ) - -let filename = Sys.argv.(1) -let offset = int_of_string Sys.argv.(2) - -(* Load the file. *) -let bits = bitstring_of_file filename - -(* Split into header + data at the 4KB boundary. *) -let header, data = takebits (4096 * 8) bits, dropbits (4096 * 8) bits - -(* Overwrite everything after @offset, so ... *) -let nrpages = (bitstring_length data / 8 - offset) / 4096 -let data = takebits (offset * 8) data - -(* Create the empty pages. They're not all the same because each - * page contains its own page_offset. - *) -let pages = - let noblock = - let seg_len = 4096 - 32 in - let zeroes = zeroes_bitstring ((seg_len - 4) * 8) in - BITSTRING { - Int32.of_int seg_len : 4*8 : littleendian; - zeroes : (seg_len - 4) * 8 : bitstring - } in - let zeroes = zeroes_bitstring (20*8) in - let rec loop page_offset i = - if i < nrpages then ( - let page = - BITSTRING { - "hbin" : 4*8 : string; - Int32.of_int page_offset : 4*8 : littleendian; - 4096_l : 4*8 : littleendian; (* page length *) - zeroes : 20*8 : bitstring; - noblock : (4096 - 32) * 8 : bitstring - } in - page :: loop (page_offset + 4096) (i+1) - ) else [] - in - loop offset 0 - -(* Write it. *) -let () = - let file = concat (header :: data :: pages) in - bitstring_to_file file filename diff --git a/trunk/hivex/lib/tools/truncatefile.ml b/trunk/hivex/lib/tools/truncatefile.ml deleted file mode 100644 index b519f7a..0000000 --- a/trunk/hivex/lib/tools/truncatefile.ml +++ /dev/null @@ -1,112 +0,0 @@ -(* Windows Registry reverse-engineering tool. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *) - -open Bitstring -open ExtString -open Printf -open Visualizer_utils - -let () = - if Array.length Sys.argv <> 3 then ( - eprintf "Error: missing argument. -Usage: %s hivefile endpages -" Sys.executable_name; - exit 1 - ) - -let filename = Sys.argv.(1) -let new_end_pages = int_of_string Sys.argv.(2) - -(* Load the file. *) -let bits = bitstring_of_file filename - -(* Split into header + data at the 4KB boundary. *) -let header, data = takebits (4096 * 8) bits, dropbits (4096 * 8) bits - -(* Truncate the file data. *) -let data = takebits (new_end_pages * 8) data - -(* Read the header fields. *) -let seq, last_modified, major, minor, unknown1, unknown2, - root_key, end_pages, unknown3, fname = - bitmatch header with - | { "regf" : 4*8 : string; - seq1 : 4*8 : littleendian; - seq2 : 4*8 : littleendian; - last_modified : 64 : bitstring; - major : 4*8 : littleendian; - minor : 4*8 : littleendian; - unknown1 : 4*8 : littleendian; - unknown2 : 4*8 : littleendian; - root_key : 4*8 : littleendian; - end_pages : 4*8 : littleendian; - unknown3 : 4*8 : littleendian; - fname : 64*8 : string; - unknownguid1 : 16*8 : bitstring; - unknownguid2 : 16*8 : bitstring; - unknown4 : 4*8 : littleendian; - unknownguid3 : 16*8 : bitstring; - unknown5 : 4*8 : string; - unknown6 : 340*8 : bitstring; - csum : 4*8 - : littleendian, save_offset_to (crc_offset), - check (assert (crc_offset = 0x1fc * 8); true); - unknown7 : (0x1000-0x200)*8 : bitstring } -> - seq1, last_modified, major, minor, unknown1, unknown2, - root_key, end_pages, unknown3, fname - | {_} -> assert false - -(* Create a new header, with endpages updated. *) -let header = - let zeroguid = zeroes_bitstring (16*8) in - let before_csum = - BITSTRING { - "regf" : 4*8 : string; - seq : 4*8 : littleendian; - seq : 4*8 : littleendian; - last_modified : 64 : bitstring; - major : 4*8 : littleendian; - minor : 4*8 : littleendian; - unknown1 : 4*8 : littleendian; - unknown2 : 4*8 : littleendian; - root_key : 4*8 : littleendian; - Int32.of_int new_end_pages : 4*8 : littleendian; - unknown3 : 4*8 : littleendian; - fname : 64*8 : string; - zeroguid : 16*8 : bitstring; - zeroguid : 16*8 : bitstring; - 0_l : 4*8 : littleendian; - zeroguid : 16*8 : bitstring; - 0_l : 4*8 : littleendian; - zeroes_bitstring (340*8) : 340*8 : bitstring - } in - assert (bitstring_length before_csum = 0x1fc * 8); - let csum = bitstring_fold_left_int32_le Int32.logxor 0_l before_csum in - let csum_and_after = - BITSTRING { - csum : 4*8 : littleendian; - zeroes_bitstring ((0x1000-0x200)*8) : (0x1000-0x200)*8 : bitstring - } in - let new_header = concat [before_csum; csum_and_after] in - assert (bitstring_length header = bitstring_length new_header); - new_header - -(* Write it. *) -let () = - let file = concat [header; data] in - bitstring_to_file file filename diff --git a/trunk/hivex/lib/tools/visualizer.ml b/trunk/hivex/lib/tools/visualizer.ml deleted file mode 100644 index cc71748..0000000 --- a/trunk/hivex/lib/tools/visualizer.ml +++ /dev/null @@ -1,984 +0,0 @@ -(* Windows Registry reverse-engineering tool. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For existing information on the registry format, please refer - * to the following documents. Note they are both incomplete - * and inaccurate in some respects. - * - * http://www.sentinelchicken.com/data/TheWindowsNTRegistryFileFormat.pdf - * http://pogostick.net/~pnh/ntpasswd/WinReg.txt - *) - -open Bitstring -open ExtString -open Printf -open Visualizer_utils -open Visualizer_NT_time - -let () = - if Array.length Sys.argv <> 2 then ( - eprintf "Error: missing argument. -Usage: %s hivefile > out -where - 'hivefile' is the input hive file from a Windows machine - 'out' is an output file where we will write all the keys, - values etc for extended debugging purposes. -Errors, inconsistencies and unexpected fields in the hive file -are written to stderr. -" Sys.executable_name; - exit 1 - ) - -let filename = Sys.argv.(1) -let basename = Filename.basename filename - -(* Load the file. *) -let bits = bitstring_of_file filename - -(* Split into header + data at the 4KB boundary. *) -let header, data = takebits (4096 * 8) bits, dropbits (4096 * 8) bits - -(* Define a persistent pattern which matches the header fields. By - * using persistent patterns, we can reuse them later in the - * program. - *) -let bitmatch header_fields = - { "regf" : 4*8 : string; - seq1 : 4*8 : littleendian; - seq2 : 4*8 : littleendian; - last_modified : 64 - : littleendian, bind (nt_to_time_t last_modified); - major : 4*8 : littleendian; - minor : 4*8 : littleendian; - - (* "Type". Contains 0. *) - unknown1 : 4*8 : littleendian; - - (* "Format". Contains 1. *) - unknown2 : 4*8 : littleendian; - - root_key : 4*8 - : littleendian, bind (get_offset root_key); - end_pages : 4*8 - : littleendian, bind (get_offset end_pages); - - (* "Cluster". Contains 1. *) - unknown3 : 4*8 : littleendian; - - filename : 64*8 : string; - - (* All three GUIDs here confirmed in Windows 7 registries. In - * Windows <= 2003 these GUID fields seem to contain junk. - * - * If you write zeroes to the GUID fields, load and unload in Win7 - * REGEDIT, then Windows 7 writes some random GUIDs. - * - * Also (on Win7) unknownguid1 == unknownguid2. unknownguid3 is - * different. - *) - unknownguid1 : 16*8 : bitstring; - unknownguid2 : 16*8 : bitstring; - - (* Wrote zero to unknown4, loaded and unloaded it in Win7 REGEDIT, - * and it still contained zero. In existing registries it seems to - * contain random junk. - *) - unknown4 : 4*8 : littleendian; - unknownguid3 : 16*8 : bitstring; - - (* If you write zero to unknown5, load and unload it in REGEDIT, - * Windows 7 puts the string "rmtm" here. Existing registries also - * seen containing this string. However on older Windows it can - * be all zeroes. - *) - unknown5 : 4*8 : string; - - (* This seems to contain junk from other parts of the registry. I - * wrote zeroes here, loaded and unloaded it in Win7 REGEDIT, and - * it still contained zeroes. - *) - unknown6 : 340*8 : bitstring; - csum : 4*8 - : littleendian, save_offset_to (crc_offset), - check (assert (crc_offset = 0x1fc * 8); true); - unknown7 : (0x1000-0x200)*8 : bitstring } - -let fprintf_header chan bits = - bitmatch bits with - | { :header_fields } -> - fprintf chan - "HD %6ld %6ld %s %ld.%ld %08lx %08lx %s %s %08lx %s %s %s %08lx %s %s %s %08lx %s\n" - seq1 seq2 (print_time last_modified) major minor - unknown1 unknown2 - (print_offset root_key) (print_offset end_pages) - unknown3 (print_utf16 filename) - (print_guid unknownguid1) (print_guid unknownguid2) - unknown4 (print_guid unknownguid3) unknown5 - (print_bitstring unknown6) - csum (print_bitstring unknown7) - -(* Parse the header and check it. *) -let root_key, end_pages = - bitmatch header with - | { :header_fields } -> - fprintf_header stdout header; - - if major <> 1_l then - eprintf "HD hive file major <> 1 (major.minor = %ld.%ld)\n" - major minor; - if seq1 <> seq2 then - eprintf "HD hive file sequence numbers should match (%ld <> %ld)\n" - seq1 seq2; - if unknown1 <> 0_l then - eprintf "HD unknown1 field <> 0 (%08lx)\n" unknown1; - if unknown2 <> 1_l then - eprintf "HD unknown2 field <> 1 (%08lx)\n" unknown2; - if unknown3 <> 1_l then - eprintf "HD unknown3 field <> 1 (%08lx)\n" unknown3; - if not (equals unknownguid1 unknownguid2) then - eprintf "HD unknownguid1 <> unknownguid2 (%s, %s)\n" - (print_guid unknownguid1) (print_guid unknownguid2); - (* We think this is junk. - if unknown4 <> 0_l then - eprintf "HD unknown4 field <> 0 (%08lx)\n" unknown4; - *) - if unknown5 <> "rmtm" && unknown5 <> "\000\000\000\000" then - eprintf "HD unknown5 field <> \"rmtm\" & <> zeroes (%s)\n" unknown5; - (* We think this is junk. - if not (is_zero_bitstring unknown6) then - eprintf "HD unknown6 area is not zero (%s)\n" - (print_bitstring unknown6); - *) - if not (is_zero_bitstring unknown7) then - eprintf "HD unknown7 area is not zero (%s)\n" - (print_bitstring unknown7); - - root_key, end_pages - | {_} -> - failwithf "%s: this doesn't look like a registry hive file\n" basename - -(* Define persistent patterns to match page and block fields. *) -let bitmatch page_fields = - { "hbin" : 4*8 : string; - page_offset : 4*8 - : littleendian, bind (get_offset page_offset); - page_size : 4*8 - : littleendian, check (Int32.rem page_size 4096_l = 0_l), - bind (Int32.to_int page_size); - - (* In the first hbin in the file these fields contain something. - * In subsequent hbins these fields are all zero. - * - * From existing hives (first hbin only): - * - * unknown1 unknown2 unknown5 - * 00 00 00 00 00 00 00 00 9C 77 3B 02 6A 7D CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 50 3A 15 07 B5 9B CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 57 86 90 D4 9A 58 CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 52 3F 90 9D CF 7C CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 E8 86 C1 17 BD 06 CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 4A 77 CE 7A CF 7C CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 E4 EA 23 FF 69 7D CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 50 13 BA 8D A2 9A CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 0E 07 93 13 BD 06 CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 9D 55 D0 B3 99 58 CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 46 AC FF 8B CF 7C CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 80 29 2D 02 6A 7D CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 90 8D 36 07 B5 9B CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 5C 9B 8B B8 6A 06 CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 85 9F BB 99 9A 58 CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 BE 3D 21 02 6A 7D CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 70 53 09 07 B5 9B CA 01 00 00 00 00 - * 00 00 00 00 00 00 00 00 5B 62 42 B6 9A 58 CA 01 00 00 00 00 - * 01 00 00 00 00 00 00 00 B2 46 9B 9E CF 7C CA 01 00 00 00 00 - * 01 00 00 00 00 00 00 00 CA 88 EE 1A BD 06 CA 01 00 00 00 00 - * - * From the above we worked out that fields 3 and 4 are an NT - * timestamp, which seems to be "last modified" (when REGEDIT - * unloads a hive it updates this timestamp even if nothing - * has been changed). - *) - unknown1 : 4*8 : littleendian; (* usually zero, occasionally 1 *) - unknown2 : 4*8 : littleendian; (* always zero? *) - last_modified : 64 - : littleendian, - bind (if page_offset = 0 then nt_to_time_t last_modified - else ( - assert (last_modified = 0_L); - 0. - ) - ); - (* The "B.D." document said this field contains the page size, but - * this is not true. This misinformation has been copied to the - * sentinelchicken documentation too. - *) - unknown5 : 4*8 : littleendian; (* always zero? *) - - (* Now the blocks in this page follow. *) - blocks : (page_size - 32) * 8 : bitstring; - - rest : -1 : bitstring } - -let fprintf_page chan bits = - bitmatch bits with - | { :page_fields } -> - fprintf chan "HB %s %08x %08lx %08lx %s %08lx\n" - (print_offset page_offset) - page_size unknown1 unknown2 - (if page_offset = 0 then print_time last_modified - else string_of_float last_modified) unknown5 - -let bitmatch block_fields = - { seg_len : 4*8 - : littleendian, bind (Int32.to_int seg_len); - block_data : (abs seg_len - 4) * 8 : bitstring; - rest : -1 : bitstring } - -let fprintf_block chan block_offset bits = - bitmatch bits with - | { :block_fields } -> - fprintf chan "BL %s %s %d\n" - (print_offset block_offset) - (if seg_len < 0 then "used" else "free") - (if seg_len < 0 then -seg_len else seg_len) - -(* Iterate over the pages and blocks. In the process we will examine - * each page (hbin) header. Also we will build block_list which is a - * list of (block offset, length, used flag, data). - *) -let block_list = ref [] -let () = - let rec loop_over_pages data data_offset = - if data_offset < end_pages then ( - bitmatch data with - | { rest : -1 : bitstring } when bitstring_length rest = 0 -> () - - | { :page_fields } -> - fprintf_page stdout data; - - assert (page_offset = data_offset); - - if data_offset = 0 then ( (* first hbin only *) - if unknown1 <> 0_l then - eprintf "HB %s unknown1 field <> 0 (%08lx)\n" - (print_offset page_offset) unknown1; - if unknown2 <> 0_l then - eprintf "HB %s unknown2 field <> 0 (%08lx)\n" - (print_offset page_offset) unknown2; - if unknown5 <> 0_l then - eprintf "HB %s unknown5 field <> 0 (%08lx)\n" - (print_offset page_offset) unknown5 - ) else ( (* subsequent hbins *) - if unknown1 <> 0_l || unknown2 <> 0_l || unknown5 <> 0_l then - eprintf "HB %s unknown fields <> 0 (%08lx %08lx %08lx)\n" - (print_offset page_offset) - unknown1 unknown2 unknown5; - if last_modified <> 0. then - eprintf "HB %s last_modified <> 0. (%g)\n" - (print_offset page_offset) last_modified - ); - - (* Loop over the blocks in this page. *) - loop_over_blocks blocks (data_offset + 32); - - (* Loop over rest of the pages. *) - loop_over_pages rest (data_offset + page_size) - - | {_} -> - failwithf "%s: invalid hbin at offset %s\n" - basename (print_offset data_offset) - ) else ( - (* Reached the end of the official hbins in this file, BUT the - * file can be larger than this and might contain stuff. What - * does it contain after the hbins? We think just junk, but - * we're not sure. - *) - if not (is_zero_bitstring data) then ( - eprintf "Junk in file after end of pages:\n"; - let rec loop data data_offset = - bitmatch data with - | { rest : -1 : bitstring } when bitstring_length rest = 0 -> () - | { :page_fields } -> - eprintf "\tjunk hbin %s 0x%08x\n" - (print_offset data_offset) page_size; - loop rest (data_offset + page_size); - | { _ } -> - eprintf "\tother junk %s %s\n" - (print_offset data_offset) (print_bitstring data) - in - loop data data_offset - ) - ) - and loop_over_blocks blocks block_offset = - bitmatch blocks with - | { rest : -1 : bitstring } when bitstring_length rest = 0 -> () - - | { :block_fields } -> - assert (block_offset mod 8 = 0); - - fprintf_block stdout block_offset blocks; - - let used, seg_len = - if seg_len < 0 then true, -seg_len else false, seg_len in - - let block = block_offset, (seg_len, used, block_data) in - block_list := block :: !block_list; - - (* Loop over the rest of the blocks in this page. *) - loop_over_blocks rest (block_offset + seg_len) - - | {_} -> - failwithf "%s: invalid block near offset %s\n" - basename (print_offset block_offset) - in - loop_over_pages data 0 - -(* Turn the block_list into a map so we can quickly look up a block - * from its offset. - *) -let block_list = !block_list -let block_map = - List.fold_left ( - fun map (block_offset, block) -> IntMap.add block_offset block map - ) IntMap.empty block_list -let lookup fn offset = - try - let (_, used, _) as block = IntMap.find offset block_map in - if not used then - failwithf "%s: %s: lookup: free block %s referenced from hive tree" - basename fn (print_offset offset); - block - with Not_found -> - failwithf "%s: %s: lookup: unknown block %s referenced from hive tree" - basename fn (print_offset offset) - -(* Use this to mark blocks that we've visited. If the hive contains - * no unreferenced blocks, then by the end this should just contain - * free blocks. - *) -let mark_visited, is_not_visited, unvisited_blocks = - let v = ref block_map in - let mark_visited offset = v := IntMap.remove offset !v - and is_not_visited offset = IntMap.mem offset !v - and unvisited_blocks () = !v in - mark_visited, is_not_visited, unvisited_blocks - -(* Define persistent patterns to match nk-records, vk-records and - * sk-records, which are the record types that we especially want to - * analyze later. Other blocks types (eg. value lists, lf-records) - * have no "spare space" so everything is known about them and we don't - * store these. - *) -let bitmatch nk_fields = - { "nk" : 2*8 : string; - (* Flags stored in the file as a little endian word, hence the - * unusual ordering: - *) - virtmirrored : 1; - predefinedhandle : 1; keynameascii : 1; symlinkkey : 1; - cannotbedeleted : 1; isroot : 1; ismountpoint : 1; isvolatile : 1; - unknownflag8000 : 1; unknownflag4000 : 1; - unknownflag2000 : 1; unknownflag1000 : 1; - unknownflag0800 : 1; unknownflag0400 : 1; - virtualstore : 1; virttarget : 1; - timestamp : 64 : littleendian, bind (nt_to_time_t timestamp); - unknown1 : 4*8 : littleendian; - parent : 4*8 : littleendian, bind (get_offset parent); - nr_subkeys : 4*8 : littleendian, bind (Int32.to_int nr_subkeys); - nr_subkeys_vol : 4*8; - subkeys : 4*8 : littleendian, bind (get_offset subkeys); - subkeys_vol : 4*8; - nr_values : 4*8 : littleendian, bind (Int32.to_int nr_values); - vallist : 4*8 : littleendian, bind (get_offset vallist); - sk : 4*8 : littleendian, bind (get_offset sk); - classname : 4*8 : littleendian, bind (get_offset classname); - (* sentinelchicken.com says this is a single 32 bit field - * containing maximum number of bytes in a subkey name, however - * that does not seem to be correct. We think it is several - * fields, the first being the maximum number of bytes in the - * UTF16-LE encoded version of the subkey names, (since subkey - * names are usually ASCII, that would be max length of names * 2). - * This is a historical maximum, so it can be greater than the - * current maximum name field. - * - * The remaining fields are often non-zero, but the purpose is - * unknown. - * - * In the hives we examined the other fields had values as - * follows: - * userflags: 0, 2, 0xa, 0xe - * virtcontrolflags: 0, 1 - * debug: always 0 - *) - max_subkey_name_len : 2*8 : littleendian; - unknown2_userflags : 4; - unknown2_virtcontrolflags : 4; - unknown2_debug : 8; - - (* sentinelchicken.com says: maximum subkey CLASSNAME length, - * however that does not seem to be correct. In hives I looked - * at, it has value 0, 0xc, 0x10, 0x18, 0x1a, 0x28. - *) - unknown3 : 4*8 : littleendian; - (* sentinelchicken.com says: maximum number of bytes in a value - * name, however that does not seem to be correct. We think it is - * the maximum number of bytes in the UTF16-LE encoded version of - * the value names (since value names are usually ASCII, that would - * be max length of names * 2). This is a historical maximum, so - * it can be greater than the current maximum name field. - *) - max_vk_name_len : 4*8 : littleendian, bind (Int32.to_int max_vk_name_len); - (* sentinelchicken.com says: maximum value data size, and this - * agrees with my observations. It is the largest data size (not - * seg_len, but vk.data_len) for any value in this key. We think - * that this field is a historical max, so eg if a maximally sized - * value is deleted then this field is not reduced. Certainly - * max_vk_data_len >= the measured maximum in all the hives that we - * have observed. - *) - max_vk_data_len : 4*8 : littleendian, bind (Int32.to_int max_vk_data_len); - unknown6 : 4*8 : littleendian; - name_len : 2*8 : littleendian; - classname_len : 2*8 : littleendian; - name : name_len * 8 : string } - -let fprintf_nk chan nk = - let (_, _, bits) = lookup "fprintf_nk" nk in - bitmatch bits with - | { :nk_fields } -> - fprintf chan - "NK %s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s %s %08lx %s %d %ld %s %08lx %d %s %s %s %d %x %x %x %08lx %d %d %08lx %d %d %s\n" - (print_offset nk) - (if unknownflag8000 then "8" else ".") - (if unknownflag4000 then "4" else ".") - (if unknownflag2000 then "2" else ".") - (if unknownflag1000 then "1" else ".") - (if unknownflag0800 then "8" else ".") - (if unknownflag0400 then "4" else ".") - (if virtualstore then "s" else ".") - (if virttarget then "t" else ".") - (if virtmirrored then "m" else ".") - (if predefinedhandle then "P" else ".") - (if keynameascii then "A" else ".") - (if symlinkkey then "S" else ".") - (if cannotbedeleted then "N" else ".") - (if isroot then "R" else ".") - (if ismountpoint then "M" else ".") - (if isvolatile then "V" else ".") - (print_time timestamp) - unknown1 (print_offset parent) nr_subkeys nr_subkeys_vol - (print_offset subkeys) subkeys_vol - nr_values (print_offset vallist) - (print_offset sk) (print_offset classname) - max_subkey_name_len - unknown2_userflags unknown2_virtcontrolflags unknown2_debug - unknown3 max_vk_name_len max_vk_data_len unknown6 - name_len classname_len name - -type data_t = Inline of bitstring | Offset of int -let bitmatch vk_fields = - { "vk" : 2*8 : string; - name_len : 2*8 : littleendian; - (* Top bit set means that the data is stored inline. In that case - * the data length must be <= 4. The length can also be 0 (or - * 0x80000000) if the data type is NONE. - *) - data_len : 4*8 - : littleendian, bind ( - let is_inline = Int32.logand data_len 0x8000_0000_l = 0x8000_0000_l in - let data_len = Int32.to_int (Int32.logand data_len 0x7fff_ffff_l) in - if is_inline then assert (data_len <= 4) else assert (data_len > 4); - is_inline, data_len - ); - (* The data itself depends on the type field. - * - * For REG_SZ type, the data always seems to be NUL-terminated, which - * means because these strings are often UTF-16LE, that the string will - * end with \0\0 bytes. The termination bytes are included in data_len. - * - * For REG_MULTI_SZ, see - * http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx - *) - data : 4*8 - : bitstring, bind ( - let is_inline, data_len = data_len in - if is_inline then - Inline (takebits (data_len*8) data) - else ( - let offset = - bitmatch data with { offset : 4*8 : littleendian } -> offset in - let offset = get_offset offset in - Offset offset - ) - ); - t : 4*8 : littleendian, bind (Int32.to_int t); - (* Flags, stored as a little-endian word: *) - unknown1 : 7; - nameisascii : 1; (* Clear for default [zero-length] name, always set - * otherwise in registries that we found. Perhaps this - * is really "nameisdefault" flag? - *) - unknown2 : 8; - (* Unknown field, usually contains something. *) - unknown3 : 2*8 : littleendian; - name : name_len * 8 : string } - -let fprintf_vk chan vk = - let (_, _, bits) = lookup "fprintf_vk" vk in - bitmatch bits with - | { :vk_fields } -> - let real_data = - match data with - | Inline data -> data - | Offset offset -> - let (_, _, bits) = lookup "fprintf_vk (data)" offset in - bits in - let is_inline, data_len = data_len in - fprintf chan "VK %s %s %s %d %s%s %s %08x %s %08x %08x\n" - (print_offset vk) - name (if is_inline then "inline" else "-") data_len - (match data with - | Inline _ -> "" - | Offset offset -> "["^print_offset offset^"]") - (print_bitstring real_data) - (print_vk_type t) - unknown1 (if nameisascii then "A" else "L") - unknown2 unknown3 - -let bitmatch sk_fields = - { "sk" : 2*8 : string; - unknown1 : 2*8 : littleendian; - sk_next : 4*8 : littleendian, bind (get_offset sk_next); - sk_prev : 4*8 : littleendian, bind (get_offset sk_prev); - refcount : 4*8 : littleendian, bind (Int32.to_int refcount); - sec_len : 4*8 : littleendian, bind (Int32.to_int sec_len); - sec_desc : sec_len * 8 : bitstring } - -let fprintf_sk chan sk = - let (_, _, bits) = lookup "fprintf_sk" sk in - bitmatch bits with - | { :sk_fields } -> - fprintf chan "SK %s %04x %s %s %d %d\n" - (print_offset sk) unknown1 - (print_offset sk_next) (print_offset sk_prev) - refcount sec_len - (* print_bitstring sec_desc -- suppress this *) - -(* Store lists of records we encounter (lists of offsets). *) -let nk_records = ref [] -and vk_records = ref [] -and sk_records = ref [] - -(* Functions to visit each block, starting at the root. Each block - * that we visit is printed. - *) -let rec visit_nk ?(nk_is_root = false) nk = - let (_, _, bits) = lookup "visit_nk" nk in - mark_visited nk; - (bitmatch bits with - | { :nk_fields } -> - fprintf_nk stdout nk; - - nk_records := nk :: !nk_records; - - (* Check the isroot flag is only set on the root node. *) - assert (isroot = nk_is_root); - - if unknownflag8000 then - eprintf "NK %s unknownflag8000 is set\n" (print_offset nk); - if unknownflag4000 then - eprintf "NK %s unknownflag4000 is set\n" (print_offset nk); - if unknownflag2000 then - eprintf "NK %s unknownflag2000 is set\n" (print_offset nk); - if unknownflag1000 then - eprintf "NK %s unknownflag1000 is set\n" (print_offset nk); - if unknownflag0800 then - eprintf "NK %s unknownflag0800 is set\n" (print_offset nk); - if unknownflag0400 then - eprintf "NK %s unknownflag0400 is set\n" (print_offset nk); - if unknown1 <> 0_l then - eprintf "NK %s unknown1 <> 0 (%08lx)\n" (print_offset nk) unknown1; - if unknown2_userflags <> 0 then - eprintf "NK %s unknown2_userflags <> 0 (%x)\n" - (print_offset nk) unknown2_userflags; - if unknown2_virtcontrolflags <> 0 then - eprintf "NK %s unknown2_virtcontrolflags <> 0 (%x)\n" - (print_offset nk) unknown2_virtcontrolflags; - if unknown2_debug <> 0 then - eprintf "NK %s unknown2_debug <> 0 (%x)\n" - (print_offset nk) unknown2_debug; - if unknown3 <> 0_l then - eprintf "NK %s unknown3 <> 0 (%08lx)\n" (print_offset nk) unknown3; - if unknown6 <> 0_l then - eprintf "NK %s unknown6 <> 0 (%08lx)\n" (print_offset nk) unknown6; - - (* -- common, assume it's not an error - if classname = -1 then - eprintf "NK %s has no classname\n" (print_offset nk); - if classname_len = 0 then - eprintf "NK %s has zero-length classname\n" (print_offset nk); - *) - if sk = -1 then - eprintf "NK %s has no sk-record\n" (print_offset nk); - if name_len = 0 then - eprintf "NK %s has zero-length name\n" (print_offset nk); - - (* Visit the values first at this node. *) - let max_data_len, max_name_len = - if vallist <> -1 then - visit_vallist nr_values vallist - else - 0, 0 in - - if max_vk_data_len < max_data_len then - eprintf "NK %s nk.max_vk_data_len (%d) < actual max data_len (%d)\n" - (print_offset nk) max_vk_data_len max_data_len; - - if max_vk_name_len < max_name_len * 2 then - eprintf "NK %s nk.max_vk_name_len (%d) < actual max name_len * 2 (%d)\n" - (print_offset nk) max_vk_name_len (max_name_len * 2); - - (* Visit the subkeys of this node. *) - if subkeys <> -1 then ( - let counted, max_name_len, _ = visit_subkeys subkeys in - - if counted <> nr_subkeys then - failwithf "%s: incorrect count of subkeys (%d, counted %d) in subkey list at %s\n" - basename nr_subkeys counted (print_offset subkeys); - - if max_subkey_name_len < max_name_len * 2 then - eprintf "NK %s nk.max_subkey_name_len (%d) < actual max name_len * 2 (%d)\n" - (print_offset nk) max_subkey_name_len (max_name_len * 2); - ); - - (* Visit the sk-record and classname. *) - if sk <> -1 then - visit_sk sk; - if classname <> -1 then - visit_classname classname classname_len; - - | {_} -> - failwithf "%s: invalid nk block at offset %s\n" - basename (print_offset nk) - ) - -and visit_vallist nr_values vallist = - let (seg_len, _, bits) = lookup "visit_vallist" vallist in - mark_visited vallist; - printf "VL %s %d %d\n" (print_offset vallist) nr_values seg_len; - visit_values_in_vallist nr_values vallist bits - -and visit_values_in_vallist nr_values vallist bits = - if nr_values > 0 then ( - bitmatch bits with - | { rest : -1 : bitstring } when bitstring_length rest = 0 -> - assert (nr_values = 0); - 0, 0 - - | { value : 4*8 : littleendian, bind (get_offset value); - rest : -1 : bitstring } -> - let data_len, name_len = visit_vk value in - let max_data_len, max_name_len = - visit_values_in_vallist (nr_values-1) vallist rest in - max max_data_len data_len, max max_name_len name_len - - | {_} -> - failwithf "%s: invalid offset in value list at %s\n" - basename (print_offset vallist) - ) else 0, 0 - -and visit_vk vk = - let (_, _, bits) = lookup "visit_vk" vk in - mark_visited vk; - - (bitmatch bits with - | { :vk_fields } -> - fprintf_vk stdout vk; - - let is_inline, data_len = data_len in - - if unknown1 <> 0 then - eprintf "VK %s unknown1 flags set (%02x)\n" - (print_offset vk) unknown1; - if unknown2 <> 0 then - eprintf "VK %s unknown2 flags set (%02x)\n" - (print_offset vk) unknown2; - if unknown3 <> 0 then - eprintf "VK %s unknown3 flags set (%04x)\n" - (print_offset vk) unknown3; - - (* Note this is common for default [ie. zero-length] key names. *) - if not nameisascii && name_len > 0 then - eprintf "VK %s has non-ASCII name flag set (name is %s)\n" - (print_offset vk) (print_binary_string name); - - vk_records := vk :: !vk_records; - (match data with - | Inline data -> () - | Offset offset -> - let _ = lookup "visit_vk (data)" offset in - mark_visited offset - ); - - data_len, name_len - - | {_} -> - failwithf "%s: invalid vk block at offset %s\n" - basename (print_offset vk) - ) - -(* Visits subkeys, recursing through intermediate lf/lh/ri structures, - * and returns the number of subkeys actually seen. - *) -and visit_subkeys subkeys = - let (_, _, bits) = lookup "visit_subkeys" subkeys in - mark_visited subkeys; - (bitmatch bits with - | { "lf" : 2*8 : string; - len : 2*8 : littleendian; (* number of subkeys of this node *) - rest : len*8*8 : bitstring } -> - printf "LF %s %d\n" (print_offset subkeys) len; - visit_subkeys_in_lf_list false subkeys len rest - - | { "lh" : 2*8 : string; - len : 2*8 : littleendian; (* number of subkeys of this node *) - rest : len*8*8 : bitstring } -> - printf "LF %s %d\n" (print_offset subkeys) len; - visit_subkeys_in_lf_list true subkeys len rest - - | { "ri" : 2*8 : string; - len : 2*8 : littleendian; - rest : len*4*8 : bitstring } -> - printf "RI %s %d\n" (print_offset subkeys) len; - visit_subkeys_in_ri_list subkeys len rest - - (* In theory you can have an li-record here, but we've never - * seen one. - *) - - | { "nk" : 2*8 : string } -> - visit_nk subkeys; - let name, name_len = name_of_nk subkeys in - 1, name_len, name - - | {_} -> - failwithf "%s: invalid subkey node found at %s\n" - basename (print_offset subkeys) - ) - -and visit_subkeys_in_lf_list newstyle_hash subkeys_top len bits = - if len > 0 then ( - bitmatch bits with - | { rest : -1 : bitstring } when bitstring_length rest = 0 -> - assert (len = 0); - 0, 0, "" - - | { offset : 4*8 : littleendian, bind (get_offset offset); - hash : 4*8 : bitstring; - rest : -1 : bitstring } -> - let c1, name_len1, name = visit_subkeys offset in - - check_hash offset newstyle_hash hash name; - - let c2, name_len2, _ = - visit_subkeys_in_lf_list newstyle_hash subkeys_top (len-1) rest in - c1 + c2, max name_len1 name_len2, "" - - | {_} -> - failwithf "%s: invalid subkey in lf/lh list at %s\n" - basename (print_offset subkeys_top) - ) else 0, 0, "" - -and visit_subkeys_in_ri_list subkeys_top len bits = - if len > 0 then ( - bitmatch bits with - | { rest : -1 : bitstring } when bitstring_length rest = 0 -> - assert (len = 0); - 0, 0, "" - - | { offset : 4*8 : littleendian, bind (get_offset offset); - rest : -1 : bitstring } -> - let c1, name_len1, _ = visit_subkeys offset in - let c2, name_len2, _ = - visit_subkeys_in_ri_list subkeys_top (len-1) rest in - c1 + c2, max name_len1 name_len2, "" - - | {_} -> - failwithf "%s: invalid subkey in ri list at %s\n" - basename (print_offset subkeys_top) - ) else 0, 0, "" - -and check_hash offset newstyle_hash hash name = - if not newstyle_hash then ( - (* Old-style lf record hash the first four bytes of the name - * as the has. - *) - let len = String.length name in - let name_bits = - if len >= 4 then - bitstring_of_string (String.sub name 0 4) - else ( - let zeroes = zeroes_bitstring ((4-len)*8) in - concat [bitstring_of_string name; zeroes] - ) in - if not (equals hash name_bits) then - eprintf "LF incorrect hash for name %s, expected %s, actual %s\n" - name (print_bitstring name_bits) (print_bitstring hash) - ) else ( - (* New-style lh record has a proper hash. *) - let actual = bitmatch hash with { hash : 4*8 : littleendian } -> hash in - let h = ref 0_l in - String.iter ( - fun c -> - h := Int32.mul !h 37_l; - h := Int32.add !h (Int32.of_int (Char.code (Char.uppercase c))) - ) name; - if actual <> !h then - eprintf "LH incorrect hash for name %s, expected 0x%08lx, actual 0x%08lx\n" - name !h actual - ) - -and name_of_nk nk = - let (_, _, bits) = lookup "name_of_nk" nk in - bitmatch bits with - | { :nk_fields } -> name, name_len - -and visit_sk sk = - let (_, _, bits) = lookup "visit_sk" sk in - if is_not_visited sk then ( - mark_visited sk; - (bitmatch bits with - | { :sk_fields } -> - fprintf_sk stdout sk; - - if unknown1 <> 0 then - eprintf "SK %s unknown1 <> 0 (%04x)\n" (print_offset sk) unknown1; - - sk_records := sk :: !sk_records - - | {_} -> - failwithf "%s: invalid sk-record at %s\n" - basename (print_offset sk) - ) - ) - -and visit_classname classname classname_len = - let (seg_len, _, bits) = lookup "visit_classname" classname in - mark_visited classname; - assert (seg_len >= classname_len); - printf "CL %s %s\n" (print_offset classname) (print_bitstring bits) - -let () = - visit_nk ~nk_is_root:true root_key - -(* These are immutable now. *) -let nk_records = !nk_records -let vk_records = !vk_records -let sk_records = !sk_records - -(* So we can rapidly tell what is an nk/vk/sk offset. *) -let nk_set = - List.fold_left (fun set offs -> IntSet.add offs set) IntSet.empty nk_records -let vk_set = - List.fold_left (fun set offs -> IntSet.add offs set) IntSet.empty vk_records -let sk_set = - List.fold_left (fun set offs -> IntSet.add offs set) IntSet.empty sk_records - -(* Now after visiting all the blocks, are there any used blocks which - * are unvisited? If there are any then that would indicate either (a) - * that the hive contains unreferenced blocks, or (b) that there are - * referenced blocks that we did not visit because we don't have a full - * understanding of the hive format. - * - * Windows 7 registries often contain a few of these -- not clear - * how serious they are, but don't fail here. - *) -let () = - let unvisited = unvisited_blocks () in - IntMap.iter ( - fun offset block -> - match block with - | (_, false, _) -> () (* ignore unused blocks *) - | (seg_len, true, _) -> - eprintf "used block %s (length %d) is not referenced\n" - (print_offset offset) seg_len - ) unvisited - -(* Check the SKs are: - * (a) linked into a single circular list through the sk_prev/sk_next - * pointers - * (b) refcounts are correct - *) -let () = - if List.length sk_records > 0 then ( - let sk0 = List.hd sk_records in (* start at any arbitrary sk *) - (* This loop follows the chain of sk pointers until we arrive - * back at the original, checking prev/next are consistent. - *) - let rec loop visited prevsk sk = - if sk <> sk0 then ( - if not (IntSet.mem sk sk_set) then - eprintf "SK %s not an sk-record (faulty sk_next somewhere)\n" - (print_offset sk) - else ( - let _, _, bits = lookup "loop sk circular list" sk in - bitmatch bits with - | { :sk_fields } -> - if sk_prev <> prevsk then - eprintf "SK %s sk_prev != previous sk (%s, %s)\n" - (print_offset sk) - (print_offset sk_prev) (print_offset prevsk); - if IntSet.mem sk visited then - eprintf "SK %s already visited (bad circular list)\n" - (print_offset sk); - let visited = IntSet.add sk visited in - loop visited sk sk_next - ) - ) - in - let _, _, bits = lookup "start sk circular list" sk0 in - (bitmatch bits with - | { :sk_fields } -> - loop IntSet.empty sk_prev sk0 - ); - - (* For every nk-record, if it references an sk-record count that, - * then check this matches the refcounts in the sk-records - * themselves. - *) - let refcounts = Counter.create () in - List.iter ( - fun nk -> - let _, _, bits = lookup "sk refcounter (nk)" nk in - (bitmatch bits with - | { :nk_fields } -> - Counter.incr refcounts sk - ) - ) nk_records; - - List.iter ( - fun sk -> - let _, _, bits = lookup "sk refcounter (sk)" sk in - (bitmatch bits with - | { :sk_fields } -> - let actual = Counter.get refcounts sk in - if actual <> refcount then - eprintf "SK %s incorrect refcount (actual %d, in file %d)\n" - (print_offset sk) actual refcount - ) - ) sk_records - ) diff --git a/trunk/hivex/lib/tools/visualizer_NT_time.ml b/trunk/hivex/lib/tools/visualizer_NT_time.ml deleted file mode 100644 index a752112..0000000 --- a/trunk/hivex/lib/tools/visualizer_NT_time.ml +++ /dev/null @@ -1,30 +0,0 @@ -(* Windows Registry reverse-engineering tool. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For existing information on the registry format, please refer - * to the following documents. Note they are both incomplete - * and inaccurate in some respects. - *) - -(* Convert an NT file timestamp to time_t. See: - * http://blogs.msdn.com/oldnewthing/archive/2003/09/05/54806.aspx - * http://support.microsoft.com/kb/167296 - *) -let nt_to_time_t t = - let t = Int64.sub t 116444736000000000L in - let t = Int64.div t 10000000L in - Int64.to_float t diff --git a/trunk/hivex/lib/tools/visualizer_utils.ml b/trunk/hivex/lib/tools/visualizer_utils.ml deleted file mode 100644 index 2f0d6b7..0000000 --- a/trunk/hivex/lib/tools/visualizer_utils.ml +++ /dev/null @@ -1,163 +0,0 @@ -(* Windows Registry reverse-engineering tool. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For existing information on the registry format, please refer - * to the following documents. Note they are both incomplete - * and inaccurate in some respects. - *) - -open ExtString -open Printf - -let failwithf fs = ksprintf failwith fs - -(* Useful function to convert unknown bitstring fragments into - * printable strings. - *) -let rec print_bitstring bits = - let str = Bitstring.string_of_bitstring bits in - print_binary_string str -and print_binary_string str = - let rec printable = function - | '\x00' -> "\\0" | '\x01' -> "\\1" | '\x02' -> "\\2" | '\x03' -> "\\3" - | '\x04' -> "\\4" | '\x05' -> "\\5" | '\x06' -> "\\6" | '\x07' -> "\\7" - | ('\x08'..'\x31' as c) - | ('\x7f'..'\xff' as c) -> sprintf "\\x%02x" (Char.code c) - | ('\x32'..'\x7e' as c) -> String.make 1 c - and repeat str = function - | n when n <= 0 -> "" - | n -> str ^ repeat str (n-1) - in - let chars = String.explode str in - let rec loop acc = function - | [] -> List.rev acc - | x :: xs -> - let rec loop2 i = function - | y :: ys when x = y -> loop2 (i+1) ys - | ys -> i, ys - in - let count, ys = loop2 1 xs in - let acc = (count, x) :: acc in - loop acc ys - in - let frags = loop [] chars in - let frags = - List.map (function - | (nr, x) when nr <= 4 -> repeat (printable x) nr - | (nr, x) -> sprintf "%s<%d times>" (printable x) nr - ) frags in - "\"" ^ String.concat "" frags ^ "\"" - -(* Convert an offset from the file to an offset. The only special - * thing is that 0xffffffff in the file is used as a kind of "NULL - * pointer". We map these null values to -1. - *) -let get_offset = function - | 0xffffffff_l -> -1 - | i -> Int32.to_int i - -(* Print an offset. *) -let print_offset = function - | -1 -> "NULL" - | i -> sprintf "@%08x" i - -(* Print time. *) -let print_time t = - let tm = Unix.gmtime t in - sprintf "%04d-%02d-%02d %02d:%02d:%02d" - (tm.Unix.tm_year + 1900) (tm.Unix.tm_mon + 1) tm.Unix.tm_mday - tm.Unix.tm_hour tm.Unix.tm_min tm.Unix.tm_sec - -(* Print UTF16LE. *) -let print_utf16 str = - let n = String.length str in - if n land 1 <> 0 then - print_binary_string str - else ( - let rec loop i = - if i < n-1 then ( - let c1 = Char.code (str.[i]) in - let c2 = Char.code (str.[i+1]) in - if c1 <> 0 || c2 <> 0 then ( - (* Well, this doesn't print non-7bit-ASCII ... *) - let c = - if c2 = 0 then String.make 1 (Char.chr c1) - else sprintf "\\u%04d" (c2 * 256 + c1) in - c :: loop (i+2) - ) else [] - ) else [] - in - let frags = loop 0 in - "L\"" ^ String.concat "" frags ^ "\"" - ) - -(* A map of int -> anything. *) -module IntMap = Map.Make (struct type t = int let compare = compare end) - -(* A set of ints. *) -module IntSet = Set.Make (struct type t = int let compare = compare end) - -(* Print registry vk-record type field. *) -let print_vk_type = function - | 0 -> "NONE" - | 1 -> "SZ" - | 2 -> "EXPAND_SZ" - | 3 -> "BINARY" - | 4 -> "DWORD" - | 5 -> "DWORD_BIG_ENDIAN" - | 6 -> "LINK" - | 7 -> "MULTI_SZ" - | 8 -> "RESOURCE_LiST" - | 9 -> "FULL_RESOURCE_DESCRIPTOR" - | 10 -> "RESOURCE_REQUIREMENTS_LIST" - | 11 -> "QWORD" - | i -> sprintf "UNKNOWN_VK_TYPE_%d" i - -(* XXX We should write a more efficient version of this and - * push it into the bitstring library. - *) -let is_zero_bitstring bits = - let len = Bitstring.bitstring_length bits in - let zeroes = Bitstring.zeroes_bitstring len in - 0 = Bitstring.compare bits zeroes - -let is_zero_guid = is_zero_bitstring - -(* http://msdn.microsoft.com/en-us/library/aa373931(VS.85).aspx - * Endianness of GUIDs is not clear from the MSDN documentation, - * so this is just a guess. - *) -let print_guid bits = - bitmatch bits with - | { data1 : 4*8 : littleendian; - data2 : 2*8 : littleendian; - data3 : 2*8 : littleendian; - data4_1 : 2*8 : littleendian; - data4_2 : 6*8 : littleendian } -> - sprintf "%08lX-%04X-%04X-%04X-%012LX" data1 data2 data3 data4_1 data4_2 - | { _ } -> - assert false - -(* Fold over little-endian 32-bit integers in a bitstring. *) -let rec bitstring_fold_left_int32_le f a bits = - bitmatch bits with - | { i : 4*8 : littleendian; - rest : -1 : bitstring } -> - bitstring_fold_left_int32_le f (f a i) rest - | { rest : -1 : bitstring } when Bitstring.bitstring_length rest = 0 -> a - | { _ } -> - invalid_arg "bitstring_fold_left_int32_le: length not a multiple of 32 bits" diff --git a/trunk/hivex/m4/ocaml.m4 b/trunk/hivex/m4/ocaml.m4 deleted file mode 100644 index fddd6a0..0000000 --- a/trunk/hivex/m4/ocaml.m4 +++ /dev/null @@ -1,217 +0,0 @@ -dnl autoconf macros for OCaml -dnl -dnl Copyright © 2009 Richard W.M. Jones -dnl Copyright © 2009 Stefano Zacchiroli -dnl Copyright © 2000-2005 Olivier Andrieu -dnl Copyright © 2000-2005 Jean-Christophe Filliâtre -dnl Copyright © 2000-2005 Georges Mariano -dnl -dnl For documentation, please read the ocaml.m4 man page. - -AC_DEFUN([AC_PROG_OCAML], -[dnl - # checking for ocamlc - AC_CHECK_TOOL([OCAMLC],[ocamlc],[no]) - - if test "$OCAMLC" != "no"; then - OCAMLVERSION=`$OCAMLC -v | sed -n -e 's|.*version* *\(.*\)$|\1|p'` - AC_MSG_RESULT([OCaml version is $OCAMLVERSION]) - OCAMLLIB=`$OCAMLC -where 2>/dev/null || $OCAMLC -v|tail -1|cut -d ' ' -f 4` - AC_MSG_RESULT([OCaml library path is $OCAMLLIB]) - - AC_SUBST([OCAMLVERSION]) - AC_SUBST([OCAMLLIB]) - - # checking for ocamlopt - AC_CHECK_TOOL([OCAMLOPT],[ocamlopt],[no]) - OCAMLBEST=byte - if test "$OCAMLOPT" = "no"; then - AC_MSG_WARN([Cannot find ocamlopt; bytecode compilation only.]) - else - TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' ` - if test "$TMPVERSION" != "$OCAMLVERSION" ; then - AC_MSG_RESULT([versions differs from ocamlc; ocamlopt discarded.]) - OCAMLOPT=no - else - OCAMLBEST=opt - fi - fi - - AC_SUBST([OCAMLBEST]) - - # checking for ocamlc.opt - AC_CHECK_TOOL([OCAMLCDOTOPT],[ocamlc.opt],[no]) - if test "$OCAMLCDOTOPT" != "no"; then - TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' ` - if test "$TMPVERSION" != "$OCAMLVERSION" ; then - AC_MSG_RESULT([versions differs from ocamlc; ocamlc.opt discarded.]) - else - OCAMLC=$OCAMLCDOTOPT - fi - fi - - # checking for ocamlopt.opt - if test "$OCAMLOPT" != "no" ; then - AC_CHECK_TOOL([OCAMLOPTDOTOPT],[ocamlopt.opt],[no]) - if test "$OCAMLOPTDOTOPT" != "no"; then - TMPVERSION=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' ` - if test "$TMPVERSION" != "$OCAMLVERSION" ; then - AC_MSG_RESULT([version differs from ocamlc; ocamlopt.opt discarded.]) - else - OCAMLOPT=$OCAMLOPTDOTOPT - fi - fi - fi - - AC_SUBST([OCAMLOPT]) - fi - - AC_SUBST([OCAMLC]) - - # checking for ocamldep - AC_CHECK_TOOL([OCAMLDEP],[ocamldep],[no]) - - # checking for ocamlmktop - AC_CHECK_TOOL([OCAMLMKTOP],[ocamlmktop],[no]) - - # checking for ocamlmklib - AC_CHECK_TOOL([OCAMLMKLIB],[ocamlmklib],[no]) - - # checking for ocamldoc - AC_CHECK_TOOL([OCAMLDOC],[ocamldoc],[no]) - - # checking for ocamlbuild - AC_CHECK_TOOL([OCAMLBUILD],[ocamlbuild],[no]) -]) - - -AC_DEFUN([AC_PROG_OCAMLLEX], -[dnl - # checking for ocamllex - AC_CHECK_TOOL([OCAMLLEX],[ocamllex],[no]) - if test "$OCAMLLEX" != "no"; then - AC_CHECK_TOOL([OCAMLLEXDOTOPT],[ocamllex.opt],[no]) - if test "$OCAMLLEXDOTOPT" != "no"; then - OCAMLLEX=$OCAMLLEXDOTOPT - fi - fi - AC_SUBST([OCAMLLEX]) -]) - -AC_DEFUN([AC_PROG_OCAMLYACC], -[dnl - AC_CHECK_TOOL([OCAMLYACC],[ocamlyacc],[no]) - AC_SUBST([OCAMLYACC]) -]) - - -AC_DEFUN([AC_PROG_CAMLP4], -[dnl - AC_REQUIRE([AC_PROG_OCAML])dnl - - # checking for camlp4 - AC_CHECK_TOOL([CAMLP4],[camlp4],[no]) - if test "$CAMLP4" != "no"; then - TMPVERSION=`$CAMLP4 -v 2>&1| sed -n -e 's|.*version *\(.*\)$|\1|p'` - if test "$TMPVERSION" != "$OCAMLVERSION" ; then - AC_MSG_RESULT([versions differs from ocamlc]) - CAMLP4=no - fi - fi - AC_SUBST([CAMLP4]) - - # checking for companion tools - AC_CHECK_TOOL([CAMLP4BOOT],[camlp4boot],[no]) - AC_CHECK_TOOL([CAMLP4O],[camlp4o],[no]) - AC_CHECK_TOOL([CAMLP4OF],[camlp4of],[no]) - AC_CHECK_TOOL([CAMLP4OOF],[camlp4oof],[no]) - AC_CHECK_TOOL([CAMLP4ORF],[camlp4orf],[no]) - AC_CHECK_TOOL([CAMLP4PROF],[camlp4prof],[no]) - AC_CHECK_TOOL([CAMLP4R],[camlp4r],[no]) - AC_CHECK_TOOL([CAMLP4RF],[camlp4rf],[no]) - AC_SUBST([CAMLP4BOOT]) - AC_SUBST([CAMLP4O]) - AC_SUBST([CAMLP4OF]) - AC_SUBST([CAMLP4OOF]) - AC_SUBST([CAMLP4ORF]) - AC_SUBST([CAMLP4PROF]) - AC_SUBST([CAMLP4R]) - AC_SUBST([CAMLP4RF]) -]) - - -AC_DEFUN([AC_PROG_FINDLIB], -[dnl - AC_REQUIRE([AC_PROG_OCAML])dnl - - # checking for ocamlfind - AC_CHECK_TOOL([OCAMLFIND],[ocamlfind],[no]) - AC_SUBST([OCAMLFIND]) -]) - - -dnl Thanks to Jim Meyering for working this next bit out for us. -dnl XXX We should define AS_TR_SH if it's not defined already -dnl (eg. for old autoconf). -AC_DEFUN([AC_CHECK_OCAML_PKG], -[dnl - AC_REQUIRE([AC_PROG_FINDLIB])dnl - - AC_MSG_CHECKING([for OCaml findlib package $1]) - - unset found - unset pkg - found=no - for pkg in $1 $2 ; do - if $OCAMLFIND query $pkg >/dev/null 2>/dev/null; then - AC_MSG_RESULT([found]) - AS_TR_SH([OCAML_PKG_$1])=$pkg - found=yes - break - fi - done - if test "$found" = "no" ; then - AC_MSG_RESULT([not found]) - AS_TR_SH([OCAML_PKG_$1])=no - fi - - AC_SUBST(AS_TR_SH([OCAML_PKG_$1])) -]) - - -AC_DEFUN([AC_CHECK_OCAML_MODULE], -[dnl - AC_MSG_CHECKING([for OCaml module $2]) - - cat > conftest.ml <&5 2>&5 ; then - found=yes - break - fi - done - - if test "$found" ; then - AC_MSG_RESULT([$$1]) - else - AC_MSG_RESULT([not found]) - $1=no - fi - AC_SUBST([$1]) -]) - - -dnl XXX Cross-compiling -AC_DEFUN([AC_CHECK_OCAML_WORD_SIZE], -[dnl - AC_MSG_CHECKING([for OCaml compiler word size]) - cat > conftest.ml < $@-t - mv $@-t $@ - -include .depend - -SUFFIXES = .cmo .cmi .cmx .ml .mli .mll .mly - -# Do the installation by hand, because we want to run ocamlfind. -install_files = META *.so *.a *.cma *.cmi $(srcdir)/*.mli - -if HAVE_OCAMLOPT -install_files += *.cmx *.cmxa -endif - -install-data-hook: - mkdir -p $(DESTDIR)$(OCAMLLIB)/stublibs - $(OCAMLFIND) install \ - -ldconf ignore -destdir $(DESTDIR)$(OCAMLLIB) \ - $(PACKAGE_NAME) \ - $(install_files) - -CLEANFILES += $(noinst_DATA) - -endif - -# Tell version 3.79 and up of GNU make to not build goals in this -# directory in parallel. (See RHBZ#502309). -.NOTPARALLEL: diff --git a/trunk/hivex/ocaml/t/hivex_005_load.ml b/trunk/hivex/ocaml/t/hivex_005_load.ml deleted file mode 100644 index 704dc0b..0000000 --- a/trunk/hivex/ocaml/t/hivex_005_load.ml +++ /dev/null @@ -1,20 +0,0 @@ -(* 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. - *) - -(* Just links with the library, doesn't run anything. *) -let _ = Hivex.open_file diff --git a/trunk/hivex/ocaml/t/hivex_010_open.ml b/trunk/hivex/ocaml/t/hivex_010_open.ml deleted file mode 100644 index 5a74a7b..0000000 --- a/trunk/hivex/ocaml/t/hivex_010_open.ml +++ /dev/null @@ -1,33 +0,0 @@ -(* 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. - *) - -(* Test that we can open, read in and close a hive file. *) - -open Unix -open Printf -let (//) = Filename.concat -let srcdir = try Sys.getenv "srcdir" with Not_found -> "." - -let () = - let h = Hivex.open_file (srcdir // "../images/minimal") [] in - Hivex.close h; - - (* Gc.compact is a good way to ensure we don't have - * heap corruption or double-freeing. - *) - Gc.compact () diff --git a/trunk/hivex/ocaml/t/hivex_020_root.ml b/trunk/hivex/ocaml/t/hivex_020_root.ml deleted file mode 100644 index d11c991..0000000 --- a/trunk/hivex/ocaml/t/hivex_020_root.ml +++ /dev/null @@ -1,34 +0,0 @@ -(* 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. - *) - -(* Test that the root of the minimal hive exists. *) - -open Unix -open Printf -let (//) = Filename.concat -let srcdir = try Sys.getenv "srcdir" with Not_found -> "." - -let () = - let h = Hivex.open_file (srcdir // "../images/minimal") [] in - ignore (Hivex.root h); - Hivex.close h; - - (* Gc.compact is a good way to ensure we don't have - * heap corruption or double-freeing. - *) - Gc.compact () diff --git a/trunk/hivex/ocaml/t/hivex_100_errors.ml b/trunk/hivex/ocaml/t/hivex_100_errors.ml deleted file mode 100644 index 0577632..0000000 --- a/trunk/hivex/ocaml/t/hivex_100_errors.ml +++ /dev/null @@ -1,69 +0,0 @@ -(* 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. - *) - -(* Test different types of error handling used by the API. *) - -open Unix -open Printf -let (//) = Filename.concat -let srcdir = try Sys.getenv "srcdir" with Not_found -> "." - -let () = - printf "01 non-existent file\n%!"; - (try - ignore (Hivex.open_file "no_such_file" []); - failwith "no exception thrown when opening a non-existent file" - with - | Hivex.Error ("open", ENOENT, _) -> () (* ok *) - (* let any other exception escape and stop the test *) - ); - - printf "02 closed handle\n%!"; - let h = Hivex.open_file (srcdir // "../images/minimal") [] in - Hivex.close h; - (try - ignore (Hivex.root h) - with - | Hivex.Handle_closed "root" -> () (* ok *) - (* let any other exception escape and stop the test *) - ); - - printf "03 write to read-only file\n%!"; - let h = Hivex.open_file (srcdir // "../images/minimal") [] in - (try - ignore (Hivex.node_add_child h (Hivex.root h) "Foo") - with - | Hivex.Error ("node_add_child", EROFS, _) -> () (* ok *) - (* let any other exception escape and stop the test *) - ); - Hivex.close h; - - printf "04 node_get_child node not found\n%!"; - let h = Hivex.open_file (srcdir // "../images/minimal") [] in - (try - ignore (Hivex.node_get_child h (Hivex.root h) "NoSuchNode") - with - | Not_found -> () (* ok *) - (* let any other exception escape and stop the test *) - ); - Hivex.close h; - - (* Gc.compact is a good way to ensure we don't have - * heap corruption or double-freeing. - *) - Gc.compact () diff --git a/trunk/hivex/ocaml/t/hivex_110_gc_handle.ml b/trunk/hivex/ocaml/t/hivex_110_gc_handle.ml deleted file mode 100644 index 0820a89..0000000 --- a/trunk/hivex/ocaml/t/hivex_110_gc_handle.ml +++ /dev/null @@ -1,32 +0,0 @@ -(* 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. - *) - -(* Test that the handle is GC'd (closed) when unreachable. - * - * XXX Actually we cannot really test that, but at least make - * sure there is no error. - *) - -open Unix -open Printf -let (//) = Filename.concat -let srcdir = try Sys.getenv "srcdir" with Not_found -> "." - -let () = - ignore (Hivex.open_file (srcdir // "../images/minimal") []); - Gc.compact () diff --git a/trunk/hivex/ocaml/t/hivex_120_rlenvalue.ml b/trunk/hivex/ocaml/t/hivex_120_rlenvalue.ml deleted file mode 100644 index 827dc46..0000000 --- a/trunk/hivex/ocaml/t/hivex_120_rlenvalue.ml +++ /dev/null @@ -1,44 +0,0 @@ -(* hivex OCaml bindings - * Copyright (C) 2009-2010, 2012 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 srcdir = try Sys.getenv "srcdir" with Not_found -> "." - -let () = - let h = Hivex.open_file (srcdir // "../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 () diff --git a/trunk/hivex/ocaml/t/hivex_200_write.ml b/trunk/hivex/ocaml/t/hivex_200_write.ml deleted file mode 100644 index f70deee..0000000 --- a/trunk/hivex/ocaml/t/hivex_200_write.ml +++ /dev/null @@ -1,75 +0,0 @@ -(* 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. - *) - -(* Test some significant write operations. Take the minimal hive - * and algorithmically construct a large, deep hive. - *) - -open Unix -open Printf -let (//) = Filename.concat -let srcdir = try Sys.getenv "srcdir" with Not_found -> "." - -let () = - let h = Hivex.open_file (srcdir // "../images/minimal") [Hivex.OPEN_WRITE] in - - let degrees = [| 3; 1; 4; 1; 5; 9; 2 |] (* ~1000 nodes *) in - let numbers = [| "Zero"; "One"; "Two"; "Three"; "Four"; - "Five"; "Six"; "Seven"; "Eight"; "Nine" |] in - let animals = [| "Horse"; "Ant"; "Mouse"; "Rabbit"; "Cat"; - "Giraffe"; "Kangaroo"; "Tiger"; "Zebra"; "Elephant" |] in - - let rec iter depth posn parent = - if depth < Array.length degrees then ( - let degree = degrees.(depth) in - for i = 0 to degree-1 do - let node_name = numbers.(depth) ^ " " ^ animals.(i) in - let node = Hivex.node_add_child h parent node_name in - iter (depth+1) i node - done; - let values = Array.init (10-posn) ( - fun i -> - { Hivex.key = animals.(i); - t = Hivex.REG_SZ; - value = utf16le_of_ascii numbers.(i) } - ) in - Hivex.node_set_values h parent values - ) - - (* Make a nul-terminated UTF16-LE string from an ASCII string. *) - and utf16le_of_ascii str = - let len = String.length str in - let len' = len * 2 + 2 in - let str' = String.create len' in - for i = 0 to len-1 do - str'.[i*2] <- str.[i]; - str'.[i*2+1] <- '\000' - done; - str'.[len'-2] <- '\000'; - str'.[len'-1] <- '\000'; - str' - in - iter 0 0 (Hivex.root h); - - (* Discard the changes. *) - Hivex.close h; - - (* Gc.compact is a good way to ensure we don't have - * heap corruption or double-freeing. - *) - Gc.compact () diff --git a/trunk/hivex/ocaml/t/hivex_300_fold.ml b/trunk/hivex/ocaml/t/hivex_300_fold.ml deleted file mode 100644 index c8de6e8..0000000 --- a/trunk/hivex/ocaml/t/hivex_300_fold.ml +++ /dev/null @@ -1,52 +0,0 @@ -(* 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. - *) - -(* Fold over the large hive. *) - -open Unix -open Printf -let (//) = Filename.concat - -(* This is a generic function to fold over hives. - * fn : 'a -> node -> 'a is called for each node - * fv : 'a -> node -> value array -> 'a is called for the values at each node - *) -let hive_fold h fn fv a root = - let rec fold a node = - let a = fn a node in - let a = fv a node (Hivex.node_values h node) in - Array.fold_left fold a (Hivex.node_children h node) - in - fold a root - -let () = - let h = Hivex.open_file ("../images/large") [] in - - (* Count the number of nodes and values in the hive. *) - let count_node (nodes, values) _ = (nodes+1, values) in - let count_values (nodes, values) _ vs = (nodes, values + Array.length vs) in - let root = Hivex.root h in - let (nodes, values) = hive_fold h count_node count_values (0, 0) root in - printf "large test hive contains %d nodes and %d values\n%!" nodes values; - - Hivex.close h; - - (* Gc.compact is a good way to ensure we don't have - * heap corruption or double-freeing. - *) - Gc.compact () diff --git a/trunk/hivex/perl/Makefile.PL.in b/trunk/hivex/perl/Makefile.PL.in deleted file mode 100644 index 77b4a0e..0000000 --- a/trunk/hivex/perl/Makefile.PL.in +++ /dev/null @@ -1,31 +0,0 @@ -# hivex Perl 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. - -use Config; -use ExtUtils::MakeMaker; - -WriteMakefile ( - FIRST_MAKEFILE => 'Makefile-pl', - - NAME => 'Win::Hivex', - VERSION => '@PACKAGE_VERSION@', - - LIBS => '-L@top_builddir@/lib/.libs -lhivex', - INC => '-I@top_builddir@/lib -I@top_srcdir@/lib', - TYPEMAPS => [ '@srcdir@/typemap' ], - CCFLAGS => $Config{ccflags} . ' @CFLAGS@', - ); diff --git a/trunk/hivex/perl/Makefile.am b/trunk/hivex/perl/Makefile.am deleted file mode 100644 index 22dd98c..0000000 --- a/trunk/hivex/perl/Makefile.am +++ /dev/null @@ -1,66 +0,0 @@ -# hivex Perl 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. - -# Old RHEL 5 autoconf doesn't have builddir or abs_srcdir. -builddir ?= $(top_builddir)/perl -abs_srcdir ?= $(shell unset CDPATH; cd $(srcdir) && pwd) - -EXTRA_DIST = \ - Makefile.PL.in \ - run-perl-tests \ - lib/Win/Hivex.pm \ - lib/Win/Hivex/Regedit.pm \ - Hivex.xs \ - t/*.t \ - typemap - -if HAVE_PERL - -# Interfacing automake and ExtUtils::MakeMaker known to be -# a nightmare, news at 11. - -# hivex source dependencies -.PHONY: src_deps -src_deps: $(top_builddir)/lib/libhivex.la - -TESTS = run-perl-tests - -$(TESTS): src_deps all - -TESTS_ENVIRONMENT = \ - LD_LIBRARY_PATH=$(top_builddir)/lib/.libs - -INSTALLDIRS = site - -all: Makefile-pl src_deps - $(MAKE) -f Makefile-pl - -Makefile-pl: Makefile.PL - -[ $(srcdir) != $(builddir) ] && cp -rsu $(abs_srcdir)/. $(builddir)/. - perl Makefile.PL INSTALLDIRS=$(INSTALLDIRS) PREFIX=$(prefix) - -# No! Otherwise it is deleted before the clean-local rule runs. -#CLEANFILES = Makefile-pl - -clean-local: - -$(MAKE) -f Makefile-pl clean - rm -f Makefile-pl Makefile-pl.old - -install-data-hook: - $(MAKE) -f Makefile-pl DESTDIR=$(DESTDIR) install - -endif diff --git a/trunk/hivex/perl/lib/Win/Hivex/Regedit.pm b/trunk/hivex/perl/lib/Win/Hivex/Regedit.pm deleted file mode 100644 index 8914f9e..0000000 --- a/trunk/hivex/perl/lib/Win/Hivex/Regedit.pm +++ /dev/null @@ -1,687 +0,0 @@ -# Win::Hivex::Regedit -# Copyright (C) 2009-2011 Red Hat Inc. -# Derived from code by Petter Nordahl-Hagen under a compatible license: -# Copyright (c) 1997-2007 Petter Nordahl-Hagen. -# Derived from code by Markus Stephany under a compatible license: -# Copyright (c)2000-2004, Markus Stephany. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -=pod - -=head1 NAME - -Win::Hivex::Regedit - Helper for reading and writing regedit format files - -=head1 SYNOPSIS - - use Win::Hivex; - use Win::Hivex::Regedit qw(reg_import reg_export); - - $h = Win::Hivex->open ('SOFTWARE', write => 1); - - open FILE, "updates.reg"; - reg_import (\*FILE, $h); - $h->commit (undef); - - reg_export ($h, "\\Microsoft\\Windows NT\\CurrentVersion", \*OUTFILE, - prefix => "HKEY_LOCAL_MACHINE\\SOFTWARE"); - -=head1 DESCRIPTION - -Win::Hivex::Regedit is a helper library for reading and writing the -Windows regedit (or C<.REG>) file format. This is the textual format -that is commonly used on Windows for distributing groups of Windows -Registry changes, and this format is read and written by the -proprietary C and C programs supplied with -Windows. It is I the same as the binary "hive" format which the -hivex library itself can read and write. Note that the regedit format -is not well-specified, and hence deviations can occur between what the -Windows program can read/write and what we can read/write. (Please -file bugs for any deviations found). - -Win::Hivex::Regedit is the low-level Perl library. There is also a -command line tool for combining hive files and reg files -(L). If you have a Windows virtual machine that you need -to merge regedit-format changes into, use the high-level -L tool (part of libguestfs tools). - -=head2 FUNCTIONS - -=cut - -package Win::Hivex::Regedit; - -use strict; -use warnings; - -use Carp qw(croak confess); -use Encode qw(encode decode); - -require Exporter; - -use vars qw(@EXPORT_OK @ISA); - -@ISA = qw(Exporter); -@EXPORT_OK = qw(reg_import reg_export); - -=head2 reg_import - - reg_import ($fh, ($h|$map), [encoding => "UTF-16LE"]); - -This function imports the registry keys from file handle C<$fh> either -into the hive C<$h> or via a map function. - -The hive handle C<$h> must have been opened for writing, ie. -using the C 1> flag to Copen>. - -In the binary hive file, the first part of the key name (eg. -C) is not stored. You just have to know -(somehow) that this maps to the C hive. Therefore if you -are given a file containing a mixture of keys that have to be added to -different hives, you have to have a way to map these to the hive -handles. This is outside the scope of the hivex library, but if the -second argument is a CODEREF (ie. reference to a function) then this -C<$map> function is called on each key name: - - map ($keyname) - ==> ($h, $keyname) - -As shown, the function should return a pair, hive handle, and the true -key name (with the prefix stripped off). For example: - - sub map { - if ($_[0] =~ /^HKEY_LOCAL_MACHINE\\SOFTWARE(.*)/i) { - return ($software_h, $1); - } else ... - } - -C is the encoding used by default for strings. If not -specified, this defaults to C<"UTF-16LE">, however we highly advise -you to specify it. See L below. - -As with the regedit program, we merge the new registry keys with -existing ones, and new node values with old ones. You can use the -C<-> (minus) character to delete individual keys and values. This is -explained in detail in the Wikipedia page on the Windows Registry. - -Remember you need to call C<$h-Ecommit (undef)> on the hivex -handle before any changes are written to the hive file. See -L. - -=cut - -sub reg_import -{ - local $_; - my $fh = shift; - my $hmap = shift; - my %params = @_; - - my $encoding = $params{encoding} || "utf-16le"; - - my $state = "outer"; - my $newnode; - my @newvalues; - my @delvalues; - my $lineno = 0; - - while (<$fh>) { - # Join continuation lines. This is recipe 8.1 from the Perl - # Cookbook. Note we allow spaces after the final \ because - # this is fairly common in pasted regedit files. - $lineno++; - chomp; - if (s/\\\s*$//) { - $_ .= <$fh>; - redo unless eof ($fh); - } - - #print STDERR "reg_import: parsing <<<$_>>>\n"; - - if ($state eq "outer") { - # Ignore blank lines, headers. - next if /^\s*$/; - - # .* is needed before Windows Registry Editor Version.. in - # order to eat a possible Unicode BOM which regedit writes - # there. - next if /^.*Windows Registry Editor Version.*/; - next if /^REGEDIT/; - - # Ignore comments. - next if /^\s*;/; - - # Expect to see [...] or [-...] - # to merge or delete a node respectively. - if (/^\[-(.*)\]\s*$/) { - _delete_node ($hmap, \%params, $1); - $state = "outer"; - } elsif (/^\[(.*)\]\s*$/) { - $state = "inner"; - $newnode = $1; - @newvalues = (); - @delvalues = (); - } else { - croak (_unexpected ($_, $lineno)); - } - } elsif ($state eq "inner") { - if (/^(".*)=-\s*$/) { # delete value - my $key = _parse_quoted_string ($_); - croak (_parse_error ($_, $lineno)) unless defined $key; - push @delvalues, $key; - } elsif (/^@=-\s*$/) { # delete default key - push @delvalues, ""; - } elsif (/^".*"=/) { # ordinary value - my $value = _parse_key_value ($_, $encoding); - croak (_parse_error ($_, $lineno)) unless defined $value; - push @newvalues, $value; - } elsif (/^@=(.*)/) { # default key - my $value = _parse_value ("", $1, $encoding); - croak (_parse_error ($_, $lineno)) unless defined $value; - push @newvalues, $value; - } elsif (/^\s*$/) { # blank line after values - _merge_node ($hmap, \%params, $newnode, \@newvalues, \@delvalues); - $state = "outer"; - } else { - croak (_unexpected ($_, $lineno)); - } - } - } # while - - # Still got a node left over to merge? - if ($state eq "inner") { - _merge_node ($hmap, \%params, $newnode, \@newvalues, \@delvalues); - } -} - -sub _parse_key_value -{ - local $_ = shift; - my $encoding = shift; - my $key; - ($key, $_) = _parse_quoted_string ($_); - return undef unless defined $key; - return undef unless substr ($_, 0, 1) eq "="; - return _parse_value ($key, substr ($_, 1), $encoding); -} - -# Parse a double-quoted string, returning the string. \ is used to -# escape double-quotes and other backslash characters. -# -# If called in array context and if there is anything after the quoted -# string, it is returned as the second element of the array. -# -# Returns undef if there was a parse error. -sub _parse_quoted_string -{ - local $_ = shift; - - # No initial quote character. - return undef if substr ($_, 0, 1) ne "\""; - - my $i; - my $out = ""; - for ($i = 1; $i < length; ++$i) { - my $c = substr ($_, $i, 1); - if ($c eq "\"") { - last - } elsif ($c eq "\\") { - $i++; - $c = substr ($_, $i, 1); - $out .= $c; - } else { - $out .= $c; - } - } - - # No final quote character. - return undef if $i == length; - - $_ = substr ($_, $i+1); - if (wantarray) { - return ($out, $_); - } else { - return $out; - } -} - -# Parse the value, optionally prefixed by a type. - -sub _parse_value -{ - local $_; - my $key = shift; - $_ = shift; - my $encoding = shift; # default encoding for strings - - my $type; - my $data; - - if (m/^dword:([[:xdigit:]]{8})$/) { # DWORD - $type = 4; - $data = _dword_le (hex ($1)); - } elsif (m/^hex:(.*)$/) { # hex digits - $type = 3; - $data = _data_from_hex_digits ($1); - return undef unless defined $data; - } elsif (m/^hex\(([[:xdigit:]]+)\):(.*)$/) { # hex digits - $type = hex ($1); - $data = _data_from_hex_digits ($2); - return undef unless defined $data; - } elsif (m/^str:(".*")$/) { # only in Wine fake-registries, I think - $type = 1; - $data = _parse_quoted_string ($1); - return undef unless defined $data; - $data .= "\0"; # Value strings are implicitly ASCIIZ. - $data = encode ($encoding, $data); - } elsif (m/^str\(([[:xdigit:]]+)\):(".*")$/) { - $type = hex ($1); - $data = _parse_quoted_string ($2); - return undef unless defined $data; - $data .= "\0"; # Value strings are implicitly ASCIIZ. - $data = encode ($encoding, $data); - } elsif (m/^(".*")$/) { - $type = 1; - $data = _parse_quoted_string ($1); - return undef unless defined $data; - $data .= "\0"; # Value strings are implicitly ASCIIZ. - $data = encode ($encoding, $data); - } else { - return undef; - } - - my %h = ( key => $key, t => $type, value => $data ); - return \%h; -} - -sub _dword_le -{ - pack ("V", $_[0]); -} - -sub _data_from_hex_digits -{ - local $_ = shift; - s/[,[:space:]]//g; - pack ("H*", $_) -} - -sub _merge_node -{ - local $_; - my $hmap = shift; - my $params = shift; - my $path = shift; - my $newvalues = shift; - my $delvalues = shift; - - my $h; - ($h, $path) = _map_handle ($hmap, $path); - - my $node = _node_lookup ($h, $path); - if (!defined $node) { # Need to create this node. - my $name = $path; - $name = $1 if $path =~ /([^\\]+)$/; - my $parentpath = $path; - $parentpath =~ s/[^\\]+$//; - my $parent = _node_lookup ($h, $parentpath); - if (!defined $parent) { - confess "reg_import: cannot create $path since parent $parentpath does not exist" - } - $node = $h->node_add_child ($parent, $name); - } - - # Get the current set of values at this node. - my @values = $h->node_values ($node); - - # Delete values in @delvalues original and values that are going - # to be replaced. - my @delvalues = @$delvalues; - foreach (@$newvalues) { - push @delvalues, $_->{key}; - } - @values = grep { ! _imember ($h->value_key ($_), @delvalues) } @values; - - # Get the actual values from the hive. - @values = map { - my $key = $h->value_key ($_); - my ($type, $data) = $h->value_value ($_); - my %h = ( key => $key, t => $type, value => $data ); - $_ = \%h; - } @values; - - # Add the new values. - push @values, @$newvalues; - - $h->node_set_values ($node, \@values); -} - -sub _delete_node -{ - local $_; - my $hmap = shift; - my $params = shift; - my $path = shift; - - my $h; - ($h, $path) = _map_handle ($hmap, $path); - - my $node = _node_lookup ($h, $path); - # Not an error to delete a non-existant node. - return unless defined $node; - - # However you cannot delete the root node. - confess "reg_import: the root node of a hive cannot be deleted" - if $node == $h->root (); - - $h->node_delete_child ($node); -} - -# Call the map function, if necessary. -sub _map_handle -{ - local $_; # called function may use this - my $hmap = shift; - my $path = shift; - my $h = $hmap; - - if (ref ($hmap) eq "CODE") { - ($h, $path) = &$hmap ($path); - } - return ($h, $path); -} - -sub _imember -{ - local $_; - my $item = shift; - - foreach (@_) { - return 1 if lc ($_) eq lc ($item); - } - return 0; -} - -sub _unexpected -{ - local $_ = shift; - my $lineno = shift; - - "reg_import: parse error: unexpected text found at line $lineno near\n$_" -} - -sub _parse_error -{ - local $_ = shift; - my $lineno = shift; - - "reg_import: parse error: at line $lineno near\n$_" -} - -=head2 reg_export - - reg_export ($h, $key, $fh, - [prefix => $prefix], - [unsafe_printable_strings => 1]); - -This function exports the registry keys starting at the root -C<$key> and recursively downwards into the file handle C<$fh>. - -C<$key> is a case-insensitive path of the node to start from, relative -to the root of the hive. It is an error if this path does not exist. -Path elements should be separated by backslash characters. - -C<$prefix> is prefixed to each key name. The usual use for this is to -make key names appear as they would on Windows. For example the key -C<\Foo> in the SOFTWARE Registry, with $prefix -C, would be written as: - - [HKEY_LOCAL_MACHINE\SOFTWARE\Foo] - "Key 1"=... - "Key 2"=... - -If C is not given or is false, then the -output is written as pure 7 bit ASCII, with line endings which are the -default for the local host. Strings are always encoded as hex bytes. -This is safe because it preserves the original content and encoding of -strings. See L below. - -If C is true, then strings are assumed to be -UTF-16LE and are converted to UTF-8 for output. The final zero -codepoint in the string is removed if there is one. This is unsafe -because it does not preserve the fidelity of the strings in the -Registry and because the content type of strings is not always -UTF-16LE. However it is useful if you just want to display strings -for quick hacking and debugging. - -You may need to convert the file's encoding using L and line -endings using L if sending to a Windows user. - -Nodes and keys are sorted alphabetically in the output. - -This function does I print a header. The real regedit program -will print a header like: - - Windows Registry Editor Version 5.00 - -followed by a blank line. (Other headers are possible, see the -Wikipedia page on the Windows Registry). If you want a header, you -need to write it out yourself. - -=cut - -sub reg_export -{ - my $h = shift; - my $key = shift; - - my $node = _node_lookup ($h, $key); - croak "$key: path not found in this hive" unless $node; - - reg_export_node ($h, $node, @_); -} - -=head2 reg_export_node - - reg_export_node ($h, $node, $fh, ...); - -This is exactly the same as L except that instead -of specifying the path to a key as a string, you pass a hivex -library C<$node> handle. - -=cut - -sub reg_export_node -{ - local $_; - my $h = shift; - my $node = shift; - my $fh = shift; - my %params = @_; - - confess "reg_export_node: \$node parameter was undef" unless defined $node; - - # Get the canonical path of this node. - my $path = _node_canonical_path ($h, $node); - - # Print the path. - print $fh "["; - my $prefix = $params{prefix}; - if (defined $prefix) { - chop $prefix if substr ($prefix, -1, 1) eq "\\"; - print $fh $prefix; - } - print $fh $path; - print $fh "]\n"; - - my $unsafe_printable_strings = $params{unsafe_printable_strings}; - - # Get the values. - my @values = $h->node_values ($node); - - foreach (@values) { - use bytes; - - my $key = $h->value_key ($_); - my ($type, $data) = $h->value_value ($_); - $_ = { key => $key, type => $type, data => $data } - } - - @values = sort { $a->{key} cmp $b->{key} } @values; - - # Print the values. - foreach (@values) { - my $key = $_->{key}; - my $type = $_->{type}; - my $data = $_->{data}; - - if ($key eq "") { - print $fh '@=' # default key - } else { - print $fh '"', _escape_quotes ($key), '"=' - } - - if ($type eq 4 && length ($data) == 4) { # only handle dword specially - my $dword = unpack ("V", $data); - printf $fh "dword:%08x\n", $dword - } elsif ($unsafe_printable_strings && ($type eq 1 || $type eq 2)) { - # Guess that the encoding is UTF-16LE. Convert it to UTF-8 - # for printing. - $data = decode ("utf16le", $data); - $data =~ s/\x{0}$//; # remove final zero codepoint - $data =~ s/"/\\"/g; # XXX more quoting needed? - printf $fh "str(%x):\"%s\"\n", $type, $data; - } else { - # Encode everything else as hex, see encoding section below. - printf $fh "hex(%x):", $type; - my $hex = join (",", map { sprintf "%02x", ord } split (//, $data)); - print $fh "$hex\n" - } - } - print $fh "\n"; - - my @children = $h->node_children ($node); - @children = sort { $h->node_name ($a) cmp $h->node_name ($b) } @children; - reg_export_node ($h, $_, $fh, @_) foreach @children; -} - -# Escape " and \ when printing keys. -sub _escape_quotes -{ - local $_ = shift; - s/\\/\\\\/g; - s/"/\\"/g; - $_; -} - -# Look up a node in the registry starting from the path. -# Return undef if it doesn't exist. - -sub _node_lookup -{ - local $_; - my $h = shift; - my $path = shift; - - my @path = split /\\/, $path; - shift @path if @path > 0 && $path[0] eq ""; - - my $node = $h->root (); - foreach (@path) { - $node = $h->node_get_child ($node, $_); - return undef unless defined $node; - } - - return $node; -} - -# Return the canonical path of node in the hive. - -sub _node_canonical_path -{ - local $_; - my $h = shift; - my $node = shift; - - return "\\" if $node == $h->root (); - $_ = $h->node_name ($node); - my $parent = $h->node_parent ($node); - my $path = _node_canonical_path ($h, $parent); - if ($path eq "\\") { - return "$path$_" - } else { - return "$path\\$_" - } -} - -=head1 ENCODING STRINGS - -The situation with encoding strings in the Registry on Windows is very -confused. There are two main encodings that you would find in the -binary (hive) file, 7 bit ASCII and UTF-16LE. (Other encodings are -possible, it's also possible to have arbitrary binary data incorrectly -marked with a string type). - -The hive file itself doesn't contain any indication of string -encoding. Windows probably guesses the encoding. - -We think that regedit probably either guesses which encoding to use -based on the file encoding, or else has different defaults for -different versions of Windows. Neither choice is appropriate for a -tool used in a real operating system. - -When using L, you should specify the default encoding for -strings using the C parameter. If not specified, it -defaults to UTF-16LE. - -The file itself that is imported should be in the local encoding for -files (usually UTF-8 on modern Linux systems). This means if you -receive a regedit file from a Windows system, you may sometimes have -to reencode it: - - iconv -f utf-16le -t utf-8 < input.reg | dos2unix > output.reg - -When writing regedit files (L) we bypass this madness -completely. I strings (even pure ASCII) are written as hex bytes -so there is no doubt about how they should be encoded when they are -read back in. - -=cut - -1; - -=head1 COPYRIGHT - -Copyright (C) 2010-2011 Red Hat Inc. - -=head1 LICENSE - -Please see the file COPYING.LIB for the full license. - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L, -L, -L, -L. - -=cut diff --git a/trunk/hivex/perl/run-perl-tests b/trunk/hivex/perl/run-perl-tests deleted file mode 100755 index 770df94..0000000 --- a/trunk/hivex/perl/run-perl-tests +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# hivex Perl 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. - -set -e - -make -f Makefile-pl test "$@" diff --git a/trunk/hivex/perl/t/005-pod.t b/trunk/hivex/perl/t/005-pod.t deleted file mode 100644 index 8fef583..0000000 --- a/trunk/hivex/perl/t/005-pod.t +++ /dev/null @@ -1,24 +0,0 @@ -# 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. - -use Test::More; -use strict; -use warnings; - -eval "use Test::Pod 1.00"; -plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; -all_pod_files_ok (); diff --git a/trunk/hivex/perl/t/006-pod-coverage.t b/trunk/hivex/perl/t/006-pod-coverage.t deleted file mode 100644 index bcfb6d8..0000000 --- a/trunk/hivex/perl/t/006-pod-coverage.t +++ /dev/null @@ -1,24 +0,0 @@ -# hivex Perl bindings -*- perl -*- -# Copyright (C) 2009 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. - -use Test::More; -use strict; -use warnings; - -eval "use Test::Pod::Coverage 1.00"; -plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD" if $@; -all_pod_coverage_ok (); diff --git a/trunk/hivex/perl/t/010-load.t b/trunk/hivex/perl/t/010-load.t deleted file mode 100644 index 9abcdc8..0000000 --- a/trunk/hivex/perl/t/010-load.t +++ /dev/null @@ -1,24 +0,0 @@ -# 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. - -use strict; -use warnings; -use Test::More tests => 1; - -BEGIN { - use_ok ("Win::Hivex"); -} diff --git a/trunk/hivex/perl/t/020-open.t b/trunk/hivex/perl/t/020-open.t deleted file mode 100644 index b3c58f0..0000000 --- a/trunk/hivex/perl/t/020-open.t +++ /dev/null @@ -1,27 +0,0 @@ -# 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. - -use strict; -use warnings; -use Test::More tests => 1; - -use Win::Hivex; - -my $srcdir = $ENV{srcdir} || "."; - -my $h = Win::Hivex->open ("$srcdir/../images/minimal"); -ok ($h); diff --git a/trunk/hivex/perl/t/021-close.t b/trunk/hivex/perl/t/021-close.t deleted file mode 100644 index f6388fc..0000000 --- a/trunk/hivex/perl/t/021-close.t +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -use strict; -use warnings; -use Test::More tests => 2; - -use Win::Hivex; - -my $srcdir = $ENV{srcdir} || "."; - -# Put it in a block so the handle gets destroyed as well. -{ - my $h = Win::Hivex->open ("$srcdir/../images/minimal"); - ok ($h); -} -ok (1); diff --git a/trunk/hivex/perl/t/120-rlenvalue.t b/trunk/hivex/perl/t/120-rlenvalue.t deleted file mode 100644 index 70e9060..0000000 --- a/trunk/hivex/perl/t/120-rlenvalue.t +++ /dev/null @@ -1,46 +0,0 @@ -# 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); diff --git a/trunk/hivex/perl/t/200-write.t b/trunk/hivex/perl/t/200-write.t deleted file mode 100644 index e7fd570..0000000 --- a/trunk/hivex/perl/t/200-write.t +++ /dev/null @@ -1,49 +0,0 @@ -# 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. - -use strict; -use warnings; -use Test::More tests => 6; - -use Win::Hivex; - -my $srcdir = $ENV{srcdir} || "."; - -my $h = Win::Hivex->open ("$srcdir/../images/minimal", write => 1); -ok ($h); - -my $root = $h->root (); -ok ($root); - -$h->node_add_child ($root, "A"); -ok (1); - -$h->node_add_child ($root, "B"); -ok (1); - -my $b = $h->node_get_child ($root, "B"); -ok ($b); - -my $values = [ - { key => "Key1", t => 3, value => "ABC" }, - { key => "Key2", t => 3, value => "DEF" } - ]; -$h->node_set_values ($b, $values); -ok (1); - -# don't commit because that would overwrite the original file -# $h->commit (); diff --git a/trunk/hivex/perl/t/210-setvalue.t b/trunk/hivex/perl/t/210-setvalue.t deleted file mode 100644 index 8e24121..0000000 --- a/trunk/hivex/perl/t/210-setvalue.t +++ /dev/null @@ -1,65 +0,0 @@ -# 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. - -use strict; -use warnings; -use Test::More tests => 11; - -use Win::Hivex; - -my $srcdir = $ENV{srcdir} || "."; - -my $h = Win::Hivex->open ("$srcdir/../images/minimal", write => 1); -ok ($h); - -my $root = $h->root (); -ok ($root); - -$h->node_add_child ($root, "B"); -ok (1); - -my $b = $h->node_get_child ($root, "B"); -ok ($b); - -my $values = [ - { key => "Key1", t => 3, value => "ABC" }, - { key => "Key2", t => 3, value => "DEF" } - ]; -$h->node_set_values ($b, $values); -ok (1); - -my $value1 = { key => "Key3", t => 3, value => "GHI" }; -$h->node_set_value ($b, $value1); -ok (1); - -my $value2 = { key => "Key1", t => 3, value => "JKL" }; -$h->node_set_value ($b, $value2); -ok (1); - -my ($val, $t, $data); -$val = $h->node_get_value ($b, "Key1"); -($t, $data) = $h->value_value ($val); -ok ($t == 3); -ok ($data eq "JKL"); - -$val = $h->node_get_value ($b, "Key3"); -($t, $data) = $h->value_value ($val); -ok ($t == 3); -ok ($data eq "GHI"); - -# don't commit because that would overwrite the original file -# $h->commit (); diff --git a/trunk/hivex/perl/t/510-regedit-load.t b/trunk/hivex/perl/t/510-regedit-load.t deleted file mode 100644 index feebe42..0000000 --- a/trunk/hivex/perl/t/510-regedit-load.t +++ /dev/null @@ -1,24 +0,0 @@ -# Win::Hivex::Regedit tests -*- 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. - -use strict; -use warnings; -use Test::More tests => 1; - -BEGIN { - use_ok ("Win::Hivex::Regedit"); -} diff --git a/trunk/hivex/perl/t/550-regedit-export.t b/trunk/hivex/perl/t/550-regedit-export.t deleted file mode 100644 index 2099157..0000000 --- a/trunk/hivex/perl/t/550-regedit-export.t +++ /dev/null @@ -1,102 +0,0 @@ -# Win::Hivex::Regedit test -*- 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. - -use strict; -use warnings; - -use Encode qw(from_to); -use IO::Scalar; - -use Test::More tests => 8; - -use Win::Hivex; -use Win::Hivex::Regedit qw(reg_export); - -my $srcdir = $ENV{srcdir} || "."; - -my $h = Win::Hivex->open ("$srcdir/../images/minimal", write => 1); -ok ($h); - -my $root = $h->root (); -ok ($root); - -$h->node_add_child ($root, "B"); -ok (1); - -$h->node_add_child ($root, "A"); -ok (1); - -my $b = $h->node_get_child ($root, "B"); -ok ($b); - -# Encode a string as UTF16-LE. -sub utf16le -{ - my $s = shift; - from_to ($s, "ascii", "utf-16le"); - $s; -} - -# Convert a 32 bit integer to a little endian 4 byte data field. -sub dwordle -{ - pack ("V", $_[0]); -} - -my @values = ( - # Values are entered in a random order here, but they should be - # sorted on export. - { key => "Key2", t => 2, value => utf16le ("DEF") }, - { key => "", t => 1, value => "Default" }, - { key => "Key3", t => 4, value => dwordle (0xff876543) }, - { key => "Key1", t => 1, value => "ABC" }, - ); -$h->node_set_values ($b, \@values); -ok (1); - -my $fh = new IO::Scalar; -reg_export ($h, "\\", $fh, prefix => "HKEY_LOCAL_MACHINE\\SOFTWARE\\"); - -my $expected = '[HKEY_LOCAL_MACHINE\\SOFTWARE\\] - -[HKEY_LOCAL_MACHINE\\SOFTWARE\\A] - -[HKEY_LOCAL_MACHINE\\SOFTWARE\\B] -@=hex(1):44,65,66,61,75,6c,74 -"Key1"=hex(1):41,42,43 -"Key2"=hex(2):44,00,45,00,46,00 -"Key3"=dword:ff876543 - -'; - -ok (${$fh->sref} eq $expected); - -$fh = new IO::Scalar; -reg_export ($h, "\\B", $fh); - -$expected = '[\\B] -@=hex(1):44,65,66,61,75,6c,74 -"Key1"=hex(1):41,42,43 -"Key2"=hex(2):44,00,45,00,46,00 -"Key3"=dword:ff876543 - -'; - -ok (${$fh->sref} eq $expected); - -# don't commit because that would overwrite the original file -# $h->commit (); diff --git a/trunk/hivex/perl/t/560-regedit-import.t b/trunk/hivex/perl/t/560-regedit-import.t deleted file mode 100644 index effb024..0000000 --- a/trunk/hivex/perl/t/560-regedit-import.t +++ /dev/null @@ -1,161 +0,0 @@ -# Win::Hivex::Regedit test -*- 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. - -use strict; -use warnings; - -use IO::Scalar; - -use Test::More tests => 16; - -use Win::Hivex; -use Win::Hivex::Regedit qw(reg_import reg_export); - -my $srcdir = $ENV{srcdir} || "."; - -my $h = Win::Hivex->open ("$srcdir/../images/minimal", write => 1); -ok ($h); - -my ($data, $expected); - -# Note that we don't clear the hive between tests, so results of -# next test depend on the previous test. - -$data = ' -[\A] - -[\B] - -[\C] -"Key1"=hex(2):48,00,65,00,6c,00,6c,00,6f,00 -"Key2"=str(2):"Hello" -"Key3"=hex:48,00,65,00,6c,00,6c,00,6f,00,\ - 48,00,65,00,6c,00,6c,00,6f,00 -"Key4"=dword:ff123456'; -$expected = '[\] - -[\A] - -[\B] - -[\C] -"Key1"=hex(2):48,00,65,00,6c,00,6c,00,6f,00 -"Key2"=hex(2):48,00,65,00,6c,00,6c,00,6f,00,00,00 -"Key3"=hex(3):48,00,65,00,6c,00,6c,00,6f,00,48,00,65,00,6c,00,6c,00,6f,00 -"Key4"=dword:ff123456 - -'; - -run_test ($data, $expected); - -$data = ' -[\A] -@="Hello" - -[-\B] -'; -$expected = '[\] - -[\A] -@=hex(1):48,00,65,00,6c,00,6c,00,6f,00,00,00 - -[\C] -"Key1"=hex(2):48,00,65,00,6c,00,6c,00,6f,00 -"Key2"=hex(2):48,00,65,00,6c,00,6c,00,6f,00,00,00 -"Key3"=hex(3):48,00,65,00,6c,00,6c,00,6f,00,48,00,65,00,6c,00,6c,00,6f,00 -"Key4"=dword:ff123456 - -'; - -run_test ($data, $expected); - -$data = ' -[\A] -@=- - -[-\C] - -[\A\B] -'; -$expected = '[\] - -[\A] - -[\A\B] - -'; - -run_test ($data, $expected); - -# In the next test, the value of ValueContainingEscapes in the -# imported data is \\W\\, which will become \W\ in the final hive. -# However Perl has complex and inconsistent rules on quoting -# backslashes. See: -# http://en.wikibooks.org/wiki/Perl_Programming/Strings#Single_Quoted_Strings -$data = ' -[\A] -"NotExistant"=- - -[\A\B] -"Key\"Containing\"Quotes"=hex(0): -"ValueContainingEscapes"="\\\\W\\\\" -'; -$expected = '[\] - -[\A] - -[\A\B] -"Key\"Containing\"Quotes"=hex(0): -"ValueContainingEscapes"=hex(1):5c,00,57,00,5c,00,00,00 - -'; - -run_test ($data, $expected); - -$data = ' -[\A\B] -"Key\"Containing\"Quotes"=- -"ValueContainingEscapes"=- - -[-\A] -'; -$expected = '[\] - -'; - -run_test ($data, $expected); - -#---------------------------------------------------------------------- - -sub run_test { - my $data = shift; - my $expected = shift; - - my $fh = new IO::Scalar \$data; - reg_import ($fh, $h); - ok (1); - - $fh = new IO::Scalar; - reg_export ($h, "\\", $fh); - ok (1); - - my $actual = ${$fh->sref}; - warn "\n\n----- ACTUAL -----\n$actual\n----- EXPECTED -----\n$expected\n\n" - if $actual ne $expected; - - ok ($actual eq $expected) -} diff --git a/trunk/hivex/perl/t/570-regedit-import2.t b/trunk/hivex/perl/t/570-regedit-import2.t deleted file mode 100644 index a952fb0..0000000 --- a/trunk/hivex/perl/t/570-regedit-import2.t +++ /dev/null @@ -1,82 +0,0 @@ -# Win::Hivex::Regedit test -*- 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. - -use strict; -use warnings; - -use Encode qw(from_to); -use IO::Scalar; - -use Test::More tests => 6; - -use Win::Hivex; -use Win::Hivex::Regedit qw(reg_import reg_export); - -my $srcdir = $ENV{srcdir} || "."; - -my $h = Win::Hivex->open ("$srcdir/../images/minimal", write => 1); -ok ($h); - -my $data; - -# Note: These tests are supposed to fail. - -# Need a blank line between sections. -$data = ' -[A] -[B]'; -run_test ($data); - -# Invalid header. -$data = ' -[A]B'; -run_test ($data); - -# Must create intermediate nodes first. -$data = ' -[A\B\C\D]'; -run_test ($data); - -# Invalid quoting. -$data = ' -[A] -"Quote"it"="Hello"'; -run_test ($data); - -$data = ' -[A] -"Quote it\"="Hello"'; -run_test ($data); - -# Invalid hex -- fails, 'pack' processes it anyway. -#$data = ' -#[A] -#"Key"=hex(1):xy'; -#run_test ($data); - -#---------------------------------------------------------------------- - -sub run_test { - my $data = shift; - - eval { - my $fh = new IO::Scalar \$data; - reg_import ($h, $fh); - }; - #warn "$@\n"; - ok ($@); -} diff --git a/trunk/hivex/perl/typemap b/trunk/hivex/perl/typemap deleted file mode 100644 index c29c02d..0000000 --- a/trunk/hivex/perl/typemap +++ /dev/null @@ -1,18 +0,0 @@ -TYPEMAP -char * T_PV -const char * T_PV -hive_h * O_OBJECT_hive_h -int64_t T_IV - -INPUT -O_OBJECT_hive_h - if (sv_isobject ($arg) && SvTYPE (SvRV ($arg)) == SVt_PVMG) - $var = ($type) SvIV ((SV *) SvRV ($arg)); - else { - warn (\"${Package}::$func_name(): $var is not a blessed SV reference\"); - XSRETURN_UNDEF; - } - -OUTPUT -O_OBJECT_hive_h - sv_setref_pv ($arg, "Win::Hivex", (void *) $var); diff --git a/trunk/hivex/po/POTFILES.in b/trunk/hivex/po/POTFILES.in deleted file mode 100644 index 3e02786..0000000 --- a/trunk/hivex/po/POTFILES.in +++ /dev/null @@ -1,2 +0,0 @@ -sh/hivexsh.c -xml/hivexml.c diff --git a/trunk/hivex/po/es.po b/trunk/hivex/po/es.po deleted file mode 100644 index 7092ecd..0000000 --- a/trunk/hivex/po/es.po +++ /dev/null @@ -1,178 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Spanish (Castilian) \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Bienvenido a hivexsh, el entorno interactivo de hivex para examinar\n" -"archivos binarios hive de registro Windows.\n" -"\n" -"Ingrese: 'help' para obtener ayuda\n" -" 'quit' para abandonar este entorno\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: error al intentar obtener padre del nodo %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: error al intentar obtener el nombre-nodo del nodo %zu\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "hivexsh: debe caragr un archivo hive utilizando 'load hivefile'\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "hivexsh: comando '%s' desconocido, utilice 'help' para obtener ayuda\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "" -"hivexsh: cargar: no se ha indicado un nombre de archivo hive para cargar\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: falló al intentar abrir el archivo hive: %s: %m\n" -"\n" -"Si considera que este archivo es un archivo hive binario de windows válido\n" -"(_no_ un archivo regedit *.reg), entonces por favor ejecute el siguiente " -"comando\n" -"nuevamente, utilizando la opción hivexsh '-d', y adjunte la salida completa " -"_y_\n" -"el archivo hive que ha fallado, en un reporte de error en https://bugzilla." -"redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: el comando '%s' no debería necesitar argumentos\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ los caracteres en la ruta se encuentran duplicados - ¿está " -"escapando el parámetro correctamente?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: no se encuentra la subllave '%s'\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Desplácese a través de las llaves hive utilizando el comando 'cd',\n" -"como si fuera un sistema de archivos, y utilice 'ls' para listar las\n" -"subllaves de la llave actual. Puede encontrar documentación completa\n" -"en la página man de hivexsh(1).\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: no se ha encontrado la llave\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: parámetro entero no válido (%s devolvió %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: el entero se encuentra fuera del rango\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: final inesperado de la salida\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): para la entrada, solo existe soporte para cadenas " -"ASCII de 7 bit\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: rastreando basura luego de la cadena hex\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: no es posible analizar el valor de la cadena, por favor " -"consulte la página man de hivexsh(1) para obtener ayuda: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: el nodo raíz no puede ser eliminado\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: falló al escribir documento XML\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: no se encuentra el nombre del archivo de entrada\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: falló al crear escritor XML\n" diff --git a/trunk/hivex/po/fr.po b/trunk/hivex/po/fr.po deleted file mode 100644 index c43f692..0000000 --- a/trunk/hivex/po/fr.po +++ /dev/null @@ -1,187 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-27 20:53+0000\n" -"Last-Translator: bozzo \n" -"Language-Team: French \n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Bienvenue dans hivexsh, l'interpréteur de commandes interactif hivex pour " -"examiner\n" -"les fichiers « hive » du registre Windows.\n" -"\n" -"Tapez: « help » pour un résumé de l'aide\n" -" « quit » pour quitter l'interpréteur de commandes\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh : erreur en récupérant le parent du nœud %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh : erreur en récupérant le nom du nœud %zx\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh : vous devez charger un fichier hive en utilisant « load hivefile »\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" -"hivexsh : commande « %s » inconnue, utilisez « help » pour obtenir un résumé " -"de l'aide\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "" -"hivexsh : load : aucun nom de fichier hive donné à la fonction « load »\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh : échec de l'ouverture du fichier hive : %s : %m\n" -"\n" -"Si vous pensez que ce fichier est un fichier binaire hive de Windows valide " -"(_pas_\n" -"un fichier regedit *.reg) alors veuillez lancer à nouveau cette commande, " -"avec\n" -"l'option hivexsh « -d », et joindre le résultat complet _avec_ le fichier " -"hive\n" -"qui échoue dans un rapport d'anomalie à l'adresse https://bugzilla.redhat." -"com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh : la commande « %s » ne doit pas avoir d'arguments\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s : %s : les caractères « \\ » sont doublés dans le chemin, échappez-vous " -"correctement le chemin en paramètre ?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh : cd : la sous-clé « %s » est introuvable\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Naviguez dans les clés de hive à l'aide de la commande « cd », comme si il\n" -"contenait un système de fichiers, et utilisez « ls » pour lister les sous-" -"clés de la\n" -"clé courrante. Toute la documentation est disponible dans la page de manuel " -"de hivexsh(1).\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s : %s : clé introuvable\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s : %s : paramètre entier invalide (%s a retourné %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s : %s : entier hors limites\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh : setval : fin inattendue de l'entrée\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh : string(utf16le) : seules les chaines ASCII 7 bits sont supportées " -"pour l'entrée\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" -"hivexsh : setval : effacement du tampon après lecture de la chaîne " -"hexadécimale\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh : setval : impossible d'analyser la valeur de la chaîne, veuillez " -"vous référer à la page de manuel de hivexsh(1) pour obtenir de l'aide : %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh : del : le nœud racine ne peut pas être supprimé\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s : échec de l'écriture du document XML\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml : nom du fichier en entrée manquant\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "" -"xmlNewTextWriterFilename : échec de la création du tampon d'écriture XML\n" diff --git a/trunk/hivex/po/gu.po b/trunk/hivex/po/gu.po deleted file mode 100644 index 826a676..0000000 --- a/trunk/hivex/po/gu.po +++ /dev/null @@ -1,165 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: sweta \n" -"Language-Team: Gujarati \n" -"Language: gu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"hivexsh માં તમારુ સ્વાગત છે, Windows રજીસ્ટરી બાઇનરી hive ફાઇલોનું નિરીક્ષણ કરવા માટે " -"hivex ઇન્ટરૅક્ટિવ શેલ.\n" -"\n" -"લખો: મદદ સાર માટે 'help'\n" -" શેલમાંથી બહાર નીકળવા માટે 'quit'\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: મુખ્ય નોડ %zu ને મેળવી રહ્યા હોય ત્યારે ભૂલ\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: નોડ %zx નાં નોડ નામને મેળવી રહ્યા હોય ત્યારે ભૂલ\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "hivexsh: તમારે 'load hivefile' ની મદદથી પહેલાં hive ફાઇલને લાવવુ જોઇએ\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "hivexsh: અજ્ઞાત આદેશ '%s', મદદ સારાંશ માટે 'help' વાપરો\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: લોડ: લોડ કરવા માટે hive ફાઇલ નામ આપેલ નથી\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: hive ફાઇલને ખોલતી વખતે નિષ્ફળતા: %s: %m\n" -"\n" -"જો તમે એવુ વિચારો કે આ ફાઇલ યોગ્ય Windows બાઇનરી hive ફાઇલ છે (_not_\n" -"a regedit *.reg ફાઇલ) પછી મહેરબાની કરીને hivexsh વિકલ્પ '-d' મદદથી ફરીથી આ આદેશને " -"ચલાવો અને સંપૂર્ણ આઉટપુટ અને hive ફાઇલને જોડો\n" -"કે જે https://bugzilla.redhat.com પર ભૂલને અહેવાલ કરવામાં નિષ્ફળ જાય છે/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: '%s' આદેશે દલીલોને આપવી જોઇએ નહિં\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ પાથમાં અક્ષરો બેગણાં છે - શું તમે યોગ્ય પાથ પરિમાણ માંથી છૂટા થવા માંગો છો?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: સબકી '%s' મળી નથી\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: કી મળી નથી\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: અયોગ્ય ઇંટિજર પરિમાણ (%s એ %d ને પાછુ લાવેલ છે)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: સીમાની બહાર ઇંટિજર\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: ઇનપુટનો અનિચ્છનીય અંત\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "hivexsh: string(utf16le): ફક્ત 7 bit ASCII શબ્દમાળા ઇનપુટ માટે આધારભૂત છે\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: રુટ નોડને કાઢી શકાતુ નથી\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: XML દસ્તાવેજને લખતી વખતે નિષ્ફળતા\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: ઇનપુટ ફાઇલનું ગુમ થયેલ નામ\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: XML લેખકને બનાવવાનું નિષ્ફળ\n" diff --git a/trunk/hivex/po/hi.po b/trunk/hivex/po/hi.po deleted file mode 100644 index e9b438f..0000000 --- a/trunk/hivex/po/hi.po +++ /dev/null @@ -1,175 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Hindi \n" -"Language: hi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: नोड %zu के जनक को पाने में त्रुटि\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: नोड %zx के नोड नाम को पाने में त्रुटि\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: आपको जरूर एक पहले हाइव फाइल को 'load hivefile' के प्रयोग के पहले लोड करना " -"चाहिए\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "hivexsh: अज्ञात कमांड '%s', 'help' को मदद सारांश के लिए उपयोग करें\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: किसी हाइव फाइल नाम लोड करने के लिए है\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: '%s' कमांड को दिए तर्क में नहीं देना चाहिए\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: subkey '%s' not found\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"हाइव कुंजी से होकर संचरित करें 'cd' कमांड के उपयोग से, जैसे कि\n" -"यह एक फाइलसिस्टम समाहित करता है, और 'ls' का उपयोग मौजूदा कुंजी के\n" -"उपकुंजी की सूती के लिए करें. hivexsh(1) मैनुअल पेज में पूर्ण दस्तावेजीकरण है.\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: कुंजी नहीं मिला\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: अवैध पूर्णांक पैरामीटर (%s ने %d लौटाया)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: परिसर के बाहर पूर्णांक\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: इनपुट का अप्रत्याशित अंत\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): केवल 7 bit ASCII स्ट्रिंग को इनपुट के लिए समर्थन दिया गया " -"है\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: हेक्स स्ट्रिंग के बाद पीछा करता कचड़ा\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: मान स्ट्रिंग को विश्लेषित नहीं कर सका, कृपयाhivexsh(1) का मदद के " -"लिए संदर्भ लें: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: रूट नोड को मिटाया नहीं जा सकता है\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: XML दस्तावेजीकरण लिखने में विफल\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: इनपुट फाइल का अनुपस्थित नाम\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: XML राइटर बनाने में विफल\n" diff --git a/trunk/hivex/po/hivex.pot b/trunk/hivex/po/hivex.pot deleted file mode 100644 index 9f68a0d..0000000 --- a/trunk/hivex/po/hivex.pot +++ /dev/null @@ -1,150 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: hivex 1.3.7\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "" diff --git a/trunk/hivex/po/kn.po b/trunk/hivex/po/kn.po deleted file mode 100644 index a4d81ff..0000000 --- a/trunk/hivex/po/kn.po +++ /dev/null @@ -1,177 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Kannada \n" -"Language: kn\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"hivexsh ಗೆ ಸ್ವಾಗತ, hivex ಎನ್ನುವುದು Windows ರಿಜಿಸ್ಟ್ರಿ ಬೈನರಿ ಕಡತಗಳನ್ನು " -"ಪರಿಶೀಲಿಸುವ \n" -"ಒಂದು ಸಂವಾದಾತ್ಮಕವಾದ ಶೆಲ್ ಆಗಿದೆ.\n" -"\n" -"ಹೀಗೆ ನಮೂದಿಸಿ: ನೆರವಿನ ಸಾರಾಂಶಕ್ಕಾಗಿ 'help' ಎಂದು \n" -" ನಿರ್ಗಮಿಸಲು 'quit ಎಂದು'\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: %zu ನ ಮೂಲ ನೋಡ್ ಅನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ದೋಷ\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: %zu ನ ಮೂಲ ನೋಡ್ ಹೆಸರನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ದೋಷ\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: ನೀವು ಮೊದಲಿಗೆ 'load hivefile' ಅನ್ನು ಬಳಸಿಕೊಂಡು ಒಂದು ಹೈವ್ ಕಡತವನ್ನು ಲೋಡ್ " -"ಮಾಡಬೇಕು\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "hivexsh: ಗೊತ್ತಿಲ್ಲದ ಆಜ್ಞೆ '%s', ನೆರವಿನ ಸಾರಾಂಶಕ್ಕಾಗಿ 'help' ಅನ್ನು ಬಳಸಿ\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: ಲೋಡ್ ಮಾಡಲು ಯಾವುದೆ ಹೈವ್ ಕಡತದ ಹೆಸರನ್ನು ನೀಡಲಾಗಿಲ್ಲ\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: ಹೈವ್ ಕಡತವನ್ನು ತೆರೆಯಲಾಗಿಲ್ಲ: %s: %m\n" -"\n" -"ಇದು ಒಂದು Windows ಬೈನರಿ ಹೈವ್ ಕಡತವಾಗಿದೆ ಎಂದು ನೀವು ಭಾವಿಸಿದಲ್ಲಿ (ಒಂದು \n" -"regedit *.reg _ಕಡತವಾಗಿಲ್ಲದೆ_ ಇದ್ದಲ್ಲಿ) hivexsh ಆಯ್ಕೆ '-d' ಅನ್ನು ಬಳಸಿಕೊಂಡು \n" -"ಈ ಆಜ್ಞೆಯನ್ನು ಪುನಃ ಚಲಾಯಿಸಿ ಹಾಗು https://bugzilla.redhat.com/ ನಲ್ಲಿ ಒಂದು ದೋಷವನ್ನು\n" -"ವರದಿ ಮಾಡಿ ಮತ್ತು ಸಂಪೂರ್ಣ ಔಟ್‌ಪುಟ್ ಅನ್ನು _ಹಾಗು_ ವಿಫಲಗೊಂಡಂತಹ ಹೈವ್ ಕಡತವನ್ನು ಅದಕ್ಕೆ " -"ಲಗತ್ತಿಸಿ\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: '%s' ಎಂಬ ಆಜ್ಞೆಯೊಂದಿಗೆ ಆರ್ಗುಮೆಂಟ್‌ಗಳನ್ನು ಒದಗಿಸುವಂತಿಲ್ಲ\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ ಮಾರ್ಗದಲ್ಲಿರುವ ಅಕ್ಷರಗಳನ್ನು ಎರಡು ಬಾರಿ ನಮೂದಿಸಲಾಗಿದೆ - ನೀವು ಮಾರ್ಗದ " -"ನಿಯತಾಂಕಗಳನ್ನು ಸರಿಯಾಗಿ ತಪ್ಪಿಸುತ್ತಿದ್ದೀರೆ?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: ಉಪಕೀಲಿ '%s' ಕಂಡುಬಂದಿಲ್ಲ\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"'cd' ಆಜ್ಞೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಹೈವ್‌ನ ಕೀಲಿಗಳು ಒಂದು ಕಡತವ್ಯವಸ್ಥೆಯಲ್ಲಿರುವಂತೆ\n" -"ವೀಕ್ಷಿಸಿ ಪ್ರಸಕ್ತ ಕೀಲಿಯ ಉಪಕೀಲಿಗಳ ಪಟ್ಟಿಯನ್ನು ನೋಡಲು 'ls' ಅನ್ನು ಬಳಸಿ.\n" -"ಸಂಪೂರ್ಣ ದಸ್ತಾವೇಜು hivexsh(1) ಮಾರ್ಗದರ್ಶಿ ಪುಟದಲ್ಲಿದೆ.\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: ಕೀಲಿಯು ಕಂಡುಬಂದಿಲ್ಲ\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: ಅಮಾನ್ಯವಾದ ಪೂರ್ಣ ನಿಯತಾಂಕ (%s ಮರಳಿಸಲಾಗಿದೆ %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: ಪೂರ್ಣಾಂಕವು ವ್ಯಾಪ್ತಿಯ ಹೊರಗಿದೆ\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: ಇನ್‌ಪುಟ್‌ಗೆ ಅನಿರೀಕ್ಷಿತವಾದ ಅಂತ್ಯ\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): ಇನ್‌ಪುಟ್‌ನಲ್ಲಿ ಕೇವಲ 7 ಬಿಟ್‌ ASCII ವಾಕ್ಯಗಳನ್ನು ಮಾತ್ರ " -"ಬೆಂಬಲಿಸಲಾಗುತ್ತದೆ\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: ಹೆಕ್ಸ್ ವಾಕ್ಯದ ನಂತರ ಹಿಂಬಾಲಿಸುವ ಗಾರ್ಬೇಜ್\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: ಮೌಲ್ಯದ ವಾಕ್ಯವನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ, ದಯವಿಟ್ಟು ನೆರವಿಗಾಗಿ " -"hivexsh(1) ಅನ್ನು ನೋಡಿ: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: ಮೂಲ ನೋಡ್ ಅನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: XML ದಸ್ತಾವೇಜನ್ನು ಬರೆಯುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: ಇನ್‌ಪುಟ್ ಕಡತದ ಹೆಸರು ಕಾಣಿಸುತ್ತಿಲ್ಲ\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: XML ಬರಹಗಾರನನ್ನು ರಚಿಸಲು ವಿಫಲಗೊಂಡಿದೆ\n" diff --git a/trunk/hivex/po/ml.po b/trunk/hivex/po/ml.po deleted file mode 100644 index 09a14f8..0000000 --- a/trunk/hivex/po/ml.po +++ /dev/null @@ -1,150 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Malayalam \n" -"Language: ml\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: അസാധുവായ ഇന്റിജര്‍ പരാമീറ്റര്‍ (%s %d തിരികെ നല്‍കിയിരിക്കുന്നു)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: ഇന്റിജര്‍ പരിധികഴിഞ്ഞിരിക്കുന്നു\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "" diff --git a/trunk/hivex/po/mr.po b/trunk/hivex/po/mr.po deleted file mode 100644 index a4d2ac0..0000000 --- a/trunk/hivex/po/mr.po +++ /dev/null @@ -1,174 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: sandeeps \n" -"Language-Team: Marathi \n" -"Language: mr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"hivexsh येथे आपले स्वागत, hivex हे \n" -"Windows Registry बाइनरी hive फाइल्सचे विश्लेषण करण्यासाठी परस्पर संवाद शेल आहे.\n" -"\n" -"टाइप: मदत सारांशकरीता 'help' टाइप करा \n" -" शेल पासून बाहेर पडण्यासाठी 'quit'\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: नोड %zu चे पॅरेंट प्राप्त करतेवेळी त्रुटी आढळली\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: नोड %zx चे नोड नाव प्राप्त करतेवेळी त्रुटी आढळली\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: 'load hivefile' चा वापर करून तुम्ही hive फाइल प्रथम लोड करायला हवे\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "hivexsh: अपरिचीत आदेश '%s', मदत सारांशकरीता 'help' चा वापर करा\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: लोडकरीता hive फाइल नाव दिले नाही\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: hive फाइल उघडण्यास अपयशी: %s: %m\n" -"\n" -"ही फाइल वैध Windows बाइनरी hive पाइल (_not_\n" -"a regedit *.reg file) असल्यास कृपया \n" -"hivexsh पर्याय '-d' चा वापर करून हे आदेश पुनः चालवा व संपूर्ण आऊटपुट _and_ अपयशी hive " -"फाइल\n" -" https://bugzilla.redhat.com/ येथील बग अहवालात जोडा\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: '%s' आदेश यांस घटके देऊ नका\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ मार्गातील अक्षरे दुप्पट केले आहेत - तुम्ही मार्ग संबंधीत घटक योग्यप्रकारे एस्केप " -"करत आहात?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: सबकि '%s' आढळली नाही\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"'cd' आदेशचा वापर करून हाइव्हच्या किज अंतर्गत, फाइलप्रणाली प्रमाणेच, संचारन करा, \n" -"व सध्याच्या कि मधील सबकिजच्या सूची करीता 'ls'\n" -"याचा वापर करा. संपूर्ण दस्तऐवजीकरण hivexsh(1) मॅन्यूअल पृष्ठात आहे.\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: कि आढळली नाही\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: अवैध इंटीजर घटक (%s ने %d पाठवले)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: इंटीजर व्याप्तीच्या बाहेर आहे\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: इंपुटची अनेपक्षीत समाप्ति\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): फक्त 7 बिट ASCII अक्षरमाळा इंपुटकरीता समर्थीत आहे\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: hex स्ट्रिंग नंतर ट्रेलिंग गार्बेज\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: वॅल्यू स्ट्रिंग वाचणे अशक्य, कृपया मदतीसाठी man page hivexsh(1) पहा: " -"%s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: रूट नोड नष्ट करणे शक्य आहे\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: XML दस्तऐवज लिहण्यास अपयशी\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: इंपुट फाइलचे नाव आढळले नाही\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: XML राईटर निर्माण करण्यास अपयशी\n" diff --git a/trunk/hivex/po/nl.po b/trunk/hivex/po/nl.po deleted file mode 100644 index 794e188..0000000 --- a/trunk/hivex/po/nl.po +++ /dev/null @@ -1,175 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Dutch <>\n" -"Language: nl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Welkom bij hivexsh, de hivex interactieve shell voor het bekijken van\n" -"Windows Registry binaire hive bestanden.\n" -"\n" -"Type: 'help' voor een hulp samenvatting\n" -" 'quit' om de shell te verlaten\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: fout bij het verkrijgen van ouder van node %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: fout bij het verkrijgen van naam van node %zu\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "hivexsh: je moet eerst een hive bestand laden met 'load hivefile'\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" -"hivexsh: onbekend commando '%s', gebruik 'help' voor een hulp samenvatting\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: er werd geen bestandsnaam opgegeven om te laden\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: openen van hive bestand %s mislukte: %m\n" -"\n" -"Als je denkt dat dit een geldig Windows binair hive bestand is (_niet_\n" -"een regedit *.reg bestand) draai dan dit commando opnieuw met de\n" -"hivexsh optie '-d' en voeg de complete output _en_ het hive bestand\n" -"dat faalt toe aan een bug rapport op https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: '%s' commando moet geen argumenten krijgen\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ karakters in pad zijn verdubbeld - weet je zeker dat de pad " -"parameter correct met escape voorzien is?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: sub-sleutel '%s' niet gevonden\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Navigeer door de sleutels van hive met het 'cd' commando, alsof het\n" -"een bestandssysteem bevat, en gebruik 'ls' om de sub-sleutels van de " -"huidige\n" -"sleutel te tonen. Volledige documentatie is in de hivexsh(1) manual pagina.\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: sleitel niet gevonden\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: ongeldige integer parameter (%s gaf %d terug)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: integer ligt buiten de reeks\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: onverwacht einde van input\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): als input worden slechts 7 bits ASCII tekenreeksen " -"ondersteund\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: onnodige input na de hex tekenreeks\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: kan waarde van tekenreeks niet ontleden, refereer naar de " -"manual pagina hivexsh(1) voor hulp: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: de root node kan niet verwijderd worden\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: het schrijven van XML document mislukte\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: naam van input bestand ontbreekt\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: aanmaken van XML schrijver mislukte\n" diff --git a/trunk/hivex/po/or.po b/trunk/hivex/po/or.po deleted file mode 100644 index 7c5f8ef..0000000 --- a/trunk/hivex/po/or.po +++ /dev/null @@ -1,150 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Oriya \n" -"Language: or\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: ଅବୈଧ ଗଣନ ସଂଖ୍ୟା ପ୍ରାଚଳ (%s ଫେରାଇଥାଏ %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: ଗଣନସଂଖ୍ୟାଟି ପରିସର ବାହାରେ\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "" diff --git a/trunk/hivex/po/pl.po b/trunk/hivex/po/pl.po deleted file mode 100644 index b2bf5a1..0000000 --- a/trunk/hivex/po/pl.po +++ /dev/null @@ -1,177 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Polish \n" -"Language: pl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Witaj w hivexsh, interaktywnej powłoce hivex do sprawdzania\n" -"binarnych plików typu \"hive\" Rejestru systemu Windows.\n" -"\n" -"Proszę podać: \"help\", aby uzyskać podsumowanie pomocy\n" -" \"quit\", aby zakończyć powłokę\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: błąd podczas uzyskiwania nadrzędnego węzła %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: błąd podczas uzyskiwania nazwy węzła %zx\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: należy najpierw wczytać plik \"hive\" używając \"load plik_hive\"\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" -"hivexsh: nieznane polecenie \"%s\", należy użyć \"help\", aby uzyskać " -"podsumowanie pomocy\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: nie podano nazwy pliku \"hive\" do wczytania\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: otwarcie pliku \"hive\" nie powiodło się: %s: %m\n" -"\n" -"Jeśli ten plik jest binarnym plikiem \"hive\" systemu Windows (a _nie_\n" -"plikiem *.reg programu regedit), proszę wykonać te polecenie ponownie,\n" -"używając opcji \"-d\" programu hivexsh i dołączyć pełne wyjście _oraz_ ten\n" -"plik \"hive\" do zgłoszenia błędu na https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: polecenie \"%s\" nie przyjmuje parametrów\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: znaki \\ w ścieżce są podwójne - czy parametr ścieżki jest poprawnie " -"poprzedzony znakiem modyfikacji?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: nie odnaleziono podklucza \"%s\"\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Należy nawigować między kluczami \"hive\" używając polecenia \"cd\", jakby\n" -"zawierały system plików oraz \"ls\" do wyświetlania podkluczy bieżącego\n" -"klucza. Pełna dokumentacja znajduje się na stronie podręcznika hivexsh(1).\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: nie odnaleziono klucza\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: nieprawidłowy parametr liczby całkowitej (%s zwróciło %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: liczba całkowita spoza zakresu\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: nieoczekiwany koniec wejścia\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): tylko 7 bitowe ciągi ASCII są obsługiwane dla " -"wejścia\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: uszkodzone wartości po ciągu ósemkowym\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: nie można przetworzyć ciągu wartości. Proszę zobaczyć " -"stronę podręcznika hivexsh(1), aby uzyskać pomoc: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: główny węzeł nie może zostać usunięty\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: zapisanie dokumentu XML nie powiodło się\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: brak nazwy pliku wejściowego\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: utworzenie zapisu XML nie powiodło się\n" diff --git a/trunk/hivex/po/pt_BR.po b/trunk/hivex/po/pt_BR.po deleted file mode 100644 index fa74238..0000000 --- a/trunk/hivex/po/pt_BR.po +++ /dev/null @@ -1,179 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-23 17:07+0000\n" -"Last-Translator: Taylon \n" -"Language-Team: Portuguese (Brazilian) \n" -"Language: pt_BR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Bem-vindo ao hivexsh, o shell interativo hivex usado para examinar\n" -"arquivos hive de registros binários do Windows.\n" -"\n" -"Digite: 'help' para o sumário de ajuda\n" -" 'quit' para sair do shell\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: erro ao obter a herança do nó %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: erro ao obter o nome do nó %zx\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: você deve carregar um arquivo hive antes de usar 'load hivefile'\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" -"hivexsh: comando desconhecido '%s', use 'help' para ver o sumário de ajuda\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "" -"hivexsh: carregar: não foi dado nenhum nome de arquivo hive para ser " -"carregado\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: falha ao abrir o arquivo hive: %s: %m\n" -"\n" -"Se você acha que esse é um arquivo hive válido (e _não_\n" -"um arquivo do regedit *.reg) então por favor, execute esse comando novamente " -"usando a\n" -"opção '-d' do hivexsh e anexe a saída completa _e_ o arquivo hive\n" -"que causou o erro em um relato de bug em https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: argumentos não devem ser dados ao comando '%s'\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: os caracteres \\ no caminho estão duplicados - você está escapando o " -"parâmetro do caminho corretamente?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: subchave '%s' não encontrada\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Navegar pelas chaves do arquivo hive usando o comando 'cd' como se ele\n" -"estivesse em um sistema de arquivos, e usar 'ls' para listar as subchaves " -"da\n" -"chave atual. A documentação completa está na página de manual hivexsh(1).\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: chave não encontrada\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: parâmetro inteiro inválido (%s retornou %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: inteiro fora do limite\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: fim da entrada inesperado\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): na entrada, apenas strings ASCII 7 bit são " -"suportadas\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: não foi possível analisar o valor da string, por favor, " -"consulte a página de manual hivexsh(1) para obter ajuda: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: o nó raiz não pode ser deletado\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: falha ao escrever o documento XML\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: faltando o nome do arquivo de entrada\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: falha ao criar o escritor de XML\n" diff --git a/trunk/hivex/po/ru.po b/trunk/hivex/po/ru.po deleted file mode 100644 index 49f3412..0000000 --- a/trunk/hivex/po/ru.po +++ /dev/null @@ -1,178 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: rjones \n" -"Language-Team: Russian \n" -"Language: ru\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Добро пожаловать в hivexsh — интерактивную оболочку для\n" -"анализа двоичных файлов куста реестра Windows.\n" -"\n" -"Введите «help» для получения помощи, \n" -" «quit» для выхода из оболочки\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: ошибка получения родительского узла для %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: ошибка получения имени узла для %zx\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: сначала необходимо загрузить файл с помощью команды «load " -"hivefile»\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" -"hivexsh: неизвестная команда «%s». Выполните «help» для получения помощи\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: не задан файл для загрузки\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: не удалось открыть файл %s: %m\n" -"\n" -"Если вы уверены, что этот файл является двоичным файлом куста Windows\n" -"(НЕ файл *.reg), повторно выполните команду с опцией «-d»\n" -"и включите её вывод и сам файл куста в отчёт Bugzilla:\n" -"https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: не передавайте аргументы команде «%s»\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: \\ символы в пути повторяются. Проверьте правильность управляющей " -"последовательности.\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: подраздел «%s» не найден\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Переход между разделами куста осуществляется с помощью команды «cd»,\n" -"аналогично навигации в файловой системе.\n" -"«ls» позволяет просмотреть список подразделов.\n" -"Подробную информацию можно найти на странице помощи hivexsh(1).\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: раздел не найден\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: недопустимое целое значение параметра (%s вернул %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: целое значение выходит за пределы диапазона\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: непредвиденный конец ввода\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): при вводе поддерживаются только 7-битные строки " -"ASCII\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: мусор в конце шестнадцатеричной строки\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: не удалось разобрать значение. Обратитесь к странице помощи " -"hivexsh(1): %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: невозможно удалить корневой элемент\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: не удалось записать XML\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: отсутствует имя входного файла\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: не удалось создать модуль записи XML\n" diff --git a/trunk/hivex/po/uk.po b/trunk/hivex/po/uk.po deleted file mode 100644 index 6231947..0000000 --- a/trunk/hivex/po/uk.po +++ /dev/null @@ -1,180 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-22 15:29+0000\n" -"Last-Translator: yurchor \n" -"Language-Team: Ukrainian \n" -"Language: uk\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"Ласкаво просимо до hivexsh, інтерактивної оболонки hivex для вивчення\n" -"бінарних файлів гілок регістру Windows.\n" -"\n" -"Введіть: «help», щоб переглянути довідку\n" -" «quit», щоб вийти з оболонки\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh: помилка під час отримання батьківського елемента вузла %zu\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh: помилка під час спроби отримання назви вузла %zx\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "" -"hivexsh: вам слід спочатку завантажити файл гілки за допомогою команди «load " -"hivefile»\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "" -"hivexsh: невідома команда «%s», скористайтеся командою «help», щоб " -"переглянути довідку щодо команд\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: load: у команді load не вказано назви файла гілки\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: не вдалося відкрити файл гілки: %s: %m\n" -"\n" -"Якщо ви певні, що цей файл є коректним бінарним файлом гілки Windows (_не_\n" -"файлом *.reg regedit), повторіть запуск команди з використанням параметра\n" -"hivexsh «-d», і долучіть виведені дані _та_ файл гілки, який призвів до\n" -"помилки, до звіту щодо вади на https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: команді «%s» не потрібно передавати жодних аргументів\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "" -"%s: %s: символи \\ у визначенні адреси здубльовано. Чи правильно екрановано " -"параметр адреси?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: не знайдено підключа «%s»\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"Перехід між ключами гілки можна здійснювати за допомогою команди «cd»,\n" -"подібно до переходу теками файлової системи, за допомогою «ls»\n" -"можна отримувати список підключів поточного ключа. З повною документацією\n" -"можна ознайомитися за допомогою сторінки підручника (man) hivexsh(1).\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: ключ не знайдено\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: некоректний цілий параметр (%s повернуто %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: ціле значення поза межами діапазону\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: неочікуване завершення вхідних даних\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "" -"hivexsh: string(utf16le): передбачено підтримку введення лише 7-бітових " -"рядків ASCII\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "" -"hivexsh: setval: помилкові кінцеві символи після шістнадцяткового рядка\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: не вдалося обробити рядок значення, будь ласка, зверніться " -"до сторінки man hivexsh(1), щоб дізнатися більше: %s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: не можна вилучати кореневий вузол\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: не вдалося виконати запис документа XML\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: не вказано назви файла вхідних даних\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: не вдалося створити процес запису XML\n" diff --git a/trunk/hivex/po/zh_CN.po b/trunk/hivex/po/zh_CN.po deleted file mode 100644 index ed58a99..0000000 --- a/trunk/hivex/po/zh_CN.po +++ /dev/null @@ -1,168 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: hivex\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-11 12:43+0100\n" -"PO-Revision-Date: 2011-03-26 15:06+0000\n" -"Last-Translator: lovenemesis \n" -"Language-Team: Chinese (China) \n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0\n" - -#: sh/hivexsh.c:156 -#, c-format -msgid "" -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n" -msgstr "" -"\n" -"欢迎使用 hivexsh, Windows 注册表二进制 hive \n" -"文件交互式命令行程序。\n" -"\n" -"输入: 'help' 来获得简略帮助\n" -" 'quit' 来退出命令行\n" -"\n" - -#: sh/hivexsh.c:270 -#, c-format -msgid "hivexsh: error getting parent of node %zu\n" -msgstr "hivexsh:获取父节点 %zu 错误\n" - -#: sh/hivexsh.c:280 -#, c-format -msgid "hivexsh: error getting node name of node %zx\n" -msgstr "hivexsh:获取节点 %zx 名称错误\n" - -#: sh/hivexsh.c:419 -#, c-format -msgid "hivexsh: you must load a hive file first using 'load hivefile'\n" -msgstr "hivexsh: 您必须首先使用 'load hivefile' 来载入一个 hive 文件\n" - -#: sh/hivexsh.c:440 -#, c-format -msgid "hivexsh: unknown command '%s', use 'help' for help summary\n" -msgstr "hivexsh: 未知的命令 '%s',使用 'help' 来获得简略帮助\n" - -#: sh/hivexsh.c:450 -#, c-format -msgid "hivexsh: load: no hive file name given to load\n" -msgstr "hivexsh: 载入: 指定的 hive 文件不存在\n" - -#: sh/hivexsh.c:466 -#, c-format -msgid "" -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n" -msgstr "" -"hivexsh: 打开 hive 文件失败: %s: %m\n" -"\n" -"如果您认为该文件确实是有效的 Windows 二进制 hive 文件(_不是_\n" -"注册表 *.reg 文件) 那么请再次使用 '-d' 选项运行\n" -"hivexsh 并将完整的输出_和_失败的hive文件做为错误报告\n" -"的附件,提交至 https://bugzilla.redhat.com/\n" -"\n" - -#: sh/hivexsh.c:499 sh/hivexsh.c:608 sh/hivexsh.c:1074 -#, c-format -msgid "hivexsh: '%s' command should not be given arguments\n" -msgstr "hivexsh: '%s' 命令不应该包含任何参数\n" - -#: sh/hivexsh.c:541 -#, c-format -msgid "" -"%s: %s: \\ characters in path are doubled - are you escaping the path " -"parameter correctly?\n" -msgstr "%s: %s: \\ 字符在路径中出现两次 - 您正确换码了路径参数吗?\n" - -#: sh/hivexsh.c:579 -#, c-format -msgid "hivexsh: cd: subkey '%s' not found\n" -msgstr "hivexsh: cd: 子键 '%s' 未找到\n" - -#: sh/hivexsh.c:597 -#, c-format -msgid "" -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n" -msgstr "" -"使用 'cd' 命令在 hive 键之间跳转,如同它\n" -"包含了文件系统一样,并使用 'ls' 来列出当前键之下的子键。\n" -" 完整的说明位于 hivexsh(1) 手册中。\n" - -#: sh/hivexsh.c:672 -#, c-format -msgid "%s: %s: key not found\n" -msgstr "%s: %s: 键未找到\n" - -#: sh/hivexsh.c:848 sh/hivexsh.c:952 sh/hivexsh.c:978 sh/hivexsh.c:1007 -#, c-format -msgid "%s: %s: invalid integer parameter (%s returned %d)\n" -msgstr "%s: %s: 非法的整数参数 (%s 返回 %d)\n" - -#: sh/hivexsh.c:853 sh/hivexsh.c:958 sh/hivexsh.c:984 sh/hivexsh.c:1013 -#, c-format -msgid "%s: %s: integer out of range\n" -msgstr "%s: %s: 超出范围的整数\n" - -#: sh/hivexsh.c:875 sh/hivexsh.c:893 -#, c-format -msgid "hivexsh: setval: unexpected end of input\n" -msgstr "hivexsh: setval: 输入意外结束\n" - -#: sh/hivexsh.c:914 sh/hivexsh.c:933 -#, c-format -msgid "" -"hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n" -msgstr "hivexsh: string(utf16le): 仅支持输入 7 bit ASCII 字符串\n" - -#: sh/hivexsh.c:1044 -#, c-format -msgid "hivexsh: setval: trailing garbage after hex string\n" -msgstr "hivexsh: setval: 十六进制字符串后包含无用的结尾\n" - -#: sh/hivexsh.c:1051 -#, c-format -msgid "" -"hivexsh: setval: cannot parse value string, please refer to the man page " -"hivexsh(1) for help: %s\n" -msgstr "" -"hivexsh: setval: 不能解析值域字符串,请参阅手册页 hivexsh(1) 以获得帮助:%s\n" - -#: sh/hivexsh.c:1080 -#, c-format -msgid "hivexsh: del: the root node cannot be deleted\n" -msgstr "hivexsh: del: 不能删除根节点\n" - -#: xml/hivexml.c:80 -#, c-format -msgid "%s: failed to write XML document\n" -msgstr "%s: 写入 XML 文档失败\n" - -#: xml/hivexml.c:113 -#, c-format -msgid "hivexml: missing name of input file\n" -msgstr "hivexml: 缺少输入文件名\n" - -#: xml/hivexml.c:132 -#, c-format -msgid "xmlNewTextWriterFilename: failed to create XML writer\n" -msgstr "xmlNewTextWriterFilename: 创建 XML 写入器失败\n" diff --git a/trunk/hivex/python/Makefile.am b/trunk/hivex/python/Makefile.am deleted file mode 100644 index 034f9c7..0000000 --- a/trunk/hivex/python/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -# hivex Python 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. - -# Old RHEL 5 autoconf doesn't have builddir. -builddir ?= $(top_builddir)/python - -EXTRA_DIST = \ - run-python-tests \ - hivex.py \ - hivex-py.c \ - t/*.py - -if HAVE_PYTHON - -pythondir = $(PYTHON_INSTALLDIR) - -python_DATA = hivex.py - -python_LTLIBRARIES = libhivexmod.la - -libhivexmod_la_SOURCES = hivex-py.c -libhivexmod_la_CFLAGS = -Wall $(PYTHON_CFLAGS) \ - -I$(top_srcdir)/lib -I$(top_builddir)/lib -libhivexmod_la_LIBADD = $(top_builddir)/lib/libhivex.la -libhivexmod_la_LDFLAGS = -avoid-version -shared -module -shrext $(PYTHON_EXT_SUFFIX) - -TESTS_ENVIRONMENT = \ - PYTHONPATH=$(builddir):$(builddir)/.libs - -TESTS = run-python-tests - -CLEANFILES = hivex.pyc - -endif diff --git a/trunk/hivex/python/run-python-tests.in b/trunk/hivex/python/run-python-tests.in deleted file mode 100755 index 70e8165..0000000 --- a/trunk/hivex/python/run-python-tests.in +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -# hivex Python bindings -# 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. - -set -e -shopt -s nullglob - -for f in @srcdir@t/*.py; do - basename "$f" - @PYTHON@ "$f" -done diff --git a/trunk/hivex/python/t/010-import.py b/trunk/hivex/python/t/010-import.py deleted file mode 100644 index 9979914..0000000 --- a/trunk/hivex/python/t/010-import.py +++ /dev/null @@ -1,18 +0,0 @@ -# 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. - -import hivex diff --git a/trunk/hivex/python/t/020-open.py b/trunk/hivex/python/t/020-open.py deleted file mode 100644 index 57339a7..0000000 --- a/trunk/hivex/python/t/020-open.py +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -import os -import hivex - -srcdir = os.environ["srcdir"] -if not srcdir: - srcdir = "." - -h = hivex.Hivex ("%s/../images/minimal" % srcdir) -assert h diff --git a/trunk/hivex/python/t/021-close.py b/trunk/hivex/python/t/021-close.py deleted file mode 100644 index 876836d..0000000 --- a/trunk/hivex/python/t/021-close.py +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -import os -import hivex - -srcdir = os.environ["srcdir"] -if not srcdir: - srcdir = "." - -h = hivex.Hivex ("%s/../images/minimal" % srcdir) -assert h - -del h diff --git a/trunk/hivex/python/t/120-rlenvalue.py b/trunk/hivex/python/t/120-rlenvalue.py deleted file mode 100644 index ebc48f5..0000000 --- a/trunk/hivex/python/t/120-rlenvalue.py +++ /dev/null @@ -1,42 +0,0 @@ -# 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 diff --git a/trunk/hivex/python/t/200-write.py b/trunk/hivex/python/t/200-write.py deleted file mode 100644 index 0692f11..0000000 --- a/trunk/hivex/python/t/200-write.py +++ /dev/null @@ -1,43 +0,0 @@ -# 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. - -import os -import hivex - -srcdir = os.environ["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, "A") - -h.node_add_child (root, "B") - -b = h.node_get_child (root, "B") -assert b - -values = [ - { "key": "Key1", "t": 3, "value": "ABC" }, - { "key": "Key2", "t": 3, "value": "DEF" } -] -h.node_set_values (b, values) diff --git a/trunk/hivex/python/t/210-setvalue.py b/trunk/hivex/python/t/210-setvalue.py deleted file mode 100644 index 9d93519..0000000 --- a/trunk/hivex/python/t/210-setvalue.py +++ /dev/null @@ -1,66 +0,0 @@ -# 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. - -import sys -import os -import hivex - -srcdir = os.environ["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, "B") - -b = h.node_get_child (root, "B") -assert b - -values = [ - { "key": "Key1", "t": 3, "value": "ABC" }, - { "key": "Key2", "t": 3, "value": "DEF" } -] -h.node_set_values (b, values) - -value1 = { "key": "Key3", "t": 3, "value": "GHI" } -h.node_set_value (b, value1) - -value1 = { "key": "Key1", "t": 3, "value": "JKL" } -h.node_set_value (b, value1) - -# In Python2, the data is returned as a string. In Python3, it is -# returned as bytes. Provide a function to convert either to a string. -def to_string (data): - if sys.version_info[0] == 2: - return data - else: - return str (data, "utf-8") - -val = h.node_get_value (b, "Key1") -t_data = h.value_value (val) -assert t_data[0] == 3 -assert to_string (t_data[1]) == "JKL" - -val = h.node_get_value (b, "Key3") -t_data = h.value_value (val) -assert t_data[0] == 3 -assert to_string (t_data[1]) == "GHI" diff --git a/trunk/hivex/regedit/Makefile.am b/trunk/hivex/regedit/Makefile.am deleted file mode 100644 index 4353ee8..0000000 --- a/trunk/hivex/regedit/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -# hivex -# 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. - -EXTRA_DIST = \ - hivexregedit \ - run-locally - -bin_SCRIPTS = hivexregedit - -man_MANS = hivexregedit.1 - -hivexregedit.1: hivexregedit - $(POD2MAN) \ - --section 1 \ - -c "Windows Registry" \ - --name "hivexregedit" \ - --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ - $< > $@-t; mv $@-t $@ - -noinst_DATA = \ - $(top_builddir)/html/hivexregedit.1.html - -$(top_builddir)/html/hivexregedit.1.html: hivexregedit - mkdir -p $(top_builddir)/html - cd $(top_builddir) && pod2html \ - --css 'pod.css' \ - --htmldir html \ - --outfile html/hivexregedit.1.html \ - regedit/hivexregedit - -CLEANFILES = $(man_MANS) diff --git a/trunk/hivex/regedit/hivexregedit b/trunk/hivex/regedit/hivexregedit deleted file mode 100755 index 0e534de..0000000 --- a/trunk/hivex/regedit/hivexregedit +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/perl -w -# Copyright (C) 2010-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. - -use warnings; -use strict; - -use Win::Hivex; -use Win::Hivex::Regedit qw(reg_import reg_export); - -use Pod::Usage; -use Getopt::Long; - -=encoding utf8 - -=head1 NAME - -hivexregedit - Merge and export Registry changes from regedit-format files. - -=head1 SYNOPSIS - - hivexregedit --merge [--prefix prefix] [--encoding enc] \ - hivefile [regfile] - - hivexregedit --export [--prefix prefix] hivefile key > regfile - -=head1 DESCRIPTION - -Please note hivexregedit is a low-level tool for manipulating hive -files directly. To merge or export registry changes to Windows -virtual machines it's better to use L. - -Given a local binary ("hive") file, there are two modes. C<--merge> -imports (merges) changes from a regedit-format file into the hive. It -is similar to using the C switch in Windows regedit.exe. - -C<--export> exports a Registry key (recursively) into the regedit format. - -=head2 ENCODING - -C expects that regedit files have already been re-encoded -in the local encoding. Usually on Linux hosts, this means UTF-8 with -Unix-style line endings. Since Windows regedit files are often in -UTF-16LE with Windows-style line endings, you may need to re-encode the -whole file before or after processing. - -To re-encode a file from Windows format to Linux (before processing it -with the C<--merge> option), you would do something like this: - - iconv -f utf-16le -t utf-8 < win.reg | dos2unix > linux.reg - -To go in the opposite direction, after using C<--export> and before -sending the file to a Windows user, do something like this: - - unix2dos < linux.reg | iconv -f utf-8 -t utf-16le > win.reg - -For more information about encoding, see L. - -If you are unsure about the current encoding, use the L -command. Recent versions of Windows regedit.exe produce a UTF-16LE -file with Windows-style (CRLF) line endings, like this: - - $ file software.reg - software.reg: Little-endian UTF-16 Unicode text, with very long lines, - with CRLF line terminators - -This file would need conversion before you could C<--merge> it. - -=head2 SHELL QUOTING - -Be careful when passing parameters containing C<\> (backslash) in the -shell. Usually you will have to use 'single quotes' or double -backslashes (but not both) to protect them from the shell. - -=head2 CurrentControlSet etc. - -Registry keys like C don't really exist in the -Windows Registry at the level of the hive file, and therefore you -cannot modify these. - -C is usually an alias for C. In -some circumstances it might refer to another control set. The way -to find out is to look at the C key: - - $ hivexregedit --export SYSTEM '\Select' - [\Select] - "Current"=dword:00000001 - "Default"=dword:00000001 - "Failed"=dword:00000000 - "LastKnownGood"=dword:00000002 - -"Current" is the one which Windows will choose when it boots. - -Similarly, other C keys in the path may need to -be replaced. - -=head1 EXAMPLE - - $ virt-cat WindowsGuest /Windows/System32/config/software > software.hive - $ hivexregedit --export \ - --prefix 'HKEY_LOCAL_MACHINE\SOFTWARE' \ - software.hive '\Microsoft' > ms-keys.reg - - $ hivexregedit --merge system.hive \ - --prefix 'HKEY_LOCAL_MACHINE\SYSTEM' additions.reg - -=head1 OPTIONS - -=over 4 - -=cut - -my $help; - -=item B<--help> - -Display help. - -=cut - -my $debug; - -=item B<--debug> - -Enable debugging in the hivex library. This is useful for diagnosing -bugs and also malformed hive files. - -=cut - -my $merge; - -=item B<--merge> - - hivexregedit --merge [--prefix prefix] [--encoding enc] \ - hivefile [regfile] - -Merge C (a regedit-format text file) into the hive -C. If C is omitted, then the program reads from -standard input. (Also you can give multiple input files). - -C<--prefix> specifies the Windows Registry prefix. It is almost -always necessary to use this when dealing with real hive files. - -C<--encoding> specifies the encoding for unmarked strings in the -input. It defaults to C which should work for recent -versions of Windows. Another possibility is to use C. - -=cut - -my $export; - -=item B<--export> - - hivexregedit --export [--prefix prefix] hivefile key > regfile - -C is a path within the hive C. (The key should not -contain any prefix and should be quoted to defend backslashes from the -shell). The key is exported, recursively, to standard output in the -textual regedit format. - -C<--prefix> specifies the Windows Registry prefix. It is almost -always necessary to use this when dealing with real hive files. - -=cut - -my $prefix; - -=item B<--prefix> prefix - -Hive files and Windows Registry key names are indirectly related. For -example, inside the software hive, all keys are stored relative to -C. Thus -C appears in the hive file as -C<\Microsoft>. - -The hive format itself does not store this prefix, so you have to -supply it based on outside knowledge. (L, amongst -other things, already knows about this). - -Usually it is sufficient to pass the parameter -C<--prefix 'HKEY_LOCAL_MACHINE\SOFTWARE'> or similar when doing -merges and exports. - -=cut - -my $encoding; - -=item B<--encoding> UTF-16LE|ASCII - -When merging (only), you may need to specify the encoding for strings -to be used in the hive file. This is explained in detail in -L. - -The default is to use UTF-16LE, which should work with recent versions -of Windows. - -=cut - -my $unsafe_printable_strings; - -=item B<--unsafe-printable-strings> - -When exporting (only), assume strings are UTF-16LE and print them as -strings instead of hex sequences. Remove the final zero codepoint -from strings if present. - -This is unsafe and does not preserve the fidelity of strings in the -original hive for various reasons: - -=over 4 - -=item * - -Assumes the original encoding is UTF-16LE. ASCII strings and strings -in other encodings will be corrupted by this transformation. - -=item * - -Assumes that everything which has type 1 or 2 is really a string -and that everything else is not a string, but the type field in -real hives is not reliable. - -=item * - -Loses information about whether a zero codepoint followed the string -in the hive or not. - -=back - -This all happens because the hive itself contains no information about -how strings are encoded (see -L). - -You should only use this option for quick hacking and debugging of the -hive contents, and I use it if the output is going to be passed -into another program or stored in another hive. - -=back - -=cut - -GetOptions ("help|?" => \$help, - "debug" => \$debug, - "merge|import" => \$merge, - "export" => \$export, - "prefix=s" => \$prefix, - "encoding=s" => \$encoding, - "unsafe-printable-strings" => \$unsafe_printable_strings, - ) or pod2usage (2); -pod2usage (1) if $help; - -if ($merge && $export) { - die "hivexregedit: cannot use --merge and --export at the same time\n" -} - -unless ($merge || $export) { - die "hivexregedit: use --merge or --export, see the manpage for help\n" -} - -if ($export && defined $encoding) { - die "hivexregedit: --encoding has no effect when used with --export\n" -} - -if ($merge) { # --merge (reg_import) - if (@ARGV < 1) { - die "hivexregedit --merge hivefile [input.reg ...]\n" - } - - my $hivefile = shift @ARGV; - - my $h = Win::Hivex->open ($hivefile, write => 1, debug => $debug); - - # Read from stdin unless other files have been specified. - unshift (@ARGV, '-') unless @ARGV; - - foreach (@ARGV) { - open FILE, $_ or die "$_: $!"; - reg_import (\*FILE, sub { - local $_ = shift; - # Remove prefix from the start of the path, matching - # case insensitively. - if (defined $prefix) { - my $len = length $prefix; - if (length $_ >= $len && - lc (substr ($_, 0, $len)) eq lc ($prefix)) { - $_ = substr ($_, $len); - } - } - ($h, $_) - }); - } - - $h->commit (undef); -} else { # --export (reg_export) - if (@ARGV != 2) { - die "hivexregedit --export hivefile key\n" - } - - my $hivefile = shift @ARGV; - my $key = shift @ARGV; - - my $h = Win::Hivex->open ($hivefile, debug => $debug); - - print "Windows Registry Editor Version 5.00\n\n"; - - reg_export ($h, $key, \*STDOUT, - prefix => $prefix, - unsafe_printable_strings => $unsafe_printable_strings); -} - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L, -L. - -=head1 AUTHOR - -Richard W.M. Jones L - -=head1 COPYRIGHT - -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. diff --git a/trunk/hivex/regedit/run-locally b/trunk/hivex/regedit/run-locally deleted file mode 100755 index 9d9cca9..0000000 --- a/trunk/hivex/regedit/run-locally +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/perl -# Copyright (C) 2009 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. - -# This script sets up the environment so you can run hivexregedit in -# place without needing to do 'make install' first. -# -# Use it like this: -# ./run-locally [usual hivexregedit args ...] -# eg: -# ./run-locally --export software.hive '\Microsoft' - -use strict; -use warnings; - -use File::Basename qw(dirname); -use File::Spec; -use Cwd qw(abs_path); - -my $path = $0; - -# Follow symlinks until we get to the real file -while(-l $path) { - my $link = readlink($path) or die "readlink: $path: $!"; - if(File::Spec->file_name_is_absolute($link)) { - $path = $link; - } else { - $path = File::Spec->catfile(dirname($path), $link); - } -} - -# Get the absolute path of the parent directory -$path = abs_path(dirname($path).'/..'); - -$ENV{LD_LIBRARY_PATH} = $path.'/lib/.libs'; -$ENV{PERL5LIB} = $path.'/perl/blib/lib:'.$path.'/perl/blib/arch'; - -#print (join " ", ("$path/regedit/hivexregedit", @ARGV), "\n"); -exec('perl', "$path/regedit/hivexregedit", @ARGV); diff --git a/trunk/hivex/ruby/Makefile.am b/trunk/hivex/ruby/Makefile.am deleted file mode 100644 index 7e57516..0000000 --- a/trunk/hivex/ruby/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# hivex Ruby bindings -# 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. - -EXTRA_DIST = \ - Rakefile.in \ - README.rdoc \ - doc/site/index.html \ - ext/hivex/extconf.rb \ - ext/hivex/_hivex.c \ - lib/hivex.rb \ - run-ruby-tests \ - tests/tc_*.rb - -CLEANFILES = \ - lib/*~ \ - tests/*~ \ - ext/hivex/*~ \ - ext/hivex/extconf.h \ - ext/hivex/_hivex.o \ - ext/hivex/_hivex.so \ - ext/hivex/mkmf.log \ - ext/hivex/Makefile - -if HAVE_RUBY - -TESTS = run-ruby-tests - -TESTS_ENVIRONMENT = \ - LD_LIBRARY_PATH=$(top_builddir)/src/.libs \ - RUBY=$(RUBY) RAKE=$(RAKE) - -all: - $(RAKE) build - $(RAKE) rdoc - -RUBY_SITELIB := $(shell $(RUBY) -rrbconfig -e "puts RbConfig::CONFIG['sitelibdir']") -RUBY_SITEARCH := $(shell $(RUBY) -rrbconfig -e "puts RbConfig::CONFIG['sitearchdir']") - -install: - $(MKDIR_P) $(DESTDIR)$(RUBY_SITELIB) - $(MKDIR_P) $(DESTDIR)$(RUBY_SITEARCH) - $(INSTALL) -p -m 0644 lib/hivex.rb $(DESTDIR)$(RUBY_SITELIB) - $(INSTALL) -p -m 0755 ext/hivex/_hivex.so $(DESTDIR)$(RUBY_SITEARCH) - -endif diff --git a/trunk/hivex/ruby/README.rdoc b/trunk/hivex/ruby/README.rdoc deleted file mode 100644 index 7965650..0000000 --- a/trunk/hivex/ruby/README.rdoc +++ /dev/null @@ -1,4 +0,0 @@ -= Ruby bindings for hivex - -The module Hivex provides Ruby bindings for -{the hivex API}[http://libguestfs.org/hivex.3.html]. diff --git a/trunk/hivex/ruby/Rakefile.in b/trunk/hivex/ruby/Rakefile.in deleted file mode 100644 index 204e37c..0000000 --- a/trunk/hivex/ruby/Rakefile.in +++ /dev/null @@ -1,129 +0,0 @@ -# hivex Ruby bindings -*- ruby -*- -# @configure_input@ -# 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. - -require 'rake/clean' -require 'rake/testtask' - -# Used to be rake/rdoctask. Now it's rdoc/task. -begin - require 'rdoc/task' -rescue - require 'rake/rdoctask' -end - -# Used to be rake/gempackagetask. Now it's rubygems/package_task. Also -# we need to use the appropriate class name below. -begin - require 'rubygems/package_task' - gempackagetask='Gem::PackageTask' -rescue - require 'rake/gempackagetask' - gempackagetask='Rake::GemPackageTask' -end - -PKG_NAME='@PACKAGE_NAME@' -PKG_VERSION='@PACKAGE_VERSION@' - -EXT_CONF='@abs_srcdir@/ext/hivex/extconf.rb' -MAKEFILE='@builddir@/ext/hivex/Makefile' -HIVEX_MODULE='@builddir@/ext/hivex/_hivex.so' -HIVEX_SRC='@abs_srcdir@/ext/hivex/_hivex.c' - -CLEAN.include [ "@builddir@/ext/**/*.o", HIVEX_MODULE, - "@builddir@/ext/**/depend" ] - -CLOBBER.include [ "@builddir@/config.save", "@builddir@/ext/**/mkmf.log", - MAKEFILE ] - -# 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" - $stderr.puts "Failed to run extconf" - break - end -end -file HIVEX_MODULE => [ MAKEFILE, HIVEX_SRC ] do |t| - Dir::chdir("@builddir@/ext/hivex") do - unless sh "make" - $stderr.puts "make failed" - break - end - end -end -desc "Build the native library" -task :build => HIVEX_MODULE - -Rake::TestTask.new(:test) do |t| - t.test_files = FileList['tests/tc_*.rb'] - t.libs = [ 'lib', 'ext/hivex' ] -end -task :test => :build - -RDOC_FILES = FileList[ - "@srcdir@/README.rdoc", - "@srcdir@/lib/**/*.rb", - "@srcdir@/ext/**/*.[ch]" -] - -Rake::RDocTask.new do |rd| - rd.main = "@srcdir@/README.rdoc" - rd.rdoc_dir = "doc/site/api" - rd.rdoc_files.include(RDOC_FILES) -end - -Rake::RDocTask.new(:ri) do |rd| - rd.main = "@srcdir@/README.rdoc" - rd.rdoc_dir = "doc/ri" - rd.options << "--ri-system" - rd.rdoc_files.include(RDOC_FILES) -end - -# Package tasks - -PKG_FILES = FileList[ - "Rakefile", "COPYING", "README", "NEWS", "@srcdir@/README.rdoc", - "lib/**/*.rb", - "ext/**/*.[ch]", "ext/**/MANIFEST", "ext/**/extconf.rb", - "tests/**/*", - "spec/**/*" -] - -DIST_FILES = FileList[ - "pkg/*.src.rpm", "pkg/*.gem", "pkg/*.zip", "pkg/*.tgz" -] - -SPEC = Gem::Specification.new do |s| - s.name = PKG_NAME - s.version = PKG_VERSION - s.email = "rjones@redhat.com" - s.homepage = "http://libguestfs.org/" - s.summary = "Ruby bindings for hivex" - s.files = PKG_FILES - s.autorequire = "hivex" - s.required_ruby_version = '>= 1.8.1' - s.extensions = "ext/hivex/extconf.rb" - s.description = < -Ruby documentation for hivex - -

- Ruby API documentation for hivex -

- - diff --git a/trunk/hivex/ruby/ext/hivex/extconf.rb b/trunk/hivex/ruby/ext/hivex/extconf.rb deleted file mode 100644 index c144c4b..0000000 --- a/trunk/hivex/ruby/ext/hivex/extconf.rb +++ /dev/null @@ -1,33 +0,0 @@ -# hivex Ruby bindings -*- ruby -*- -# @configure_input@ -# 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. - -require 'mkmf' - -extension_name = '_hivex' - -dir_config(extension_name) - -unless have_header("hivex.h") - raise " not found" -end -unless have_library("hivex", "hivex_open", "hivex.h") - raise "hivex library not found" -end - -create_header -create_makefile(extension_name) diff --git a/trunk/hivex/ruby/lib/hivex.rb b/trunk/hivex/ruby/lib/hivex.rb deleted file mode 100644 index a142db1..0000000 --- a/trunk/hivex/ruby/lib/hivex.rb +++ /dev/null @@ -1,18 +0,0 @@ -# hivex Ruby bindings -# Copyright (C) 2009-2011 Red Hat Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -require '_hivex' diff --git a/trunk/hivex/ruby/run-ruby-tests b/trunk/hivex/ruby/run-ruby-tests deleted file mode 100755 index 74afb9f..0000000 --- a/trunk/hivex/ruby/run-ruby-tests +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -# hivex Ruby bindings -# 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. - -set -e - -export LD_LIBRARY_PATH=../lib/.libs - -# Run them one at a time, otherwise rake runs them in parallel (which -# 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" -done diff --git a/trunk/hivex/ruby/tests/tc_010_load.rb b/trunk/hivex/ruby/tests/tc_010_load.rb deleted file mode 100644 index 113ab69..0000000 --- a/trunk/hivex/ruby/tests/tc_010_load.rb +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -require 'test/unit' -$:.unshift(File::join(File::dirname(__FILE__), "..", "lib")) -$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "hivex")) -require 'hivex' - -class TestLoad < Test::Unit::TestCase - def test_load - h = Hivex::open("../images/minimal", {}) - assert_not_nil (h) - end -end diff --git a/trunk/hivex/ruby/tests/tc_021_close.rb b/trunk/hivex/ruby/tests/tc_021_close.rb deleted file mode 100644 index a089cf3..0000000 --- a/trunk/hivex/ruby/tests/tc_021_close.rb +++ /dev/null @@ -1,29 +0,0 @@ -# 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. - -require 'test/unit' -$:.unshift(File::join(File::dirname(__FILE__), "..", "lib")) -$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "hivex")) -require 'hivex' - -class TestClose < Test::Unit::TestCase - def test_close - h = Hivex::open("../images/minimal", {}) - assert_not_nil (h) - h.close() - end -end diff --git a/trunk/hivex/ruby/tests/tc_120_rlenvalue.rb b/trunk/hivex/ruby/tests/tc_120_rlenvalue.rb deleted file mode 100644 index 368cb19..0000000 --- a/trunk/hivex/ruby/tests/tc_120_rlenvalue.rb +++ /dev/null @@ -1,46 +0,0 @@ -# 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 diff --git a/trunk/hivex/ruby/tests/tc_200_write.rb b/trunk/hivex/ruby/tests/tc_200_write.rb deleted file mode 100644 index b46dc7b..0000000 --- a/trunk/hivex/ruby/tests/tc_200_write.rb +++ /dev/null @@ -1,46 +0,0 @@ -# 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. - -require 'test/unit' -$:.unshift(File::join(File::dirname(__FILE__), "..", "lib")) -$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "hivex")) -require 'hivex' - -class TestWrite < Test::Unit::TestCase - def test_write - h = Hivex::open("../images/minimal", {:write => 1}) - assert_not_nil (h) - - root = h.root() - assert (root) - - h.node_add_child(root, "A") - h.node_add_child(root, "B") - b = h.node_get_child(root, "B") - assert (b) - - values = [ - { :key => "Key1", :type => 3, :value => "ABC" }, - { :key => "Key2", :type => 3, :value => "DEF" } - ] - h.node_set_values(b, values) - - # Don't actually commit here because that would overwrite - # the original file. - # h.commit() - end -end diff --git a/trunk/hivex/ruby/tests/tc_210_setvalue.rb b/trunk/hivex/ruby/tests/tc_210_setvalue.rb deleted file mode 100644 index e55e5fe..0000000 --- a/trunk/hivex/ruby/tests/tc_210_setvalue.rb +++ /dev/null @@ -1,68 +0,0 @@ -# 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. - -require 'test/unit' -$:.unshift(File::join(File::dirname(__FILE__), "..", "lib")) -$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "hivex")) -require 'hivex' - -class TestSetValue < Test::Unit::TestCase - def test_set_value - h = Hivex::open("../images/minimal", {:write => 1}) - assert_not_nil (h) - - root = h.root() - assert (root) - - h.node_add_child(root, "B") - b = h.node_get_child(root, "B") - - values = [ - { :key => "Key1", :type => 3, :value => "ABC" }, - { :key => "Key2", :type => 2, :value => "DEF" } - ] - h.node_set_values(b, values) - - value1 = { :key => "Key3", :type => 3, :value => "GHI" } - h.node_set_value(b, value1) - - value2 = { :key => "Key1", :type => 3, :value => "JKL" } - h.node_set_value(b, value2) - - val = h.node_get_value(b, "Key1") - hash = h.value_value(val) - assert (hash[:type] == 3) - assert (hash[:value] == "JKL") - assert (hash[:len] == 3) - - val = h.node_get_value(b, "Key2") - hash = h.value_value(val) - assert (hash[:type] == 2) - assert (hash[:value] == "DEF") - assert (hash[:len] == 3) - - val = h.node_get_value(b, "Key3") - hash = h.value_value(val) - assert (hash[:type] == 3) - assert (hash[:value] == "GHI") - assert (hash[:len] == 3) - - # Don't actually commit here because that would overwrite - # the original file. - # h.commit() - end -end diff --git a/trunk/hivex/sh/Makefile.am b/trunk/hivex/sh/Makefile.am deleted file mode 100644 index a6f5ae6..0000000 --- a/trunk/hivex/sh/Makefile.am +++ /dev/null @@ -1,84 +0,0 @@ -# hivex -# 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. - -EXTRA_DIST = \ - hivexget.pod \ - hivexget \ - hivexsh.pod \ - example1 \ - example2 \ - example3 \ - example4 \ - example5 \ - example6 - -bin_PROGRAMS = hivexsh -bin_SCRIPTS = hivexget -noinst_SCRIPTS = example1 example2 example3 example4 example5 example6 - -hivexsh_SOURCES = \ - hivexsh.c \ - ../lib/hivex.h \ - ../lib/byte_conversions.h - -hivexsh_LDADD = ../lib/libhivex.la ../gnulib/lib/libgnu.la $(LIBREADLINE) -hivexsh_CFLAGS = \ - -I$(top_srcdir)/gnulib/lib \ - -I$(top_builddir)/gnulib/lib \ - -I$(top_srcdir)/lib \ - -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) - -man_MANS = hivexget.1 hivexsh.1 - -hivexget.1: hivexget.pod - $(POD2MAN) \ - --section 1 \ - -c "Windows Registry" \ - --name "hivexget" \ - --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ - $< > $@-t; mv $@-t $@ - -hivexsh.1: hivexsh.pod - $(POD2MAN) \ - --section 1 \ - -c "Windows Registry" \ - --name "hivexsh" \ - --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ - $< > $@-t; mv $@-t $@ - -noinst_DATA = \ - $(top_builddir)/html/hivexget.1.html \ - $(top_builddir)/html/hivexsh.1.html - -$(top_builddir)/html/hivexget.1.html: hivexget.pod - mkdir -p $(top_builddir)/html - cd $(top_builddir) && pod2html \ - --css 'pod.css' \ - --htmldir html \ - --outfile html/hivexget.1.html \ - sh/hivexget.pod - -$(top_builddir)/html/hivexsh.1.html: hivexsh.pod - mkdir -p $(top_builddir)/html - cd $(top_builddir) && pod2html \ - --css 'pod.css' \ - --htmldir html \ - --outfile html/hivexsh.1.html \ - sh/hivexsh.pod - -CLEANFILES = $(man_MANS) diff --git a/trunk/hivex/sh/example1 b/trunk/hivex/sh/example1 deleted file mode 100755 index a2e1775..0000000 --- a/trunk/hivex/sh/example1 +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# 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. - -set -e - -# Example program which loads and saves a hive. -# -# The intention of this example is just to check that we can do this -# without corrupting the hive (header etc). -# -# NB: The copy of the hive will not be absolutely identical. The -# sequence numbers in the header will change. If we implement the -# last modified field in the header, then that and the checksum will -# also change. - -if [ $# -ne 2 ]; then - echo "$0 input output" - exit 1 -fi - -d=`dirname $0` - -$d/hivexsh -w < Unload Hive. -# -# Don't replace the original Windows hive, else you'll break things :-) - -if [ $# -ne 0 ]; then - echo "$0: no arguments required" - exit 1 -fi - -d=`dirname $0` - -$d/hivexsh -w < Unload Hive. -# -# Don't replace the original Windows hive, else you'll break things :-) - -if [ $# -ne 0 ]; then - echo "$0: no arguments required" - exit 1 -fi - -d=`dirname $0` - -$d/hivexsh -w <. -For proper regedit formatting, use L. - -=head1 DESCRIPTION - -This program navigates through a Windows Registry binary "hive" -file and extracts I all the (key, value) data pairs -stored in that subkey I just the single named data item. - -In the first form: - - hivexget hivefile '\Path\To\SubKey' - -C is some Windows Registry binary hive, and C<\Path\To\Subkey> -is a path within that hive. I the path is relative to the top -of this hive, and is I the full path as you would use in Windows -(eg. C is not a valid path). - -If the subkey exists, then the output lists all data pairs under this -subkey, in a format similar to C in Windows. - -In the second form: - - hivexget hivefile '\Path\To\SubKey' name - -C and path are as above. C is the name of the value -of interest (use C<@> for the default value). - -The corresponding data item is printed "raw" (ie. no processing or -escaping) except: - -=over 4 - -=item 1 - -If it's a string we will convert it from Windows UTF-16 to UTF-8, if -this conversion is possible. The string is printed with a single -trailing newline. - -=item 2 - -If it's a multiple-string value, each string is printed on a separate -line. - -=item 3 - -If it's a numeric value, it is printed as a decimal number. - -=back - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L, -L, -L. - -=head1 AUTHORS - -Richard W.M. Jones (C) - -=head1 COPYRIGHT - -Copyright (C) 2009 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., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/trunk/hivex/sh/hivexsh.c b/trunk/hivex/sh/hivexsh.c deleted file mode 100644 index f578ccc..0000000 --- a/trunk/hivex/sh/hivexsh.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* hivexsh - Hive shell. - * Copyright (C) 2009 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_LIBINTL_H -#include -#endif - -#ifdef HAVE_LIBREADLINE -#include -#include -#endif - -#ifdef HAVE_GETTEXT -#include "gettext.h" -#define _(str) dgettext(PACKAGE, (str)) -//#define N_(str) dgettext(PACKAGE, (str)) -#else -#define _(str) str -//#define N_(str) str -#endif - -#define STREQ(a,b) (strcmp((a),(b)) == 0) -#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0) -#define STRNEQ(a,b) (strcmp((a),(b)) != 0) -//#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0) -//#define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0) -//#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0) -//#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0) -//#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0) -#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0) - -#include "c-ctype.h" -#include "xstrtol.h" - -#include "hivex.h" -#include "byte_conversions.h" - -#define HIVEX_MAX_VALUES 1000 - -static int quit = 0; -static int is_tty; -static hive_h *h = NULL; -static char *prompt_string = NULL; /* Normal prompt string. */ -static char *loaded = NULL; /* Basename of loaded file, if any. */ -static hive_node_h cwd; /* Current node. */ -static int open_flags = 0; /* Flags used when loading a hive file. */ - -static void usage (void) __attribute__((noreturn)); -static void print_node_path (hive_node_h, FILE *); -static void set_prompt_string (void); -static void initialize_readline (void); -static void cleanup_readline (void); -static void add_history_line (const char *); -static char *rl_gets (const char *prompt_string); -static void sort_strings (char **strings, int len); -static int get_xdigit (char c); -static int dispatch (char *cmd, char *args); -static int cmd_add (char *name); -static int cmd_cd (char *path); -static int cmd_close (char *path); -static int cmd_commit (char *path); -static int cmd_del (char *args); -static int cmd_help (char *args); -static int cmd_load (char *hivefile); -static int cmd_ls (char *args); -static int cmd_lsval (char *args); -static int cmd_setval (char *args); - -static void -usage (void) -{ - fprintf (stderr, "hivexsh [-dfw] [hivefile]\n"); - exit (EXIT_FAILURE); -} - -int -main (int argc, char *argv[]) -{ - setlocale (LC_ALL, ""); -#ifdef HAVE_BINDTEXTDOMAIN - bindtextdomain (PACKAGE, LOCALEBASEDIR); - textdomain (PACKAGE); -#endif - - int c; - const char *filename = NULL; - - set_prompt_string (); - - while ((c = getopt (argc, argv, "df:w")) != EOF) { - switch (c) { - case 'd': - open_flags |= HIVEX_OPEN_DEBUG; - break; - case 'f': - filename = optarg; - break; - case 'w': - open_flags |= HIVEX_OPEN_WRITE; - break; - default: - usage (); - } - } - - if (optind < argc) { - if (optind + 1 != argc) - usage (); - if (cmd_load (argv[optind]) == -1) - exit (EXIT_FAILURE); - } - - /* -f filename parameter */ - if (filename) { - close (0); - if (open (filename, O_RDONLY) == -1) { - perror (filename); - exit (EXIT_FAILURE); - } - } - - /* Main loop. */ - is_tty = isatty (0); - initialize_readline (); - - if (is_tty) - printf (_( -"\n" -"Welcome to hivexsh, the hivex interactive shell for examining\n" -"Windows Registry binary hive files.\n" -"\n" -"Type: 'help' for help summary\n" -" 'quit' to quit the shell\n" -"\n")); - - while (!quit) { - char *buf = rl_gets (prompt_string); - if (!buf) { - quit = 1; - if (is_tty) - printf ("\n"); - break; - } - - while (*buf && c_isspace (*buf)) - buf++; - - /* Ignore blank line. */ - if (!*buf) continue; - - /* If the next character is '#' then this is a comment. */ - if (*buf == '#') continue; - - /* Parsing is very simple - much simpler than guestfish. This is - * because Registry keys often contain spaces, and we don't want - * to bother with quoting. Therefore here we just split at the - * first whitespace into "cmdarg(s)". We let the - * command decide how to deal with arg(s), if at all. - */ - size_t len = strcspn (buf, " \t"); - - if (len == 0) continue; - - char *cmd = buf; - char *args; - - if (buf[len] == '\0') { - /* This is mostly safe. Although the cmd_* functions do sometimes - * modify args, then shouldn't do so when args is "". - */ - args = (char *) ""; - goto got_command; - } - - buf[len] = '\0'; - args = buf + len + 1 + strspn (&buf[len+1], " \t"); - - len = strlen (args); - while (len > 0 && c_isspace (args[len-1])) { - args[len-1] = '\0'; - len--; - } - - got_command: - /*printf ("command: '%s' args: '%s'\n", cmd, args)*/; - int r = dispatch (cmd, args); - if (!is_tty && r == -1) - exit (EXIT_FAILURE); - } - - cleanup_readline (); - free (prompt_string); - free (loaded); - if (h) hivex_close (h); - exit (0); -} - -/* Set the prompt string. This is called whenever it could change, eg. - * after loading a file or changing directory. - */ -static void -set_prompt_string (void) -{ - free (prompt_string); - prompt_string = NULL; - - FILE *fp; - char *ptr; - size_t size; - fp = open_memstream (&ptr, &size); - if (fp == NULL) { - perror ("open_memstream"); - exit (EXIT_FAILURE); - } - - if (h) { - assert (loaded != NULL); - assert (cwd != 0); - - fputs (loaded, fp); - print_node_path (cwd, fp); - } - - fprintf (fp, "> "); - fclose (fp); - prompt_string = ptr; -} - -/* Print the \full\path of a node. */ -static void -print_node_path (hive_node_h node, FILE *fp) -{ - hive_node_h root = hivex_root (h); - - if (node == root) { - fputc ('\\', fp); - return; - } - - hive_node_h parent = hivex_node_parent (h, node); - if (parent == 0) { - fprintf (stderr, _("hivexsh: error getting parent of node %zu\n"), node); - return; - } - print_node_path (parent, fp); - - if (parent != root) - fputc ('\\', fp); - - char *name = hivex_node_name (h, node); - if (name == NULL) { - fprintf (stderr, _("hivexsh: error getting node name of node %zx\n"), node); - return; - } - - fputs (name, fp); - free (name); -} - -static char *line_read = NULL; - -static char * -rl_gets (const char *prompt_string) -{ -#ifdef HAVE_LIBREADLINE - - if (is_tty) { - if (line_read) { - free (line_read); - line_read = NULL; - } - - line_read = readline (prompt_string); - - if (line_read && *line_read) - add_history_line (line_read); - - return line_read; - } - -#endif /* HAVE_LIBREADLINE */ - - static char buf[8192]; - int len; - - if (is_tty) - printf ("%s", prompt_string); - line_read = fgets (buf, sizeof buf, stdin); - - if (line_read) { - len = strlen (line_read); - if (len > 0 && buf[len-1] == '\n') buf[len-1] = '\0'; - } - - return line_read; -} - -#ifdef HAVE_LIBREADLINE -static char histfile[1024]; -static int nr_history_lines = 0; -#endif - -static void -initialize_readline (void) -{ -#ifdef HAVE_LIBREADLINE - const char *home; - - home = getenv ("HOME"); - if (home) { - snprintf (histfile, sizeof histfile, "%s/.hivexsh", home); - using_history (); - (void) read_history (histfile); - } - - rl_readline_name = "hivexsh"; -#endif -} - -static void -cleanup_readline (void) -{ -#ifdef HAVE_LIBREADLINE - int fd; - - if (histfile[0] != '\0') { - fd = open (histfile, O_WRONLY|O_CREAT, 0644); - if (fd == -1) { - perror (histfile); - return; - } - close (fd); - - (void) append_history (nr_history_lines, histfile); - } -#endif -} - -static void -add_history_line (const char *line) -{ -#ifdef HAVE_LIBREADLINE - add_history (line); - nr_history_lines++; -#endif -} - -static int -compare (const void *vp1, const void *vp2) -{ - char * const *p1 = (char * const *) vp1; - char * const *p2 = (char * const *) vp2; - return strcasecmp (*p1, *p2); -} - -static void -sort_strings (char **strings, int len) -{ - qsort (strings, len, sizeof (char *), compare); -} - -static int -get_xdigit (char c) -{ - switch (c) { - case '0'...'9': return c - '0'; - case 'a'...'f': return c - 'a' + 10; - case 'A'...'F': return c - 'A' + 10; - default: return -1; - } -} - -static int -dispatch (char *cmd, char *args) -{ - if (STRCASEEQ (cmd, "help")) - return cmd_help (args); - else if (STRCASEEQ (cmd, "load")) - return cmd_load (args); - else if (STRCASEEQ (cmd, "exit") || - STRCASEEQ (cmd, "q") || - STRCASEEQ (cmd, "quit")) { - quit = 1; - return 0; - } - - /* If no hive file is loaded (!h) then only the small selection of - * commands above will work. - */ - if (!h) { - fprintf (stderr, _("hivexsh: you must load a hive file first using 'load hivefile'\n")); - return -1; - } - - if (STRCASEEQ (cmd, "add")) - return cmd_add (args); - else if (STRCASEEQ (cmd, "cd")) - return cmd_cd (args); - else if (STRCASEEQ (cmd, "close") || STRCASEEQ (cmd, "unload")) - return cmd_close (args); - else if (STRCASEEQ (cmd, "commit")) - return cmd_commit (args); - else if (STRCASEEQ (cmd, "del")) - return cmd_del (args); - else if (STRCASEEQ (cmd, "ls")) - return cmd_ls (args); - else if (STRCASEEQ (cmd, "lsval")) - return cmd_lsval (args); - else if (STRCASEEQ (cmd, "setval")) - return cmd_setval (args); - else { - fprintf (stderr, _("hivexsh: unknown command '%s', use 'help' for help summary\n"), - cmd); - return -1; - } -} - -static int -cmd_load (char *hivefile) -{ - if (STREQ (hivefile, "")) { - fprintf (stderr, _("hivexsh: load: no hive file name given to load\n")); - return -1; - } - - if (h) hivex_close (h); - h = NULL; - - free (loaded); - loaded = NULL; - - cwd = 0; - - h = hivex_open (hivefile, open_flags); - if (h == NULL) { - fprintf (stderr, - _( -"hivexsh: failed to open hive file: %s: %m\n" -"\n" -"If you think this file is a valid Windows binary hive file (_not_\n" -"a regedit *.reg file) then please run this command again using the\n" -"hivexsh option '-d' and attach the complete output _and_ the hive file\n" -"which fails into a bug report at https://bugzilla.redhat.com/\n" -"\n"), - hivefile); - return -1; - } - - /* Get the basename of the file for the prompt. */ - char *p = strrchr (hivefile, '/'); - if (p) - loaded = strdup (p+1); - else - loaded = strdup (hivefile); - if (!loaded) { - perror ("strdup"); - exit (EXIT_FAILURE); - } - - cwd = hivex_root (h); - - set_prompt_string (); - - return 0; -} - -static int -cmd_close (char *args) -{ - if (STRNEQ (args, "")) { - fprintf (stderr, _("hivexsh: '%s' command should not be given arguments\n"), - "close"); - return -1; - } - - if (h) hivex_close (h); - h = NULL; - - free (loaded); - loaded = NULL; - - cwd = 0; - - set_prompt_string (); - - return 0; -} - -static int -cmd_commit (char *path) -{ - if (STREQ (path, "")) - path = NULL; - - if (hivex_commit (h, path, 0) == -1) { - perror ("hivexsh: commit"); - return -1; - } - - return 0; -} - -static int -cmd_cd (char *path) -{ - if (STREQ (path, "")) { - print_node_path (cwd, stdout); - fputc ('\n', stdout); - return 0; - } - - if (path[0] == '\\' && path[1] == '\\') { - fprintf (stderr, _("%s: %s: \\ characters in path are doubled - are you escaping the path parameter correctly?\n"), "hivexsh", path); - return -1; - } - - hive_node_h new_cwd = cwd; - hive_node_h root = hivex_root (h); - - if (path[0] == '\\') { - new_cwd = root; - path++; - } - - while (path[0]) { - size_t len = strcspn (path, "\\"); - if (len == 0) { - path++; - continue; - } - - char *elem = path; - path = path[len] == '\0' ? &path[len] : &path[len+1]; - elem[len] = '\0'; - - if (len == 1 && STREQ (elem, ".")) - continue; - - if (len == 2 && STREQ (elem, "..")) { - if (new_cwd != root) - new_cwd = hivex_node_parent (h, new_cwd); - continue; - } - - errno = 0; - new_cwd = hivex_node_get_child (h, new_cwd, elem); - if (new_cwd == 0) { - if (errno) - perror ("hivexsh: cd"); - else - fprintf (stderr, _("hivexsh: cd: subkey '%s' not found\n"), - elem); - return -1; - } - } - - if (new_cwd != cwd) { - cwd = new_cwd; - set_prompt_string (); - } - - return 0; -} - -static int -cmd_help (char *args) -{ - printf (_( -"Navigate through the hive's keys using the 'cd' command, as if it\n" -"contained a filesystem, and use 'ls' to list the subkeys of the\n" -"current key. Full documentation is in the hivexsh(1) manual page.\n")); - - return 0; -} - -static int -cmd_ls (char *args) -{ - if (STRNEQ (args, "")) { - fprintf (stderr, _("hivexsh: '%s' command should not be given arguments\n"), - "ls"); - return -1; - } - - /* Get the subkeys. */ - hive_node_h *children = hivex_node_children (h, cwd); - if (children == NULL) { - perror ("ls"); - return -1; - } - - /* Get names for each subkey. */ - size_t len; - for (len = 0; children[len] != 0; ++len) - ; - - char **names = calloc (len, sizeof (char *)); - if (names == NULL) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - - int ret = -1; - size_t i; - for (i = 0; i < len; ++i) { - names[i] = hivex_node_name (h, children[i]); - if (names[i] == NULL) { - perror ("hivex_node_name"); - goto error; - } - } - - /* Sort the names. */ - sort_strings (names, len); - - for (i = 0; i < len; ++i) - printf ("%s\n", names[i]); - - ret = 0; - error: - free (children); - for (i = 0; i < len; ++i) - free (names[i]); - free (names); - return ret; -} - -static int -cmd_lsval (char *key) -{ - if (STRNEQ (key, "")) { - hive_value_h value; - - errno = 0; - if (STREQ (key, "@")) /* default key written as "@" */ - value = hivex_node_get_value (h, cwd, ""); - else - value = hivex_node_get_value (h, cwd, key); - - if (value == 0) { - if (errno) - goto error; - /* else key not found */ - fprintf (stderr, _("%s: %s: key not found\n"), "hivexsh", key); - return -1; - } - - /* Print the value. */ - hive_type t; - size_t len; - if (hivex_value_type (h, value, &t, &len) == -1) - goto error; - - switch (t) { - case hive_t_string: - case hive_t_expand_string: - case hive_t_link: { - char *str = hivex_value_string (h, value); - if (!str) - goto error; - - puts (str); /* note: this adds a single \n character */ - free (str); - break; - } - - case hive_t_dword: - case hive_t_dword_be: { - int32_t j = hivex_value_dword (h, value); - printf ("%" PRIi32 "\n", j); - break; - } - - case hive_t_qword: { - int64_t j = hivex_value_qword (h, value); - printf ("%" PRIi64 "\n", j); - break; - } - - case hive_t_multiple_strings: { - char **strs = hivex_value_multiple_strings (h, value); - if (!strs) - goto error; - size_t j; - for (j = 0; strs[j] != NULL; ++j) { - puts (strs[j]); - free (strs[j]); - } - free (strs); - break; - } - - case hive_t_none: - case hive_t_binary: - case hive_t_resource_list: - case hive_t_full_resource_description: - case hive_t_resource_requirements_list: - default: { - size_t r; - char *data; - - data = hivex_value_value (h, value, &t, &len); - if (!data) - goto error; - - r = fwrite (data, 1, len, stdout); - free (data); - if (r != len) - goto error; - - break; - } - } /* switch */ - } else { - /* No key specified, so print all keys in this node. We do this - * in a format which looks like the output of regedit, although - * this isn't a particularly useful format. - */ - hive_value_h *values; - - values = hivex_node_values (h, cwd); - if (values == NULL) - goto error; - - size_t i; - for (i = 0; values[i] != 0; ++i) { - char *key = hivex_value_key (h, values[i]); - if (!key) goto error; - - if (*key) { - putchar ('"'); - size_t j; - for (j = 0; key[j] != 0; ++j) { - if (key[j] == '"' || key[j] == '\\') - putchar ('\\'); - putchar (key[j]); - } - putchar ('"'); - } else - printf ("\"@\""); /* default key in regedit files */ - putchar ('='); - free (key); - - hive_type t; - size_t len; - if (hivex_value_type (h, values[i], &t, &len) == -1) - goto error; - - switch (t) { - case hive_t_string: - case hive_t_expand_string: - case hive_t_link: { - char *str = hivex_value_string (h, values[i]); - if (!str) - goto error; - - if (t != hive_t_string) - printf ("str(%d):", t); - putchar ('"'); - size_t j; - for (j = 0; str[j] != 0; ++j) { - if (str[j] == '"' || str[j] == '\\') - putchar ('\\'); - putchar (str[j]); - } - putchar ('"'); - free (str); - break; - } - - case hive_t_dword: - case hive_t_dword_be: { - int32_t j = hivex_value_dword (h, values[i]); - printf ("dword:%08" PRIx32, j); - break; - } - - case hive_t_qword: /* sic */ - case hive_t_none: - case hive_t_binary: - case hive_t_multiple_strings: - case hive_t_resource_list: - case hive_t_full_resource_description: - case hive_t_resource_requirements_list: - default: { - unsigned char *data = - (unsigned char *) hivex_value_value (h, values[i], &t, &len); - if (!data) - goto error; - - printf ("hex(%d):", t); - size_t j; - for (j = 0; j < len; ++j) { - if (j > 0) - putchar (','); - printf ("%02x", data[j]); - } - - free (data); - - break; - } - } /* switch */ - - putchar ('\n'); - } /* for */ - - free (values); - } - - return 0; - - error: - perror ("hivexsh: lsval"); - return -1; -} - -static int -cmd_setval (char *nrvals_str) -{ - strtol_error xerr; - - /* Parse number of values. */ - long nrvals; - xerr = xstrtol (nrvals_str, NULL, 0, &nrvals, ""); - if (xerr != LONGINT_OK) { - fprintf (stderr, _("%s: %s: invalid integer parameter (%s returned %d)\n"), - "setval", "nrvals", "xstrtol", xerr); - return -1; - } - if (nrvals < 0 || nrvals > HIVEX_MAX_VALUES) { - fprintf (stderr, _("%s: %s: integer out of range\n"), - "setval", "nrvals"); - return -1; - } - - struct hive_set_value *values = - calloc (nrvals, sizeof (struct hive_set_value)); - if (values == NULL) { - perror ("calloc"); - exit (EXIT_FAILURE); - } - - int ret = -1; - - /* Read nrvals * 2 lines of input, nrvals * (key, value) pairs, as - * explained in the man page. - */ - int i, j; - for (i = 0; i < nrvals; ++i) { - /* Read key. */ - char *buf = rl_gets (" key> "); - if (!buf) { - fprintf (stderr, _("hivexsh: setval: unexpected end of input\n")); - quit = 1; - goto error; - } - - /* Note that buf will be overwritten by the next call to rl_gets. */ - if (STREQ (buf, "@")) - values[i].key = strdup (""); - else - values[i].key = strdup (buf); - if (values[i].key == NULL) { - perror ("strdup"); - exit (EXIT_FAILURE); - } - - /* Read value. */ - buf = rl_gets ("value> "); - if (!buf) { - fprintf (stderr, _("hivexsh: setval: unexpected end of input\n")); - quit = 1; - goto error; - } - - if (STREQ (buf, "none")) { - values[i].t = hive_t_none; - values[i].len = 0; - } - else if (STRPREFIX (buf, "string:")) { - buf += 7; - values[i].t = hive_t_string; - int nr_chars = strlen (buf); - values[i].len = 2 * (nr_chars + 1); - values[i].value = malloc (values[i].len); - if (!values[i].value) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - for (j = 0; j <= /* sic */ nr_chars; ++j) { - if (buf[j] & 0x80) { - fprintf (stderr, _("hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n")); - goto error; - } - values[i].value[2*j] = buf[j]; - values[i].value[2*j+1] = '\0'; - } - } - else if (STRPREFIX (buf, "expandstring:")) { - buf += 13; - values[i].t = hive_t_expand_string; - int nr_chars = strlen (buf); - values[i].len = 2 * (nr_chars + 1); - values[i].value = malloc (values[i].len); - if (!values[i].value) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - for (j = 0; j <= /* sic */ nr_chars; ++j) { - if (buf[j] & 0x80) { - fprintf (stderr, _("hivexsh: string(utf16le): only 7 bit ASCII strings are supported for input\n")); - goto error; - } - values[i].value[2*j] = buf[j]; - values[i].value[2*j+1] = '\0'; - } - } - else if (STRPREFIX (buf, "dword:")) { - buf += 6; - values[i].t = hive_t_dword; - values[i].len = 4; - values[i].value = malloc (4); - if (!values[i].value) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - long n; - xerr = xstrtol (buf, NULL, 0, &n, ""); - if (xerr != LONGINT_OK) { - fprintf (stderr, _("%s: %s: invalid integer parameter (%s returned %d)\n"), - "setval", "dword", "xstrtol", xerr); - goto error; - } -#if SIZEOF_LONG > 4 - if (n < 0 || n > UINT32_MAX) { - fprintf (stderr, _("%s: %s: integer out of range\n"), - "setval", "dword"); - goto error; - } -#endif - uint32_t u32 = htole32 (n); - memcpy (values[i].value, &u32, 4); - } - else if (STRPREFIX (buf, "qword:")) { - buf += 6; - values[i].t = hive_t_qword; - values[i].len = 8; - values[i].value = malloc (8); - if (!values[i].value) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - long long n; - xerr = xstrtoll (buf, NULL, 0, &n, ""); - if (xerr != LONGINT_OK) { - fprintf (stderr, _("%s: %s: invalid integer parameter (%s returned %d)\n"), - "setval", "dword", "xstrtoll", xerr); - goto error; - } -#if 0 - if (n < 0 || n > UINT64_MAX) { - fprintf (stderr, _("%s: %s: integer out of range\n"), - "setval", "dword"); - goto error; - } -#endif - uint64_t u64 = htole64 (n); - memcpy (values[i].value, &u64, 4); - } - else if (STRPREFIX (buf, "hex:")) { - /* Read the type. */ - buf += 4; - size_t len = strcspn (buf, ":"); - char *nextbuf; - if (buf[len] == '\0') /* "hex:t" */ - nextbuf = &buf[len]; - else { /* "hex:t:..." */ - buf[len] = '\0'; - nextbuf = &buf[len+1]; - } - - long t; - xerr = xstrtol (buf, NULL, 0, &t, ""); - if (xerr != LONGINT_OK) { - fprintf (stderr, _("%s: %s: invalid integer parameter (%s returned %d)\n"), - "setval", "hex", "xstrtol", xerr); - goto error; - } -#if SIZEOF_LONG > 4 - if (t < 0 || t > UINT32_MAX) { - fprintf (stderr, _("%s: %s: integer out of range\n"), - "setval", "hex"); - goto error; - } -#endif - values[i].t = t; - - /* Read the hex data. */ - buf = nextbuf; - - /* The allocation length is an overestimate, but it doesn't matter. */ - values[i].value = malloc (1 + strlen (buf) / 2); - if (!values[i].value) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - values[i].len = 0; - - while (*buf) { - int c = 0; - - for (j = 0; *buf && j < 2; buf++) { - if (c_isxdigit (*buf)) { /* NB: ignore non-hex digits. */ - c <<= 4; - c |= get_xdigit (*buf); - j++; - } - } - - if (j == 2) values[i].value[values[i].len++] = c; - else if (j == 1) { - fprintf (stderr, _("hivexsh: setval: trailing garbage after hex string\n")); - goto error; - } - } - } - else { - fprintf (stderr, - _("hivexsh: setval: cannot parse value string, please refer to the man page hivexsh(1) for help: %s\n"), - buf); - goto error; - } - } - - ret = hivex_node_set_values (h, cwd, nrvals, values, 0); - - error: - /* Free values array. */ - for (i = 0; i < nrvals; ++i) { - free (values[i].key); - free (values[i].value); - } - free (values); - - return ret; -} - -static int -cmd_del (char *args) -{ - if (STRNEQ (args, "")) { - fprintf (stderr, _("hivexsh: '%s' command should not be given arguments\n"), - "del"); - return -1; - } - - if (cwd == hivex_root (h)) { - fprintf (stderr, _("hivexsh: del: the root node cannot be deleted\n")); - return -1; - } - - hive_node_h new_cwd = hivex_node_parent (h, cwd); - - if (hivex_node_delete_child (h, cwd) == -1) { - perror ("hivexsh: del"); - return -1; - } - - cwd = new_cwd; - set_prompt_string (); - return 0; -} - -static int -cmd_add (char *name) -{ - hive_node_h node = hivex_node_add_child (h, cwd, name); - if (node == 0) { - perror ("hivexsh: add"); - return -1; - } - return 0; -} diff --git a/trunk/hivex/sh/hivexsh.pod b/trunk/hivex/sh/hivexsh.pod deleted file mode 100644 index 7d7fc0a..0000000 --- a/trunk/hivex/sh/hivexsh.pod +++ /dev/null @@ -1,287 +0,0 @@ -=encoding utf8 - -=head1 NAME - -hivexsh - Windows Registry hive shell - -=head1 SYNOPSIS - - hivexsh [-options] [hivefile] - -=head1 DESCRIPTION - -This program provides a simple shell for navigating Windows Registry -'hive' files. It uses the hivex library for access to these binary -files. - -Firstly you will need to provide a hive file from a Windows operating -system. The hive files are usually located in -C and have names like C, -C etc (without any file extension). For more information -about hive files, read L. For information about downloading -files from virtual machines, read L and L. - -You can provide the name of the hive file to examine on the command -line. For example: - - hivexsh software - -Or you can start C without any arguments, and immediately use -the C command to load a hive: - - $ hivexsh - - Welcome to hivexsh, the hivex interactive shell for examining - Windows Registry binary hive files. - - Type: 'help' for help with commands - 'quit' to quit the shell - - > load software - software\> - -Navigate through the hive's keys using the C command, as if it -contained a filesystem, and use C to list the subkeys of the -current key. Other commands are listed below. - -=head1 OPTIONS - -=over 4 - -=item B<-d> - -Enable lots of debug messages. If you find a Registry file that this -program cannot parse, please enable this option and post the complete -output I the Registry hive file in your bug report. - -=item B<-f> filename - -Read commands from C instead of stdin. To write a hivexsh -script, use: - - #!/usr/bin/hivexsh -f - -=item B<-w> - -If this option is given, then writes are allowed to the hive -(see L command below, and the discussion of -modifying hives in L). - -B Even if you specify this option, nothing is written -to a hive unless you call the L command. If you exit the -shell without committing, all changes will be discarded. - -If this option is not given, then write commands are disabled. - -=back - -=head1 COMMANDS - -=over 4 - -=item B name - -Add a subkey named C below the current node. The name may -contain spaces and punctuation characters, and does not need to be -quoted. - -The new key will have no subkeys and no values (see C). - -There must be no existing subkey called C, or this command will -fail. To replace an existing subkey, delete it first like this: - - cd name - del - -=item B path - -Change to the subkey C. Use Windows-style backslashes to -separate path elements, and start with a backslash in order to start -from the root of the hive. For example: - - cd \Classes\* - -moves from the root node, to the C node, to the C<*> node. -If you were already at the root node, you could do this instead: - - cd Classes\* - -or even: - - cd Classes - cd * - -Path elements (node names) are matched case insensitively, and -characters like space, C<*>, and C have I special significance. - -C may be used to go to the parent directory. - -C without any arguments prints the current path. - -Be careful with C since the readline library has an undocumented -behaviour where it will think the final backslash is a continuation -(it reads the next line of input and appends it). Put a single space -after the backslash. - -=item B | B - -Close the currently loaded hive. - -If you modified the hive, all uncommitted writes are lost when you -call this command (or if the shell exits). You have to call C -to write changes. - -=item B [newfile] - -Commit changes to the hive. If the optional C parameter is -supplied, then the hive is written to that file, else the original -file is overwritten. - -Note that you have to specify the C<-w> flag, otherwise no writes are -allowed. - -=item B - -Delete the current node and everything beneath it. The current -directory is moved up one level (as if you did C) after -this command. - -You cannot delete the root node. - -=item B | B - -Exit the shell. - -=item B hivefile - -Load the binary hive named C. The currently loaded hive, if -any, is closed. The current directory is changed back to the root -node. - -=item B - -List the subkeys of the current hive Registry key. Note this command -does not take any arguments. - -=item B [key] - -List the (key, value) pairs of the current hive Registry key. If no -argument is given then all pairs are displayed. If C is given, -then the value of the named key is displayed. If C<@> is given, then -the value of the default key is displayed. - -=item B nrvals - -This command replaces all (key, value) pairs at the current node with -the values in subsequent input. C is the number of values -(ie. (key, value) pairs), and any existing values at this node are -deleted. So C just deletes any values at the current node. - -The command reads 2 * nrvals lines of input, with each pair of -lines of input corresponding to a key and a value to add. - -For example, the following setval command replaces whatever is at the -current node with two (key, value) pairs. The default key is set to -the UTF16-LE-encoded string "abcd". The other value is named -"ANumber" and is a little-endian DWORD 0x12345678. - - setval 2 - @ - string:abcd - ANumber - dword:12345678 - -The first line of each pair is the key (the special key C<@> means -the default key, but you can also use a blank line). - -The second line of each pair is the value, which has a special format -C with possible types summarized in the table below: - - none No data is stored, and the type is set to 0. - - string:abc "abc" is stored as a UTF16-LE-encoded - string (type 1). Note that only 7 bit - ASCII strings are supported as input. - - expandstring:... Same as string but with type 2. - - dword:0x01234567 A DWORD (type 4) with the hex value - 0x01234567. You can also use decimal - or octal numbers here. - - qword:0x0123456789abcdef - A QWORD (type 11) with the hex value - 0x0123456789abcdef. You can also use - decimal or octal numbers here. - - hex:: - hex:1:41,00,42,00,43,00,44,00,00,00 - This is the generic way to enter any - value. is the integer value type. - is a list of pairs of hex - digits which are treated as bytes. - (Any non-hex-digits here are ignored, - so you can separate bytes with commas - or spaces if you want). - -=back - -=head1 EXAMPLE - - $ guestfish --ro -i Windows7 - > download win:c:\windows\system32\config\software software - > quit - - $ hivexsh software - - Welcome to hivexsh, the hivex interactive shell for examining - Windows Registry binary hive files. - - Type: 'help' for help with commands - 'quit' to quit the shell - - software\> ls - ATI Technologies - Classes - Clients - Intel - Microsoft - ODBC - Policies - RegisteredApplications - Sonic - Wow6432Node - software\> quit - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L, -L. - -=head1 AUTHORS - -Richard W.M. Jones (C) - -=head1 COPYRIGHT - -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., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/trunk/hivex/tx-pull.sh b/trunk/hivex/tx-pull.sh deleted file mode 100755 index 0cdd6c0..0000000 --- a/trunk/hivex/tx-pull.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Pull translations from Transifex. -# Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -set -e -set -v - -echo tx pull -tx pull - -# Remove PO files that have no translations in them. -for f in po/*.po; do - if ! grep -q '^msgstr "[^"]' $f; then - echo rm $f - rm $f - fi -done diff --git a/trunk/hivex/xml/Makefile.am b/trunk/hivex/xml/Makefile.am deleted file mode 100644 index 67ba248..0000000 --- a/trunk/hivex/xml/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -# hivex -# 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. - -EXTRA_DIST = \ - hivexml.pod - -bin_PROGRAMS = hivexml - -hivexml_SOURCES = \ - hivexml.c - -hivexml_LDADD = ../lib/libhivex.la ../gnulib/lib/libgnu.la $(LIBXML2_LIBS) -hivexml_CFLAGS = \ - -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - -I$(top_srcdir)/gnulib/lib \ - -I$(top_builddir)/gnulib/lib \ - -I$(top_srcdir)/lib \ - $(LIBXML2_CFLAGS) \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) - -man_MANS = hivexml.1 - -hivexml.1: hivexml.pod - $(POD2MAN) \ - --section 1 \ - -c "Windows Registry" \ - --name "hivexml" \ - --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ - $< > $@-t; mv $@-t $@ - -noinst_DATA = \ - $(top_builddir)/html/hivexml.1.html - -$(top_builddir)/html/hivexml.1.html: hivexml.pod - mkdir -p $(top_builddir)/html - cd $(top_builddir) && pod2html \ - --css 'pod.css' \ - --htmldir html \ - --outfile html/hivexml.1.html \ - xml/hivexml.pod - -CLEANFILES = $(man_MANS) diff --git a/trunk/hivex/xml/hivexml.c b/trunk/hivex/xml/hivexml.c deleted file mode 100644 index a4bc7eb..0000000 --- a/trunk/hivex/xml/hivexml.c +++ /dev/null @@ -1,534 +0,0 @@ -/* hivexml - Convert Windows Registry "hive" to XML file. - * Copyright (C) 2009 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_LIBINTL_H -#include -#endif - -#include - -#include - -#include "hivex.h" - -#ifdef HAVE_GETTEXT -#include "gettext.h" -#define _(str) dgettext(PACKAGE, (str)) -//#define N_(str) dgettext(PACKAGE, (str)) -#else -#define _(str) str -//#define N_(str) str -#endif - -static char *filetime_to_8601 (int64_t windows_ticks); - -/* Callback functions. */ -static int node_start (hive_h *, void *, hive_node_h, const char *name); -static int node_end (hive_h *, void *, hive_node_h, const char *name); -static int value_string (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *str); -static int value_multiple_strings (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, char **argv); -static int value_string_invalid_utf16 (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *str); -static int value_dword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t); -static int value_qword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t); -static int value_binary (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); -static int value_none (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); -static int value_other (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value); - -static struct hivex_visitor visitor = { - .node_start = node_start, - .node_end = node_end, - .value_string = value_string, - .value_multiple_strings = value_multiple_strings, - .value_string_invalid_utf16 = value_string_invalid_utf16, - .value_dword = value_dword, - .value_qword = value_qword, - .value_binary = value_binary, - .value_none = value_none, - .value_other = value_other -}; - -#define XML_CHECK(proc, args) \ - do { \ - if ((proc args) == -1) { \ - fprintf (stderr, _("%s: failed to write XML document\n"), #proc); \ - exit (EXIT_FAILURE); \ - } \ - } while (0) - -int -main (int argc, char *argv[]) -{ - setlocale (LC_ALL, ""); -#ifdef HAVE_BINDTEXTDOMAIN - bindtextdomain (PACKAGE, LOCALEBASEDIR); - textdomain (PACKAGE); -#endif - - int c; - int open_flags = 0; - int visit_flags = 0; - - while ((c = getopt (argc, argv, "dk")) != EOF) { - switch (c) { - case 'd': - open_flags |= HIVEX_OPEN_DEBUG; - break; - case 'k': - visit_flags |= HIVEX_VISIT_SKIP_BAD; - break; - default: - fprintf (stderr, "hivexml [-dk] regfile > output.xml\n"); - exit (EXIT_FAILURE); - } - } - - if (optind + 1 != argc) { - fprintf (stderr, _("hivexml: missing name of input file\n")); - exit (EXIT_FAILURE); - } - - hive_h *h = hivex_open (argv[optind], open_flags); - if (h == NULL) { - perror (argv[optind]); - exit (EXIT_FAILURE); - } - - /* Note both this macro, and xmlTextWriterStartDocument leak memory. There - * doesn't seem to be any way to recover that memory, but it's not a - * large amount. - */ - LIBXML_TEST_VERSION; - - xmlTextWriterPtr writer; - writer = xmlNewTextWriterFilename ("/dev/stdout", 0); - if (writer == NULL) { - fprintf (stderr, _("xmlNewTextWriterFilename: failed to create XML writer\n")); - exit (EXIT_FAILURE); - } - - XML_CHECK (xmlTextWriterStartDocument, (writer, NULL, "utf-8", NULL)); - XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "hive")); - - int64_t hive_mtime = hivex_last_modified (h); - if (hive_mtime >= 0) { - char *timebuf = filetime_to_8601 (hive_mtime); - if (timebuf) { - XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "mtime")); - XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST timebuf)); - XML_CHECK (xmlTextWriterEndElement, (writer)); - free (timebuf); - } - } - - if (hivex_visit (h, &visitor, sizeof visitor, writer, visit_flags) == -1) { - perror (argv[optind]); - exit (EXIT_FAILURE); - } - - if (hivex_close (h) == -1) { - perror (argv[optind]); - exit (EXIT_FAILURE); - } - - XML_CHECK (xmlTextWriterEndElement, (writer)); - XML_CHECK (xmlTextWriterEndDocument, (writer)); - xmlFreeTextWriter (writer); - - exit (EXIT_SUCCESS); -} - -/* Convert Windows filetime to ISO 8601 format. - * http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux/6161842#6161842 - * - * Source for time_t->char* conversion: Fiwalk version 0.6.14's - * fiwalk.cpp. - * - * The caller should free the returned buffer. - * - * This function returns NULL on a 0 input. In the context of - * hives, which only have mtimes, 0 will always be a complete - * absence of data. - */ - -#define WINDOWS_TICK 10000000LL -#define SEC_TO_UNIX_EPOCH 11644473600LL -#define TIMESTAMP_BUF_LEN 32 - -static char * -filetime_to_8601 (int64_t windows_ticks) -{ - char *ret; - time_t t; - struct tm *tm; - - if (windows_ticks == 0LL) - return NULL; - - t = windows_ticks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH; - tm = gmtime (&t); - if (tm == NULL) - return NULL; - - ret = malloc (TIMESTAMP_BUF_LEN); - if (ret == NULL) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - - if (strftime (ret, TIMESTAMP_BUF_LEN, "%FT%TZ", tm) == 0) { - perror ("strftime"); - exit (EXIT_FAILURE); - } - - 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")); - XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "name", BAD_CAST name)); - - if (node == hivex_root (h)) { - XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "root", BAD_CAST "1")); - } - - last_modified = hivex_node_timestamp (h, node); - if (last_modified >= 0) { - timebuf = filetime_to_8601 (last_modified); - if (timebuf) { - XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "mtime")); - XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST timebuf)); - XML_CHECK (xmlTextWriterEndElement, (writer)); - free (timebuf); - } - } - - ret = node_byte_runs (h, writer_v, node); - return ret; -} - -static int -node_end (hive_h *h, void *writer_v, hive_node_h node, const char *name) -{ - xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; - XML_CHECK (xmlTextWriterEndElement, (writer)); - return 0; -} - -static void -start_value (xmlTextWriterPtr writer, - const char *key, const char *type, const char *encoding) -{ - XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "value")); - XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "type", BAD_CAST type)); - if (encoding) - XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "encoding", BAD_CAST encoding)); - if (*key) - XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "key", BAD_CAST key)); - else /* default key */ - XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "default", BAD_CAST "1")); -} - -static void -end_value (xmlTextWriterPtr writer) -{ - XML_CHECK (xmlTextWriterEndElement, (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; - case hive_t_expand_string: type = "expand"; break; - case hive_t_link: type = "link"; break; - - case hive_t_none: - case hive_t_binary: - case hive_t_dword: - case hive_t_dword_be: - case hive_t_multiple_strings: - case hive_t_resource_list: - case hive_t_full_resource_description: - case hive_t_resource_requirements_list: - case hive_t_qword: - abort (); /* internal error - should not happen */ - - default: - type = "unknown"; - } - - start_value (writer, key, type, NULL); - 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 ret; -} - -static int -value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node, - hive_value_h value, hive_type t, size_t len, - const char *key, char **argv) -{ - xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; - int ret = 0; - start_value (writer, key, "string-list", NULL); - - size_t i; - for (i = 0; argv[i] != NULL; ++i) { - XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "string")); - XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST argv[i])); - XML_CHECK (xmlTextWriterEndElement, (writer)); - } - - ret = value_byte_runs (h, writer_v, value); - end_value (writer); - return ret; -} - -static int -value_string_invalid_utf16 (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 /* original data */) -{ - xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; - const char *type; - int ret = 0; - - switch (t) { - case hive_t_string: type = "bad-string"; break; - case hive_t_expand_string: type = "bad-expand"; break; - case hive_t_link: type = "bad-link"; break; - case hive_t_multiple_strings: type = "bad-string-list"; break; - - case hive_t_none: - case hive_t_binary: - case hive_t_dword: - case hive_t_dword_be: - case hive_t_resource_list: - case hive_t_full_resource_description: - case hive_t_resource_requirements_list: - case hive_t_qword: - abort (); /* internal error - should not happen */ - - default: - type = "unknown"; - } - - start_value (writer, key, type, "base64"); - 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 ret; -} - -static int -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 ret; -} - -static int -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 ret; -} - -static int -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 ret; -} - -static int -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 ret; -} - -static int -value_other (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; - const char *type; - int ret = 0; - - switch (t) { - case hive_t_none: - case hive_t_binary: - case hive_t_dword: - case hive_t_dword_be: - case hive_t_qword: - case hive_t_string: - case hive_t_expand_string: - case hive_t_link: - case hive_t_multiple_strings: - abort (); /* internal error - should not happen */ - - case hive_t_resource_list: type = "resource-list"; break; - case hive_t_full_resource_description: type = "resource-description"; break; - case hive_t_resource_requirements_list: type = "resource-requirements"; break; - - default: - type = "unknown"; - } - - start_value (writer, key, type, "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 ret; -} diff --git a/trunk/hivex/xml/hivexml.pod b/trunk/hivex/xml/hivexml.pod deleted file mode 100644 index 257257c..0000000 --- a/trunk/hivex/xml/hivexml.pod +++ /dev/null @@ -1,66 +0,0 @@ -=encoding utf8 - -=head1 NAME - -hivexml - Convert Windows Registry binary "hive" into XML - -=head1 SYNOPSIS - - hivexml [-dk] hivefile > output.xml - -=head1 DESCRIPTION - -This program converts a single Windows Registry binary "hive" -file into a self-describing XML format. - -=head1 OPTIONS - -=over 4 - -=item B<-d> - -Enable lots of debug messages. If you find a Registry file -that this program cannot parse, please enable this option and -post the complete output I the Registry file in your -bug report. - -=item B<-k> - -Keep going even if we find errors in the Registry file. This -skips over any parts of the Registry that we cannot read. - -=back - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L, -L, -L. - -=head1 AUTHORS - -Richard W.M. Jones (C) - -=head1 COPYRIGHT - -Copyright (C) 2009 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., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.