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;
714 /* NOTE: This API is documented in the man page hivex(3). */
717 typedef struct hive_h hive_h;
719 /* Nodes and values. */
720 typedef size_t hive_node_h;
721 typedef size_t hive_value_h;
725 # define HIVEX_NO_KEY ENOKEY
727 # define HIVEX_NO_KEY ENOENT
730 /* Pre-defined types. */
734 fun (t, old_style, new_style, description) ->
735 pr " /* %s */\n" description;
736 pr " hive_t_REG_%s,\n" new_style;
737 pr "#define hive_t_%s hive_t_REG_%s\n" old_style new_style;
743 typedef enum hive_type hive_type;
745 /* Bitmask of flags passed to hivex_open. */
748 fun (v, flag, description) ->
749 pr " /* %s */\n" description;
750 pr "#define HIVEX_OPEN_%-10s %d\n" flag v;
755 /* Array of (key, value) pairs passed to hivex_node_set_values. */
756 struct hive_set_value {
762 typedef struct hive_set_value hive_set_value;
766 pr "/* Functions. */\n";
768 (* Function declarations. *)
770 fun (shortname, style, _, _) ->
771 let name = "hivex_" ^ shortname in
772 generate_c_prototype ~extern:true name style
775 (* The visitor pattern. *)
777 /* Visit all nodes. This is specific to the C API and is not made
778 * available to other languages. This is because of the complexity
779 * of binding callbacks in other languages, but also because other
780 * languages make it much simpler to iterate over a tree.
782 struct hivex_visitor {
783 int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name);
784 int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name);
785 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);
786 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);
787 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);
788 int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t);
789 int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t);
790 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);
791 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);
792 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);
793 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);
796 #define HIVEX_VISIT_SKIP_BAD 1
798 extern int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
799 extern int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
803 (* Finish the header file. *)
809 #endif /* HIVEX_H_ */
812 and generate_c_prototype ?(extern = false) name style =
813 if extern then pr "extern ";
814 (match fst style with
816 | RErrDispose -> pr "int "
817 | RHive -> pr "hive_h *"
818 | RNode -> pr "hive_node_h "
819 | RNodeNotFound -> pr "hive_node_h "
820 | RNodeList -> pr "hive_node_h *"
821 | RValue -> pr "hive_value_h "
822 | RValueList -> pr "hive_value_h *"
823 | RString -> pr "char *"
824 | RStringList -> pr "char **"
825 | RLenType -> pr "int "
826 | RLenTypeVal -> pr "char *"
827 | RInt32 -> pr "int32_t "
828 | RInt64 -> pr "int64_t "
831 let comma = ref false in
834 if !comma then pr ", "; comma := true;
836 | AHive -> pr "hive_h *h"
837 | ANode n -> pr "hive_node_h %s" n
838 | AValue n -> pr "hive_value_h %s" n
839 | AString n | AStringNullable n -> pr "const char *%s" n
840 | AOpenFlags | AUnusedFlags -> pr "int flags"
841 | ASetValues -> pr "size_t nr_values, const hive_set_value *values"
842 | ASetValue -> pr "const hive_set_value *val"
844 (match fst style with
845 | RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len"
850 and generate_c_pod () =
851 generate_header PODCommentStyle GPLv2;
858 hivex - Windows Registry \"hive\" extraction library
866 fun (shortname, style, _, _) ->
867 let name = "hivex_" ^ shortname in
869 generate_c_prototype ~extern:false name style;
874 Link with I<-lhivex>.
878 Hivex is a library for extracting the contents of Windows Registry
879 \"hive\" files. It is designed to be secure against buggy or malicious
882 Unlike other tools in this area, it doesn't use the textual .REG
883 format, because parsing that is as much trouble as parsing the
884 original binary format. Instead it makes the file available
885 through a C API, and then wraps this API in higher level scripting
888 There is a separate program to export the hive as XML
889 (see L<hivexml(1)>), or to navigate the file (see L<hivexsh(1)>).
890 There is also a Perl script to export and merge the
891 file as a textual .REG (regedit) file, see L<hivexregedit(1)>.
893 If you just want to export or modify the Registry of a Windows
894 virtual machine, you should look at L<virt-win-reg(1)>.
896 Hivex is also comes with language bindings for
897 OCaml, Perl and Python.
903 This handle describes an open hive file.
905 =head2 C<hive_node_h>
907 This is a node handle, an integer but opaque outside the library.
908 Valid node handles cannot be 0. The library returns 0 in some
909 situations to indicate an error.
913 The enum below describes the possible types for the value(s)
914 stored at each node. Note that you should not trust the
915 type field in a Windows Registry, as it very often has no
916 relationship to reality. Some applications use their own
917 types. The encoding of strings is not specified. Some
918 programs store everything (including strings) in binary blobs.
923 fun (t, _, new_style, description) ->
924 pr " /* %s */\n" description;
925 pr " hive_t_REG_%s = %d,\n" new_style t
930 =head2 C<hive_value_h>
932 This is a value handle, an integer but opaque outside the library.
933 Valid value handles cannot be 0. The library returns 0 in some
934 situations to indicate an error.
936 =head2 C<hive_set_value>
938 The typedef C<hive_set_value> is used in conjunction with the
939 C<hivex_node_set_values> call described below.
941 struct hive_set_value {
942 char *key; /* key - a UTF-8 encoded ASCIIZ string */
943 hive_type t; /* type of value field */
944 size_t len; /* length of value field in bytes */
945 char *value; /* value field */
947 typedef struct hive_set_value hive_set_value;
949 To set the default value for a node, you have to pass C<key = \"\">.
951 Note that the C<value> field is just treated as a list of bytes, and
952 is stored directly in the hive. The caller has to ensure correct
953 encoding and endianness, for example converting dwords to little
956 The correct type and encoding for values depends on the node and key
957 in the registry, the version of Windows, and sometimes even changes
958 between versions of Windows for the same key. We don't document it
959 here. Often it's not documented at all.
965 fun (shortname, style, _, longdesc) ->
966 let name = "hivex_" ^ shortname in
967 pr "=head2 %s\n" name;
969 generate_c_prototype ~extern:false name style;
974 if List.mem AUnusedFlags (snd style) then
975 pr "The flags parameter is unused. Always pass 0.\n\n";
977 if List.mem ASetValues (snd style) then
978 pr "C<values> is an array of (key, value) pairs. There
979 should be C<nr_values> elements in this array.
981 Any existing values stored at the node are discarded, and their
982 C<hive_value_h> handles become invalid. Thus you can remove all
983 values stored at C<node> by passing C<nr_values = 0>.\n\n";
985 if List.mem ASetValue (snd style) then
986 pr "C<value> is a single (key, value) pair.
988 Existing C<hive_value_h> handles become invalid.\n\n";
990 (match fst style with
993 Returns 0 on success.
994 On error this returns -1 and sets errno.\n\n"
997 Returns 0 on success.
998 On error this returns -1 and sets errno.
1000 This function frees the hive handle (even if it returns an error).
1001 The hive handle must not be used again after calling this function.\n\n"
1004 Returns a new hive handle.
1005 On error this returns NULL and sets errno.\n\n"
1008 Returns a node handle.
1009 On error this returns 0 and sets errno.\n\n"
1012 Returns a node handle.
1013 If the node was not found, this returns 0 without setting errno.
1014 On error this returns 0 and sets errno.\n\n"
1017 Returns a 0-terminated array of nodes.
1018 The array must be freed by the caller when it is no longer needed.
1019 On error this returns NULL and sets errno.\n\n"
1022 Returns a value handle.
1023 On error this returns 0 and sets errno.\n\n"
1026 Returns a 0-terminated array of values.
1027 The array must be freed by the caller when it is no longer needed.
1028 On error this returns NULL and sets errno.\n\n"
1032 The string must be freed by the caller when it is no longer needed.
1033 On error this returns NULL and sets errno.\n\n"
1036 Returns a NULL-terminated array of C strings.
1037 The strings and the array must all be freed by the caller when
1038 they are no longer needed.
1039 On error this returns NULL and sets errno.\n\n"
1042 Returns 0 on success.
1043 On error this returns -1 and sets errno.\n\n"
1046 The value is returned as an array of bytes (of length C<len>).
1047 The value must be freed by the caller when it is no longer needed.
1048 On error this returns NULL and sets errno.\n\n"
1049 | RInt32 | RInt64 -> ()
1054 =head1 WRITING TO HIVE FILES
1056 The hivex library supports making limited modifications to hive files.
1057 We have tried to implement this very conservatively in order to reduce
1058 the chance of corrupting your registry. However you should be careful
1059 and take back-ups, since Microsoft has never documented the hive
1060 format, and so it is possible there are nuances in the
1061 reverse-engineered format that we do not understand.
1063 To be able to modify a hive, you must pass the C<HIVEX_OPEN_WRITE>
1064 flag to C<hivex_open>, otherwise any write operation will return with
1067 The write operations shown below do not modify the on-disk file
1068 immediately. You must call C<hivex_commit> in order to write the
1069 changes to disk. If you call C<hivex_close> without committing then
1070 any writes are discarded.
1072 Hive files internally consist of a \"memory dump\" of binary blocks
1073 (like the C heap), and some of these blocks can be unused. The hivex
1074 library never reuses these unused blocks. Instead, to ensure
1075 robustness in the face of the partially understood on-disk format,
1076 hivex only allocates new blocks after the end of the file, and makes
1077 minimal modifications to existing structures in the file to point to
1078 these new blocks. This makes hivex slightly less disk-efficient than
1079 it could be, but disk is cheap, and registry modifications tend to be
1082 When deleting nodes, it is possible that this library may leave
1083 unreachable live blocks in the hive. This is because certain parts of
1084 the hive disk format such as security (sk) records and big data (db)
1085 records and classname fields are not well understood (and not
1086 documented at all) and we play it safe by not attempting to modify
1087 them. Apart from wasting a little bit of disk space, it is not
1088 thought that unreachable blocks are a problem.
1090 =head2 WRITE OPERATIONS WHICH ARE NOT SUPPORTED
1096 Changing the root node.
1100 Creating a new hive file from scratch. This is impossible at present
1101 because not all fields in the header are understood. In the hivex
1102 source tree is a file called C<images/minimal> which could be used as
1103 the basis for a new hive (but I<caveat emptor>).
1107 Modifying or deleting single values at a node.
1111 Modifying security key (sk) records or classnames.
1112 Previously we did not understand these records. However now they
1113 are well-understood and we could add support if it was required
1114 (but nothing much really uses them).
1118 =head1 VISITING ALL NODES
1120 The visitor pattern is useful if you want to visit all nodes
1121 in the tree or all nodes below a certain point in the tree.
1123 First you set up your own C<struct hivex_visitor> with your
1126 Each of these callback functions should return 0 on success or -1
1127 on error. If any callback returns -1, then the entire visit
1128 terminates immediately. If you don't need a callback function at
1129 all, set the function pointer to NULL.
1131 struct hivex_visitor {
1132 int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name);
1133 int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name);
1134 int (*value_string) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1135 hive_type t, size_t len, const char *key, const char *str);
1136 int (*value_multiple_strings) (hive_h *, void *opaque, hive_node_h,
1137 hive_value_h, hive_type t, size_t len, const char *key, char **argv);
1138 int (*value_string_invalid_utf16) (hive_h *, void *opaque, hive_node_h,
1139 hive_value_h, hive_type t, size_t len, const char *key,
1141 int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1142 hive_type t, size_t len, const char *key, int32_t);
1143 int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1144 hive_type t, size_t len, const char *key, int64_t);
1145 int (*value_binary) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1146 hive_type t, size_t len, const char *key, const char *value);
1147 int (*value_none) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1148 hive_type t, size_t len, const char *key, const char *value);
1149 int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1150 hive_type t, size_t len, const char *key, const char *value);
1151 /* If value_any callback is not NULL, then the other value_*
1152 * callbacks are not used, and value_any is called on all values.
1154 int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1155 hive_type t, size_t len, const char *key, const char *value);
1162 int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
1164 Visit all the nodes recursively in the hive C<h>.
1166 C<visitor> should be a C<hivex_visitor> structure with callback
1167 fields filled in as required (unwanted callbacks can be set to
1168 NULL). C<len> must be the length of the 'visitor' struct (you
1169 should pass C<sizeof (struct hivex_visitor)> for this).
1171 This returns 0 if the whole recursive visit was completed
1172 successfully. On error this returns -1. If one of the callback
1173 functions returned an error than we don't touch errno. If the
1174 error was generated internally then we set errno.
1176 You can skip bad registry entries by setting C<flag> to
1177 C<HIVEX_VISIT_SKIP_BAD>. If this flag is not set, then a bad registry
1178 causes the function to return an error immediately.
1180 This function is robust if the registry contains cycles or
1181 pointers which are invalid or outside the registry. It detects
1182 these cases and returns an error.
1184 =item hivex_visit_node
1186 int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque);
1188 Same as C<hivex_visit> but instead of starting out at the root, this
1193 =head1 THE STRUCTURE OF THE WINDOWS REGISTRY
1195 Note: To understand the relationship between hives and the common
1196 Windows Registry keys (like C<HKEY_LOCAL_MACHINE>) please see the
1197 Wikipedia page on the Windows Registry.
1199 The Windows Registry is split across various binary files, each
1200 file being known as a \"hive\". This library only handles a single
1201 hive file at a time.
1203 Hives are n-ary trees with a single root. Each node in the tree
1206 Each node in the tree (including non-leaf nodes) may have an
1207 arbitrary list of (key, value) pairs attached to it. It may
1208 be the case that one of these pairs has an empty key. This
1209 is referred to as the default key for the node.
1211 The (key, value) pairs are the place where the useful data is
1212 stored in the registry. The key is always a string (possibly the
1213 empty string for the default key). The value is a typed object
1214 (eg. string, int32, binary, etc.).
1216 =head2 RELATIONSHIP TO .REG FILES
1218 The hivex C library does not care about or deal with Windows .REG
1219 files. Instead we push this complexity up to the Perl
1220 L<Win::Hivex(3)> library and the Perl programs
1221 L<hivexregedit(1)> and L<virt-win-reg(1)>.
1222 Nevertheless it is useful to look at the relationship between the
1223 Registry and .REG files because they are so common.
1225 A .REG file is a textual representation of the registry, or part of the
1226 registry. The actual registry hives that Windows uses are binary
1227 files. There are a number of Windows and Linux tools that let you
1228 generate .REG files, or merge .REG files back into the registry hives.
1229 Notable amongst them is Microsoft's REGEDIT program (formerly known as
1232 A typical .REG file will contain many sections looking like this:
1234 [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack]
1235 \"@\"=\"Generic Stack\"
1236 \"TileInfo\"=\"prop:System.FileCount\"
1237 \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\"
1238 \"ThumbnailCutoff\"=dword:00000000
1239 \"FriendlyTypeName\"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,\\
1240 6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,\\
1241 33,00,32,00,5c,00,73,00,65,00,61,00,72,00,63,00,68,00,66,00,\\
1242 6f,00,6c,00,64,00,65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,\\
1243 2d,00,39,00,30,00,32,00,38,00,00,00,d8
1245 Taking this one piece at a time:
1247 [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack]
1249 This is the path to this node in the registry tree. The first part,
1250 C<HKEY_LOCAL_MACHINE\\SOFTWARE> means that this comes from a hive
1251 file called C<C:\\WINDOWS\\SYSTEM32\\CONFIG\\SOFTWARE>.
1252 C<\\Classes\\Stack> is the real path part,
1253 starting at the root node of the C<SOFTWARE> hive.
1255 Below the node name is a list of zero or more key-value pairs. Any
1256 interior or leaf node in the registry may have key-value pairs
1259 \"@\"=\"Generic Stack\"
1261 This is the \"default key\". In reality (ie. inside the binary hive)
1262 the key string is the empty string. In .REG files this is written as
1263 C<@> but this has no meaning either in the hives themselves or in this
1264 library. The value is a string (type 1 - see C<enum hive_type>
1267 \"TileInfo\"=\"prop:System.FileCount\"
1269 This is a regular (key, value) pair, with the value being a type 1
1270 string. Note that inside the binary file the string is likely to be
1271 UTF-16LE encoded. This library converts to and from UTF-8 strings
1272 transparently in some cases.
1274 \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\"
1276 The value in this case has type 2 (expanded string) meaning that some
1277 %%...%% variables get expanded by Windows. (This library doesn't know
1278 or care about variable expansion).
1280 \"ThumbnailCutoff\"=dword:00000000
1282 The value in this case is a dword (type 4).
1284 \"FriendlyTypeName\"=hex(2):40,00,....
1286 This value is an expanded string (type 2) represented in the .REG file
1287 as a series of hex bytes. In this case the string appears to be a
1290 =head1 NOTE ON THE USE OF ERRNO
1292 Many functions in this library set errno to indicate errors. These
1293 are the values of errno you may encounter (this list is not
1300 Corrupt or unsupported Registry file format.
1308 Passed an invalid argument to the function.
1312 Followed a Registry pointer which goes outside
1313 the registry or outside a registry block.
1317 Registry contains cycles.
1321 Field in the registry out of range.
1325 Registry key already exists.
1329 Tried to write to a registry which is not opened for writing.
1333 =head1 ENVIRONMENT VARIABLES
1339 Setting HIVEX_DEBUG=1 will enable very verbose messages. This is
1340 useful for debugging problems with the library itself.
1353 L<http://libguestfs.org/>,
1356 L<http://en.wikipedia.org/wiki/Windows_Registry>.
1360 Richard W.M. Jones (C<rjones at redhat dot com>)
1364 Copyright (C) 2009-2010 Red Hat Inc.
1366 Derived from code by Petter Nordahl-Hagen under a compatible license:
1367 Copyright (C) 1997-2007 Petter Nordahl-Hagen.
1369 Derived from code by Markus Stephany under a compatible license:
1370 Copyright (C) 2000-2004 Markus Stephany.
1372 This library is free software; you can redistribute it and/or
1373 modify it under the terms of the GNU Lesser General Public
1374 License as published by the Free Software Foundation;
1375 version 2.1 of the License only.
1377 This library is distributed in the hope that it will be useful,
1378 but WITHOUT ANY WARRANTY; without even the implied warranty of
1379 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1380 Lesser General Public License for more details.
1383 (* Generate the linker script which controls the visibility of
1384 * symbols in the public ABI and ensures no other symbols get
1385 * exported accidentally.
1387 and generate_linker_script () =
1388 generate_header HashStyle GPLv2plus;
1396 List.map (fun (name, _, _, _) -> "hivex_" ^ name)
1398 let globals = List.sort compare (globals @ functions) in
1402 List.iter (pr " %s;\n") globals;
1409 and generate_ocaml_interface () =
1410 generate_header OCamlStyle LGPLv2plus;
1414 (** A [hive_h] hive file handle. *)
1418 (** Nodes and values. *)
1420 exception Error of string * Unix.error * string
1421 (** Error raised by a function.
1423 The first parameter is the name of the function which raised the error.
1424 The second parameter is the errno (see the [Unix] module). The third
1425 parameter is a human-readable string corresponding to the errno.
1427 See hivex(3) for a partial list of interesting errno values that
1428 can be generated by the library. *)
1429 exception Handle_closed of string
1430 (** This exception is raised if you call a function on a closed handle. *)
1436 fun (t, _, new_style, description) ->
1438 pr " | REG_%s (** %s *)\n" new_style description
1442 | REG_UNKNOWN of int32 (** unknown type *)
1443 (** Hive type field. *)
1449 fun (v, flag, description) ->
1450 assert (1 lsl i = v);
1451 pr " | OPEN_%s (** %s *)\n" flag description
1455 (** Open flags for {!open_file} call. *)
1462 (** (key, value) pair passed (as an array) to {!node_set_values}. *)
1466 fun (name, style, shortdesc, _) ->
1468 generate_ocaml_prototype name style;
1469 pr "(** %s *)\n" shortdesc
1472 and generate_ocaml_implementation () =
1473 generate_header OCamlStyle LGPLv2plus;
1480 exception Error of string * Unix.error * string
1481 exception Handle_closed of string
1483 (* Give the exceptions names, so they can be raised from the C code. *)
1485 Callback.register_exception \"ocaml_hivex_error\"
1486 (Error (\"\", Unix.EUNKNOWNERR 0, \"\"));
1487 Callback.register_exception \"ocaml_hivex_closed\" (Handle_closed \"\")
1493 fun (t, _, new_style, _) ->
1495 pr " | REG_%s\n" new_style
1499 | REG_UNKNOWN of int32
1505 fun (v, flag, description) ->
1506 assert (1 lsl i = v);
1507 pr " | OPEN_%s (** %s *)\n" flag description
1521 fun (name, style, _, _) ->
1522 generate_ocaml_prototype ~is_external:true name style
1525 and generate_ocaml_prototype ?(is_external = false) name style =
1526 let ocaml_name = if name = "open" then "open_file" else name in
1528 if is_external then pr "external " else pr "val ";
1529 pr "%s : " ocaml_name;
1532 | AHive -> pr "t -> "
1533 | ANode _ -> pr "node -> "
1534 | AValue _ -> pr "value -> "
1535 | AString _ -> pr "string -> "
1536 | AStringNullable _ -> pr "string option -> "
1537 | AOpenFlags -> pr "open_flag list -> "
1538 | AUnusedFlags -> ()
1539 | ASetValues -> pr "set_value array -> "
1540 | ASetValue -> pr "set_value -> "
1542 (match fst style with
1543 | RErr -> pr "unit" (* all errors are turned into exceptions *)
1544 | RErrDispose -> pr "unit"
1546 | RNode -> pr "node"
1547 | RNodeNotFound -> pr "node"
1548 | RNodeList -> pr "node array"
1549 | RValue -> pr "value"
1550 | RValueList -> pr "value array"
1551 | RString -> pr "string"
1552 | RStringList -> pr "string array"
1553 | RLenType -> pr "hive_type * int"
1554 | RLenTypeVal -> pr "hive_type * string"
1555 | RInt32 -> pr "int32"
1556 | RInt64 -> pr "int64"
1559 pr " = \"ocaml_hivex_%s\"" name;
1562 and generate_ocaml_c () =
1563 generate_header CStyle LGPLv2plus;
1574 #include <caml/config.h>
1575 #include <caml/alloc.h>
1576 #include <caml/callback.h>
1577 #include <caml/custom.h>
1578 #include <caml/fail.h>
1579 #include <caml/memory.h>
1580 #include <caml/mlvalues.h>
1581 #include <caml/signals.h>
1583 #ifdef HAVE_CAML_UNIXSUPPORT_H
1584 #include <caml/unixsupport.h>
1586 extern value unix_error_of_code (int errcode);
1589 #ifndef HAVE_CAML_RAISE_WITH_ARGS
1591 caml_raise_with_args (value tag, int nargs, value args[])
1594 CAMLxparamN (args, nargs);
1598 bucket = caml_alloc_small (1 + nargs, 0);
1599 Field(bucket, 0) = tag;
1600 for (i = 0; i < nargs; i++) Field(bucket, 1 + i) = args[i];
1608 #define Hiveh_val(v) (*((hive_h **)Data_custom_val(v)))
1609 static value Val_hiveh (hive_h *);
1610 static int HiveOpenFlags_val (value);
1611 static hive_set_value *HiveSetValue_val (value);
1612 static hive_set_value *HiveSetValues_val (value);
1613 static hive_type HiveType_val (value);
1614 static value Val_hive_type (hive_type);
1615 static value copy_int_array (size_t *);
1616 static value copy_type_len (size_t, hive_type);
1617 static value copy_type_value (const char *, size_t, hive_type);
1618 static void raise_error (const char *) Noreturn;
1619 static void raise_closed (const char *) Noreturn;
1625 fun (name, style, _, _) ->
1626 pr "/* Automatically generated wrapper for function\n";
1627 pr " * "; generate_ocaml_prototype name style;
1633 | ASetValues -> ["nrvalues"; "values"]
1634 | AUnusedFlags -> ["0"]
1635 | arg -> [name_of_argt arg]) (snd style) in
1637 match fst style with
1638 | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]]
1640 let c_params = List.concat c_params in
1643 filter_map (function
1644 | AUnusedFlags -> None
1645 | arg -> Some (name_of_argt arg ^ "v")) (snd style) in
1647 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
1648 pr "CAMLprim value ocaml_hivex_%s (value %s" name (List.hd params);
1649 List.iter (pr ", value %s") (List.tl params); pr ");\n";
1652 pr "CAMLprim value\n";
1653 pr "ocaml_hivex_%s (value %s" name (List.hd params);
1654 List.iter (pr ", value %s") (List.tl params);
1658 pr " CAMLparam%d (%s);\n"
1659 (List.length params) (String.concat ", " params);
1660 pr " CAMLlocal1 (rv);\n";
1666 pr " hive_h *h = Hiveh_val (hv);\n";
1667 pr " if (h == NULL)\n";
1668 pr " raise_closed (\"%s\");\n" name
1670 pr " hive_node_h %s = Int_val (%sv);\n" n n
1672 pr " hive_value_h %s = Int_val (%sv);\n" n n
1674 pr " const char *%s = String_val (%sv);\n" n n
1675 | AStringNullable n ->
1676 pr " const char *%s =\n" n;
1677 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
1680 pr " int flags = HiveOpenFlags_val (flagsv);\n"
1681 | AUnusedFlags -> ()
1683 pr " int nrvalues = Wosize_val (valuesv);\n";
1684 pr " hive_set_value *values = HiveSetValues_val (valuesv);\n"
1686 pr " hive_set_value *val = HiveSetValue_val (valv);\n"
1691 match fst style with
1692 | RErr -> pr " int r;\n"; "-1"
1693 | RErrDispose -> pr " int r;\n"; "-1"
1694 | RHive -> pr " hive_h *r;\n"; "NULL"
1695 | RNode -> pr " hive_node_h r;\n"; "0"
1698 pr " hive_node_h r;\n";
1700 | RNodeList -> pr " hive_node_h *r;\n"; "NULL"
1701 | RValue -> pr " hive_value_h r;\n"; "0"
1702 | RValueList -> pr " hive_value_h *r;\n"; "NULL"
1703 | RString -> pr " char *r;\n"; "NULL"
1704 | RStringList -> pr " char **r;\n"; "NULL"
1707 pr " size_t len;\n";
1708 pr " hive_type t;\n";
1712 pr " size_t len;\n";
1713 pr " hive_type t;\n";
1722 "-1 && errno != 0" in
1724 (* The libguestfs OCaml bindings call enter_blocking_section
1725 * here. However I don't think that is safe, because we are
1726 * holding pointers to caml strings during the call, and these
1727 * could be moved or freed by other threads. In any case, there
1728 * is very little reason to enter_blocking_section for any hivex
1729 * call, so don't do it. XXX
1731 (*pr " caml_enter_blocking_section ();\n";*)
1732 pr " r = hivex_%s (%s" name (List.hd c_params);
1733 List.iter (pr ", %s") (List.tl c_params);
1735 (*pr " caml_leave_blocking_section ();\n";*)
1738 (* Dispose of the hive handle (even if hivex_close returns error). *)
1739 (match fst style with
1741 pr " /* So we don't double-free in the finalizer. */\n";
1742 pr " Hiveh_val (hv) = NULL;\n";
1749 | AHive | ANode _ | AValue _ | AString _ | AStringNullable _
1750 | AOpenFlags | AUnusedFlags -> ()
1752 pr " free (values);\n";
1755 pr " free (val);\n";
1759 (* Check for errors. *)
1760 pr " if (r == %s)\n" error_code;
1761 pr " raise_error (\"%s\");\n" name;
1764 (match fst style with
1765 | RErr -> pr " rv = Val_unit;\n"
1766 | RErrDispose -> pr " rv = Val_unit;\n"
1767 | RHive -> pr " rv = Val_hiveh (r);\n"
1768 | RNode -> pr " rv = Val_int (r);\n"
1770 pr " if (r == 0)\n";
1771 pr " caml_raise_not_found ();\n";
1773 pr " rv = Val_int (r);\n"
1775 pr " rv = copy_int_array (r);\n";
1777 | RValue -> pr " rv = Val_int (r);\n"
1779 pr " rv = copy_int_array (r);\n";
1782 pr " rv = caml_copy_string (r);\n";
1785 pr " rv = caml_copy_string_array ((const char **) r);\n";
1786 pr " for (int i = 0; r[i] != NULL; ++i) free (r[i]);\n";
1788 | RLenType -> pr " rv = copy_type_len (len, t);\n"
1790 pr " rv = copy_type_value (r, len, t);\n";
1792 | RInt32 -> pr " rv = caml_copy_int32 (r);\n"
1793 | RInt64 -> pr " rv = caml_copy_int64 (r);\n"
1796 pr " CAMLreturn (rv);\n";
1804 HiveOpenFlags_val (value v)
1809 while (v != Val_int (0)) {
1811 flags |= 1 << Int_val (v2);
1818 static hive_set_value *
1819 HiveSetValue_val (value v)
1821 hive_set_value *val = malloc (sizeof (hive_set_value));
1823 val->key = String_val (Field (v, 0));
1824 val->t = HiveType_val (Field (v, 1));
1825 val->len = caml_string_length (Field (v, 2));
1826 val->value = String_val (Field (v, 2));
1831 static hive_set_value *
1832 HiveSetValues_val (value v)
1834 size_t nr_values = Wosize_val (v);
1835 hive_set_value *values = malloc (nr_values * sizeof (hive_set_value));
1839 for (i = 0; i < nr_values; ++i) {
1841 values[i].key = String_val (Field (v2, 0));
1842 values[i].t = HiveType_val (Field (v2, 1));
1843 values[i].len = caml_string_length (Field (v2, 2));
1844 values[i].value = String_val (Field (v2, 2));
1851 HiveType_val (value v)
1854 return Int_val (v); /* REG_NONE etc. */
1856 return Int32_val (Field (v, 0)); /* REG_UNKNOWN of int32 */
1860 Val_hive_type (hive_type t)
1866 CAMLreturn (Val_int (t));
1868 rv = caml_alloc (1, 0); /* REG_UNKNOWN of int32 */
1869 v = caml_copy_int32 (t);
1870 caml_modify (&Field (rv, 0), v);
1876 copy_int_array (size_t *xs)
1882 for (nr = 0; xs[nr] != 0; ++nr)
1885 CAMLreturn (Atom (0));
1887 rv = caml_alloc (nr, 0);
1888 for (i = 0; i < nr; ++i) {
1889 v = Val_int (xs[i]);
1890 Store_field (rv, i, v); /* Safe because v is not a block. */
1897 copy_type_len (size_t len, hive_type t)
1902 rv = caml_alloc (2, 0);
1903 v = Val_hive_type (t);
1904 Store_field (rv, 0, v);
1906 Store_field (rv, 1, len);
1911 copy_type_value (const char *r, size_t len, hive_type t)
1916 rv = caml_alloc (2, 0);
1917 v = Val_hive_type (t);
1918 Store_field (rv, 0, v);
1919 v = caml_alloc_string (len);
1920 memcpy (String_val (v), r, len);
1921 caml_modify (&Field (rv, 1), v);
1925 /* Raise exceptions. */
1927 raise_error (const char *function)
1929 /* Save errno early in case it gets trashed. */
1933 CAMLlocal3 (v1, v2, v3);
1935 v1 = caml_copy_string (function);
1936 v2 = unix_error_of_code (err);
1937 v3 = caml_copy_string (strerror (err));
1938 value vvv[] = { v1, v2, v3 };
1939 caml_raise_with_args (*caml_named_value (\"ocaml_hivex_error\"), 3, vvv);
1945 raise_closed (const char *function)
1950 v = caml_copy_string (function);
1951 caml_raise_with_arg (*caml_named_value (\"ocaml_hivex_closed\"), v);
1956 /* Allocate handles and deal with finalization. */
1958 hivex_finalize (value hv)
1960 hive_h *h = Hiveh_val (hv);
1961 if (h) hivex_close (h);
1964 static struct custom_operations hivex_custom_operations = {
1965 (char *) \"hivex_custom_operations\",
1967 custom_compare_default,
1968 custom_hash_default,
1969 custom_serialize_default,
1970 custom_deserialize_default
1974 Val_hiveh (hive_h *h)
1979 rv = caml_alloc_custom (&hivex_custom_operations,
1980 sizeof (hive_h *), 0, 1);
1987 and generate_perl_pm () =
1988 generate_header HashStyle LGPLv2plus;
1995 Win::Hivex - Perl bindings for reading and writing Windows Registry hive files
2001 $h = Win::Hivex->open ('SOFTWARE');
2002 $root_node = $h->root ();
2003 print $h->node_name ($root_node);
2007 The C<Win::Hivex> module provides a Perl XS binding to the
2008 L<hivex(3)> API for reading and writing Windows Registry binary
2013 All errors turn into calls to C<croak> (see L<Carp(3)>).
2027 XSLoader::load ('Win::Hivex');
2031 $h = Win::Hivex->open ($filename,";
2035 pr "\n [%s => 1,]" (String.lowercase flag)
2040 Open a Windows Registry binary hive file.
2042 The C<verbose> and C<debug> flags enable different levels of
2045 The C<write> flag is required if you will be modifying the
2046 hive file (see L<hivex(3)/WRITING TO HIVE FILES>).
2048 This function returns a hive handle. The hive handle is
2049 closed automatically when its reference count drops to 0.
2055 my $class = ref ($proto) || $proto;
2056 my $filename = shift;
2063 fun (n, flag, description) ->
2064 pr " # %s\n" description;
2065 pr " $flags += %d if $flags{%s};\n" n (String.lowercase flag)
2070 my $self = Win::Hivex::_open ($filename, $flags);
2071 bless $self, $class;
2078 fun (name, style, _, longdesc) ->
2079 (* The close call isn't explicit in Perl: handles are closed
2080 * when their reference count drops to 0.
2082 * The open call is coded specially in Perl.
2084 * Therefore we don't generate prototypes for these two calls:
2086 if fst style <> RErrDispose && List.hd (snd style) = AHive then (
2087 let longdesc = replace_str longdesc "C<hivex_" "C<" in
2088 pr "=item %s\n\n " name;
2089 generate_perl_prototype name style;
2091 pr "%s\n\n" longdesc;
2093 (match fst style with
2105 This returns a node handle.\n\n"
2108 This returns a node handle, or C<undef> if the node was not found.\n\n"
2111 This returns a list of node handles.\n\n"
2114 This returns a value handle.\n\n"
2117 This returns a list of value handles.\n\n"
2120 if List.mem ASetValues (snd style) then
2121 pr "C<@values> is an array of (keys, value) pairs.
2122 Each element should be a hashref containing C<key>, C<t> (type)
2125 Any existing values stored at the node are discarded, and their
2126 C<value> handles become invalid. Thus you can remove all
2127 values stored at C<node> by passing C<@values = []>.\n\n"
2140 Copyright (C) %s Red Hat Inc.
2144 Please see the file COPYING.LIB for the full license.
2150 L<http://libguestfs.org>,
2156 and generate_perl_prototype name style =
2158 (match fst style with
2161 | RHive -> pr "$h = "
2163 | RNodeNotFound -> pr "$node = "
2164 | RNodeList -> pr "@nodes = "
2165 | RValue -> pr "$value = "
2166 | RValueList -> pr "@values = "
2167 | RString -> pr "$string = "
2168 | RStringList -> pr "@strings = "
2169 | RLenType -> pr "($type, $len) = "
2170 | RLenTypeVal -> pr "($type, $data) = "
2171 | RInt32 -> pr "$int32 = "
2172 | RInt64 -> pr "$int64 = "
2175 let args = List.tl (snd style) in
2177 (* AUnusedFlags is dropped in the bindings. *)
2178 let args = List.filter ((<>) AUnusedFlags) args in
2182 let comma = ref false in
2185 if !comma then pr ", "; comma := true;
2190 | AString n -> pr "$%s" n
2191 | AStringNullable n -> pr "[$%s|undef]" n
2192 | AOpenFlags -> pr "[flags]"
2193 | AUnusedFlags -> assert false
2194 | ASetValues -> pr "\\@values"
2195 | ASetValue -> pr "$val"
2200 and generate_perl_xs () =
2201 generate_header CStyle LGPLv2plus;
2204 #include \"EXTERN.h\"
2210 #include <inttypes.h>
2213 my_newSVll(long long val) {
2214 #ifdef USE_64_BIT_ALL
2215 return newSViv(val);
2219 len = snprintf(buf, 100, \"%%\" PRId64, val);
2220 return newSVpv(buf, len);
2226 my_newSVull(unsigned long long val) {
2227 #ifdef USE_64_BIT_ALL
2228 return newSVuv(val);
2232 len = snprintf(buf, 100, \"%%\" PRIu64, val);
2233 return newSVpv(buf, len);
2239 /* http://www.perlmonks.org/?node_id=680842 */
2241 XS_unpack_charPtrPtr (SV *arg) {
2246 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
2247 croak (\"array reference expected\");
2249 av = (AV *)SvRV (arg);
2250 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
2252 croak (\"malloc failed\");
2254 for (i = 0; i <= av_len (av); i++) {
2255 SV **elem = av_fetch (av, i, 0);
2257 if (!elem || !*elem)
2258 croak (\"missing element in list\");
2260 ret[i] = SvPV_nolen (*elem);
2269 /* Handle set_values parameter. */
2270 typedef struct pl_set_values {
2272 hive_set_value *values;
2275 static pl_set_values
2276 unpack_pl_set_values (SV *sv)
2282 if (!sv || !SvOK (sv) || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV)
2283 croak (\"array reference expected\");
2285 av = (AV *)SvRV(sv);
2286 ret.nr_values = av_len (av) + 1;
2287 ret.values = malloc (ret.nr_values * sizeof (hive_set_value));
2289 croak (\"malloc failed\");
2291 for (i = 0; i <= av_len (av); i++) {
2292 SV **hvp = av_fetch (av, i, 0);
2294 if (!hvp || !*hvp || !SvROK (*hvp) || SvTYPE (SvRV (*hvp)) != SVt_PVHV)
2295 croak (\"missing element in list or not a hash ref\");
2297 HV *hv = (HV *)SvRV(*hvp);
2300 svp = hv_fetch (hv, \"key\", 3, 0);
2302 croak (\"missing 'key' in hash\");
2303 ret.values[i].key = SvPV_nolen (*svp);
2305 svp = hv_fetch (hv, \"t\", 1, 0);
2307 croak (\"missing 't' in hash\");
2308 ret.values[i].t = SvIV (*svp);
2310 svp = hv_fetch (hv, \"value\", 5, 0);
2312 croak (\"missing 'value' in hash\");
2313 ret.values[i].value = SvPV (*svp, ret.values[i].len);
2319 static hive_set_value *
2320 unpack_set_value (SV *sv)
2322 hive_set_value *ret;
2324 if (!sv || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVHV)
2325 croak (\"not a hash ref\");
2327 ret = malloc (sizeof (hive_set_value));
2329 croak (\"malloc failed\");
2331 HV *hv = (HV *)SvRV(sv);
2334 svp = hv_fetch (hv, \"key\", 3, 0);
2336 croak (\"missing 'key' in hash\");
2337 ret->key = SvPV_nolen (*svp);
2339 svp = hv_fetch (hv, \"t\", 1, 0);
2341 croak (\"missing 't' in hash\");
2342 ret->t = SvIV (*svp);
2344 svp = hv_fetch (hv, \"value\", 5, 0);
2346 croak (\"missing 'value' in hash\");
2347 ret->value = SvPV (*svp, ret->len);
2352 MODULE = Win::Hivex PACKAGE = Win::Hivex
2357 _open (filename, flags)
2361 RETVAL = hivex_open (filename, flags);
2363 croak (\"hivex_open: %%s: %%s\", filename, strerror (errno));
2371 if (hivex_close (h) == -1)
2372 croak (\"hivex_close: %%s\", strerror (errno));
2377 fun (name, style, _, longdesc) ->
2378 (* The close and open calls are handled specially above. *)
2379 if fst style <> RErrDispose && List.hd (snd style) = AHive then (
2380 (match fst style with
2381 | RErr -> pr "void\n"
2382 | RErrDispose -> failwith "perl bindings cannot handle a call which disposes of the handle"
2383 | RHive -> failwith "perl bindings cannot handle a call which returns a handle"
2387 | RString -> pr "SV *\n"
2392 | RLenTypeVal -> pr "void\n"
2393 | RInt32 -> pr "SV *\n"
2394 | RInt64 -> pr "SV *\n"
2397 (* Call and arguments. *)
2399 filter_map (function
2400 | AUnusedFlags -> None
2401 | arg -> Some (name_of_argt arg)) (snd style) in
2405 | AUnusedFlags -> "0"
2406 | ASetValues -> "values.nr_values, values.values"
2407 | arg -> name_of_argt arg) (snd style) in
2409 pr "%s (%s)\n" name (String.concat ", " perl_params);
2420 | AStringNullable n ->
2421 (* http://www.perlmonks.org/?node_id=554277 *)
2422 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n i i
2425 | AUnusedFlags -> ()
2427 pr " pl_set_values values = unpack_pl_set_values (ST(%d));\n" i
2429 pr " hive_set_value *val = unpack_set_value (ST(%d));\n" i
2436 pr " free (values.values);\n"
2439 | AHive | ANode _ | AValue _ | AString _ | AStringNullable _
2440 | AOpenFlags | AUnusedFlags -> ()
2445 (match fst style with
2450 pr " r = hivex_%s (%s);\n"
2451 name (String.concat ", " c_params);
2453 pr " if (r == -1)\n";
2454 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2457 | RErrDispose -> assert false
2458 | RHive -> assert false
2463 pr " /* hive_node_h = hive_value_h = size_t so we cheat\n";
2464 pr " here to simplify the generator */\n";
2467 pr " r = hivex_%s (%s);\n"
2468 name (String.concat ", " c_params);
2470 pr " if (r == 0)\n";
2471 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2473 pr " RETVAL = newSViv (r);\n";
2479 pr " hive_node_h r;\n";
2482 pr " r = hivex_%s (%s);\n"
2483 name (String.concat ", " c_params);
2485 pr " if (r == 0 && errno != 0)\n";
2486 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2488 pr " if (r == 0)\n";
2489 pr " RETVAL = &PL_sv_undef;\n";
2491 pr " RETVAL = newSViv (r);\n";
2499 pr " r = hivex_%s (%s);\n"
2500 name (String.concat ", " c_params);
2502 pr " if (r == NULL)\n";
2503 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2505 pr " RETVAL = newSVpv (r, 0);\n";
2516 pr " r = hivex_%s (%s);\n"
2517 name (String.concat ", " c_params);
2519 pr " if (r == NULL)\n";
2520 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2522 pr " for (n = 0; r[n] != 0; ++n) /**/;\n";
2523 pr " EXTEND (SP, n);\n";
2524 pr " for (i = 0; i < n; ++i)\n";
2525 pr " PUSHs (sv_2mortal (newSViv (r[i])));\n";
2533 pr " r = hivex_%s (%s);\n"
2534 name (String.concat ", " c_params);
2536 pr " if (r == NULL)\n";
2537 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2539 pr " for (n = 0; r[n] != NULL; ++n) /**/;\n";
2540 pr " EXTEND (SP, n);\n";
2541 pr " for (i = 0; i < n; ++i) {\n";
2542 pr " PUSHs (sv_2mortal (newSVpv (r[i], 0)));\n";
2543 pr " free (r[i]);\n";
2550 pr " size_t len;\n";
2551 pr " hive_type type;\n";
2553 pr " r = hivex_%s (%s, &type, &len);\n"
2554 name (String.concat ", " c_params);
2556 pr " if (r == -1)\n";
2557 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2559 pr " EXTEND (SP, 2);\n";
2560 pr " PUSHs (sv_2mortal (newSViv (type)));\n";
2561 pr " PUSHs (sv_2mortal (newSViv (len)));\n";
2566 pr " size_t len;\n";
2567 pr " hive_type type;\n";
2569 pr " r = hivex_%s (%s, &type, &len);\n"
2570 name (String.concat ", " c_params);
2572 pr " if (r == NULL)\n";
2573 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2575 pr " EXTEND (SP, 2);\n";
2576 pr " PUSHs (sv_2mortal (newSViv (type)));\n";
2577 pr " PUSHs (sv_2mortal (newSVpvn (r, len)));\n";
2585 pr " r = hivex_%s (%s);\n"
2586 name (String.concat ", " c_params);
2588 pr " if (r == -1 && errno != 0)\n";
2589 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2591 pr " RETVAL = newSViv (r);\n";
2600 pr " r = hivex_%s (%s);\n"
2601 name (String.concat ", " c_params);
2603 pr " if (r == -1 && errno != 0)\n";
2604 pr " croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2606 pr " RETVAL = my_newSVll (r);\n";
2614 and generate_python_c () =
2615 generate_header CStyle LGPLv2plus;
2618 #define PY_SSIZE_T_CLEAN 1
2621 #if PY_VERSION_HEX < 0x02050000
2622 typedef int Py_ssize_t;
2623 #define PY_SSIZE_T_MAX INT_MAX
2624 #define PY_SSIZE_T_MIN INT_MIN
2631 #include \"hivex.h\"
2633 #ifndef HAVE_PYCAPSULE_NEW
2641 get_handle (PyObject *obj)
2644 assert (obj != Py_None);
2645 #ifndef HAVE_PYCAPSULE_NEW
2646 return ((Pyhivex_Object *) obj)->h;
2648 return (hive_h *) PyCapsule_GetPointer(obj, \"hive_h\");
2653 put_handle (hive_h *h)
2656 #ifndef HAVE_PYCAPSULE_NEW
2658 PyCObject_FromVoidPtrAndDesc ((void *) h, (char *) \"hive_h\", NULL);
2660 return PyCapsule_New ((void *) h, \"hive_h\", NULL);
2664 /* This returns pointers into the Python objects, which should
2668 get_value (PyObject *v, hive_set_value *ret)
2672 obj = PyDict_GetItemString (v, \"key\");
2674 PyErr_SetString (PyExc_RuntimeError, \"no 'key' element in dictionary\");
2677 if (!PyString_Check (obj)) {
2678 PyErr_SetString (PyExc_RuntimeError, \"'key' element is not a string\");
2681 ret->key = PyString_AsString (obj);
2683 obj = PyDict_GetItemString (v, \"t\");
2685 PyErr_SetString (PyExc_RuntimeError, \"no 't' element in dictionary\");
2688 if (!PyInt_Check (obj)) {
2689 PyErr_SetString (PyExc_RuntimeError, \"'t' element is not an integer\");
2692 ret->t = PyInt_AsLong (obj);
2694 obj = PyDict_GetItemString (v, \"value\");
2696 PyErr_SetString (PyExc_RuntimeError, \"no 'value' element in dictionary\");
2699 if (!PyString_Check (obj)) {
2700 PyErr_SetString (PyExc_RuntimeError, \"'value' element is not a string\");
2703 ret->value = PyString_AsString (obj);
2704 ret->len = PyString_Size (obj);
2709 typedef struct py_set_values {
2711 hive_set_value *values;
2715 get_values (PyObject *v, py_set_values *ret)
2720 if (!PyList_Check (v)) {
2721 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
2725 slen = PyList_Size (v);
2727 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: PyList_Size failure\");
2730 len = (size_t) slen;
2731 ret->nr_values = len;
2732 ret->values = malloc (len * sizeof (hive_set_value));
2734 PyErr_SetString (PyExc_RuntimeError, strerror (errno));
2738 for (i = 0; i < len; ++i) {
2739 if (get_value (PyList_GetItem (v, i), &(ret->values[i])) == -1) {
2749 put_string_list (char * const * const argv)
2754 for (argc = 0; argv[argc] != NULL; ++argc)
2757 list = PyList_New (argc);
2758 for (i = 0; i < argc; ++i)
2759 PyList_SetItem (list, i, PyString_FromString (argv[i]));
2765 free_strings (char **argv)
2769 for (argc = 0; argv[argc] != NULL; ++argc)
2774 /* Since hive_node_t is the same as hive_value_t this also works for values. */
2776 put_node_list (hive_node_h *nodes)
2781 for (argc = 0; nodes[argc] != 0; ++argc)
2784 list = PyList_New (argc);
2785 for (i = 0; i < argc; ++i)
2786 PyList_SetItem (list, i, PyLong_FromLongLong ((long) nodes[i]));
2792 put_len_type (size_t len, hive_type t)
2794 PyObject *r = PyTuple_New (2);
2795 PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t));
2796 PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) len));
2801 put_val_type (char *val, size_t len, hive_type t)
2803 PyObject *r = PyTuple_New (2);
2804 PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t));
2805 PyTuple_SetItem (r, 1, PyString_FromStringAndSize (val, len));
2811 (* Generate functions. *)
2813 fun (name, style, _, longdesc) ->
2814 pr "static PyObject *\n";
2815 pr "py_hivex_%s (PyObject *self, PyObject *args)\n" name;
2817 pr " PyObject *py_r;\n";
2820 match fst style with
2821 | RErr -> pr " int r;\n"; "-1"
2822 | RErrDispose -> pr " int r;\n"; "-1"
2823 | RHive -> pr " hive_h *r;\n"; "NULL"
2824 | RNode -> pr " hive_node_h r;\n"; "0"
2827 pr " hive_node_h r;\n";
2829 | RNodeList -> pr " hive_node_h *r;\n"; "NULL"
2830 | RValue -> pr " hive_value_h r;\n"; "0"
2831 | RValueList -> pr " hive_value_h *r;\n"; "NULL"
2832 | RString -> pr " char *r;\n"; "NULL"
2833 | RStringList -> pr " char **r;\n"; "NULL"
2836 pr " size_t len;\n";
2837 pr " hive_type t;\n";
2841 pr " size_t len;\n";
2842 pr " hive_type t;\n";
2851 "-1 && errno != 0" in
2853 (* Call and arguments. *)
2856 | AUnusedFlags -> "0"
2857 | ASetValues -> "values.nr_values, values.values"
2858 | ASetValue -> "&val"
2859 | arg -> name_of_argt arg) (snd style) in
2861 match fst style with
2862 | RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"]
2869 pr " PyObject *py_h;\n"
2874 | AStringNullable n ->
2878 | AUnusedFlags -> ()
2880 pr " py_set_values values;\n";
2881 pr " PyObject *py_values;\n"
2883 pr " hive_set_value val;\n";
2884 pr " PyObject *py_val;\n"
2889 (* Convert the required parameters. *)
2890 pr " if (!PyArg_ParseTuple (args, (char *) \"";
2900 | AStringNullable n ->
2904 | AUnusedFlags -> ()
2910 pr ":hivex_%s\"" name;
2920 | AStringNullable n ->
2924 | AUnusedFlags -> ()
2932 pr " return NULL;\n";
2934 (* Convert some Python argument types to C. *)
2938 pr " h = get_handle (py_h);\n"
2944 | AUnusedFlags -> ()
2946 pr " if (get_values (py_values, &values) == -1)\n";
2947 pr " return NULL;\n"
2949 pr " if (get_value (py_val, &val) == -1)\n";
2950 pr " return NULL;\n"
2953 (* Call the C function. *)
2954 pr " r = hivex_%s (%s);\n" name (String.concat ", " c_params);
2956 (* Free up arguments. *)
2959 | AHive | ANode _ | AValue _
2960 | AString _ | AStringNullable _
2961 | AOpenFlags | AUnusedFlags -> ()
2963 pr " free (values.values);\n"
2967 (* Check for errors from C library. *)
2968 pr " if (r == %s) {\n" error_code;
2969 pr " PyErr_SetString (PyExc_RuntimeError,\n";
2970 pr " strerror (errno));\n";
2971 pr " return NULL;\n";
2975 (* Convert return value to Python. *)
2976 (match fst style with
2979 pr " Py_INCREF (Py_None);\n";
2980 pr " py_r = Py_None;\n"
2982 pr " py_r = put_handle (r);\n"
2984 pr " py_r = PyLong_FromLongLong (r);\n"
2987 pr " py_r = PyLong_FromLongLong (r);\n";
2989 pr " Py_INCREF (Py_None);\n";
2990 pr " py_r = Py_None;\n";
2994 pr " py_r = put_node_list (r);\n";
2997 pr " py_r = PyLong_FromLongLong (r);\n"
2999 pr " py_r = PyString_FromString (r);\n";
3002 pr " py_r = put_string_list (r);\n";
3003 pr " free_strings (r);\n"
3005 pr " py_r = put_len_type (len, t);\n"
3007 pr " py_r = put_val_type (r, len, t);\n";
3010 pr " py_r = PyInt_FromLong ((long) r);\n"
3012 pr " py_r = PyLong_FromLongLong (r);\n"
3014 pr " return py_r;\n";
3019 (* Table of functions. *)
3020 pr "static PyMethodDef methods[] = {\n";
3022 fun (name, _, _, _) ->
3023 pr " { (char *) \"%s\", py_hivex_%s, METH_VARARGS, NULL },\n"
3026 pr " { NULL, NULL, 0, NULL }\n";
3030 (* Init function. *)
3033 initlibhivexmod (void)
3035 static int initialized = 0;
3037 if (initialized) return;
3038 Py_InitModule ((char *) \"libhivexmod\", methods);
3043 and generate_python_py () =
3044 generate_header HashStyle LGPLv2plus;
3047 u\"\"\"Python bindings for hivex
3050 h = hivex.Hivex (filename)
3052 The hivex module provides Python bindings to the hivex API for
3053 examining and modifying Windows Registry 'hive' files.
3055 Read the hivex(3) man page to find out how to use the API.
3061 \"\"\"Instances of this class are hivex API handles.\"\"\"
3063 def __init__ (self, filename";
3066 fun (_, flag, _) -> pr ", %s = False" (String.lowercase flag)
3070 \"\"\"Create a new hivex handle.\"\"\"
3075 fun (n, flag, description) ->
3076 pr " # %s\n" description;
3077 pr " if %s: flags += %d\n" (String.lowercase flag) n
3080 pr " self._o = libhivexmod.open (filename, flags)
3083 libhivexmod.close (self._o)
3088 fun (name, style, shortdesc, _) ->
3089 (* The close and open calls are handled specially above. *)
3090 if fst style <> RErrDispose && List.hd (snd style) = AHive then (
3091 let args = List.tl (snd style) in
3092 let args = List.filter (
3093 function AOpenFlags | AUnusedFlags -> false
3097 pr " def %s (self" name;
3098 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
3100 pr " u\"\"\"%s\"\"\"\n" shortdesc;
3101 pr " return libhivexmod.%s (self._o" name;
3106 | AHive -> assert false
3107 | ANode n | AValue n
3108 | AString n | AStringNullable n -> pr "%s" n
3110 | AUnusedFlags -> assert false
3111 | ASetValues -> pr "values"
3112 | ASetValue -> pr "val"
3119 let output_to filename k =
3120 let filename_new = filename ^ ".new" in
3121 chan := open_out filename_new;
3124 chan := Pervasives.stdout;
3126 (* Is the new file different from the current file? *)
3127 if Sys.file_exists filename && files_equal filename filename_new then
3128 unlink filename_new (* same, so skip it *)
3130 (* different, overwrite old one *)
3131 (try chmod filename 0o644 with Unix_error _ -> ());
3132 rename filename_new filename;
3133 chmod filename 0o444;
3134 printf "written %s\n%!" filename;
3137 let perror msg = function
3138 | Unix_error (err, _, _) ->
3139 eprintf "%s: %s\n" msg (error_message err)
3141 eprintf "%s: %s\n" msg (Printexc.to_string exn)
3146 try openfile "configure.ac" [O_RDWR] 0
3148 | Unix_error (ENOENT, _, _) ->
3150 You are probably running this from the wrong directory.
3151 Run it from the top source directory using the command
3152 generator/generator.ml
3156 perror "open: configure.ac" exn;
3159 (* Acquire a lock so parallel builds won't try to run the generator
3160 * twice at the same time. Subsequent builds will wait for the first
3161 * one to finish. Note the lock is released implicitly when the
3164 (try lockf lock_fd F_LOCK 1
3166 perror "lock: configure.ac" exn;
3171 output_to "lib/hivex.h" generate_c_header;
3172 output_to "lib/hivex.pod" generate_c_pod;
3174 output_to "lib/hivex.syms" generate_linker_script;
3176 output_to "ocaml/hivex.mli" generate_ocaml_interface;
3177 output_to "ocaml/hivex.ml" generate_ocaml_implementation;
3178 output_to "ocaml/hivex_c.c" generate_ocaml_c;
3180 output_to "perl/lib/Win/Hivex.pm" generate_perl_pm;
3181 output_to "perl/Hivex.xs" generate_perl_xs;
3183 output_to "python/hivex.py" generate_python_py;
3184 output_to "python/hivex-py.c" generate_python_c;
3186 (* Always generate this file last, and unconditionally. It's used
3187 * by the Makefile to know when we must re-run the generator.
3189 let chan = open_out "generator/stamp-generator" in
3193 printf "generated %d lines of code\n" !lines