3 * Copyright (C) 2009-2011 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (* This script generates language bindings and some documentation for
23 * After editing this file, run it (./generator/generator.ml) to
24 * regenerate all the output files. 'make' will rerun this
25 * automatically when necessary. Note that if you are using a separate
26 * build directory you must run generator.ml from the _source_
29 * IMPORTANT: This script should NOT print any warnings. If it prints
30 * warnings, you should treat them as errors.
32 * OCaml tips: (1) In emacs, install tuareg-mode to display and format
33 * OCaml code correctly. 'vim' comes with a good OCaml editing mode by
34 * default. (2) Read the resources at http://ocaml-tutorial.org/
43 type style = ret * args
45 | RErr (* 0 = ok, -1 = error *)
46 | RErrDispose (* Disposes handle, see hivex_close. *)
47 | RHive (* Returns a hive_h or NULL. *)
48 | RNode (* Returns hive_node_h or 0. *)
49 | RNodeNotFound (* See hivex_node_get_child. *)
50 | RNodeList (* Returns hive_node_h* or NULL. *)
51 | RValue (* Returns hive_value_h or 0. *)
52 | RValueList (* Returns hive_value_h* or NULL. *)
53 | RString (* Returns char* or NULL. *)
54 | RStringList (* Returns char** or NULL. *)
55 | RLenType (* See hivex_value_type. *)
56 | RLenTypeVal (* See hivex_value_value. *)
57 | RInt32 (* Returns int32. *)
58 | RInt64 (* Returns int64. *)
60 and args = argt list (* List of parameters. *)
62 and argt = (* Note, cannot be NULL/0 unless it
63 says so explicitly below. *)
65 | ANode of string (* hive_node_h *)
66 | AValue of string (* hive_value_h *)
67 | AString of string (* char* *)
68 | AStringNullable of string (* char* (can be NULL) *)
69 | AOpenFlags (* HIVEX_OPEN_* flags list. *)
70 | AUnusedFlags (* Flags arg that is always 0 *)
71 | ASetValues (* See hivex_node_set_values. *)
72 | ASetValue (* See hivex_node_set_value. *)
75 * https://secure.wikimedia.org/wikipedia/en/wiki/Windows_Registry#Keys_and_values
77 * It's unfortunate that in our original C binding we strayed away from
78 * the names that Windows uses (eg. REG_SZ for strings). We include
79 * both our names and the Windows names.
83 "Just a key without a value";
85 "A Windows string (encoding is unknown, but often UTF16-LE)";
86 2, "expand_string", "EXPAND_SZ",
87 "A Windows string that contains %env% (environment variable expansion)";
88 3, "binary", "BINARY",
91 "DWORD (32 bit integer), little endian";
92 5, "dword_be", "DWORD_BIG_ENDIAN",
93 "DWORD (32 bit integer), big endian";
95 "Symbolic link to another part of the registry tree";
96 7, "multiple_strings", "MULTI_SZ",
97 "Multiple Windows strings. See http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx";
98 8, "resource_list", "RESOURCE_LIST",
100 9, "full_resource_description", "FULL_RESOURCE_DESCRIPTOR",
101 "Resource descriptor";
102 10, "resource_requirements_list", "RESOURCE_REQUIREMENTS_LIST",
103 "Resouce requirements list";
104 11, "qword", "QWORD",
105 "QWORD (64 bit integer), unspecified endianness but usually little endian"
107 let max_hive_type = 11
109 (* Open flags (bitmask passed to AOpenFlags) *)
111 1, "VERBOSE", "Verbose messages";
112 2, "DEBUG", "Debug messages";
113 4, "WRITE", "Enable writes to the hive";
118 "open", (RHive, [AString "filename"; AOpenFlags]),
121 Opens the hive named C<filename> for reading.
123 Flags is an ORed list of the open flags (or C<0> if you don't
124 want to pass any flags). These flags are defined:
128 =item HIVEX_OPEN_VERBOSE
132 =item HIVEX_OPEN_DEBUG
134 Very verbose messages, suitable for debugging problems in the library
137 This is also selected if the C<HIVEX_DEBUG> environment variable
140 =item HIVEX_OPEN_WRITE
142 Open the hive for writing. If omitted, the hive is read-only.
144 See L<hivex(3)/WRITING TO HIVE FILES>.
148 "close", (RErrDispose, [AHive]),
149 "close a hive handle",
151 Close a hive handle and free all associated resources.
153 Note that any uncommitted writes are I<not> committed by this call,
154 but instead are lost. See L<hivex(3)/WRITING TO HIVE FILES>.";
156 "root", (RNode, [AHive]),
157 "return the root node of the hive",
159 Return root node of the hive. All valid hives must contain a root node.";
161 "last_modified", (RInt64, [AHive]),
162 "return the modification time from the header of the hive",
164 Return the modification time from the header of the hive.
166 The returned value is a Windows filetime.
167 To convert this to a Unix C<time_t> see:
168 L<http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux/6161842#6161842>";
170 "node_name", (RString, [AHive; ANode "node"]),
171 "return the name of the node",
173 Return the name of the node.
175 Note that the name of the root node is a dummy, such as
176 C<$$$PROTO.HIV> (other names are possible: it seems to depend on the
177 tool or program that created the hive in the first place). You can
178 only know the \"real\" name of the root node by knowing which registry
179 file this hive originally comes from, which is knowledge that is
180 outside the scope of this library.";
182 "node_timestamp", (RInt64, [AHive; ANode "node"]),
183 "return the modification time of the node",
185 Return the modification time of the node.
187 The returned value is a Windows filetime.
188 To convert this to a Unix C<time_t> see:
189 L<http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux/6161842#6161842>";
191 "node_children", (RNodeList, [AHive; ANode "node"]),
192 "return children of node",
194 Return an array of nodes which are the subkeys
195 (children) of C<node>.";
197 "node_get_child", (RNodeNotFound, [AHive; ANode "node"; AString "name"]),
198 "return named child of node",
200 Return the child of node with the name C<name>, if it exists.
202 The name is matched case insensitively.";
204 "node_parent", (RNode, [AHive; ANode "node"]),
205 "return the parent of node",
207 Return the parent of C<node>.
209 The parent pointer of the root node in registry files that we
210 have examined seems to be invalid, and so this function will
211 return an error if called on the root node.";
213 "node_values", (RValueList, [AHive; ANode "node"]),
214 "return (key, value) pairs attached to a node",
216 Return the array of (key, value) pairs attached to this node.";
218 "node_get_value", (RValue, [AHive; ANode "node"; AString "key"]),
219 "return named key at node",
221 Return the value attached to this node which has the name C<key>,
224 The key name is matched case insensitively.
226 Note that to get the default key, you should pass the empty
227 string C<\"\"> here. The default key is often written C<\"@\">, but
228 inside hives that has no meaning and won't give you the
231 "value_key", (RString, [AHive; AValue "val"]),
232 "return the key of a (key, value) pair",
234 Return the key (name) of a (key, value) pair. The name
235 is reencoded as UTF-8 and returned as a string.
237 The string should be freed by the caller when it is no longer needed.
239 Note that this function can return a zero-length string. In the
240 context of Windows Registries, this means that this value is the
241 default key for this node in the tree. This is usually written
244 "value_type", (RLenType, [AHive; AValue "val"]),
245 "return data length and data type of a value",
247 Return the data length and data type of the value in this (key, value)
248 pair. See also C<hivex_value_value> which returns all this
249 information, and the value itself. Also, C<hivex_value_*> functions
250 below which can be used to return the value in a more useful form when
251 you know the type in advance.";
253 "value_value", (RLenTypeVal, [AHive; AValue "val"]),
254 "return data length, data type and data of a value",
256 Return the value of this (key, value) pair. The value should
257 be interpreted according to its type (see C<hive_type>).";
259 "value_string", (RString, [AHive; AValue "val"]),
260 "return value as a string",
262 If this value is a string, return the string reencoded as UTF-8
263 (as a C string). This only works for values which have type
264 C<hive_t_string>, C<hive_t_expand_string> or C<hive_t_link>.";
266 "value_multiple_strings", (RStringList, [AHive; AValue "val"]),
267 "return value as multiple strings",
269 If this value is a multiple-string, return the strings reencoded
270 as UTF-8 (in C, as a NULL-terminated array of C strings, in other
271 language bindings, as a list of strings). This only
272 works for values which have type C<hive_t_multiple_strings>.";
274 "value_dword", (RInt32, [AHive; AValue "val"]),
275 "return value as a DWORD",
277 If this value is a DWORD (Windows int32), return it. This only works
278 for values which have type C<hive_t_dword> or C<hive_t_dword_be>.";
280 "value_qword", (RInt64, [AHive; AValue "val"]),
281 "return value as a QWORD",
283 If this value is a QWORD (Windows int64), return it. This only
284 works for values which have type C<hive_t_qword>.";
286 "commit", (RErr, [AHive; AStringNullable "filename"; AUnusedFlags]),
287 "commit (write) changes to file",
289 Commit (write) any changes which have been made.
291 C<filename> is the new file to write. If C<filename> is null/undefined
292 then we overwrite the original file (ie. the file name that was passed to
295 Note this does not close the hive handle. You can perform further
296 operations on the hive after committing, including making more
297 modifications. If you no longer wish to use the hive, then you
298 should close the handle after committing.";
300 "node_add_child", (RNode, [AHive; ANode "parent"; AString "name"]),
303 Add a new child node named C<name> to the existing node C<parent>.
304 The new child initially has no subnodes and contains no keys or
305 values. The sk-record (security descriptor) is inherited from
308 The parent must not have an existing child called C<name>, so if you
309 want to overwrite an existing child, call C<hivex_node_delete_child>
312 "node_delete_child", (RErr, [AHive; ANode "node"]),
315 Delete the node C<node>. All values at the node and all subnodes are
316 deleted (recursively). The C<node> handle and the handles of all
317 subnodes become invalid. You cannot delete the root node.";
319 "node_set_values", (RErr, [AHive; ANode "node"; ASetValues; AUnusedFlags]),
320 "set (key, value) pairs at a node",
322 This call can be used to set all the (key, value) pairs
325 C<node> is the node to modify.";
327 "node_set_value", (RErr, [AHive; ANode "node"; ASetValue; AUnusedFlags]),
328 "set a single (key, value) pair at a given node",
330 This call can be used to replace a single C<(key, value)> pair
331 stored in C<node>. If the key does not already exist, then a
332 new key is added. Key matching is case insensitive.
334 C<node> is the node to modify.";
337 (* Used to memoize the result of pod2text. *)
338 let pod2text_memo_filename = "generator/.pod2text.data"
339 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
341 let chan = open_in pod2text_memo_filename in
342 let v = input_value chan in
346 _ -> Hashtbl.create 13
347 let pod2text_memo_updated () =
348 let chan = open_out pod2text_memo_filename in
349 output_value chan pod2text_memo;
353 * Note we don't want to use any external OCaml libraries which
354 * makes this a bit harder than it should be.
356 module StringMap = Map.Make (String)
358 let failwithf fs = ksprintf failwith fs
360 let unique = let i = ref 0 in fun () -> incr i; !i
362 let replace_char s c1 c2 =
363 let s2 = String.copy s in
365 for i = 0 to String.length s2 - 1 do
366 if String.unsafe_get s2 i = c1 then (
367 String.unsafe_set s2 i c2;
371 if not !r then s else s2
375 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
377 let triml ?(test = isspace) str =
379 let n = ref (String.length str) in
380 while !n > 0 && test str.[!i]; do
385 else String.sub str !i !n
387 let trimr ?(test = isspace) str =
388 let n = ref (String.length str) in
389 while !n > 0 && test str.[!n-1]; do
392 if !n = String.length str then str
393 else String.sub str 0 !n
395 let trim ?(test = isspace) str =
396 trimr ~test (triml ~test str)
399 let len = String.length s in
400 let sublen = String.length sub in
402 if i <= len-sublen then (
405 if s.[i+j] = sub.[j] then loop2 (j+1)
411 if r = -1 then loop (i+1) else r
417 let rec replace_str s s1 s2 =
418 let len = String.length s in
419 let sublen = String.length s1 in
423 let s' = String.sub s 0 i in
424 let s'' = String.sub s (i+sublen) (len-i-sublen) in
425 s' ^ s2 ^ replace_str s'' s1 s2
428 let rec string_split sep str =
429 let len = String.length str in
430 let seplen = String.length sep in
431 let i = find str sep in
434 let s' = String.sub str 0 i in
435 let s'' = String.sub str (i+seplen) (len-i-seplen) in
436 s' :: string_split sep s''
439 let files_equal n1 n2 =
440 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
441 match Sys.command cmd with
444 | i -> failwithf "%s: failed with error code %d" cmd i
446 let rec filter_map f = function
450 | Some y -> y :: filter_map f xs
451 | None -> filter_map f xs
453 let rec find_map f = function
454 | [] -> raise Not_found
458 | None -> find_map f xs
461 let rec loop i = function
463 | x :: xs -> f i x; loop (i+1) xs
468 let rec loop i = function
470 | x :: xs -> let r = f i x in r :: loop (i+1) xs
474 let count_chars c str =
476 for i = 0 to String.length str - 1 do
477 if c = String.unsafe_get str i then incr count
481 let name_of_argt = function
483 | ANode n | AValue n | AString n | AStringNullable n -> n
484 | AOpenFlags | AUnusedFlags -> "flags"
485 | ASetValues -> "values"
488 (* Check function names etc. for consistency. *)
489 let check_functions () =
490 let contains_uppercase str =
491 let len = String.length str in
493 if i >= len then false
496 if c >= 'A' && c <= 'Z' then true
503 (* Check function names. *)
505 fun (name, _, _, _) ->
506 if String.length name >= 7 && String.sub name 0 7 = "hivex" then
507 failwithf "function name %s does not need 'hivex' prefix" name;
509 failwithf "function name is empty";
510 if name.[0] < 'a' || name.[0] > 'z' then
511 failwithf "function name %s must start with lowercase a-z" name;
512 if String.contains name '-' then
513 failwithf "function name %s should not contain '-', use '_' instead."
517 (* Check function parameter/return names. *)
519 fun (name, style, _, _) ->
520 let check_arg_ret_name n =
521 if contains_uppercase n then
522 failwithf "%s param/ret %s should not contain uppercase chars"
524 if String.contains n '-' || String.contains n '_' then
525 failwithf "%s param/ret %s should not contain '-' or '_'"
528 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;
529 if n = "int" || n = "char" || n = "short" || n = "long" then
530 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
531 if n = "i" || n = "n" then
532 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
533 if n = "argv" || n = "args" then
534 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
536 (* List Haskell, OCaml and C keywords here.
537 * http://www.haskell.org/haskellwiki/Keywords
538 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
539 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
540 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
541 * |perl -pe 's/(.+)/"$1";/'|fmt -70
542 * Omitting _-containing words, since they're handled above.
543 * Omitting the OCaml reserved word, "val", is ok,
544 * and saves us from renaming several parameters.
547 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
548 "char"; "class"; "const"; "constraint"; "continue"; "data";
549 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
550 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
551 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
552 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
553 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
555 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
556 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
557 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
558 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
559 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
560 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
561 "volatile"; "when"; "where"; "while";
563 if List.mem n reserved then
564 failwithf "%s has param/ret using reserved word %s" name n;
567 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
570 (* Check short descriptions. *)
572 fun (name, _, shortdesc, _) ->
573 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
574 failwithf "short description of %s should begin with lowercase." name;
575 let c = shortdesc.[String.length shortdesc-1] in
576 if c = '\n' || c = '.' then
577 failwithf "short description of %s should not end with . or \\n." name
580 (* Check long dscriptions. *)
582 fun (name, _, _, longdesc) ->
583 if longdesc.[String.length longdesc-1] = '\n' then
584 failwithf "long description of %s should not end with \\n." name
587 (* 'pr' prints to the current output file. *)
588 let chan = ref Pervasives.stdout
593 let i = count_chars '\n' str in
595 output_string !chan str
598 let copyright_years =
599 let this_year = 1900 + (localtime (time ())).tm_year in
600 if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
602 (* Generate a header block in a number of standard styles. *)
604 | CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
606 type license = GPLv2plus | LGPLv2plus | GPLv2 | LGPLv2
608 let generate_header ?(extra_inputs = []) comment license =
609 let inputs = "generator/generator.ml" :: extra_inputs in
610 let c = match comment with
611 | CStyle -> pr "/* "; " *"
612 | CPlusPlusStyle -> pr "// "; "//"
613 | HashStyle -> pr "# "; "#"
614 | OCamlStyle -> pr "(* "; " *"
615 | HaskellStyle -> pr "{- "; " "
616 | PODCommentStyle -> pr "=begin comment\n\n "; "" in
617 pr "hivex generated file\n";
618 pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
619 List.iter (pr "%s %s\n" c) inputs;
620 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
622 pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
623 pr "%s Derived from code by Petter Nordahl-Hagen under a compatible license:\n" c;
624 pr "%s Copyright (c) 1997-2007 Petter Nordahl-Hagen.\n" c;
625 pr "%s Derived from code by Markus Stephany under a compatible license:\n" c;
626 pr "%s Copyright (c)2000-2004, Markus Stephany.\n" c;
630 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
631 pr "%s it under the terms of the GNU General Public License as published by\n" c;
632 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
633 pr "%s (at your option) any later version.\n" c;
635 pr "%s This program is distributed in the hope that it will be useful,\n" c;
636 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
637 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
638 pr "%s GNU General Public License for more details.\n" c;
640 pr "%s You should have received a copy of the GNU General Public License along\n" c;
641 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
642 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
645 pr "%s This library is free software; you can redistribute it and/or\n" c;
646 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
647 pr "%s License as published by the Free Software Foundation; either\n" c;
648 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
650 pr "%s This library is distributed in the hope that it will be useful,\n" c;
651 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
652 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
653 pr "%s Lesser General Public License for more details.\n" c;
655 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
656 pr "%s License along with this library; if not, write to the Free Software\n" c;
657 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
660 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
661 pr "%s it under the terms of the GNU General Public License as published by\n" c;
662 pr "%s the Free Software Foundation; version 2 of the License only.\n" c;
664 pr "%s This program is distributed in the hope that it will be useful,\n" c;
665 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
666 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
667 pr "%s GNU General Public License for more details.\n" c;
669 pr "%s You should have received a copy of the GNU General Public License along\n" c;
670 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
671 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
674 pr "%s This library is free software; you can redistribute it and/or\n" c;
675 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
676 pr "%s License as published by the Free Software Foundation;\n" c;
677 pr "%s version 2.1 of the License only.\n" c;
679 pr "%s This library is distributed in the hope that it will be useful,\n" c;
680 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
681 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
682 pr "%s Lesser General Public License for more details.\n" c;
684 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
685 pr "%s License along with this library; if not, write to the Free Software\n" c;
686 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
689 | CStyle -> pr " */\n"
692 | OCamlStyle -> pr " *)\n"
693 | HaskellStyle -> pr "-}\n"
694 | PODCommentStyle -> pr "\n=end comment\n"
698 (* Start of main code generation functions below this line. *)
700 let rec generate_c_header () =
701 generate_header CStyle LGPLv2;
713 /* NOTE: This API is documented in the man page hivex(3). */
716 typedef struct hive_h hive_h;
718 /* Nodes and values. */
719 typedef size_t hive_node_h;
720 typedef size_t hive_value_h;
724 # define HIVEX_NO_KEY ENOKEY
726 # define HIVEX_NO_KEY ENOENT
729 /* Pre-defined types. */
733 fun (t, old_style, new_style, description) ->
734 pr " /* %s */\n" description;
735 pr " hive_t_REG_%s,\n" new_style;
736 pr "#define hive_t_%s hive_t_REG_%s\n" old_style new_style;
742 typedef enum hive_type hive_type;
744 /* Bitmask of flags passed to hivex_open. */
747 fun (v, flag, description) ->
748 pr " /* %s */\n" description;
749 pr "#define HIVEX_OPEN_%-10s %d\n" flag v;
754 /* Array of (key, value) pairs passed to hivex_node_set_values. */
755 struct hive_set_value {
761 typedef struct hive_set_value hive_set_value;
765 pr "/* Functions. */\n";
767 (* Function declarations. *)
769 fun (shortname, style, _, _) ->
770 let name = "hivex_" ^ shortname in
771 generate_c_prototype ~extern:true name style
774 (* The visitor pattern. *)
776 /* Visit all nodes. This is specific to the C API and is not made
777 * available to other languages. This is because of the complexity
778 * of binding callbacks in other languages, but also because other
779 * languages make it much simpler to iterate over a tree.
781 struct hivex_visitor {
782 int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name);
783 int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name);
784 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);
785 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);
786 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);
787 int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t);
788 int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t);
789 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);
790 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);
791 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);
792 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);
795 #define HIVEX_VISIT_SKIP_BAD 1
797 extern int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
798 extern int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
802 (* Finish the header file. *)
808 #endif /* HIVEX_H_ */
811 and generate_c_prototype ?(extern = false) name style =
812 if extern then pr "extern ";
813 (match fst style with
815 | RErrDispose -> pr "int "
816 | RHive -> pr "hive_h *"
817 | RNode -> pr "hive_node_h "
818 | RNodeNotFound -> pr "hive_node_h "
819 | RNodeList -> pr "hive_node_h *"
820 | RValue -> pr "hive_value_h "
821 | RValueList -> pr "hive_value_h *"
822 | RString -> pr "char *"
823 | RStringList -> pr "char **"
824 | RLenType -> pr "int "
825 | RLenTypeVal -> pr "char *"
826 | RInt32 -> pr "int32_t "
827 | RInt64 -> pr "int64_t "
830 let comma = ref false in
833 if !comma then pr ", "; comma := true;
835 | AHive -> pr "hive_h *h"
836 | ANode n -> pr "hive_node_h %s" n
837 | AValue n -> pr "hive_value_h %s" n
838 | AString n | AStringNullable n -> pr "const char *%s" n
839 | AOpenFlags | AUnusedFlags -> pr "int flags"
840 | ASetValues -> pr "size_t nr_values, const hive_set_value *values"
841 | ASetValue -> pr "const hive_set_value *val"
843 (match fst style with
844 | RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len"
849 and generate_c_pod () =
850 generate_header PODCommentStyle GPLv2;
857 hivex - Windows Registry \"hive\" extraction library
865 fun (shortname, style, _, _) ->
866 let name = "hivex_" ^ shortname in
868 generate_c_prototype ~extern:false name style;
873 Link with I<-lhivex>.
877 Hivex is a library for extracting the contents of Windows Registry
878 \"hive\" files. It is designed to be secure against buggy or malicious
881 Unlike other tools in this area, it doesn't use the textual .REG
882 format, because parsing that is as much trouble as parsing the
883 original binary format. Instead it makes the file available
884 through a C API, and then wraps this API in higher level scripting
887 There is a separate program to export the hive as XML
888 (see L<hivexml(1)>), or to navigate the file (see L<hivexsh(1)>).
889 There is also a Perl script to export and merge the
890 file as a textual .REG (regedit) file, see L<hivexregedit(1)>.
892 If you just want to export or modify the Registry of a Windows
893 virtual machine, you should look at L<virt-win-reg(1)>.
895 Hivex is also comes with language bindings for
896 OCaml, Perl and Python.
902 This handle describes an open hive file.
904 =head2 C<hive_node_h>
906 This is a node handle, an integer but opaque outside the library.
907 Valid node handles cannot be 0. The library returns 0 in some
908 situations to indicate an error.
912 The enum below describes the possible types for the value(s)
913 stored at each node. Note that you should not trust the
914 type field in a Windows Registry, as it very often has no
915 relationship to reality. Some applications use their own
916 types. The encoding of strings is not specified. Some
917 programs store everything (including strings) in binary blobs.
922 fun (t, _, new_style, description) ->
923 pr " /* %s */\n" description;
924 pr " hive_t_REG_%s = %d,\n" new_style t
929 =head2 C<hive_value_h>
931 This is a value handle, an integer but opaque outside the library.
932 Valid value handles cannot be 0. The library returns 0 in some
933 situations to indicate an error.
935 =head2 C<hive_set_value>
937 The typedef C<hive_set_value> is used in conjunction with the
938 C<hivex_node_set_values> call described below.
940 struct hive_set_value {
941 char *key; /* key - a UTF-8 encoded ASCIIZ string */
942 hive_type t; /* type of value field */
943 size_t len; /* length of value field in bytes */
944 char *value; /* value field */
946 typedef struct hive_set_value hive_set_value;
948 To set the default value for a node, you have to pass C<key = \"\">.
950 Note that the C<value> field is just treated as a list of bytes, and
951 is stored directly in the hive. The caller has to ensure correct
952 encoding and endianness, for example converting dwords to little
955 The correct type and encoding for values depends on the node and key
956 in the registry, the version of Windows, and sometimes even changes
957 between versions of Windows for the same key. We don't document it
958 here. Often it's not documented at all.
964 fun (shortname, style, _, longdesc) ->
965 let name = "hivex_" ^ shortname in
966 pr "=head2 %s\n" name;
968 generate_c_prototype ~extern:false name style;
973 if List.mem AUnusedFlags (snd style) then
974 pr "The flags parameter is unused. Always pass 0.\n\n";
976 if List.mem ASetValues (snd style) then
977 pr "C<values> is an array of (key, value) pairs. There
978 should be C<nr_values> elements in this array.
980 Any existing values stored at the node are discarded, and their
981 C<hive_value_h> handles become invalid. Thus you can remove all
982 values stored at C<node> by passing C<nr_values = 0>.\n\n";
984 if List.mem ASetValue (snd style) then
985 pr "C<value> is a single (key, value) pair.
987 Existing C<hive_value_h> handles become invalid.\n\n";
989 (match fst style with
992 Returns 0 on success.
993 On error this returns -1 and sets errno.\n\n"
996 Returns 0 on success.
997 On error this returns -1 and sets errno.
999 This function frees the hive handle (even if it returns an error).
1000 The hive handle must not be used again after calling this function.\n\n"
1003 Returns a new hive handle.
1004 On error this returns NULL and sets errno.\n\n"
1007 Returns a node handle.
1008 On error this returns 0 and sets errno.\n\n"
1011 Returns a node handle.
1012 If the node was not found, this returns 0 without setting errno.
1013 On error this returns 0 and sets errno.\n\n"
1016 Returns a 0-terminated array of nodes.
1017 The array must be freed by the caller when it is no longer needed.
1018 On error this returns NULL and sets errno.\n\n"
1021 Returns a value handle.
1022 On error this returns 0 and sets errno.\n\n"
1025 Returns a 0-terminated array of values.
1026 The array must be freed by the caller when it is no longer needed.
1027 On error this returns NULL and sets errno.\n\n"
1031 The string must be freed by the caller when it is no longer needed.
1032 On error this returns NULL and sets errno.\n\n"
1035 Returns a NULL-terminated array of C strings.
1036 The strings and the array must all be freed by the caller when
1037 they are no longer needed.
1038 On error this returns NULL and sets errno.\n\n"
1041 Returns 0 on success.
1042 On error this returns -1 and sets errno.\n\n"
1045 The value is returned as an array of bytes (of length C<len>).
1046 The value must be freed by the caller when it is no longer needed.
1047 On error this returns NULL and sets errno.\n\n"
1048 | RInt32 | RInt64 -> ()
1053 =head1 WRITING TO HIVE FILES
1055 The hivex library supports making limited modifications to hive files.
1056 We have tried to implement this very conservatively in order to reduce
1057 the chance of corrupting your registry. However you should be careful
1058 and take back-ups, since Microsoft has never documented the hive
1059 format, and so it is possible there are nuances in the
1060 reverse-engineered format that we do not understand.
1062 To be able to modify a hive, you must pass the C<HIVEX_OPEN_WRITE>
1063 flag to C<hivex_open>, otherwise any write operation will return with
1066 The write operations shown below do not modify the on-disk file
1067 immediately. You must call C<hivex_commit> in order to write the
1068 changes to disk. If you call C<hivex_close> without committing then
1069 any writes are discarded.
1071 Hive files internally consist of a \"memory dump\" of binary blocks
1072 (like the C heap), and some of these blocks can be unused. The hivex
1073 library never reuses these unused blocks. Instead, to ensure
1074 robustness in the face of the partially understood on-disk format,
1075 hivex only allocates new blocks after the end of the file, and makes
1076 minimal modifications to existing structures in the file to point to
1077 these new blocks. This makes hivex slightly less disk-efficient than
1078 it could be, but disk is cheap, and registry modifications tend to be
1081 When deleting nodes, it is possible that this library may leave
1082 unreachable live blocks in the hive. This is because certain parts of
1083 the hive disk format such as security (sk) records and big data (db)
1084 records and classname fields are not well understood (and not
1085 documented at all) and we play it safe by not attempting to modify
1086 them. Apart from wasting a little bit of disk space, it is not
1087 thought that unreachable blocks are a problem.
1089 =head2 WRITE OPERATIONS WHICH ARE NOT SUPPORTED
1095 Changing the root node.
1099 Creating a new hive file from scratch. This is impossible at present
1100 because not all fields in the header are understood. In the hivex
1101 source tree is a file called C<images/minimal> which could be used as
1102 the basis for a new hive (but I<caveat emptor>).
1106 Modifying or deleting single values at a node.
1110 Modifying security key (sk) records or classnames.
1111 Previously we did not understand these records. However now they
1112 are well-understood and we could add support if it was required
1113 (but nothing much really uses them).
1117 =head1 VISITING ALL NODES
1119 The visitor pattern is useful if you want to visit all nodes
1120 in the tree or all nodes below a certain point in the tree.
1122 First you set up your own C<struct hivex_visitor> with your
1125 Each of these callback functions should return 0 on success or -1
1126 on error. If any callback returns -1, then the entire visit
1127 terminates immediately. If you don't need a callback function at
1128 all, set the function pointer to NULL.
1130 struct hivex_visitor {
1131 int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name);
1132 int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name);
1133 int (*value_string) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1134 hive_type t, size_t len, const char *key, const char *str);
1135 int (*value_multiple_strings) (hive_h *, void *opaque, hive_node_h,
1136 hive_value_h, hive_type t, size_t len, const char *key, char **argv);
1137 int (*value_string_invalid_utf16) (hive_h *, void *opaque, hive_node_h,
1138 hive_value_h, hive_type t, size_t len, const char *key,
1140 int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1141 hive_type t, size_t len, const char *key, int32_t);
1142 int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1143 hive_type t, size_t len, const char *key, int64_t);
1144 int (*value_binary) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1145 hive_type t, size_t len, const char *key, const char *value);
1146 int (*value_none) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1147 hive_type t, size_t len, const char *key, const char *value);
1148 int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1149 hive_type t, size_t len, const char *key, const char *value);
1150 /* If value_any callback is not NULL, then the other value_*
1151 * callbacks are not used, and value_any is called on all values.
1153 int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1154 hive_type t, size_t len, const char *key, const char *value);
1161 int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
1163 Visit all the nodes recursively in the hive C<h>.
1165 C<visitor> should be a C<hivex_visitor> structure with callback
1166 fields filled in as required (unwanted callbacks can be set to
1167 NULL). C<len> must be the length of the 'visitor' struct (you
1168 should pass C<sizeof (struct hivex_visitor)> for this).
1170 This returns 0 if the whole recursive visit was completed
1171 successfully. On error this returns -1. If one of the callback
1172 functions returned an error than we don't touch errno. If the
1173 error was generated internally then we set errno.
1175 You can skip bad registry entries by setting C<flag> to
1176 C<HIVEX_VISIT_SKIP_BAD>. If this flag is not set, then a bad registry
1177 causes the function to return an error immediately.
1179 This function is robust if the registry contains cycles or
1180 pointers which are invalid or outside the registry. It detects
1181 these cases and returns an error.
1183 =item hivex_visit_node
1185 int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque);
1187 Same as C<hivex_visit> but instead of starting out at the root, this
1192 =head1 THE STRUCTURE OF THE WINDOWS REGISTRY
1194 Note: To understand the relationship between hives and the common
1195 Windows Registry keys (like C<HKEY_LOCAL_MACHINE>) please see the
1196 Wikipedia page on the Windows Registry.
1198 The Windows Registry is split across various binary files, each
1199 file being known as a \"hive\". This library only handles a single
1200 hive file at a time.
1202 Hives are n-ary trees with a single root. Each node in the tree
1205 Each node in the tree (including non-leaf nodes) may have an
1206 arbitrary list of (key, value) pairs attached to it. It may
1207 be the case that one of these pairs has an empty key. This
1208 is referred to as the default key for the node.
1210 The (key, value) pairs are the place where the useful data is
1211 stored in the registry. The key is always a string (possibly the
1212 empty string for the default key). The value is a typed object
1213 (eg. string, int32, binary, etc.).
1215 =head2 RELATIONSHIP TO .REG FILES
1217 The hivex C library does not care about or deal with Windows .REG
1218 files. Instead we push this complexity up to the Perl
1219 L<Win::Hivex(3)> library and the Perl programs
1220 L<hivexregedit(1)> and L<virt-win-reg(1)>.
1221 Nevertheless it is useful to look at the relationship between the
1222 Registry and .REG files because they are so common.
1224 A .REG file is a textual representation of the registry, or part of the
1225 registry. The actual registry hives that Windows uses are binary
1226 files. There are a number of Windows and Linux tools that let you
1227 generate .REG files, or merge .REG files back into the registry hives.
1228 Notable amongst them is Microsoft's REGEDIT program (formerly known as
1231 A typical .REG file will contain many sections looking like this:
1233 [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack]
1234 \"@\"=\"Generic Stack\"
1235 \"TileInfo\"=\"prop:System.FileCount\"
1236 \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\"
1237 \"ThumbnailCutoff\"=dword:00000000
1238 \"FriendlyTypeName\"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,\\
1239 6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,\\
1240 33,00,32,00,5c,00,73,00,65,00,61,00,72,00,63,00,68,00,66,00,\\
1241 6f,00,6c,00,64,00,65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,\\
1242 2d,00,39,00,30,00,32,00,38,00,00,00,d8
1244 Taking this one piece at a time:
1246 [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack]
1248 This is the path to this node in the registry tree. The first part,
1249 C<HKEY_LOCAL_MACHINE\\SOFTWARE> means that this comes from a hive
1250 file called C<C:\\WINDOWS\\SYSTEM32\\CONFIG\\SOFTWARE>.
1251 C<\\Classes\\Stack> is the real path part,
1252 starting at the root node of the C<SOFTWARE> hive.
1254 Below the node name is a list of zero or more key-value pairs. Any
1255 interior or leaf node in the registry may have key-value pairs
1258 \"@\"=\"Generic Stack\"
1260 This is the \"default key\". In reality (ie. inside the binary hive)
1261 the key string is the empty string. In .REG files this is written as
1262 C<@> but this has no meaning either in the hives themselves or in this
1263 library. The value is a string (type 1 - see C<enum hive_type>
1266 \"TileInfo\"=\"prop:System.FileCount\"
1268 This is a regular (key, value) pair, with the value being a type 1
1269 string. Note that inside the binary file the string is likely to be
1270 UTF-16LE encoded. This library converts to and from UTF-8 strings
1271 transparently in some cases.
1273 \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\"
1275 The value in this case has type 2 (expanded string) meaning that some
1276 %%...%% variables get expanded by Windows. (This library doesn't know
1277 or care about variable expansion).
1279 \"ThumbnailCutoff\"=dword:00000000
1281 The value in this case is a dword (type 4).
1283 \"FriendlyTypeName\"=hex(2):40,00,....
1285 This value is an expanded string (type 2) represented in the .REG file
1286 as a series of hex bytes. In this case the string appears to be a
1289 =head1 NOTE ON THE USE OF ERRNO
1291 Many functions in this library set errno to indicate errors. These
1292 are the values of errno you may encounter (this list is not
1299 Corrupt or unsupported Registry file format.
1307 Passed an invalid argument to the function.
1311 Followed a Registry pointer which goes outside
1312 the registry or outside a registry block.
1316 Registry contains cycles.
1320 Field in the registry out of range.
1324 Registry key already exists.
1328 Tried to write to a registry which is not opened for writing.
1332 =head1 ENVIRONMENT VARIABLES
1338 Setting HIVEX_DEBUG=1 will enable very verbose messages. This is
1339 useful for debugging problems with the library itself.
1352 L<http://libguestfs.org/>,
1355 L<http://en.wikipedia.org/wiki/Windows_Registry>.
1359 Richard W.M. Jones (C<rjones at redhat dot com>)
1363 Copyright (C) 2009-2010 Red Hat Inc.
1365 Derived from code by Petter Nordahl-Hagen under a compatible license:
1366 Copyright (C) 1997-2007 Petter Nordahl-Hagen.
1368 Derived from code by Markus Stephany under a compatible license:
1369 Copyright (C) 2000-2004 Markus Stephany.
1371 This library is free software; you can redistribute it and/or
1372 modify it under the terms of the GNU Lesser General Public
1373 License as published by the Free Software Foundation;
1374 version 2.1 of the License only.
1376 This library is distributed in the hope that it will be useful,
1377 but WITHOUT ANY WARRANTY; without even the implied warranty of
1378 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1379 Lesser General Public License for more details.
1382 (* Generate the linker script which controls the visibility of
1383 * symbols in the public ABI and ensures no other symbols get
1384 * exported accidentally.
1386 and generate_linker_script () =
1387 generate_header HashStyle GPLv2plus;
1395 List.map (fun (name, _, _, _) -> "hivex_" ^ name)
1397 let globals = List.sort compare (globals @ functions) in
1401 List.iter (pr " %s;\n") globals;
1408 and generate_ocaml_interface () =
1409 generate_header OCamlStyle LGPLv2plus;
1413 (** A [hive_h] hive file handle. *)
1417 (** Nodes and values. *)
1419 exception Error of string * Unix.error * string
1420 (** Error raised by a function.
1422 The first parameter is the name of the function which raised the error.
1423 The second parameter is the errno (see the [Unix] module). The third
1424 parameter is a human-readable string corresponding to the errno.
1426 See hivex(3) for a partial list of interesting errno values that
1427 can be generated by the library. *)
1428 exception Handle_closed of string
1429 (** This exception is raised if you call a function on a closed handle. *)
1435 fun (t, _, new_style, description) ->
1437 pr " | REG_%s (** %s *)\n" new_style description
1441 | REG_UNKNOWN of int32 (** unknown type *)
1442 (** Hive type field. *)
1448 fun (v, flag, description) ->
1449 assert (1 lsl i = v);
1450 pr " | OPEN_%s (** %s *)\n" flag description
1454 (** Open flags for {!open_file} call. *)
1461 (** (key, value) pair passed (as an array) to {!node_set_values}. *)
1465 fun (name, style, shortdesc, _) ->
1467 generate_ocaml_prototype name style;
1468 pr "(** %s *)\n" shortdesc
1471 and generate_ocaml_implementation () =
1472 generate_header OCamlStyle LGPLv2plus;
1479 exception Error of string * Unix.error * string
1480 exception Handle_closed of string
1482 (* Give the exceptions names, so they can be raised from the C code. *)
1484 Callback.register_exception \"ocaml_hivex_error\"
1485 (Error (\"\", Unix.EUNKNOWNERR 0, \"\"));
1486 Callback.register_exception \"ocaml_hivex_closed\" (Handle_closed \"\")
1492 fun (t, _, new_style, _) ->
1494 pr " | REG_%s\n" new_style
1498 | REG_UNKNOWN of int32
1504 fun (v, flag, description) ->
1505 assert (1 lsl i = v);
1506 pr " | OPEN_%s (** %s *)\n" flag description
1520 fun (name, style, _, _) ->
1521 generate_ocaml_prototype ~is_external:true name style
1524 and generate_ocaml_prototype ?(is_external = false) name style =
1525 let ocaml_name = if name = "open" then "open_file" else name in
1527 if is_external then pr "external " else pr "val ";
1528 pr "%s : " ocaml_name;
1531 | AHive -> pr "t -> "
1532 | ANode _ -> pr "node -> "
1533 | AValue _ -> pr "value -> "
1534 | AString _ -> pr "string -> "
1535 | AStringNullable _ -> pr "string option -> "
1536 | AOpenFlags -> pr "open_flag list -> "
1537 | AUnusedFlags -> ()
1538 | ASetValues -> pr "set_value array -> "
1539 | ASetValue -> pr "set_value -> "
1541 (match fst style with
1542 | RErr -> pr "unit" (* all errors are turned into exceptions *)
1543 | RErrDispose -> pr "unit"
1545 | RNode -> pr "node"
1546 | RNodeNotFound -> pr "node"
1547 | RNodeList -> pr "node array"
1548 | RValue -> pr "value"
1549 | RValueList -> pr "value array"
1550 | RString -> pr "string"
1551 | RStringList -> pr "string array"
1552 | RLenType -> pr "hive_type * int"
1553 | RLenTypeVal -> pr "hive_type * string"
1554 | RInt32 -> pr "int32"
1555 | RInt64 -> pr "int64"
1558 pr " = \"ocaml_hivex_%s\"" name;
1561 and generate_ocaml_c () =
1562 generate_header CStyle LGPLv2plus;
1573 #include <caml/config.h>
1574 #include <caml/alloc.h>
1575 #include <caml/callback.h>
1576 #include <caml/custom.h>
1577 #include <caml/fail.h>
1578 #include <caml/memory.h>
1579 #include <caml/mlvalues.h>
1580 #include <caml/signals.h>
1582 #ifdef HAVE_CAML_UNIXSUPPORT_H
1583 #include <caml/unixsupport.h>
1585 extern value unix_error_of_code (int errcode);
1588 #ifndef HAVE_CAML_RAISE_WITH_ARGS
1590 caml_raise_with_args (value tag, int nargs, value args[])
1593 CAMLxparamN (args, nargs);
1597 bucket = caml_alloc_small (1 + nargs, 0);
1598 Field(bucket, 0) = tag;
1599 for (i = 0; i < nargs; i++) Field(bucket, 1 + i) = args[i];
1607 #define Hiveh_val(v) (*((hive_h **)Data_custom_val(v)))
1608 static value Val_hiveh (hive_h *);
1609 static int HiveOpenFlags_val (value);
1610 static hive_set_value *HiveSetValue_val (value);
1611 static hive_set_value *HiveSetValues_val (value);
1612 static hive_type HiveType_val (value);
1613 static value Val_hive_type (hive_type);
1614 static value copy_int_array (size_t *);
1615 static value copy_type_len (size_t, hive_type);
1616 static value copy_type_value (const char *, size_t, hive_type);
1617 static void raise_error (const char *) Noreturn;
1618 static void raise_closed (const char *) Noreturn;
1624 fun (name, style, _, _) ->
1625 pr "/* Automatically generated wrapper for function\n";
1626 pr " * "; generate_ocaml_prototype name style;
1632 | ASetValues -> ["nrvalues"; "values"]
1633 | AUnusedFlags -> ["0"]
1634 | arg -> [name_of_argt arg]) (snd style) in
1636 match fst style with
1637 | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]]
1639 let c_params = List.concat c_params in
1642 filter_map (function
1643 | AUnusedFlags -> None
1644 | arg -> Some (name_of_argt arg ^ "v")) (snd style) in
1646 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
1647 pr "CAMLprim value ocaml_hivex_%s (value %s" name (List.hd params);
1648 List.iter (pr ", value %s") (List.tl params); pr ");\n";
1651 pr "CAMLprim value\n";
1652 pr "ocaml_hivex_%s (value %s" name (List.hd params);
1653 List.iter (pr ", value %s") (List.tl params);
1657 pr " CAMLparam%d (%s);\n"
1658 (List.length params) (String.concat ", " params);
1659 pr " CAMLlocal1 (rv);\n";
1665 pr " hive_h *h = Hiveh_val (hv);\n";
1666 pr " if (h == NULL)\n";
1667 pr " raise_closed (\"%s\");\n" name
1669 pr " hive_node_h %s = Int_val (%sv);\n" n n
1671 pr " hive_value_h %s = Int_val (%sv);\n" n n
1673 pr " const char *%s = String_val (%sv);\n" n n
1674 | AStringNullable n ->
1675 pr " const char *%s =\n" n;
1676 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
1679 pr " int flags = HiveOpenFlags_val (flagsv);\n"
1680 | AUnusedFlags -> ()
1682 pr " int nrvalues = Wosize_val (valuesv);\n";
1683 pr " hive_set_value *values = HiveSetValues_val (valuesv);\n"
1685 pr " hive_set_value *val = HiveSetValue_val (valv);\n"
1690 match fst style with
1691 | RErr -> pr " int r;\n"; "-1"
1692 | RErrDispose -> pr " int r;\n"; "-1"
1693 | RHive -> pr " hive_h *r;\n"; "NULL"
1694 | RNode -> pr " hive_node_h r;\n"; "0"
1697 pr " hive_node_h r;\n";
1699 | RNodeList -> pr " hive_node_h *r;\n"; "NULL"
1700 | RValue -> pr " hive_value_h r;\n"; "0"
1701 | RValueList -> pr " hive_value_h *r;\n"; "NULL"
1702 | RString -> pr " char *r;\n"; "NULL"
1703 | RStringList -> pr " char **r;\n"; "NULL"
1706 pr " size_t len;\n";
1707 pr " hive_type t;\n";
1711 pr " size_t len;\n";
1712 pr " hive_type t;\n";
1721 "-1 && errno != 0" in
1723 (* The libguestfs OCaml bindings call enter_blocking_section
1724 * here. However I don't think that is safe, because we are
1725 * holding pointers to caml strings during the call, and these
1726 * could be moved or freed by other threads. In any case, there
1727 * is very little reason to enter_blocking_section for any hivex
1728 * call, so don't do it. XXX
1730 (*pr " caml_enter_blocking_section ();\n";*)
1731 pr " r = hivex_%s (%s" name (List.hd c_params);
1732 List.iter (pr ", %s") (List.tl c_params);
1734 (*pr " caml_leave_blocking_section ();\n";*)
1737 (* Dispose of the hive handle (even if hivex_close returns error). *)
1738 (match fst style with
1740 pr " /* So we don't double-free in the finalizer. */\n";
1741 pr " Hiveh_val (hv) = NULL;\n";
1748 | AHive | ANode _ | AValue _ | AString _ | AStringNullable _
1749 | AOpenFlags | AUnusedFlags -> ()
1751 pr " free (values);\n";
1754 pr " free (val);\n";
1758 (* Check for errors. *)
1759 pr " if (r == %s)\n" error_code;
1760 pr " raise_error (\"%s\");\n" name;
1763 (match fst style with
1764 | RErr -> pr " rv = Val_unit;\n"
1765 | RErrDispose -> pr " rv = Val_unit;\n"
1766 | RHive -> pr " rv = Val_hiveh (r);\n"
1767 | RNode -> pr " rv = Val_int (r);\n"
1769 pr " if (r == 0)\n";
1770 pr " caml_raise_not_found ();\n";
1772 pr " rv = Val_int (r);\n"
1774 pr " rv = copy_int_array (r);\n";
1776 | RValue -> pr " rv = Val_int (r);\n"
1778 pr " rv = copy_int_array (r);\n";
1781 pr " rv = caml_copy_string (r);\n";
1784 pr " rv = caml_copy_string_array ((const char **) r);\n";
1785 pr " for (int i = 0; r[i] != NULL; ++i) free (r[i]);\n";
1787 | RLenType -> pr " rv = copy_type_len (len, t);\n"
1789 pr " rv = copy_type_value (r, len, t);\n";
1791 | RInt32 -> pr " rv = caml_copy_int32 (r);\n"
1792 | RInt64 -> pr " rv = caml_copy_int64 (r);\n"
1795 pr " CAMLreturn (rv);\n";
1803 HiveOpenFlags_val (value v)
1808 while (v != Val_int (0)) {
1810 flags |= 1 << Int_val (v2);
1817 static hive_set_value *
1818 HiveSetValue_val (value v)
1820 hive_set_value *val = malloc (sizeof (hive_set_value));
1822 val->key = String_val (Field (v, 0));
1823 val->t = HiveType_val (Field (v, 1));
1824 val->len = caml_string_length (Field (v, 2));
1825 val->value = String_val (Field (v, 2));
1830 static hive_set_value *
1831 HiveSetValues_val (value v)
1833 size_t nr_values = Wosize_val (v);
1834 hive_set_value *values = malloc (nr_values * sizeof (hive_set_value));
1838 for (i = 0; i < nr_values; ++i) {
1840 values[i].key = String_val (Field (v2, 0));
1841 values[i].t = HiveType_val (Field (v2, 1));
1842 values[i].len = caml_string_length (Field (v2, 2));
1843 values[i].value = String_val (Field (v2, 2));
1850 HiveType_val (value v)
1853 return Int_val (v); /* REG_NONE etc. */
1855 return Int32_val (Field (v, 0)); /* REG_UNKNOWN of int32 */
1859 Val_hive_type (hive_type t)
1865 CAMLreturn (Val_int (t));
1867 rv = caml_alloc (1, 0); /* REG_UNKNOWN of int32 */
1868 v = caml_copy_int32 (t);
1869 caml_modify (&Field (rv, 0), v);
1875 copy_int_array (size_t *xs)
1881 for (nr = 0; xs[nr] != 0; ++nr)
1884 CAMLreturn (Atom (0));
1886 rv = caml_alloc (nr, 0);
1887 for (i = 0; i < nr; ++i) {
1888 v = Val_int (xs[i]);
1889 Store_field (rv, i, v); /* Safe because v is not a block. */
1896 copy_type_len (size_t len, hive_type t)
1901 rv = caml_alloc (2, 0);
1902 v = Val_hive_type (t);
1903 Store_field (rv, 0, v);
1905 Store_field (rv, 1, len);
1910 copy_type_value (const char *r, size_t len, hive_type t)
1915 rv = caml_alloc (2, 0);
1916 v = Val_hive_type (t);
1917 Store_field (rv, 0, v);
1918 v = caml_alloc_string (len);
1919 memcpy (String_val (v), r, len);
1920 caml_modify (&Field (rv, 1), v);
1924 /* Raise exceptions. */
1926 raise_error (const char *function)
1928 /* Save errno early in case it gets trashed. */
1932 CAMLlocal3 (v1, v2, v3);
1934 v1 = caml_copy_string (function);
1935 v2 = unix_error_of_code (err);
1936 v3 = caml_copy_string (strerror (err));
1937 value vvv[] = { v1, v2, v3 };
1938 caml_raise_with_args (*caml_named_value (\"ocaml_hivex_error\"), 3, vvv);
1944 raise_closed (const char *function)
1949 v = caml_copy_string (function);
1950 caml_raise_with_arg (*caml_named_value (\"ocaml_hivex_closed\"), v);
1955 /* Allocate handles and deal with finalization. */
1957 hivex_finalize (value hv)
1959 hive_h *h = Hiveh_val (hv);
1960 if (h) hivex_close (h);
1963 static struct custom_operations hivex_custom_operations = {
1964 (char *) \"hivex_custom_operations\",
1966 custom_compare_default,
1967 custom_hash_default,
1968 custom_serialize_default,
1969 custom_deserialize_default
1973 Val_hiveh (hive_h *h)
1978 rv = caml_alloc_custom (&hivex_custom_operations,
1979 sizeof (hive_h *), 0, 1);
1986 and generate_perl_pm () =
1987 generate_header HashStyle LGPLv2plus;
1994 Win::Hivex - Perl bindings for reading and writing Windows Registry hive files
2000 $h = Win::Hivex->open ('SOFTWARE');
2001 $root_node = $h->root ();
2002 print $h->node_name ($root_node);
2006 The C<Win::Hivex> module provides a Perl XS binding to the
2007 L<hivex(3)> API for reading and writing Windows Registry binary
2012 All errors turn into calls to C<croak> (see L<Carp(3)>).
2026 XSLoader::load ('Win::Hivex');
2030 $h = Win::Hivex->open ($filename,";
2034 pr "\n [%s => 1,]" (String.lowercase flag)
2039 Open a Windows Registry binary hive file.
2041 The C<verbose> and C<debug> flags enable different levels of
2044 The C<write> flag is required if you will be modifying the
2045 hive file (see L<hivex(3)/WRITING TO HIVE FILES>).
2047 This function returns a hive handle. The hive handle is
2048 closed automatically when its reference count drops to 0.
2054 my $class = ref ($proto) || $proto;
2055 my $filename = shift;
2062 fun (n, flag, description) ->
2063 pr " # %s\n" description;
2064 pr " $flags += %d if $flags{%s};\n" n (String.lowercase flag)
2069 my $self = Win::Hivex::_open ($filename, $flags);
2070 bless $self, $class;
2077 fun (name, style, _, longdesc) ->
2078 (* The close call isn't explicit in Perl: handles are closed
2079 * when their reference count drops to 0.
2081 * The open call is coded specially in Perl.
2083 * Therefore we don't generate prototypes for these two calls:
2085 if fst style <> RErrDispose && List.hd (snd style) = AHive then (
2086 let longdesc = replace_str longdesc "C<hivex_" "C<" in
2087 pr "=item %s\n\n " name;
2088 generate_perl_prototype name style;
2090 pr "%s\n\n" longdesc;
2092 (match fst style with
2104 This returns a node handle.\n\n"
2107 This returns a node handle, or C<undef> if the node was not found.\n\n"
2110 This returns a list of node handles.\n\n"
2113 This returns a value handle.\n\n"
2116 This returns a list of value handles.\n\n"
2119 if List.mem ASetValues (snd style) then
2120 pr "C<@values> is an array of (keys, value) pairs.
2121 Each element should be a hashref containing C<key>, C<t> (type)
2124 Any existing values stored at the node are discarded, and their
2125 C<value> handles become invalid. Thus you can remove all
2126 values stored at C<node> by passing C<@values = []>.\n\n"
2139 Copyright (C) %s Red Hat Inc.
2143 Please see the file COPYING.LIB for the full license.
2149 L<http://libguestfs.org>,
2155 and generate_perl_prototype name style =
2157 (match fst style with
2160 | RHive -> pr "$h = "
2162 | RNodeNotFound -> pr "$node = "
2163 | RNodeList -> pr "@nodes = "
2164 | RValue -> pr "$value = "
2165 | RValueList -> pr "@values = "
2166 | RString -> pr "$string = "
2167 | RStringList -> pr "@strings = "
2168 | RLenType -> pr "($type, $len) = "
2169 | RLenTypeVal -> pr "($type, $data) = "
2170 | RInt32 -> pr "$int32 = "
2171 | RInt64 -> pr "$int64 = "
2174 let args = List.tl (snd style) in
2176 (* AUnusedFlags is dropped in the bindings. *)
2177 let args = List.filter ((<>) AUnusedFlags) args in
2181 let comma = ref false in
2184 if !comma then pr ", "; comma := true;
2189 | AString n -> pr "$%s" n
2190 | AStringNullable n -> pr "[$%s|undef]" n
2191 | AOpenFlags -> pr "[flags]"
2192 | AUnusedFlags -> assert false
2193 | ASetValues -> pr "\\@values"
2194 | ASetValue -> pr "$val"
2199 and generate_perl_xs () =
2200 generate_header CStyle LGPLv2plus;
2203 #include \"EXTERN.h\"
2209 #include <inttypes.h>
2212 my_newSVll(long long val) {
2213 #ifdef USE_64_BIT_ALL
2214 return newSViv(val);
2218 len = snprintf(buf, 100, \"%%\" PRId64, val);
2219 return newSVpv(buf, len);
2225 my_newSVull(unsigned long long val) {
2226 #ifdef USE_64_BIT_ALL
2227 return newSVuv(val);
2231 len = snprintf(buf, 100, \"%%\" PRIu64, val);
2232 return newSVpv(buf, len);
2238 /* http://www.perlmonks.org/?node_id=680842 */
2240 XS_unpack_charPtrPtr (SV *arg) {
2245 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
2246 croak (\"array reference expected\");
2248 av = (AV *)SvRV (arg);
2249 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
2251 croak (\"malloc failed\");
2253 for (i = 0; i <= av_len (av); i++) {
2254 SV **elem = av_fetch (av, i, 0);
2256 if (!elem || !*elem)
2257 croak (\"missing element in list\");
2259 ret[i] = SvPV_nolen (*elem);
2268 /* Handle set_values parameter. */
2269 typedef struct pl_set_values {
2271 hive_set_value *values;
2274 static pl_set_values
2275 unpack_pl_set_values (SV *sv)
2281 if (!sv || !SvOK (sv) || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV)
2282 croak (\"array reference expected\");
2284 av = (AV *)SvRV(sv);
2285 ret.nr_values = av_len (av) + 1;
2286 ret.values = malloc (ret.nr_values * sizeof (hive_set_value));
2288 croak (\"malloc failed\");
2290 for (i = 0; i <= av_len (av); i++) {
2291 SV **hvp = av_fetch (av, i, 0);
2293 if (!hvp || !*hvp || !SvROK (*hvp) || SvTYPE (SvRV (*hvp)) != SVt_PVHV)
2294 croak (\"missing element in list or not a hash ref\");
2296 HV *hv = (HV *)SvRV(*hvp);
2299 svp = hv_fetch (hv, \"key\", 3, 0);
2301 croak (\"missing 'key' in hash\");
2302 ret.values[i].key = SvPV_nolen (*svp);
2304 svp = hv_fetch (hv, \"t\", 1, 0);
2306 croak (\"missing 't' in hash\");
2307 ret.values[i].t = SvIV (*svp);
2309 svp = hv_fetch (hv, \"value\", 5, 0);
2311 croak (\"missing 'value' in hash\");
2312 ret.values[i].value = SvPV (*svp, ret.values[i].len);
2318 static hive_set_value *
2319 unpack_set_value (SV *sv)
2321 hive_set_value *ret;
2323 if (!sv || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVHV)
2324 croak (\"not a hash ref\");
2326 ret = malloc (sizeof (hive_set_value));
2328 croak (\"malloc failed\");
2330 HV *hv = (HV *)SvRV(sv);
2333 svp = hv_fetch (hv, \"key\", 3, 0);
2335 croak (\"missing 'key' in hash\");
2336 ret->key = SvPV_nolen (*svp);
2338 svp = hv_fetch (hv, \"t\", 1, 0);
2340 croak (\"missing 't' in hash\");
2341 ret->t = SvIV (*svp);
2343 svp = hv_fetch (hv, \"value\", 5, 0);
2345 croak (\"missing 'value' in hash\");
2346 ret->value = SvPV (*svp, ret->len);
2351 MODULE = Win::Hivex PACKAGE = Win::Hivex
2356 _open (filename, flags)
2360 RETVAL = hivex_open (filename, flags);
2362 croak (\"hivex_open: %%s: %%s\", filename, strerror (errno));
2370 if (hivex_close (h) == -1)
2371 croak (\"hivex_close: %%s\", strerror (errno));
2376 fun (name, style, _, longdesc) ->
2377 (* The close and open calls are handled specially above. *)
2378 if fst style <> RErrDispose && List.hd (snd style) = AHive then (
2379 (match fst style with
2380 | RErr -> pr "void\n"
2381 | RErrDispose -> failwith "perl bindings cannot handle a call which disposes of the handle"
2382 | RHive -> failwith "perl bindings cannot handle a call which returns a handle"
2386 | RString -> pr "SV *\n"
2391 | RLenTypeVal -> pr "void\n"
2392 | RInt32 -> pr "SV *\n"
2393 | RInt64 -> pr "SV *\n"
2396 (* Call and arguments. *)
2398 filter_map (function
2399 | AUnusedFlags -> None
2400 | arg -> Some (name_of_argt arg)) (snd style) in
2404 | AUnusedFlags -> "0"
2405 | ASetValues -> "values.nr_values, values.values"
2406 | arg -> name_of_argt arg) (snd style) in
2408 pr "%s (%s)\n" name (String.concat ", " perl_params);
2419 | AStringNullable n ->
2420 (* http://www.perlmonks.org/?node_id=554277 *)
2421 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n i i
2424 | AUnusedFlags -> ()
2426 pr " pl_set_values values = unpack_pl_set_values (ST(%d));\n" i
2428 pr " hive_set_value *val = unpack_set_value (ST(%d));\n" i
2435 pr " free (values.values);\n"
2438 | AHive | ANode _ | AValue _ | AString _ | AStringNullable _
2439 | AOpenFlags | AUnusedFlags -> ()
2444 (match fst style with
2449 pr " r = hivex_%s (%s);\n"
2450 name (String.concat ", " c_params);
2452 pr " if (r == -1)\n";
2453 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2456 | RErrDispose -> assert false
2457 | RHive -> assert false
2462 pr " /* hive_node_h = hive_value_h = size_t so we cheat\n";
2463 pr " here to simplify the generator */\n";
2466 pr " r = hivex_%s (%s);\n"
2467 name (String.concat ", " c_params);
2469 pr " if (r == 0)\n";
2470 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2472 pr " RETVAL = newSViv (r);\n";
2478 pr " hive_node_h r;\n";
2481 pr " r = hivex_%s (%s);\n"
2482 name (String.concat ", " c_params);
2484 pr " if (r == 0 && errno != 0)\n";
2485 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2487 pr " if (r == 0)\n";
2488 pr " RETVAL = &PL_sv_undef;\n";
2490 pr " RETVAL = newSViv (r);\n";
2498 pr " r = hivex_%s (%s);\n"
2499 name (String.concat ", " c_params);
2501 pr " if (r == NULL)\n";
2502 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2504 pr " RETVAL = newSVpv (r, 0);\n";
2515 pr " r = hivex_%s (%s);\n"
2516 name (String.concat ", " c_params);
2518 pr " if (r == NULL)\n";
2519 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2521 pr " for (n = 0; r[n] != 0; ++n) /**/;\n";
2522 pr " EXTEND (SP, n);\n";
2523 pr " for (i = 0; i < n; ++i)\n";
2524 pr " PUSHs (sv_2mortal (newSViv (r[i])));\n";
2532 pr " r = hivex_%s (%s);\n"
2533 name (String.concat ", " c_params);
2535 pr " if (r == NULL)\n";
2536 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2538 pr " for (n = 0; r[n] != NULL; ++n) /**/;\n";
2539 pr " EXTEND (SP, n);\n";
2540 pr " for (i = 0; i < n; ++i) {\n";
2541 pr " PUSHs (sv_2mortal (newSVpv (r[i], 0)));\n";
2542 pr " free (r[i]);\n";
2549 pr " size_t len;\n";
2550 pr " hive_type type;\n";
2552 pr " r = hivex_%s (%s, &type, &len);\n"
2553 name (String.concat ", " c_params);
2555 pr " if (r == -1)\n";
2556 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2558 pr " EXTEND (SP, 2);\n";
2559 pr " PUSHs (sv_2mortal (newSViv (type)));\n";
2560 pr " PUSHs (sv_2mortal (newSViv (len)));\n";
2565 pr " size_t len;\n";
2566 pr " hive_type type;\n";
2568 pr " r = hivex_%s (%s, &type, &len);\n"
2569 name (String.concat ", " c_params);
2571 pr " if (r == NULL)\n";
2572 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2574 pr " EXTEND (SP, 2);\n";
2575 pr " PUSHs (sv_2mortal (newSViv (type)));\n";
2576 pr " PUSHs (sv_2mortal (newSVpvn (r, len)));\n";
2584 pr " r = hivex_%s (%s);\n"
2585 name (String.concat ", " c_params);
2587 pr " if (r == -1 && errno != 0)\n";
2588 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2590 pr " RETVAL = newSViv (r);\n";
2599 pr " r = hivex_%s (%s);\n"
2600 name (String.concat ", " c_params);
2602 pr " if (r == -1 && errno != 0)\n";
2603 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2605 pr " RETVAL = my_newSVll (r);\n";
2613 and generate_python_c () =
2614 generate_header CStyle LGPLv2plus;
2617 #define PY_SSIZE_T_CLEAN 1
2620 #if PY_VERSION_HEX < 0x02050000
2621 typedef int Py_ssize_t;
2622 #define PY_SSIZE_T_MAX INT_MAX
2623 #define PY_SSIZE_T_MIN INT_MIN
2630 #include \"hivex.h\"
2632 #ifndef HAVE_PYCAPSULE_NEW
2640 get_handle (PyObject *obj)
2643 assert (obj != Py_None);
2644 #ifndef HAVE_PYCAPSULE_NEW
2645 return ((Pyhivex_Object *) obj)->h;
2647 return (hive_h *) PyCapsule_GetPointer(obj, \"hive_h\");
2652 put_handle (hive_h *h)
2655 #ifndef HAVE_PYCAPSULE_NEW
2657 PyCObject_FromVoidPtrAndDesc ((void *) h, (char *) \"hive_h\", NULL);
2659 return PyCapsule_New ((void *) h, \"hive_h\", NULL);
2663 /* This returns pointers into the Python objects, which should
2667 get_value (PyObject *v, hive_set_value *ret)
2671 obj = PyDict_GetItemString (v, \"key\");
2673 PyErr_SetString (PyExc_RuntimeError, \"no 'key' element in dictionary\");
2676 if (!PyString_Check (obj)) {
2677 PyErr_SetString (PyExc_RuntimeError, \"'key' element is not a string\");
2680 ret->key = PyString_AsString (obj);
2682 obj = PyDict_GetItemString (v, \"t\");
2684 PyErr_SetString (PyExc_RuntimeError, \"no 't' element in dictionary\");
2687 if (!PyInt_Check (obj)) {
2688 PyErr_SetString (PyExc_RuntimeError, \"'t' element is not an integer\");
2691 ret->t = PyInt_AsLong (obj);
2693 obj = PyDict_GetItemString (v, \"value\");
2695 PyErr_SetString (PyExc_RuntimeError, \"no 'value' element in dictionary\");
2698 if (!PyString_Check (obj)) {
2699 PyErr_SetString (PyExc_RuntimeError, \"'value' element is not a string\");
2702 ret->value = PyString_AsString (obj);
2703 ret->len = PyString_Size (obj);
2708 typedef struct py_set_values {
2710 hive_set_value *values;
2714 get_values (PyObject *v, py_set_values *ret)
2719 if (!PyList_Check (v)) {
2720 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
2724 slen = PyList_Size (v);
2726 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: PyList_Size failure\");
2729 len = (size_t) slen;
2730 ret->nr_values = len;
2731 ret->values = malloc (len * sizeof (hive_set_value));
2733 PyErr_SetString (PyExc_RuntimeError, strerror (errno));
2737 for (i = 0; i < len; ++i) {
2738 if (get_value (PyList_GetItem (v, i), &(ret->values[i])) == -1) {
2748 put_string_list (char * const * const argv)
2753 for (argc = 0; argv[argc] != NULL; ++argc)
2756 list = PyList_New (argc);
2757 for (i = 0; i < argc; ++i)
2758 PyList_SetItem (list, i, PyString_FromString (argv[i]));
2764 free_strings (char **argv)
2768 for (argc = 0; argv[argc] != NULL; ++argc)
2773 /* Since hive_node_t is the same as hive_value_t this also works for values. */
2775 put_node_list (hive_node_h *nodes)
2780 for (argc = 0; nodes[argc] != 0; ++argc)
2783 list = PyList_New (argc);
2784 for (i = 0; i < argc; ++i)
2785 PyList_SetItem (list, i, PyLong_FromLongLong ((long) nodes[i]));
2791 put_len_type (size_t len, hive_type t)
2793 PyObject *r = PyTuple_New (2);
2794 PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t));
2795 PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) len));
2800 put_val_type (char *val, size_t len, hive_type t)
2802 PyObject *r = PyTuple_New (2);
2803 PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t));
2804 PyTuple_SetItem (r, 1, PyString_FromStringAndSize (val, len));
2810 (* Generate functions. *)
2812 fun (name, style, _, longdesc) ->
2813 pr "static PyObject *\n";
2814 pr "py_hivex_%s (PyObject *self, PyObject *args)\n" name;
2816 pr " PyObject *py_r;\n";
2819 match fst style with
2820 | RErr -> pr " int r;\n"; "-1"
2821 | RErrDispose -> pr " int r;\n"; "-1"
2822 | RHive -> pr " hive_h *r;\n"; "NULL"
2823 | RNode -> pr " hive_node_h r;\n"; "0"
2826 pr " hive_node_h r;\n";
2828 | RNodeList -> pr " hive_node_h *r;\n"; "NULL"
2829 | RValue -> pr " hive_value_h r;\n"; "0"
2830 | RValueList -> pr " hive_value_h *r;\n"; "NULL"
2831 | RString -> pr " char *r;\n"; "NULL"
2832 | RStringList -> pr " char **r;\n"; "NULL"
2835 pr " size_t len;\n";
2836 pr " hive_type t;\n";
2840 pr " size_t len;\n";
2841 pr " hive_type t;\n";
2850 "-1 && errno != 0" in
2852 (* Call and arguments. *)
2855 | AUnusedFlags -> "0"
2856 | ASetValues -> "values.nr_values, values.values"
2857 | ASetValue -> "&val"
2858 | arg -> name_of_argt arg) (snd style) in
2860 match fst style with
2861 | RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"]
2868 pr " PyObject *py_h;\n"
2873 | AStringNullable n ->
2877 | AUnusedFlags -> ()
2879 pr " py_set_values values;\n";
2880 pr " PyObject *py_values;\n"
2882 pr " hive_set_value val;\n";
2883 pr " PyObject *py_val;\n"
2888 (* Convert the required parameters. *)
2889 pr " if (!PyArg_ParseTuple (args, (char *) \"";
2899 | AStringNullable n ->
2903 | AUnusedFlags -> ()
2909 pr ":hivex_%s\"" name;
2919 | AStringNullable n ->
2923 | AUnusedFlags -> ()
2931 pr " return NULL;\n";
2933 (* Convert some Python argument types to C. *)
2937 pr " h = get_handle (py_h);\n"
2943 | AUnusedFlags -> ()
2945 pr " if (get_values (py_values, &values) == -1)\n";
2946 pr " return NULL;\n"
2948 pr " if (get_value (py_val, &val) == -1)\n";
2949 pr " return NULL;\n"
2952 (* Call the C function. *)
2953 pr " r = hivex_%s (%s);\n" name (String.concat ", " c_params);
2955 (* Free up arguments. *)
2958 | AHive | ANode _ | AValue _
2959 | AString _ | AStringNullable _
2960 | AOpenFlags | AUnusedFlags -> ()
2962 pr " free (values.values);\n"
2966 (* Check for errors from C library. *)
2967 pr " if (r == %s) {\n" error_code;
2968 pr " PyErr_SetString (PyExc_RuntimeError,\n";
2969 pr " strerror (errno));\n";
2970 pr " return NULL;\n";
2974 (* Convert return value to Python. *)
2975 (match fst style with
2978 pr " Py_INCREF (Py_None);\n";
2979 pr " py_r = Py_None;\n"
2981 pr " py_r = put_handle (r);\n"
2983 pr " py_r = PyLong_FromLongLong (r);\n"
2986 pr " py_r = PyLong_FromLongLong (r);\n";
2988 pr " Py_INCREF (Py_None);\n";
2989 pr " py_r = Py_None;\n";
2993 pr " py_r = put_node_list (r);\n";
2996 pr " py_r = PyLong_FromLongLong (r);\n"
2998 pr " py_r = PyString_FromString (r);\n";
3001 pr " py_r = put_string_list (r);\n";
3002 pr " free_strings (r);\n"
3004 pr " py_r = put_len_type (len, t);\n"
3006 pr " py_r = put_val_type (r, len, t);\n";
3009 pr " py_r = PyInt_FromLong ((long) r);\n"
3011 pr " py_r = PyLong_FromLongLong (r);\n"
3013 pr " return py_r;\n";
3018 (* Table of functions. *)
3019 pr "static PyMethodDef methods[] = {\n";
3021 fun (name, _, _, _) ->
3022 pr " { (char *) \"%s\", py_hivex_%s, METH_VARARGS, NULL },\n"
3025 pr " { NULL, NULL, 0, NULL }\n";
3029 (* Init function. *)
3032 initlibhivexmod (void)
3034 static int initialized = 0;
3036 if (initialized) return;
3037 Py_InitModule ((char *) \"libhivexmod\", methods);
3042 and generate_python_py () =
3043 generate_header HashStyle LGPLv2plus;
3046 u\"\"\"Python bindings for hivex
3049 h = hivex.Hivex (filename)
3051 The hivex module provides Python bindings to the hivex API for
3052 examining and modifying Windows Registry 'hive' files.
3054 Read the hivex(3) man page to find out how to use the API.
3060 \"\"\"Instances of this class are hivex API handles.\"\"\"
3062 def __init__ (self, filename";
3065 fun (_, flag, _) -> pr ", %s = False" (String.lowercase flag)
3069 \"\"\"Create a new hivex handle.\"\"\"
3074 fun (n, flag, description) ->
3075 pr " # %s\n" description;
3076 pr " if %s: flags += %d\n" (String.lowercase flag) n
3079 pr " self._o = libhivexmod.open (filename, flags)
3082 libhivexmod.close (self._o)
3087 fun (name, style, shortdesc, _) ->
3088 (* The close and open calls are handled specially above. *)
3089 if fst style <> RErrDispose && List.hd (snd style) = AHive then (
3090 let args = List.tl (snd style) in
3091 let args = List.filter (
3092 function AOpenFlags | AUnusedFlags -> false
3096 pr " def %s (self" name;
3097 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
3099 pr " u\"\"\"%s\"\"\"\n" shortdesc;
3100 pr " return libhivexmod.%s (self._o" name;
3105 | AHive -> assert false
3106 | ANode n | AValue n
3107 | AString n | AStringNullable n -> pr "%s" n
3109 | AUnusedFlags -> assert false
3110 | ASetValues -> pr "values"
3111 | ASetValue -> pr "val"
3118 let output_to filename k =
3119 let filename_new = filename ^ ".new" in
3120 chan := open_out filename_new;
3123 chan := Pervasives.stdout;
3125 (* Is the new file different from the current file? *)
3126 if Sys.file_exists filename && files_equal filename filename_new then
3127 unlink filename_new (* same, so skip it *)
3129 (* different, overwrite old one *)
3130 (try chmod filename 0o644 with Unix_error _ -> ());
3131 rename filename_new filename;
3132 chmod filename 0o444;
3133 printf "written %s\n%!" filename;
3136 let perror msg = function
3137 | Unix_error (err, _, _) ->
3138 eprintf "%s: %s\n" msg (error_message err)
3140 eprintf "%s: %s\n" msg (Printexc.to_string exn)
3145 try openfile "configure.ac" [O_RDWR] 0
3147 | Unix_error (ENOENT, _, _) ->
3149 You are probably running this from the wrong directory.
3150 Run it from the top source directory using the command
3151 generator/generator.ml
3155 perror "open: configure.ac" exn;
3158 (* Acquire a lock so parallel builds won't try to run the generator
3159 * twice at the same time. Subsequent builds will wait for the first
3160 * one to finish. Note the lock is released implicitly when the
3163 (try lockf lock_fd F_LOCK 1
3165 perror "lock: configure.ac" exn;
3170 output_to "lib/hivex.h" generate_c_header;
3171 output_to "lib/hivex.pod" generate_c_pod;
3173 output_to "lib/hivex.syms" generate_linker_script;
3175 output_to "ocaml/hivex.mli" generate_ocaml_interface;
3176 output_to "ocaml/hivex.ml" generate_ocaml_implementation;
3177 output_to "ocaml/hivex_c.c" generate_ocaml_c;
3179 output_to "perl/lib/Win/Hivex.pm" generate_perl_pm;
3180 output_to "perl/Hivex.xs" generate_perl_xs;
3182 output_to "python/hivex.py" generate_python_py;
3183 output_to "python/hivex-py.c" generate_python_c;
3185 (* Always generate this file last, and unconditionally. It's used
3186 * by the Makefile to know when we must re-run the generator.
3188 let chan = open_out "generator/stamp-generator" in
3192 printf "generated %d lines of code\n" !lines