hivex_root: Return errno == HIVEX_NO_KEY when root key is missing.
[hivex.git] / generator / generator.ml
1 #!/usr/bin/env ocaml
2 (* hivex
3  * Copyright (C) 2009-2010 Red Hat Inc.
4  *
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.
9  *
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.
14  *
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
18  *)
19
20 (* This script generates language bindings and some documentation for
21  * hivex.
22  * 
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_
27  * directory.
28  * 
29  * IMPORTANT: This script should NOT print any warnings.  If it prints
30  * warnings, you should treat them as errors.
31  * 
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/
35  *)
36
37 #load "unix.cma";;
38 #load "str.cma";;
39
40 open Unix
41 open Printf
42
43 type style = ret * args
44 and ret =
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. *)
59
60 and args = argt list                    (* List of parameters. *)
61
62 and argt =                              (* Note, cannot be NULL/0 unless it
63                                            says so explicitly below. *)
64   | AHive                               (* hive_h* *)
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. *)
73
74 (* Hive types, from:
75  * https://secure.wikimedia.org/wikipedia/en/wiki/Windows_Registry#Keys_and_values
76  * 
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.
80  *)
81 let hive_types = [
82   0, "none", "NONE",
83     "Just a key without a value";
84   1, "string", "SZ",
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",
89     "A blob of binary";
90   4, "dword", "DWORD",
91     "DWORD (32 bit integer), little endian";
92   5, "dword_be", "DWORD_BIG_ENDIAN",
93     "DWORD (32 bit integer), big endian";
94   6, "link", "LINK",
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",
99     "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"
106 ]
107 let max_hive_type = 11
108
109 (* Open flags (bitmask passed to AOpenFlags) *)
110 let open_flags = [
111   1, "VERBOSE", "Verbose messages";
112   2, "DEBUG", "Debug messages";
113   4, "WRITE", "Enable writes to the hive";
114 ]
115
116 (* The API calls. *)
117 let functions = [
118   "open", (RHive, [AString "filename"; AOpenFlags]),
119     "open a hive file",
120     "\
121 Opens the hive named C<filename> for reading.
122
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:
125
126 =over 4
127
128 =item HIVEX_OPEN_VERBOSE
129
130 Verbose messages.
131
132 =item HIVEX_OPEN_DEBUG
133
134 Very verbose messages, suitable for debugging problems in the library
135 itself.
136
137 This is also selected if the C<HIVEX_DEBUG> environment variable
138 is set to 1.
139
140 =item HIVEX_OPEN_WRITE
141
142 Open the hive for writing.  If omitted, the hive is read-only.
143
144 See L<hivex(3)/WRITING TO HIVE FILES>.
145
146 =back";
147
148   "close", (RErrDispose, [AHive]),
149     "close a hive handle",
150     "\
151 Close a hive handle and free all associated resources.
152
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>.";
155
156   "root", (RNode, [AHive]),
157     "return the root node of the hive",
158     "\
159 Return root node of the hive.  All valid hives must contain a root node.";
160
161   "node_name", (RString, [AHive; ANode "node"]),
162     "return the name of the node",
163     "\
164 Return the name of the node.
165
166 Note that the name of the root node is a dummy, such as
167 C<$$$PROTO.HIV> (other names are possible: it seems to depend on the
168 tool or program that created the hive in the first place).  You can
169 only know the \"real\" name of the root node by knowing which registry
170 file this hive originally comes from, which is knowledge that is
171 outside the scope of this library.";
172
173   "node_children", (RNodeList, [AHive; ANode "node"]),
174     "return children of node",
175     "\
176 Return an array of nodes which are the subkeys
177 (children) of C<node>.";
178
179   "node_get_child", (RNodeNotFound, [AHive; ANode "node"; AString "name"]),
180     "return named child of node",
181     "\
182 Return the child of node with the name C<name>, if it exists.
183
184 The name is matched case insensitively.";
185
186   "node_parent", (RNode, [AHive; ANode "node"]),
187     "return the parent of node",
188     "\
189 Return the parent of C<node>.
190
191 The parent pointer of the root node in registry files that we
192 have examined seems to be invalid, and so this function will
193 return an error if called on the root node.";
194
195   "node_values", (RValueList, [AHive; ANode "node"]),
196     "return (key, value) pairs attached to a node",
197     "\
198 Return the array of (key, value) pairs attached to this node.";
199
200   "node_get_value", (RValue, [AHive; ANode "node"; AString "key"]),
201     "return named key at node",
202     "\
203 Return the value attached to this node which has the name C<key>,
204 if it exists.
205
206 The key name is matched case insensitively.
207
208 Note that to get the default key, you should pass the empty
209 string C<\"\"> here.  The default key is often written C<\"@\">, but
210 inside hives that has no meaning and won't give you the
211 default key.";
212
213   "value_key", (RString, [AHive; AValue "val"]),
214     "return the key of a (key, value) pair",
215     "\
216 Return the key (name) of a (key, value) pair.  The name
217 is reencoded as UTF-8 and returned as a string.
218
219 The string should be freed by the caller when it is no longer needed.
220
221 Note that this function can return a zero-length string.  In the
222 context of Windows Registries, this means that this value is the
223 default key for this node in the tree.  This is usually written
224 as C<\"@\">.";
225
226   "value_type", (RLenType, [AHive; AValue "val"]),
227     "return data length and data type of a value",
228     "\
229 Return the data length and data type of the value in this (key, value)
230 pair.  See also C<hivex_value_value> which returns all this
231 information, and the value itself.  Also, C<hivex_value_*> functions
232 below which can be used to return the value in a more useful form when
233 you know the type in advance.";
234
235   "value_value", (RLenTypeVal, [AHive; AValue "val"]),
236     "return data length, data type and data of a value",
237     "\
238 Return the value of this (key, value) pair.  The value should
239 be interpreted according to its type (see C<hive_type>).";
240
241   "value_string", (RString, [AHive; AValue "val"]),
242     "return value as a string",
243     "\
244 If this value is a string, return the string reencoded as UTF-8
245 (as a C string).  This only works for values which have type
246 C<hive_t_string>, C<hive_t_expand_string> or C<hive_t_link>.";
247
248   "value_multiple_strings", (RStringList, [AHive; AValue "val"]),
249     "return value as multiple strings",
250     "\
251 If this value is a multiple-string, return the strings reencoded
252 as UTF-8 (in C, as a NULL-terminated array of C strings, in other
253 language bindings, as a list of strings).  This only
254 works for values which have type C<hive_t_multiple_strings>.";
255
256   "value_dword", (RInt32, [AHive; AValue "val"]),
257     "return value as a DWORD",
258     "\
259 If this value is a DWORD (Windows int32), return it.  This only works
260 for values which have type C<hive_t_dword> or C<hive_t_dword_be>.";
261
262   "value_qword", (RInt64, [AHive; AValue "val"]),
263     "return value as a QWORD",
264     "\
265 If this value is a QWORD (Windows int64), return it.  This only
266 works for values which have type C<hive_t_qword>.";
267
268   "commit", (RErr, [AHive; AStringNullable "filename"; AUnusedFlags]),
269     "commit (write) changes to file",
270     "\
271 Commit (write) any changes which have been made.
272
273 C<filename> is the new file to write.  If C<filename> is null/undefined
274 then we overwrite the original file (ie. the file name that was passed to
275 C<hivex_open>).
276
277 Note this does not close the hive handle.  You can perform further
278 operations on the hive after committing, including making more
279 modifications.  If you no longer wish to use the hive, then you
280 should close the handle after committing.";
281
282   "node_add_child", (RNode, [AHive; ANode "parent"; AString "name"]),
283     "add child node",
284     "\
285 Add a new child node named C<name> to the existing node C<parent>.
286 The new child initially has no subnodes and contains no keys or
287 values.  The sk-record (security descriptor) is inherited from
288 the parent.
289
290 The parent must not have an existing child called C<name>, so if you
291 want to overwrite an existing child, call C<hivex_node_delete_child>
292 first.";
293
294   "node_delete_child", (RErr, [AHive; ANode "node"]),
295     "delete child node",
296     "\
297 Delete the node C<node>.  All values at the node and all subnodes are
298 deleted (recursively).  The C<node> handle and the handles of all
299 subnodes become invalid.  You cannot delete the root node.";
300
301   "node_set_values", (RErr, [AHive; ANode "node"; ASetValues; AUnusedFlags]),
302     "set (key, value) pairs at a node",
303     "\
304 This call can be used to set all the (key, value) pairs
305 stored in C<node>.
306
307 C<node> is the node to modify.";
308
309   "node_set_value", (RErr, [AHive; ANode "node"; ASetValue; AUnusedFlags]),
310     "set a single (key, value) pair at a given node",
311     "\
312 This call can be used to replace a single C<(key, value)> pair
313 stored in C<node>.  If the key does not already exist, then a
314 new key is added.  Key matching is case insensitive.
315
316 C<node> is the node to modify.";
317 ]
318
319 (* Used to memoize the result of pod2text. *)
320 let pod2text_memo_filename = "generator/.pod2text.data"
321 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
322   try
323     let chan = open_in pod2text_memo_filename in
324     let v = input_value chan in
325     close_in chan;
326     v
327   with
328     _ -> Hashtbl.create 13
329 let pod2text_memo_updated () =
330   let chan = open_out pod2text_memo_filename in
331   output_value chan pod2text_memo;
332   close_out chan
333
334 (* Useful functions.
335  * Note we don't want to use any external OCaml libraries which
336  * makes this a bit harder than it should be.
337  *)
338 module StringMap = Map.Make (String)
339
340 let failwithf fs = ksprintf failwith fs
341
342 let unique = let i = ref 0 in fun () -> incr i; !i
343
344 let replace_char s c1 c2 =
345   let s2 = String.copy s in
346   let r = ref false in
347   for i = 0 to String.length s2 - 1 do
348     if String.unsafe_get s2 i = c1 then (
349       String.unsafe_set s2 i c2;
350       r := true
351     )
352   done;
353   if not !r then s else s2
354
355 let isspace c =
356   c = ' '
357   (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
358
359 let triml ?(test = isspace) str =
360   let i = ref 0 in
361   let n = ref (String.length str) in
362   while !n > 0 && test str.[!i]; do
363     decr n;
364     incr i
365   done;
366   if !i = 0 then str
367   else String.sub str !i !n
368
369 let trimr ?(test = isspace) str =
370   let n = ref (String.length str) in
371   while !n > 0 && test str.[!n-1]; do
372     decr n
373   done;
374   if !n = String.length str then str
375   else String.sub str 0 !n
376
377 let trim ?(test = isspace) str =
378   trimr ~test (triml ~test str)
379
380 let rec find s sub =
381   let len = String.length s in
382   let sublen = String.length sub in
383   let rec loop i =
384     if i <= len-sublen then (
385       let rec loop2 j =
386         if j < sublen then (
387           if s.[i+j] = sub.[j] then loop2 (j+1)
388           else -1
389         ) else
390           i (* found *)
391       in
392       let r = loop2 0 in
393       if r = -1 then loop (i+1) else r
394     ) else
395       -1 (* not found *)
396   in
397   loop 0
398
399 let rec replace_str s s1 s2 =
400   let len = String.length s in
401   let sublen = String.length s1 in
402   let i = find s s1 in
403   if i = -1 then s
404   else (
405     let s' = String.sub s 0 i in
406     let s'' = String.sub s (i+sublen) (len-i-sublen) in
407     s' ^ s2 ^ replace_str s'' s1 s2
408   )
409
410 let rec string_split sep str =
411   let len = String.length str in
412   let seplen = String.length sep in
413   let i = find str sep in
414   if i = -1 then [str]
415   else (
416     let s' = String.sub str 0 i in
417     let s'' = String.sub str (i+seplen) (len-i-seplen) in
418     s' :: string_split sep s''
419   )
420
421 let files_equal n1 n2 =
422   let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
423   match Sys.command cmd with
424   | 0 -> true
425   | 1 -> false
426   | i -> failwithf "%s: failed with error code %d" cmd i
427
428 let rec filter_map f = function
429   | [] -> []
430   | x :: xs ->
431       match f x with
432       | Some y -> y :: filter_map f xs
433       | None -> filter_map f xs
434
435 let rec find_map f = function
436   | [] -> raise Not_found
437   | x :: xs ->
438       match f x with
439       | Some y -> y
440       | None -> find_map f xs
441
442 let iteri f xs =
443   let rec loop i = function
444     | [] -> ()
445     | x :: xs -> f i x; loop (i+1) xs
446   in
447   loop 0 xs
448
449 let mapi f xs =
450   let rec loop i = function
451     | [] -> []
452     | x :: xs -> let r = f i x in r :: loop (i+1) xs
453   in
454   loop 0 xs
455
456 let count_chars c str =
457   let count = ref 0 in
458   for i = 0 to String.length str - 1 do
459     if c = String.unsafe_get str i then incr count
460   done;
461   !count
462
463 let name_of_argt = function
464   | AHive -> "h"
465   | ANode n | AValue n | AString n | AStringNullable n -> n
466   | AOpenFlags | AUnusedFlags -> "flags"
467   | ASetValues -> "values"
468   | ASetValue -> "val"
469
470 (* Check function names etc. for consistency. *)
471 let check_functions () =
472   let contains_uppercase str =
473     let len = String.length str in
474     let rec loop i =
475       if i >= len then false
476       else (
477         let c = str.[i] in
478         if c >= 'A' && c <= 'Z' then true
479         else loop (i+1)
480       )
481     in
482     loop 0
483   in
484
485   (* Check function names. *)
486   List.iter (
487     fun (name, _, _, _) ->
488       if String.length name >= 7 && String.sub name 0 7 = "hivex" then
489         failwithf "function name %s does not need 'hivex' prefix" name;
490       if name = "" then
491         failwithf "function name is empty";
492       if name.[0] < 'a' || name.[0] > 'z' then
493         failwithf "function name %s must start with lowercase a-z" name;
494       if String.contains name '-' then
495         failwithf "function name %s should not contain '-', use '_' instead."
496           name
497   ) functions;
498
499   (* Check function parameter/return names. *)
500   List.iter (
501     fun (name, style, _, _) ->
502       let check_arg_ret_name n =
503         if contains_uppercase n then
504           failwithf "%s param/ret %s should not contain uppercase chars"
505             name n;
506         if String.contains n '-' || String.contains n '_' then
507           failwithf "%s param/ret %s should not contain '-' or '_'"
508             name n;
509         if n = "value" then
510           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;
511         if n = "int" || n = "char" || n = "short" || n = "long" then
512           failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
513         if n = "i" || n = "n" then
514           failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
515         if n = "argv" || n = "args" then
516           failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
517
518         (* List Haskell, OCaml and C keywords here.
519          * http://www.haskell.org/haskellwiki/Keywords
520          * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
521          * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
522          * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
523          *   |perl -pe 's/(.+)/"$1";/'|fmt -70
524          * Omitting _-containing words, since they're handled above.
525          * Omitting the OCaml reserved word, "val", is ok,
526          * and saves us from renaming several parameters.
527          *)
528         let reserved = [
529           "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
530           "char"; "class"; "const"; "constraint"; "continue"; "data";
531           "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
532           "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
533           "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
534           "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
535           "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
536           "interface";
537           "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
538           "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
539           "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
540           "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
541           "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
542           "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
543           "volatile"; "when"; "where"; "while";
544           ] in
545         if List.mem n reserved then
546           failwithf "%s has param/ret using reserved word %s" name n;
547       in
548
549       List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
550   ) functions;
551
552   (* Check short descriptions. *)
553   List.iter (
554     fun (name, _, shortdesc, _) ->
555       if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
556         failwithf "short description of %s should begin with lowercase." name;
557       let c = shortdesc.[String.length shortdesc-1] in
558       if c = '\n' || c = '.' then
559         failwithf "short description of %s should not end with . or \\n." name
560   ) functions;
561
562   (* Check long dscriptions. *)
563   List.iter (
564     fun (name, _, _, longdesc) ->
565       if longdesc.[String.length longdesc-1] = '\n' then
566         failwithf "long description of %s should not end with \\n." name
567   ) functions
568
569 (* 'pr' prints to the current output file. *)
570 let chan = ref Pervasives.stdout
571 let lines = ref 0
572 let pr fs =
573   ksprintf
574     (fun str ->
575        let i = count_chars '\n' str in
576        lines := !lines + i;
577        output_string !chan str
578     ) fs
579
580 let copyright_years =
581   let this_year = 1900 + (localtime (time ())).tm_year in
582   if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
583
584 (* Generate a header block in a number of standard styles. *)
585 type comment_style =
586   | CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
587   | PODCommentStyle
588 type license = GPLv2plus | LGPLv2plus | GPLv2 | LGPLv2
589
590 let generate_header ?(extra_inputs = []) comment license =
591   let inputs = "generator/generator.ml" :: extra_inputs in
592   let c = match comment with
593     | CStyle ->         pr "/* "; " *"
594     | CPlusPlusStyle -> pr "// "; "//"
595     | HashStyle ->      pr "# ";  "#"
596     | OCamlStyle ->     pr "(* "; " *"
597     | HaskellStyle ->   pr "{- "; "  "
598     | PODCommentStyle -> pr "=begin comment\n\n "; "" in
599   pr "hivex generated file\n";
600   pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
601   List.iter (pr "%s   %s\n" c) inputs;
602   pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
603   pr "%s\n" c;
604   pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
605   pr "%s Derived from code by Petter Nordahl-Hagen under a compatible license:\n" c;
606   pr "%s   Copyright (c) 1997-2007 Petter Nordahl-Hagen.\n" c;
607   pr "%s Derived from code by Markus Stephany under a compatible license:\n" c;
608   pr "%s   Copyright (c)2000-2004, Markus Stephany.\n" c;
609   pr "%s\n" c;
610   (match license with
611    | GPLv2plus ->
612        pr "%s This program is free software; you can redistribute it and/or modify\n" c;
613        pr "%s it under the terms of the GNU General Public License as published by\n" c;
614        pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
615        pr "%s (at your option) any later version.\n" c;
616        pr "%s\n" c;
617        pr "%s This program is distributed in the hope that it will be useful,\n" c;
618        pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
619        pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" c;
620        pr "%s GNU General Public License for more details.\n" c;
621        pr "%s\n" c;
622        pr "%s You should have received a copy of the GNU General Public License along\n" c;
623        pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
624        pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
625
626    | LGPLv2plus ->
627        pr "%s This library is free software; you can redistribute it and/or\n" c;
628        pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
629        pr "%s License as published by the Free Software Foundation; either\n" c;
630        pr "%s version 2 of the License, or (at your option) any later version.\n" c;
631        pr "%s\n" c;
632        pr "%s This library is distributed in the hope that it will be useful,\n" c;
633        pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
634        pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" c;
635        pr "%s Lesser General Public License for more details.\n" c;
636        pr "%s\n" c;
637        pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
638        pr "%s License along with this library; if not, write to the Free Software\n" c;
639        pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
640
641    | GPLv2 ->
642        pr "%s This program is free software; you can redistribute it and/or modify\n" c;
643        pr "%s it under the terms of the GNU General Public License as published by\n" c;
644        pr "%s the Free Software Foundation; version 2 of the License only.\n" c;
645        pr "%s\n" c;
646        pr "%s This program is distributed in the hope that it will be useful,\n" c;
647        pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
648        pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" c;
649        pr "%s GNU General Public License for more details.\n" c;
650        pr "%s\n" c;
651        pr "%s You should have received a copy of the GNU General Public License along\n" c;
652        pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
653        pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
654
655    | LGPLv2 ->
656        pr "%s This library is free software; you can redistribute it and/or\n" c;
657        pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
658        pr "%s License as published by the Free Software Foundation;\n" c;
659        pr "%s version 2.1 of the License only.\n" c;
660        pr "%s\n" c;
661        pr "%s This library is distributed in the hope that it will be useful,\n" c;
662        pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
663        pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" c;
664        pr "%s Lesser General Public License for more details.\n" c;
665        pr "%s\n" c;
666        pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
667        pr "%s License along with this library; if not, write to the Free Software\n" c;
668        pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
669   );
670   (match comment with
671    | CStyle -> pr " */\n"
672    | CPlusPlusStyle
673    | HashStyle -> ()
674    | OCamlStyle -> pr " *)\n"
675    | HaskellStyle -> pr "-}\n"
676    | PODCommentStyle -> pr "\n=end comment\n"
677   );
678   pr "\n"
679
680 (* Start of main code generation functions below this line. *)
681
682 let rec generate_c_header () =
683   generate_header CStyle LGPLv2;
684
685   pr "\
686 #ifndef HIVEX_H_
687 #define HIVEX_H_
688
689 #include <stdint.h>
690
691 #ifdef __cplusplus
692 extern \"C\" {
693 #endif
694
695 /* NOTE: This API is documented in the man page hivex(3). */
696
697 /* Hive handle. */
698 typedef struct hive_h hive_h;
699
700 /* Nodes and values. */
701 typedef size_t hive_node_h;
702 typedef size_t hive_value_h;
703
704 #include <errno.h>
705 #ifdef ENOKEY
706 # define HIVEX_NO_KEY ENOKEY
707 #else
708 # define HIVEX_NO_KEY ENOENT
709 #endif
710
711 /* Pre-defined types. */
712 enum hive_type {
713 ";
714   List.iter (
715     fun (t, old_style, new_style, description) ->
716       pr "  /* %s */\n" description;
717       pr "  hive_t_REG_%s,\n" new_style;
718       pr "#define hive_t_%s hive_t_REG_%s\n" old_style new_style;
719       pr "\n"
720   ) hive_types;
721   pr "\
722 };
723
724 typedef enum hive_type hive_type;
725
726 /* Bitmask of flags passed to hivex_open. */
727 ";
728   List.iter (
729     fun (v, flag, description) ->
730       pr "  /* %s */\n" description;
731       pr "#define HIVEX_OPEN_%-10s %d\n" flag v;
732   ) open_flags;
733   pr "\n";
734
735   pr "\
736 /* Array of (key, value) pairs passed to hivex_node_set_values. */
737 struct hive_set_value {
738   char *key;
739   hive_type t;
740   size_t len;
741   char *value;
742 };
743 typedef struct hive_set_value hive_set_value;
744
745 ";
746
747   pr "/* Functions. */\n";
748
749   (* Function declarations. *)
750   List.iter (
751     fun (shortname, style, _, _) ->
752       let name = "hivex_" ^ shortname in
753       generate_c_prototype ~extern:true name style
754   ) functions;
755
756   (* The visitor pattern. *)
757   pr "
758 /* Visit all nodes.  This is specific to the C API and is not made
759  * available to other languages.  This is because of the complexity
760  * of binding callbacks in other languages, but also because other
761  * languages make it much simpler to iterate over a tree.
762  */
763 struct hivex_visitor {
764   int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name);
765   int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name);
766   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);
767   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);
768   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);
769   int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t);
770   int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t);
771   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);
772   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);
773   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);
774   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);
775 };
776
777 #define HIVEX_VISIT_SKIP_BAD 1
778
779 extern int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
780 extern int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
781
782 ";
783
784   (* Finish the header file. *)
785   pr "\
786 #ifdef __cplusplus
787 }
788 #endif
789
790 #endif /* HIVEX_H_ */
791 "
792
793 and generate_c_prototype ?(extern = false) name style =
794   if extern then pr "extern ";
795   (match fst style with
796    | RErr -> pr "int "
797    | RErrDispose -> pr "int "
798    | RHive -> pr "hive_h *"
799    | RNode -> pr "hive_node_h "
800    | RNodeNotFound -> pr "hive_node_h "
801    | RNodeList -> pr "hive_node_h *"
802    | RValue -> pr "hive_value_h "
803    | RValueList -> pr "hive_value_h *"
804    | RString -> pr "char *"
805    | RStringList -> pr "char **"
806    | RLenType -> pr "int "
807    | RLenTypeVal -> pr "char *"
808    | RInt32 -> pr "int32_t "
809    | RInt64 -> pr "int64_t "
810   );
811   pr "%s (" name;
812   let comma = ref false in
813   List.iter (
814     fun arg ->
815       if !comma then pr ", "; comma := true;
816       match arg with
817       | AHive -> pr "hive_h *h"
818       | ANode n -> pr "hive_node_h %s" n
819       | AValue n -> pr "hive_value_h %s" n
820       | AString n | AStringNullable n -> pr "const char *%s" n
821       | AOpenFlags | AUnusedFlags -> pr "int flags"
822       | ASetValues -> pr "size_t nr_values, const hive_set_value *values"
823       | ASetValue -> pr "const hive_set_value *val"
824   ) (snd style);
825   (match fst style with
826    | RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len"
827    | _ -> ()
828   );
829   pr ");\n"
830
831 and generate_c_pod () =
832   generate_header PODCommentStyle GPLv2;
833
834   pr "\
835   =encoding utf8
836
837 =head1 NAME
838
839 hivex - Windows Registry \"hive\" extraction library
840
841 =head1 SYNOPSIS
842
843  #include <hivex.h>
844  
845 ";
846   List.iter (
847     fun (shortname, style, _, _) ->
848       let name = "hivex_" ^ shortname in
849       pr " ";
850       generate_c_prototype ~extern:false name style;
851   ) functions;
852
853   pr "\
854
855 Link with I<-lhivex>.
856
857 =head1 DESCRIPTION
858
859 Hivex is a library for extracting the contents of Windows Registry
860 \"hive\" files.  It is designed to be secure against buggy or malicious
861 registry files.
862
863 Unlike other tools in this area, it doesn't use the textual .REG
864 format, because parsing that is as much trouble as parsing the
865 original binary format.  Instead it makes the file available
866 through a C API, and then wraps this API in higher level scripting
867 and GUI tools.
868
869 There is a separate program to export the hive as XML
870 (see L<hivexml(1)>), or to navigate the file (see L<hivexsh(1)>).
871 There is also a Perl script to export and merge the
872 file as a textual .REG (regedit) file, see L<hivexregedit(1)>.
873
874 If you just want to export or modify the Registry of a Windows
875 virtual machine, you should look at L<virt-win-reg(1)>.
876
877 Hivex is also comes with language bindings for
878 OCaml, Perl and Python.
879
880 =head1 TYPES
881
882 =head2 C<hive_h *>
883
884 This handle describes an open hive file.
885
886 =head2 C<hive_node_h>
887
888 This is a node handle, an integer but opaque outside the library.
889 Valid node handles cannot be 0.  The library returns 0 in some
890 situations to indicate an error.
891
892 =head2 C<hive_type>
893
894 The enum below describes the possible types for the value(s)
895 stored at each node.  Note that you should not trust the
896 type field in a Windows Registry, as it very often has no
897 relationship to reality.  Some applications use their own
898 types.  The encoding of strings is not specified.  Some
899 programs store everything (including strings) in binary blobs.
900
901  enum hive_type {
902 ";
903   List.iter (
904     fun (t, _, new_style, description) ->
905       pr "   /* %s */\n" description;
906       pr "   hive_t_REG_%s = %d,\n" new_style t
907   ) hive_types;
908   pr "\
909  };
910
911 =head2 C<hive_value_h>
912
913 This is a value handle, an integer but opaque outside the library.
914 Valid value handles cannot be 0.  The library returns 0 in some
915 situations to indicate an error.
916
917 =head2 C<hive_set_value>
918
919 The typedef C<hive_set_value> is used in conjunction with the
920 C<hivex_node_set_values> call described below.
921
922  struct hive_set_value {
923    char *key;     /* key - a UTF-8 encoded ASCIIZ string */
924    hive_type t;   /* type of value field */
925    size_t len;    /* length of value field in bytes */
926    char *value;   /* value field */
927  };
928  typedef struct hive_set_value hive_set_value;
929
930 To set the default value for a node, you have to pass C<key = \"\">.
931
932 Note that the C<value> field is just treated as a list of bytes, and
933 is stored directly in the hive.  The caller has to ensure correct
934 encoding and endianness, for example converting dwords to little
935 endian.
936
937 The correct type and encoding for values depends on the node and key
938 in the registry, the version of Windows, and sometimes even changes
939 between versions of Windows for the same key.  We don't document it
940 here.  Often it's not documented at all.
941
942 =head1 FUNCTIONS
943
944 ";
945   List.iter (
946     fun (shortname, style, _, longdesc) ->
947       let name = "hivex_" ^ shortname in
948       pr "=head2 %s\n" name;
949       pr "\n ";
950       generate_c_prototype ~extern:false name style;
951       pr "\n";
952       pr "%s\n" longdesc;
953       pr "\n";
954
955       if List.mem AUnusedFlags (snd style) then
956         pr "The flags parameter is unused.  Always pass 0.\n\n";
957
958       if List.mem ASetValues (snd style) then
959         pr "C<values> is an array of (key, value) pairs.  There
960 should be C<nr_values> elements in this array.
961
962 Any existing values stored at the node are discarded, and their
963 C<hive_value_h> handles become invalid.  Thus you can remove all
964 values stored at C<node> by passing C<nr_values = 0>.\n\n";
965
966       if List.mem ASetValue (snd style) then
967         pr "C<value> is a single (key, value) pair.
968
969 Existing C<hive_value_h> handles become invalid.\n\n";
970
971       (match fst style with
972        | RErr ->
973            pr "\
974 Returns 0 on success.
975 On error this returns -1 and sets errno.\n\n"
976        | RErrDispose ->
977            pr "\
978 Returns 0 on success.
979 On error this returns -1 and sets errno.
980
981 This function frees the hive handle (even if it returns an error).
982 The hive handle must not be used again after calling this function.\n\n"
983        | RHive ->
984            pr "\
985 Returns a new hive handle.
986 On error this returns NULL and sets errno.\n\n"
987        | RNode ->
988            pr "\
989 Returns a node handle.
990 On error this returns 0 and sets errno.\n\n"
991        | RNodeNotFound ->
992            pr "\
993 Returns a node handle.
994 If the node was not found, this returns 0 without setting errno.
995 On error this returns 0 and sets errno.\n\n"
996        | RNodeList ->
997            pr "\
998 Returns a 0-terminated array of nodes.
999 The array must be freed by the caller when it is no longer needed.
1000 On error this returns NULL and sets errno.\n\n"
1001        | RValue ->
1002            pr "\
1003 Returns a value handle.
1004 On error this returns 0 and sets errno.\n\n"
1005        | RValueList ->
1006            pr "\
1007 Returns a 0-terminated array of values.
1008 The array must be freed by the caller when it is no longer needed.
1009 On error this returns NULL and sets errno.\n\n"
1010        | RString ->
1011            pr "\
1012 Returns a string.
1013 The string must be freed by the caller when it is no longer needed.
1014 On error this returns NULL and sets errno.\n\n"
1015        | RStringList ->
1016            pr "\
1017 Returns a NULL-terminated array of C strings.
1018 The strings and the array must all be freed by the caller when
1019 they are no longer needed.
1020 On error this returns NULL and sets errno.\n\n"
1021        | RLenType ->
1022            pr "\
1023 Returns 0 on success.
1024 On error this returns -1 and sets errno.\n\n"
1025        | RLenTypeVal ->
1026            pr "\
1027 The value is returned as an array of bytes (of length C<len>).
1028 The value must be freed by the caller when it is no longer needed.
1029 On error this returns NULL and sets errno.\n\n"
1030        | RInt32 | RInt64 -> ()
1031       );
1032   ) functions;
1033
1034   pr "\
1035 =head1 WRITING TO HIVE FILES
1036
1037 The hivex library supports making limited modifications to hive files.
1038 We have tried to implement this very conservatively in order to reduce
1039 the chance of corrupting your registry.  However you should be careful
1040 and take back-ups, since Microsoft has never documented the hive
1041 format, and so it is possible there are nuances in the
1042 reverse-engineered format that we do not understand.
1043
1044 To be able to modify a hive, you must pass the C<HIVEX_OPEN_WRITE>
1045 flag to C<hivex_open>, otherwise any write operation will return with
1046 errno C<EROFS>.
1047
1048 The write operations shown below do not modify the on-disk file
1049 immediately.  You must call C<hivex_commit> in order to write the
1050 changes to disk.  If you call C<hivex_close> without committing then
1051 any writes are discarded.
1052
1053 Hive files internally consist of a \"memory dump\" of binary blocks
1054 (like the C heap), and some of these blocks can be unused.  The hivex
1055 library never reuses these unused blocks.  Instead, to ensure
1056 robustness in the face of the partially understood on-disk format,
1057 hivex only allocates new blocks after the end of the file, and makes
1058 minimal modifications to existing structures in the file to point to
1059 these new blocks.  This makes hivex slightly less disk-efficient than
1060 it could be, but disk is cheap, and registry modifications tend to be
1061 very small.
1062
1063 When deleting nodes, it is possible that this library may leave
1064 unreachable live blocks in the hive.  This is because certain parts of
1065 the hive disk format such as security (sk) records and big data (db)
1066 records and classname fields are not well understood (and not
1067 documented at all) and we play it safe by not attempting to modify
1068 them.  Apart from wasting a little bit of disk space, it is not
1069 thought that unreachable blocks are a problem.
1070
1071 =head2 WRITE OPERATIONS WHICH ARE NOT SUPPORTED
1072
1073 =over 4
1074
1075 =item *
1076
1077 Changing the root node.
1078
1079 =item *
1080
1081 Creating a new hive file from scratch.  This is impossible at present
1082 because not all fields in the header are understood.  In the hivex
1083 source tree is a file called C<images/minimal> which could be used as
1084 the basis for a new hive (but I<caveat emptor>).
1085
1086 =item *
1087
1088 Modifying or deleting single values at a node.
1089
1090 =item *
1091
1092 Modifying security key (sk) records or classnames.
1093 Previously we did not understand these records.  However now they
1094 are well-understood and we could add support if it was required
1095 (but nothing much really uses them).
1096
1097 =back
1098
1099 =head1 VISITING ALL NODES
1100
1101 The visitor pattern is useful if you want to visit all nodes
1102 in the tree or all nodes below a certain point in the tree.
1103
1104 First you set up your own C<struct hivex_visitor> with your
1105 callback functions.
1106
1107 Each of these callback functions should return 0 on success or -1
1108 on error.  If any callback returns -1, then the entire visit
1109 terminates immediately.  If you don't need a callback function at
1110 all, set the function pointer to NULL.
1111
1112  struct hivex_visitor {
1113    int (*node_start) (hive_h *, void *opaque, hive_node_h, const char *name);
1114    int (*node_end) (hive_h *, void *opaque, hive_node_h, const char *name);
1115    int (*value_string) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1116          hive_type t, size_t len, const char *key, const char *str);
1117    int (*value_multiple_strings) (hive_h *, void *opaque, hive_node_h,
1118          hive_value_h, hive_type t, size_t len, const char *key, char **argv);
1119    int (*value_string_invalid_utf16) (hive_h *, void *opaque, hive_node_h,
1120          hive_value_h, hive_type t, size_t len, const char *key,
1121          const char *str);
1122    int (*value_dword) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1123          hive_type t, size_t len, const char *key, int32_t);
1124    int (*value_qword) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1125          hive_type t, size_t len, const char *key, int64_t);
1126    int (*value_binary) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1127          hive_type t, size_t len, const char *key, const char *value);
1128    int (*value_none) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1129          hive_type t, size_t len, const char *key, const char *value);
1130    int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1131          hive_type t, size_t len, const char *key, const char *value);
1132    /* If value_any callback is not NULL, then the other value_*
1133     * callbacks are not used, and value_any is called on all values.
1134     */
1135    int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h,
1136          hive_type t, size_t len, const char *key, const char *value);
1137  };
1138
1139 =over 4
1140
1141 =item hivex_visit
1142
1143  int hivex_visit (hive_h *h, const struct hivex_visitor *visitor, size_t len, void *opaque, int flags);
1144
1145 Visit all the nodes recursively in the hive C<h>.
1146
1147 C<visitor> should be a C<hivex_visitor> structure with callback
1148 fields filled in as required (unwanted callbacks can be set to
1149 NULL).  C<len> must be the length of the 'visitor' struct (you
1150 should pass C<sizeof (struct hivex_visitor)> for this).
1151
1152 This returns 0 if the whole recursive visit was completed
1153 successfully.  On error this returns -1.  If one of the callback
1154 functions returned an error than we don't touch errno.  If the
1155 error was generated internally then we set errno.
1156
1157 You can skip bad registry entries by setting C<flag> to
1158 C<HIVEX_VISIT_SKIP_BAD>.  If this flag is not set, then a bad registry
1159 causes the function to return an error immediately.
1160
1161 This function is robust if the registry contains cycles or
1162 pointers which are invalid or outside the registry.  It detects
1163 these cases and returns an error.
1164
1165 =item hivex_visit_node
1166
1167  int hivex_visit_node (hive_h *h, hive_node_h node, const struct hivex_visitor *visitor, size_t len, void *opaque);
1168
1169 Same as C<hivex_visit> but instead of starting out at the root, this
1170 starts at C<node>.
1171
1172 =back
1173
1174 =head1 THE STRUCTURE OF THE WINDOWS REGISTRY
1175
1176 Note: To understand the relationship between hives and the common
1177 Windows Registry keys (like C<HKEY_LOCAL_MACHINE>) please see the
1178 Wikipedia page on the Windows Registry.
1179
1180 The Windows Registry is split across various binary files, each
1181 file being known as a \"hive\".  This library only handles a single
1182 hive file at a time.
1183
1184 Hives are n-ary trees with a single root.  Each node in the tree
1185 has a name.
1186
1187 Each node in the tree (including non-leaf nodes) may have an
1188 arbitrary list of (key, value) pairs attached to it.  It may
1189 be the case that one of these pairs has an empty key.  This
1190 is referred to as the default key for the node.
1191
1192 The (key, value) pairs are the place where the useful data is
1193 stored in the registry.  The key is always a string (possibly the
1194 empty string for the default key).  The value is a typed object
1195 (eg. string, int32, binary, etc.).
1196
1197 =head2 RELATIONSHIP TO .REG FILES
1198
1199 The hivex C library does not care about or deal with Windows .REG
1200 files.  Instead we push this complexity up to the Perl
1201 L<Win::Hivex(3)> library and the Perl programs
1202 L<hivexregedit(1)> and L<virt-win-reg(1)>.
1203 Nevertheless it is useful to look at the relationship between the
1204 Registry and .REG files because they are so common.
1205
1206 A .REG file is a textual representation of the registry, or part of the
1207 registry.  The actual registry hives that Windows uses are binary
1208 files.  There are a number of Windows and Linux tools that let you
1209 generate .REG files, or merge .REG files back into the registry hives.
1210 Notable amongst them is Microsoft's REGEDIT program (formerly known as
1211 REGEDT32).
1212
1213 A typical .REG file will contain many sections looking like this:
1214
1215  [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack]
1216  \"@\"=\"Generic Stack\"
1217  \"TileInfo\"=\"prop:System.FileCount\"
1218  \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\"
1219  \"ThumbnailCutoff\"=dword:00000000
1220  \"FriendlyTypeName\"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,\\
1221   6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,\\
1222   33,00,32,00,5c,00,73,00,65,00,61,00,72,00,63,00,68,00,66,00,\\
1223   6f,00,6c,00,64,00,65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,\\
1224   2d,00,39,00,30,00,32,00,38,00,00,00,d8
1225
1226 Taking this one piece at a time:
1227
1228  [HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Stack]
1229
1230 This is the path to this node in the registry tree.  The first part,
1231 C<HKEY_LOCAL_MACHINE\\SOFTWARE> means that this comes from a hive
1232 file called C<C:\\WINDOWS\\SYSTEM32\\CONFIG\\SOFTWARE>.
1233 C<\\Classes\\Stack> is the real path part,
1234 starting at the root node of the C<SOFTWARE> hive.
1235
1236 Below the node name is a list of zero or more key-value pairs.  Any
1237 interior or leaf node in the registry may have key-value pairs
1238 attached.
1239
1240  \"@\"=\"Generic Stack\"
1241
1242 This is the \"default key\".  In reality (ie. inside the binary hive)
1243 the key string is the empty string.  In .REG files this is written as
1244 C<@> but this has no meaning either in the hives themselves or in this
1245 library.  The value is a string (type 1 - see C<enum hive_type>
1246 above).
1247
1248  \"TileInfo\"=\"prop:System.FileCount\"
1249
1250 This is a regular (key, value) pair, with the value being a type 1
1251 string.  Note that inside the binary file the string is likely to be
1252 UTF-16LE encoded.  This library converts to and from UTF-8 strings
1253 transparently in some cases.
1254
1255  \"TilePath\"=str(2):\"%%systemroot%%\\\\system32\"
1256
1257 The value in this case has type 2 (expanded string) meaning that some
1258 %%...%% variables get expanded by Windows.  (This library doesn't know
1259 or care about variable expansion).
1260
1261  \"ThumbnailCutoff\"=dword:00000000
1262
1263 The value in this case is a dword (type 4).
1264
1265  \"FriendlyTypeName\"=hex(2):40,00,....
1266
1267 This value is an expanded string (type 2) represented in the .REG file
1268 as a series of hex bytes.  In this case the string appears to be a
1269 UTF-16LE string.
1270
1271 =head1 NOTE ON THE USE OF ERRNO
1272
1273 Many functions in this library set errno to indicate errors.  These
1274 are the values of errno you may encounter (this list is not
1275 exhaustive):
1276
1277 =over 4
1278
1279 =item ENOTSUP
1280
1281 Corrupt or unsupported Registry file format.
1282
1283 =item HIVEX_NO_KEY
1284
1285 Missing root key.
1286
1287 =item EINVAL
1288
1289 Passed an invalid argument to the function.
1290
1291 =item EFAULT
1292
1293 Followed a Registry pointer which goes outside
1294 the registry or outside a registry block.
1295
1296 =item ELOOP
1297
1298 Registry contains cycles.
1299
1300 =item ERANGE
1301
1302 Field in the registry out of range.
1303
1304 =item EEXIST
1305
1306 Registry key already exists.
1307
1308 =item EROFS
1309
1310 Tried to write to a registry which is not opened for writing.
1311
1312 =back
1313
1314 =head1 ENVIRONMENT VARIABLES
1315
1316 =over 4
1317
1318 =item HIVEX_DEBUG
1319
1320 Setting HIVEX_DEBUG=1 will enable very verbose messages.  This is
1321 useful for debugging problems with the library itself.
1322
1323 =back
1324
1325 =head1 SEE ALSO
1326
1327 L<hivexget(1)>,
1328 L<hivexml(1)>,
1329 L<hivexsh(1)>,
1330 L<hivexregedit(1)>,
1331 L<virt-win-reg(1)>,
1332 L<Win::Hivex(3)>,
1333 L<guestfs(3)>,
1334 L<http://libguestfs.org/>,
1335 L<virt-cat(1)>,
1336 L<virt-edit(1)>,
1337 L<http://en.wikipedia.org/wiki/Windows_Registry>.
1338
1339 =head1 AUTHORS
1340
1341 Richard W.M. Jones (C<rjones at redhat dot com>)
1342
1343 =head1 COPYRIGHT
1344
1345 Copyright (C) 2009-2010 Red Hat Inc.
1346
1347 Derived from code by Petter Nordahl-Hagen under a compatible license:
1348 Copyright (C) 1997-2007 Petter Nordahl-Hagen.
1349
1350 Derived from code by Markus Stephany under a compatible license:
1351 Copyright (C) 2000-2004 Markus Stephany.
1352
1353 This library is free software; you can redistribute it and/or
1354 modify it under the terms of the GNU Lesser General Public
1355 License as published by the Free Software Foundation;
1356 version 2.1 of the License only.
1357
1358 This library is distributed in the hope that it will be useful,
1359 but WITHOUT ANY WARRANTY; without even the implied warranty of
1360 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1361 Lesser General Public License for more details.
1362 "
1363
1364 (* Generate the linker script which controls the visibility of
1365  * symbols in the public ABI and ensures no other symbols get
1366  * exported accidentally.
1367  *)
1368 and generate_linker_script () =
1369   generate_header HashStyle GPLv2plus;
1370
1371   let globals = [
1372     "hivex_visit";
1373     "hivex_visit_node"
1374   ] in
1375
1376   let functions =
1377     List.map (fun (name, _, _, _) -> "hivex_" ^ name)
1378       functions in
1379   let globals = List.sort compare (globals @ functions) in
1380
1381   pr "{\n";
1382   pr "    global:\n";
1383   List.iter (pr "        %s;\n") globals;
1384   pr "\n";
1385
1386   pr "    local:\n";
1387   pr "        *;\n";
1388   pr "};\n"
1389
1390 and generate_ocaml_interface () =
1391   generate_header OCamlStyle LGPLv2plus;
1392
1393   pr "\
1394 type t
1395 (** A [hive_h] hive file handle. *)
1396
1397 type node
1398 type value
1399 (** Nodes and values. *)
1400
1401 exception Error of string * Unix.error * string
1402 (** Error raised by a function.
1403
1404     The first parameter is the name of the function which raised the error.
1405     The second parameter is the errno (see the [Unix] module).  The third
1406     parameter is a human-readable string corresponding to the errno.
1407
1408     See hivex(3) for a partial list of interesting errno values that
1409     can be generated by the library. *)
1410 exception Handle_closed of string
1411 (** This exception is raised if you call a function on a closed handle. *)
1412
1413 type hive_type =
1414 ";
1415   iteri (
1416     fun i ->
1417       fun (t, _, new_style, description) ->
1418         assert (i = t);
1419         pr "  | REG_%s (** %s *)\n" new_style description
1420   ) hive_types;
1421
1422   pr "\
1423   | REG_UNKNOWN of int32 (** unknown type *)
1424 (** Hive type field. *)
1425
1426 type open_flag =
1427 ";
1428   iteri (
1429     fun i ->
1430       fun (v, flag, description) ->
1431         assert (1 lsl i = v);
1432         pr "  | OPEN_%s (** %s *)\n" flag description
1433   ) open_flags;
1434
1435   pr "\
1436 (** Open flags for {!open_file} call. *)
1437
1438 type set_value = {
1439   key : string;
1440   t : hive_type;
1441   value : string;
1442 }
1443 (** (key, value) pair passed (as an array) to {!node_set_values}. *)
1444 ";
1445
1446   List.iter (
1447     fun (name, style, shortdesc, _) ->
1448       pr "\n";
1449       generate_ocaml_prototype name style;
1450       pr "(** %s *)\n" shortdesc
1451   ) functions
1452
1453 and generate_ocaml_implementation () =
1454   generate_header OCamlStyle LGPLv2plus;
1455
1456   pr "\
1457 type t
1458 type node = int
1459 type value = int
1460
1461 exception Error of string * Unix.error * string
1462 exception Handle_closed of string
1463
1464 (* Give the exceptions names, so they can be raised from the C code. *)
1465 let () =
1466   Callback.register_exception \"ocaml_hivex_error\"
1467     (Error (\"\", Unix.EUNKNOWNERR 0, \"\"));
1468   Callback.register_exception \"ocaml_hivex_closed\" (Handle_closed \"\")
1469
1470 type hive_type =
1471 ";
1472   iteri (
1473     fun i ->
1474       fun (t, _, new_style, _) ->
1475         assert (i = t);
1476         pr "  | REG_%s\n" new_style
1477   ) hive_types;
1478
1479   pr "\
1480   | REG_UNKNOWN of int32
1481
1482 type open_flag =
1483 ";
1484   iteri (
1485     fun i ->
1486       fun (v, flag, description) ->
1487         assert (1 lsl i = v);
1488         pr "  | OPEN_%s (** %s *)\n" flag description
1489   ) open_flags;
1490
1491   pr "\
1492
1493 type set_value = {
1494   key : string;
1495   t : hive_type;
1496   value : string;
1497 }
1498
1499 ";
1500
1501   List.iter (
1502     fun (name, style, _, _) ->
1503       generate_ocaml_prototype ~is_external:true name style
1504   ) functions
1505
1506 and generate_ocaml_prototype ?(is_external = false) name style =
1507   let ocaml_name = if name = "open" then "open_file" else name in
1508
1509   if is_external then pr "external " else pr "val ";
1510   pr "%s : " ocaml_name;
1511   List.iter (
1512     function
1513     | AHive -> pr "t -> "
1514     | ANode _ -> pr "node -> "
1515     | AValue _ -> pr "value -> "
1516     | AString _ -> pr "string -> "
1517     | AStringNullable _ -> pr "string option -> "
1518     | AOpenFlags -> pr "open_flag list -> "
1519     | AUnusedFlags -> ()
1520     | ASetValues -> pr "set_value array -> "
1521     | ASetValue -> pr "set_value -> "
1522   ) (snd style);
1523   (match fst style with
1524    | RErr -> pr "unit" (* all errors are turned into exceptions *)
1525    | RErrDispose -> pr "unit"
1526    | RHive -> pr "t"
1527    | RNode -> pr "node"
1528    | RNodeNotFound -> pr "node"
1529    | RNodeList -> pr "node array"
1530    | RValue -> pr "value"
1531    | RValueList -> pr "value array"
1532    | RString -> pr "string"
1533    | RStringList -> pr "string array"
1534    | RLenType -> pr "hive_type * int"
1535    | RLenTypeVal -> pr "hive_type * string"
1536    | RInt32 -> pr "int32"
1537    | RInt64 -> pr "int64"
1538   );
1539   if is_external then
1540     pr " = \"ocaml_hivex_%s\"" name;
1541   pr "\n"
1542
1543 and generate_ocaml_c () =
1544   generate_header CStyle LGPLv2plus;
1545
1546   pr "\
1547 #include <config.h>
1548
1549 #include <stdio.h>
1550 #include <stdlib.h>
1551 #include <string.h>
1552 #include <stdint.h>
1553 #include <errno.h>
1554
1555 #include <caml/config.h>
1556 #include <caml/alloc.h>
1557 #include <caml/callback.h>
1558 #include <caml/custom.h>
1559 #include <caml/fail.h>
1560 #include <caml/memory.h>
1561 #include <caml/mlvalues.h>
1562 #include <caml/signals.h>
1563
1564 #ifdef HAVE_CAML_UNIXSUPPORT_H
1565 #include <caml/unixsupport.h>
1566 #else
1567 extern value unix_error_of_code (int errcode);
1568 #endif
1569
1570 #ifndef HAVE_CAML_RAISE_WITH_ARGS
1571 static void
1572 caml_raise_with_args (value tag, int nargs, value args[])
1573 {
1574   CAMLparam1 (tag);
1575   CAMLxparamN (args, nargs);
1576   value bucket;
1577   int i;
1578
1579   bucket = caml_alloc_small (1 + nargs, 0);
1580   Field(bucket, 0) = tag;
1581   for (i = 0; i < nargs; i++) Field(bucket, 1 + i) = args[i];
1582   caml_raise(bucket);
1583   CAMLnoreturn;
1584 }
1585 #endif
1586
1587 #include <hivex.h>
1588
1589 #define Hiveh_val(v) (*((hive_h **)Data_custom_val(v)))
1590 static value Val_hiveh (hive_h *);
1591 static int HiveOpenFlags_val (value);
1592 static hive_set_value *HiveSetValue_val (value);
1593 static hive_set_value *HiveSetValues_val (value);
1594 static hive_type HiveType_val (value);
1595 static value Val_hive_type (hive_type);
1596 static value copy_int_array (size_t *);
1597 static value copy_type_len (size_t, hive_type);
1598 static value copy_type_value (const char *, size_t, hive_type);
1599 static void raise_error (const char *) Noreturn;
1600 static void raise_closed (const char *) Noreturn;
1601
1602 ";
1603
1604   (* The wrappers. *)
1605   List.iter (
1606     fun (name, style, _, _) ->
1607       pr "/* Automatically generated wrapper for function\n";
1608       pr " * "; generate_ocaml_prototype name style;
1609       pr " */\n";
1610       pr "\n";
1611
1612       let c_params =
1613         List.map (function
1614                   | ASetValues -> ["nrvalues"; "values"]
1615                   | AUnusedFlags -> ["0"]
1616                   | arg -> [name_of_argt arg]) (snd style) in
1617       let c_params =
1618         match fst style with
1619         | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]]
1620         | _ -> c_params in
1621       let c_params = List.concat c_params in
1622
1623       let params =
1624         filter_map (function
1625                     | AUnusedFlags -> None
1626                     | arg -> Some (name_of_argt arg ^ "v")) (snd style) in
1627
1628       pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
1629       pr "CAMLprim value ocaml_hivex_%s (value %s" name (List.hd params);
1630       List.iter (pr ", value %s") (List.tl params); pr ");\n";
1631       pr "\n";
1632
1633       pr "CAMLprim value\n";
1634       pr "ocaml_hivex_%s (value %s" name (List.hd params);
1635       List.iter (pr ", value %s") (List.tl params);
1636       pr ")\n";
1637       pr "{\n";
1638
1639       pr "  CAMLparam%d (%s);\n"
1640         (List.length params) (String.concat ", " params);
1641       pr "  CAMLlocal1 (rv);\n";
1642       pr "\n";
1643
1644       List.iter (
1645         function
1646         | AHive ->
1647             pr "  hive_h *h = Hiveh_val (hv);\n";
1648             pr "  if (h == NULL)\n";
1649             pr "    raise_closed (\"%s\");\n" name
1650         | ANode n ->
1651             pr "  hive_node_h %s = Int_val (%sv);\n" n n
1652         | AValue n ->
1653             pr "  hive_value_h %s = Int_val (%sv);\n" n n
1654         | AString n ->
1655             pr "  const char *%s = String_val (%sv);\n" n n
1656         | AStringNullable n ->
1657             pr "  const char *%s =\n" n;
1658             pr "    %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
1659               n n
1660         | AOpenFlags ->
1661             pr "  int flags = HiveOpenFlags_val (flagsv);\n"
1662         | AUnusedFlags -> ()
1663         | ASetValues ->
1664             pr "  int nrvalues = Wosize_val (valuesv);\n";
1665             pr "  hive_set_value *values = HiveSetValues_val (valuesv);\n"
1666         | ASetValue ->
1667             pr "  hive_set_value *val = HiveSetValue_val (valv);\n"
1668       ) (snd style);
1669       pr "\n";
1670
1671       let error_code =
1672         match fst style with
1673         | RErr -> pr "  int r;\n"; "-1"
1674         | RErrDispose -> pr "  int r;\n"; "-1"
1675         | RHive -> pr "  hive_h *r;\n"; "NULL"
1676         | RNode -> pr "  hive_node_h r;\n"; "0"
1677         | RNodeNotFound ->
1678             pr "  errno = 0;\n";
1679             pr "  hive_node_h r;\n";
1680             "0 && errno != 0"
1681         | RNodeList -> pr "  hive_node_h *r;\n"; "NULL"
1682         | RValue -> pr "  hive_value_h r;\n"; "0"
1683         | RValueList -> pr "  hive_value_h *r;\n"; "NULL"
1684         | RString -> pr "  char *r;\n"; "NULL"
1685         | RStringList -> pr "  char **r;\n"; "NULL"
1686         | RLenType ->
1687             pr "  int r;\n";
1688             pr "  size_t len;\n";
1689             pr "  hive_type t;\n";
1690             "-1"
1691         | RLenTypeVal ->
1692             pr "  char *r;\n";
1693             pr "  size_t len;\n";
1694             pr "  hive_type t;\n";
1695             "NULL"
1696         | RInt32 ->
1697             pr "  errno = 0;\n";
1698             pr "  int32_t r;\n";
1699             "-1 && errno != 0"
1700         | RInt64 ->
1701             pr "  errno = 0;\n";
1702             pr "  int64_t r;\n";
1703             "-1 && errno != 0" in
1704
1705       (* The libguestfs OCaml bindings call enter_blocking_section
1706        * here.  However I don't think that is safe, because we are
1707        * holding pointers to caml strings during the call, and these
1708        * could be moved or freed by other threads.  In any case, there
1709        * is very little reason to enter_blocking_section for any hivex
1710        * call, so don't do it.  XXX
1711        *)
1712       (*pr "  caml_enter_blocking_section ();\n";*)
1713       pr "  r = hivex_%s (%s" name (List.hd c_params);
1714       List.iter (pr ", %s") (List.tl c_params);
1715       pr ");\n";
1716       (*pr "  caml_leave_blocking_section ();\n";*)
1717       pr "\n";
1718
1719       (* Dispose of the hive handle (even if hivex_close returns error). *)
1720       (match fst style with
1721        | RErrDispose ->
1722            pr "  /* So we don't double-free in the finalizer. */\n";
1723            pr "  Hiveh_val (hv) = NULL;\n";
1724            pr "\n";
1725        | _ -> ()
1726       );
1727
1728       List.iter (
1729         function
1730         | AHive | ANode _ | AValue _ | AString _ | AStringNullable _
1731         | AOpenFlags | AUnusedFlags -> ()
1732         | ASetValues ->
1733             pr "  free (values);\n";
1734             pr "\n";
1735         | ASetValue ->
1736             pr "  free (val);\n";
1737             pr "\n";
1738       ) (snd style);
1739
1740       (* Check for errors. *)
1741       pr "  if (r == %s)\n" error_code;
1742       pr "    raise_error (\"%s\");\n" name;
1743       pr "\n";
1744
1745       (match fst style with
1746        | RErr -> pr "  rv = Val_unit;\n"
1747        | RErrDispose -> pr "  rv = Val_unit;\n"
1748        | RHive -> pr "  rv = Val_hiveh (r);\n"
1749        | RNode -> pr "  rv = Val_int (r);\n"
1750        | RNodeNotFound ->
1751            pr "  if (r == 0)\n";
1752            pr "    caml_raise_not_found ();\n";
1753            pr "\n";
1754            pr "  rv = Val_int (r);\n"
1755        | RNodeList ->
1756            pr "  rv = copy_int_array (r);\n";
1757            pr "  free (r);\n"
1758        | RValue -> pr "  rv = Val_int (r);\n"
1759        | RValueList ->
1760            pr "  rv = copy_int_array (r);\n";
1761            pr "  free (r);\n"
1762        | RString ->
1763            pr "  rv = caml_copy_string (r);\n";
1764            pr "  free (r);\n"
1765        | RStringList ->
1766            pr "  rv = caml_copy_string_array ((const char **) r);\n";
1767            pr "  for (int i = 0; r[i] != NULL; ++i) free (r[i]);\n";
1768            pr "  free (r);\n"
1769        | RLenType -> pr "  rv = copy_type_len (len, t);\n"
1770        | RLenTypeVal ->
1771            pr "  rv = copy_type_value (r, len, t);\n";
1772            pr "  free (r);\n"
1773        | RInt32 -> pr "  rv = caml_copy_int32 (r);\n"
1774        | RInt64 -> pr "  rv = caml_copy_int32 (r);\n"
1775       );
1776
1777       pr "  CAMLreturn (rv);\n";
1778       pr "}\n";
1779       pr "\n";
1780
1781   ) functions;
1782
1783   pr "\
1784 static int
1785 HiveOpenFlags_val (value v)
1786 {
1787   int flags = 0;
1788   value v2;
1789
1790   while (v != Val_int (0)) {
1791     v2 = Field (v, 0);
1792     flags |= 1 << Int_val (v2);
1793     v = Field (v, 1);
1794   }
1795
1796   return flags;
1797 }
1798
1799 static hive_set_value *
1800 HiveSetValue_val (value v)
1801 {
1802   hive_set_value *val = malloc (sizeof (hive_set_value));
1803
1804   val->key = String_val (Field (v, 0));
1805   val->t = HiveType_val (Field (v, 1));
1806   val->len = caml_string_length (Field (v, 2));
1807   val->value = String_val (Field (v, 2));
1808
1809   return val;
1810 }
1811
1812 static hive_set_value *
1813 HiveSetValues_val (value v)
1814 {
1815   size_t nr_values = Wosize_val (v);
1816   hive_set_value *values = malloc (nr_values * sizeof (hive_set_value));
1817   size_t i;
1818   value v2;
1819
1820   for (i = 0; i < nr_values; ++i) {
1821     v2 = Field (v, i);
1822     values[i].key = String_val (Field (v2, 0));
1823     values[i].t = HiveType_val (Field (v2, 1));
1824     values[i].len = caml_string_length (Field (v2, 2));
1825     values[i].value = String_val (Field (v2, 2));
1826   }
1827
1828   return values;
1829 }
1830
1831 static hive_type
1832 HiveType_val (value v)
1833 {
1834   if (Is_long (v))
1835     return Int_val (v); /* REG_NONE etc. */
1836   else
1837     return Int32_val (Field (v, 0)); /* REG_UNKNOWN of int32 */
1838 }
1839
1840 static value
1841 Val_hive_type (hive_type t)
1842 {
1843   CAMLparam0 ();
1844   CAMLlocal2 (rv, v);
1845
1846   if (t <= %d)
1847     CAMLreturn (Val_int (t));
1848   else {
1849     rv = caml_alloc (1, 0); /* REG_UNKNOWN of int32 */
1850     v = caml_copy_int32 (t);
1851     caml_modify (&Field (rv, 0), v);
1852     CAMLreturn (rv);
1853   }
1854 }
1855
1856 static value
1857 copy_int_array (size_t *xs)
1858 {
1859   CAMLparam0 ();
1860   CAMLlocal2 (v, rv);
1861   size_t nr, i;
1862
1863   for (nr = 0; xs[nr] != 0; ++nr)
1864     ;
1865   if (nr == 0)
1866     CAMLreturn (Atom (0));
1867   else {
1868     rv = caml_alloc (nr, 0);
1869     for (i = 0; i < nr; ++i) {
1870       v = Val_int (xs[i]);
1871       Store_field (rv, i, v); /* Safe because v is not a block. */
1872     }
1873     CAMLreturn (rv);
1874   }
1875 }
1876
1877 static value
1878 copy_type_len (size_t len, hive_type t)
1879 {
1880   CAMLparam0 ();
1881   CAMLlocal2 (v, rv);
1882
1883   rv = caml_alloc (2, 0);
1884   v = Val_hive_type (t);
1885   Store_field (rv, 0, v);
1886   v = Val_int (len);
1887   Store_field (rv, 1, len);
1888   CAMLreturn (rv);
1889 }
1890
1891 static value
1892 copy_type_value (const char *r, size_t len, hive_type t)
1893 {
1894   CAMLparam0 ();
1895   CAMLlocal2 (v, rv);
1896
1897   rv = caml_alloc (2, 0);
1898   v = Val_hive_type (t);
1899   Store_field (rv, 0, v);
1900   v = caml_alloc_string (len);
1901   memcpy (String_val (v), r, len);
1902   caml_modify (&Field (rv, 1), v);
1903   CAMLreturn (rv);
1904 }
1905
1906 /* Raise exceptions. */
1907 static void
1908 raise_error (const char *function)
1909 {
1910   /* Save errno early in case it gets trashed. */
1911   int err = errno;
1912
1913   CAMLparam0 ();
1914   CAMLlocal3 (v1, v2, v3);
1915
1916   v1 = caml_copy_string (function);
1917   v2 = unix_error_of_code (err);
1918   v3 = caml_copy_string (strerror (err));
1919   value vvv[] = { v1, v2, v3 };
1920   caml_raise_with_args (*caml_named_value (\"ocaml_hivex_error\"), 3, vvv);
1921
1922   CAMLnoreturn;
1923 }
1924
1925 static void
1926 raise_closed (const char *function)
1927 {
1928   CAMLparam0 ();
1929   CAMLlocal1 (v);
1930
1931   v = caml_copy_string (function);
1932   caml_raise_with_arg (*caml_named_value (\"ocaml_hivex_closed\"), v);
1933
1934   CAMLnoreturn;
1935 }
1936
1937 /* Allocate handles and deal with finalization. */
1938 static void
1939 hivex_finalize (value hv)
1940 {
1941   hive_h *h = Hiveh_val (hv);
1942   if (h) hivex_close (h);
1943 }
1944
1945 static struct custom_operations hivex_custom_operations = {
1946   (char *) \"hivex_custom_operations\",
1947   hivex_finalize,
1948   custom_compare_default,
1949   custom_hash_default,
1950   custom_serialize_default,
1951   custom_deserialize_default
1952 };
1953
1954 static value
1955 Val_hiveh (hive_h *h)
1956 {
1957   CAMLparam0 ();
1958   CAMLlocal1 (rv);
1959
1960   rv = caml_alloc_custom (&hivex_custom_operations,
1961                           sizeof (hive_h *), 0, 1);
1962   Hiveh_val (rv) = h;
1963
1964   CAMLreturn (rv);
1965 }
1966 " max_hive_type
1967
1968 and generate_perl_pm () =
1969   generate_header HashStyle LGPLv2plus;
1970
1971   pr "\
1972 =pod
1973
1974 =head1 NAME
1975
1976 Win::Hivex - Perl bindings for reading and writing Windows Registry hive files
1977
1978 =head1 SYNOPSIS
1979
1980  use Win::Hivex;
1981
1982  $h = Win::Hivex->open ('SOFTWARE');
1983  $root_node = $h->root ();
1984  print $h->node_name ($root_node);
1985
1986 =head1 DESCRIPTION
1987
1988 The C<Win::Hivex> module provides a Perl XS binding to the
1989 L<hivex(3)> API for reading and writing Windows Registry binary
1990 hive files.
1991
1992 =head1 ERRORS
1993
1994 All errors turn into calls to C<croak> (see L<Carp(3)>).
1995
1996 =head1 METHODS
1997
1998 =over 4
1999
2000 =cut
2001
2002 package Win::Hivex;
2003
2004 use strict;
2005 use warnings;
2006
2007 require XSLoader;
2008 XSLoader::load ('Win::Hivex');
2009
2010 =item open
2011
2012  $h = Win::Hivex->open ($filename,";
2013
2014   List.iter (
2015     fun (_, flag, _) ->
2016       pr "\n                        [%s => 1,]" (String.lowercase flag)
2017   ) open_flags;
2018
2019   pr ")
2020
2021 Open a Windows Registry binary hive file.
2022
2023 The C<verbose> and C<debug> flags enable different levels of
2024 debugging messages.
2025
2026 The C<write> flag is required if you will be modifying the
2027 hive file (see L<hivex(3)/WRITING TO HIVE FILES>).
2028
2029 This function returns a hive handle.  The hive handle is
2030 closed automatically when its reference count drops to 0.
2031
2032 =cut
2033
2034 sub open {
2035   my $proto = shift;
2036   my $class = ref ($proto) || $proto;
2037   my $filename = shift;
2038   my %%flags = @_;
2039   my $flags = 0;
2040
2041 ";
2042
2043   List.iter (
2044     fun (n, flag, description) ->
2045       pr "  # %s\n" description;
2046       pr "  $flags += %d if $flags{%s};\n" n (String.lowercase flag)
2047   ) open_flags;
2048
2049   pr "\
2050
2051   my $self = Win::Hivex::_open ($filename, $flags);
2052   bless $self, $class;
2053   return $self;
2054 }
2055
2056 ";
2057
2058   List.iter (
2059     fun (name, style, _, longdesc) ->
2060       (* The close call isn't explicit in Perl: handles are closed
2061        * when their reference count drops to 0.
2062        *
2063        * The open call is coded specially in Perl.
2064        *
2065        * Therefore we don't generate prototypes for these two calls:
2066        *)
2067       if fst style <> RErrDispose && List.hd (snd style) = AHive then (
2068         let longdesc = replace_str longdesc "C<hivex_" "C<" in
2069         pr "=item %s\n\n " name;
2070         generate_perl_prototype name style;
2071         pr "\n\n";
2072         pr "%s\n\n" longdesc;
2073
2074         (match fst style with
2075          | RErr
2076          | RErrDispose
2077          | RHive
2078          | RString
2079          | RStringList
2080          | RLenType
2081          | RLenTypeVal
2082          | RInt32
2083          | RInt64 -> ()
2084          | RNode ->
2085              pr "\
2086 This returns a node handle.\n\n"
2087          | RNodeNotFound ->
2088              pr "\
2089 This returns a node handle, or C<undef> if the node was not found.\n\n"
2090          | RNodeList ->
2091              pr "\
2092 This returns a list of node handles.\n\n"
2093          | RValue ->
2094              pr "\
2095 This returns a value handle.\n\n"
2096          | RValueList ->
2097              pr "\
2098 This returns a list of value handles.\n\n"
2099         );
2100
2101         if List.mem ASetValues (snd style) then
2102           pr "C<@values> is an array of (keys, value) pairs.
2103 Each element should be a hashref containing C<key>, C<t> (type)
2104 and C<data>.
2105
2106 Any existing values stored at the node are discarded, and their
2107 C<value> handles become invalid.  Thus you can remove all
2108 values stored at C<node> by passing C<@values = []>.\n\n"
2109       )
2110   ) functions;
2111
2112   pr "\
2113 =cut
2114
2115 1;
2116
2117 =back
2118
2119 =head1 COPYRIGHT
2120
2121 Copyright (C) %s Red Hat Inc.
2122
2123 =head1 LICENSE
2124
2125 Please see the file COPYING.LIB for the full license.
2126
2127 =head1 SEE ALSO
2128
2129 L<hivex(3)>,
2130 L<hivexsh(1)>,
2131 L<http://libguestfs.org>,
2132 L<Sys::Guestfs(3)>.
2133
2134 =cut
2135 " copyright_years
2136
2137 and generate_perl_prototype name style =
2138   (* Return type. *)
2139   (match fst style with
2140    | RErr
2141    | RErrDispose -> ()
2142    | RHive -> pr "$h = "
2143    | RNode
2144    | RNodeNotFound -> pr "$node = "
2145    | RNodeList -> pr "@nodes = "
2146    | RValue -> pr "$value = "
2147    | RValueList -> pr "@values = "
2148    | RString -> pr "$string = "
2149    | RStringList -> pr "@strings = "
2150    | RLenType -> pr "($type, $len) = "
2151    | RLenTypeVal -> pr "($type, $data) = "
2152    | RInt32 -> pr "$int32 = "
2153    | RInt64 -> pr "$int64 = "
2154   );
2155
2156   let args = List.tl (snd style) in
2157
2158   (* AUnusedFlags is dropped in the bindings. *)
2159   let args = List.filter ((<>) AUnusedFlags) args in
2160
2161   pr "$h->%s (" name;
2162
2163   let comma = ref false in
2164   List.iter (
2165     fun arg ->
2166       if !comma then pr ", "; comma := true;
2167       match arg with
2168       | AHive -> pr "$h"
2169       | ANode n
2170       | AValue n
2171       | AString n -> pr "$%s" n
2172       | AStringNullable n -> pr "[$%s|undef]" n
2173       | AOpenFlags -> pr "[flags]"
2174       | AUnusedFlags -> assert false
2175       | ASetValues -> pr "\\@values"
2176       | ASetValue -> pr "$val"
2177   ) args;
2178
2179   pr ")"
2180
2181 and generate_perl_xs () =
2182   generate_header CStyle LGPLv2plus;
2183
2184   pr "\
2185 #include \"EXTERN.h\"
2186 #include \"perl.h\"
2187 #include \"XSUB.h\"
2188
2189 #include <string.h>
2190 #include <hivex.h>
2191
2192 #ifndef PRId64
2193 #define PRId64 \"lld\"
2194 #endif
2195
2196 static SV *
2197 my_newSVll(long long val) {
2198 #ifdef USE_64_BIT_ALL
2199   return newSViv(val);
2200 #else
2201   char buf[100];
2202   int len;
2203   len = snprintf(buf, 100, \"%%\" PRId64, val);
2204   return newSVpv(buf, len);
2205 #endif
2206 }
2207
2208 #ifndef PRIu64
2209 #define PRIu64 \"llu\"
2210 #endif
2211
2212 #if 0
2213 static SV *
2214 my_newSVull(unsigned long long val) {
2215 #ifdef USE_64_BIT_ALL
2216   return newSVuv(val);
2217 #else
2218   char buf[100];
2219   int len;
2220   len = snprintf(buf, 100, \"%%\" PRIu64, val);
2221   return newSVpv(buf, len);
2222 #endif
2223 }
2224 #endif
2225
2226 #if 0
2227 /* http://www.perlmonks.org/?node_id=680842 */
2228 static char **
2229 XS_unpack_charPtrPtr (SV *arg) {
2230   char **ret;
2231   AV *av;
2232   I32 i;
2233
2234   if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
2235     croak (\"array reference expected\");
2236
2237   av = (AV *)SvRV (arg);
2238   ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
2239   if (!ret)
2240     croak (\"malloc failed\");
2241
2242   for (i = 0; i <= av_len (av); i++) {
2243     SV **elem = av_fetch (av, i, 0);
2244
2245     if (!elem || !*elem)
2246       croak (\"missing element in list\");
2247
2248     ret[i] = SvPV_nolen (*elem);
2249   }
2250
2251   ret[i] = NULL;
2252
2253   return ret;
2254 }
2255 #endif
2256
2257 /* Handle set_values parameter. */
2258 typedef struct pl_set_values {
2259   size_t nr_values;
2260   hive_set_value *values;
2261 } pl_set_values;
2262
2263 static pl_set_values
2264 unpack_pl_set_values (SV *sv)
2265 {
2266   pl_set_values ret;
2267   AV *av;
2268   I32 i;
2269
2270   if (!sv || !SvOK (sv) || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV)
2271     croak (\"array reference expected\");
2272
2273   av = (AV *)SvRV(sv);
2274   ret.nr_values = av_len (av) + 1;
2275   ret.values = malloc (ret.nr_values * sizeof (hive_set_value));
2276   if (!ret.values)
2277     croak (\"malloc failed\");
2278
2279   for (i = 0; i <= av_len (av); i++) {
2280     SV **hvp = av_fetch (av, i, 0);
2281
2282     if (!hvp || !*hvp || !SvROK (*hvp) || SvTYPE (SvRV (*hvp)) != SVt_PVHV)
2283       croak (\"missing element in list or not a hash ref\");
2284
2285     HV *hv = (HV *)SvRV(*hvp);
2286
2287     SV **svp;
2288     svp = hv_fetch (hv, \"key\", 3, 0);
2289     if (!svp || !*svp)
2290       croak (\"missing 'key' in hash\");
2291     ret.values[i].key = SvPV_nolen (*svp);
2292
2293     svp = hv_fetch (hv, \"t\", 1, 0);
2294     if (!svp || !*svp)
2295       croak (\"missing 't' in hash\");
2296     ret.values[i].t = SvIV (*svp);
2297
2298     svp = hv_fetch (hv, \"value\", 5, 0);
2299     if (!svp || !*svp)
2300       croak (\"missing 'value' in hash\");
2301     ret.values[i].value = SvPV (*svp, ret.values[i].len);
2302   }
2303
2304   return ret;
2305 }
2306
2307 static hive_set_value *
2308 unpack_set_value (SV *sv)
2309 {
2310   hive_set_value *ret;
2311
2312   if (!sv || !SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVHV)
2313     croak (\"not a hash ref\");
2314
2315   ret = malloc (sizeof (hive_set_value));
2316   if (ret == NULL)
2317     croak (\"malloc failed\");
2318
2319   HV *hv = (HV *)SvRV(sv);
2320
2321   SV **svp;
2322   svp = hv_fetch (hv, \"key\", 3, 0);
2323   if (!svp || !*svp)
2324     croak (\"missing 'key' in hash\");
2325   ret->key = SvPV_nolen (*svp);
2326
2327   svp = hv_fetch (hv, \"t\", 1, 0);
2328   if (!svp || !*svp)
2329     croak (\"missing 't' in hash\");
2330   ret->t = SvIV (*svp);
2331
2332   svp = hv_fetch (hv, \"value\", 5, 0);
2333   if (!svp || !*svp)
2334     croak (\"missing 'value' in hash\");
2335   ret->value = SvPV (*svp, ret->len);
2336
2337   return ret;
2338 }
2339
2340 MODULE = Win::Hivex  PACKAGE = Win::Hivex
2341
2342 PROTOTYPES: ENABLE
2343
2344 hive_h *
2345 _open (filename, flags)
2346       char *filename;
2347       int flags;
2348    CODE:
2349       RETVAL = hivex_open (filename, flags);
2350       if (!RETVAL)
2351         croak (\"hivex_open: %%s: %%s\", filename, strerror (errno));
2352  OUTPUT:
2353       RETVAL
2354
2355 void
2356 DESTROY (h)
2357       hive_h *h;
2358  PPCODE:
2359       if (hivex_close (h) == -1)
2360         croak (\"hivex_close: %%s\", strerror (errno));
2361
2362 ";
2363
2364   List.iter (
2365     fun (name, style, _, longdesc) ->
2366       (* The close and open calls are handled specially above. *)
2367       if fst style <> RErrDispose && List.hd (snd style) = AHive then (
2368         (match fst style with
2369          | RErr -> pr "void\n"
2370          | RErrDispose -> failwith "perl bindings cannot handle a call which disposes of the handle"
2371          | RHive -> failwith "perl bindings cannot handle a call which returns a handle"
2372          | RNode
2373          | RNodeNotFound
2374          | RValue
2375          | RString -> pr "SV *\n"
2376          | RNodeList
2377          | RValueList
2378          | RStringList
2379          | RLenType
2380          | RLenTypeVal -> pr "void\n"
2381          | RInt32 -> pr "SV *\n"
2382          | RInt64 -> pr "SV *\n"
2383         );
2384
2385         (* Call and arguments. *)
2386         let perl_params =
2387           filter_map (function
2388                       | AUnusedFlags -> None
2389                       | arg -> Some (name_of_argt arg)) (snd style) in
2390
2391         let c_params =
2392           List.map (function
2393                     | AUnusedFlags -> "0"
2394                     | ASetValues -> "values.nr_values, values.values"
2395                     | arg -> name_of_argt arg) (snd style) in
2396
2397         pr "%s (%s)\n" name (String.concat ", " perl_params);
2398         iteri (
2399           fun i ->
2400             function
2401             | AHive ->
2402                 pr "      hive_h *h;\n"
2403             | ANode n
2404             | AValue n ->
2405                 pr "      int %s;\n" n
2406             | AString n ->
2407                 pr "      char *%s;\n" n
2408             | AStringNullable n ->
2409                 (* http://www.perlmonks.org/?node_id=554277 *)
2410                 pr "      char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n i i
2411             | AOpenFlags ->
2412                 pr "      int flags;\n"
2413             | AUnusedFlags -> ()
2414             | ASetValues ->
2415                 pr "      pl_set_values values = unpack_pl_set_values (ST(%d));\n" i
2416             | ASetValue ->
2417                 pr "      hive_set_value *val = unpack_set_value (ST(%d));\n" i
2418         ) (snd style);
2419
2420         let free_args () =
2421           List.iter (
2422             function
2423             | ASetValues ->
2424                 pr "      free (values.values);\n"
2425             | ASetValue ->
2426                 pr "      free (val);\n"
2427             | AHive | ANode _ | AValue _ | AString _ | AStringNullable _
2428             | AOpenFlags | AUnusedFlags -> ()
2429           ) (snd style)
2430         in
2431
2432         (* Code. *)
2433         (match fst style with
2434          | RErr ->
2435              pr "PREINIT:\n";
2436              pr "      int r;\n";
2437              pr " PPCODE:\n";
2438              pr "      r = hivex_%s (%s);\n"
2439                name (String.concat ", " c_params);
2440              free_args ();
2441              pr "      if (r == -1)\n";
2442              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2443                name;
2444
2445          | RErrDispose -> assert false
2446          | RHive -> assert false
2447
2448          | RNode
2449          | RValue ->
2450              pr "PREINIT:\n";
2451              pr "      /* hive_node_h = hive_value_h = size_t so we cheat\n";
2452              pr "         here to simplify the generator */\n";
2453              pr "      size_t r;\n";
2454              pr "   CODE:\n";
2455              pr "      r = hivex_%s (%s);\n"
2456                name (String.concat ", " c_params);
2457              free_args ();
2458              pr "      if (r == 0)\n";
2459              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2460                name;
2461              pr "      RETVAL = newSViv (r);\n";
2462              pr " OUTPUT:\n";
2463              pr "      RETVAL\n"
2464
2465          | RNodeNotFound ->
2466              pr "PREINIT:\n";
2467              pr "      hive_node_h r;\n";
2468              pr "   CODE:\n";
2469              pr "      errno = 0;\n";
2470              pr "      r = hivex_%s (%s);\n"
2471                name (String.concat ", " c_params);
2472              free_args ();
2473              pr "      if (r == 0 && errno != 0)\n";
2474              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2475                name;
2476              pr "      if (r == 0)\n";
2477              pr "        RETVAL = &PL_sv_undef;\n";
2478              pr "      else\n";
2479              pr "        RETVAL = newSViv (r);\n";
2480              pr " OUTPUT:\n";
2481              pr "      RETVAL\n"
2482
2483          | RString ->
2484              pr "PREINIT:\n";
2485              pr "      char *r;\n";
2486              pr "   CODE:\n";
2487              pr "      r = hivex_%s (%s);\n"
2488                name (String.concat ", " c_params);
2489              free_args ();
2490              pr "      if (r == NULL)\n";
2491              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2492                name;
2493              pr "      RETVAL = newSVpv (r, 0);\n";
2494              pr "      free (r);\n";
2495              pr " OUTPUT:\n";
2496              pr "      RETVAL\n"
2497
2498          | RNodeList
2499          | RValueList ->
2500              pr "PREINIT:\n";
2501              pr "      size_t *r;\n";
2502              pr "      int i, n;\n";
2503              pr " PPCODE:\n";
2504              pr "      r = hivex_%s (%s);\n"
2505                name (String.concat ", " c_params);
2506              free_args ();
2507              pr "      if (r == NULL)\n";
2508              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2509                name;
2510              pr "      for (n = 0; r[n] != 0; ++n) /**/;\n";
2511              pr "      EXTEND (SP, n);\n";
2512              pr "      for (i = 0; i < n; ++i)\n";
2513              pr "        PUSHs (sv_2mortal (newSViv (r[i])));\n";
2514              pr "      free (r);\n";
2515
2516          | RStringList ->
2517              pr "PREINIT:\n";
2518              pr "      char **r;\n";
2519              pr "      int i, n;\n";
2520              pr " PPCODE:\n";
2521              pr "      r = hivex_%s (%s);\n"
2522                name (String.concat ", " c_params);
2523              free_args ();
2524              pr "      if (r == NULL)\n";
2525              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2526                name;
2527              pr "      for (n = 0; r[n] != NULL; ++n) /**/;\n";
2528              pr "      EXTEND (SP, n);\n";
2529              pr "      for (i = 0; i < n; ++i) {\n";
2530              pr "        PUSHs (sv_2mortal (newSVpv (r[i], 0)));\n";
2531              pr "        free (r[i]);\n";
2532              pr "      }\n";
2533              pr "      free (r);\n";
2534
2535          | RLenType ->
2536              pr "PREINIT:\n";
2537              pr "      int r;\n";
2538              pr "      size_t len;\n";
2539              pr "      hive_type type;\n";
2540              pr " PPCODE:\n";
2541              pr "      r = hivex_%s (%s, &type, &len);\n"
2542                name (String.concat ", " c_params);
2543              free_args ();
2544              pr "      if (r == -1)\n";
2545              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2546                name;
2547              pr "      EXTEND (SP, 2);\n";
2548              pr "      PUSHs (sv_2mortal (newSViv (type)));\n";
2549              pr "      PUSHs (sv_2mortal (newSViv (len)));\n";
2550
2551          | RLenTypeVal ->
2552              pr "PREINIT:\n";
2553              pr "      char *r;\n";
2554              pr "      size_t len;\n";
2555              pr "      hive_type type;\n";
2556              pr " PPCODE:\n";
2557              pr "      r = hivex_%s (%s, &type, &len);\n"
2558                name (String.concat ", " c_params);
2559              free_args ();
2560              pr "      if (r == NULL)\n";
2561              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2562                name;
2563              pr "      EXTEND (SP, 2);\n";
2564              pr "      PUSHs (sv_2mortal (newSViv (type)));\n";
2565              pr "      PUSHs (sv_2mortal (newSVpvn (r, len)));\n";
2566              pr "      free (r);\n";
2567
2568          | RInt32 ->
2569              pr "PREINIT:\n";
2570              pr "      int32_t r;\n";
2571              pr "   CODE:\n";
2572              pr "      errno = 0;\n";
2573              pr "      r = hivex_%s (%s);\n"
2574                name (String.concat ", " c_params);
2575              free_args ();
2576              pr "      if (r == -1 && errno != 0)\n";
2577              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2578                name;
2579              pr "      RETVAL = newSViv (r);\n";
2580              pr " OUTPUT:\n";
2581              pr "      RETVAL\n"
2582
2583          | RInt64 ->
2584              pr "PREINIT:\n";
2585              pr "      int64_t r;\n";
2586              pr "   CODE:\n";
2587              pr "      errno = 0;\n";
2588              pr "      r = hivex_%s (%s);\n"
2589                name (String.concat ", " c_params);
2590              free_args ();
2591              pr "      if (r == -1 && errno != 0)\n";
2592              pr "        croak (\"%%s: %%s\", \"%s\", strerror (errno));\n"
2593                name;
2594              pr "      RETVAL = my_newSVll (r);\n";
2595              pr " OUTPUT:\n";
2596              pr "      RETVAL\n"
2597         );
2598         pr "\n"
2599       )
2600   ) functions
2601
2602 and generate_python_c () =
2603   generate_header CStyle LGPLv2plus;
2604
2605   pr "\
2606 #define PY_SSIZE_T_CLEAN 1
2607 #include <Python.h>
2608
2609 #if PY_VERSION_HEX < 0x02050000
2610 typedef int Py_ssize_t;
2611 #define PY_SSIZE_T_MAX INT_MAX
2612 #define PY_SSIZE_T_MIN INT_MIN
2613 #endif
2614
2615 #include <stdio.h>
2616 #include <stdlib.h>
2617 #include <assert.h>
2618
2619 #include \"hivex.h\"
2620
2621 #ifndef HAVE_PYCAPSULE_NEW
2622 typedef struct {
2623   PyObject_HEAD
2624   hive_h *h;
2625 } Pyhivex_Object;
2626 #endif
2627
2628 static hive_h *
2629 get_handle (PyObject *obj)
2630 {
2631   assert (obj);
2632   assert (obj != Py_None);
2633 #ifndef HAVE_PYCAPSULE_NEW
2634   return ((Pyhivex_Object *) obj)->h;
2635 #else
2636   return (hive_h *) PyCapsule_GetPointer(obj, \"hive_h\");
2637 #endif
2638 }
2639
2640 static PyObject *
2641 put_handle (hive_h *h)
2642 {
2643   assert (h);
2644 #ifndef HAVE_PYCAPSULE_NEW
2645   return
2646     PyCObject_FromVoidPtrAndDesc ((void *) h, (char *) \"hive_h\", NULL);
2647 #else
2648   return PyCapsule_New ((void *) h, \"hive_h\", NULL);
2649 #endif
2650 }
2651
2652 /* This returns pointers into the Python objects, which should
2653  * not be freed.
2654  */
2655 static int
2656 get_value (PyObject *v, hive_set_value *ret)
2657 {
2658   PyObject *obj;
2659
2660   obj = PyDict_GetItemString (v, \"key\");
2661   if (!obj) {
2662     PyErr_SetString (PyExc_RuntimeError, \"no 'key' element in dictionary\");
2663     return -1;
2664   }
2665   if (!PyString_Check (obj)) {
2666     PyErr_SetString (PyExc_RuntimeError, \"'key' element is not a string\");
2667     return -1;
2668   }
2669   ret->key = PyString_AsString (obj);
2670
2671   obj = PyDict_GetItemString (v, \"t\");
2672   if (!obj) {
2673     PyErr_SetString (PyExc_RuntimeError, \"no 't' element in dictionary\");
2674     return -1;
2675   }
2676   if (!PyInt_Check (obj)) {
2677     PyErr_SetString (PyExc_RuntimeError, \"'t' element is not an integer\");
2678     return -1;
2679   }
2680   ret->t = PyInt_AsLong (obj);
2681
2682   obj = PyDict_GetItemString (v, \"value\");
2683   if (!obj) {
2684     PyErr_SetString (PyExc_RuntimeError, \"no 'value' element in dictionary\");
2685     return -1;
2686   }
2687   if (!PyString_Check (obj)) {
2688     PyErr_SetString (PyExc_RuntimeError, \"'value' element is not a string\");
2689     return -1;
2690   }
2691   ret->value = PyString_AsString (obj);
2692   ret->len = PyString_Size (obj);
2693
2694   return 0;
2695 }
2696
2697 typedef struct py_set_values {
2698   size_t nr_values;
2699   hive_set_value *values;
2700 } py_set_values;
2701
2702 static int
2703 get_values (PyObject *v, py_set_values *ret)
2704 {
2705   Py_ssize_t slen;
2706   size_t len, i;
2707
2708   if (!PyList_Check (v)) {
2709     PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
2710     return -1;
2711   }
2712
2713   slen = PyList_Size (v);
2714   if (slen < 0) {
2715     PyErr_SetString (PyExc_RuntimeError, \"get_string_list: PyList_Size failure\");
2716     return -1;
2717   }
2718   len = (size_t) slen;
2719   ret->nr_values = len;
2720   ret->values = malloc (len * sizeof (hive_set_value));
2721   if (!ret->values) {
2722     PyErr_SetString (PyExc_RuntimeError, strerror (errno));
2723     return -1;
2724   }
2725
2726   for (i = 0; i < len; ++i) {
2727     if (get_value (PyList_GetItem (v, i), &(ret->values[i])) == -1) {
2728       free (ret->values);
2729       return -1;
2730     }
2731   }
2732
2733   return 0;
2734 }
2735
2736 static PyObject *
2737 put_string_list (char * const * const argv)
2738 {
2739   PyObject *list;
2740   size_t argc, i;
2741
2742   for (argc = 0; argv[argc] != NULL; ++argc)
2743     ;
2744
2745   list = PyList_New (argc);
2746   for (i = 0; i < argc; ++i)
2747     PyList_SetItem (list, i, PyString_FromString (argv[i]));
2748
2749   return list;
2750 }
2751
2752 static void
2753 free_strings (char **argv)
2754 {
2755   size_t argc;
2756
2757   for (argc = 0; argv[argc] != NULL; ++argc)
2758     free (argv[argc]);
2759   free (argv);
2760 }
2761
2762 /* Since hive_node_t is the same as hive_value_t this also works for values. */
2763 static PyObject *
2764 put_node_list (hive_node_h *nodes)
2765 {
2766   PyObject *list;
2767   size_t argc, i;
2768
2769   for (argc = 0; nodes[argc] != 0; ++argc)
2770     ;
2771
2772   list = PyList_New (argc);
2773   for (i = 0; i < argc; ++i)
2774     PyList_SetItem (list, i, PyLong_FromLongLong ((long) nodes[i]));
2775
2776   return list;
2777 }
2778
2779 static PyObject *
2780 put_len_type (size_t len, hive_type t)
2781 {
2782   PyObject *r = PyTuple_New (2);
2783   PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t));
2784   PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) len));
2785   return r;
2786 }
2787
2788 static PyObject *
2789 put_val_type (char *val, size_t len, hive_type t)
2790 {
2791   PyObject *r = PyTuple_New (2);
2792   PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t));
2793   PyTuple_SetItem (r, 1, PyString_FromStringAndSize (val, len));
2794   return r;
2795 }
2796
2797 ";
2798
2799   (* Generate functions. *)
2800   List.iter (
2801     fun (name, style, _, longdesc) ->
2802       pr "static PyObject *\n";
2803       pr "py_hivex_%s (PyObject *self, PyObject *args)\n" name;
2804       pr "{\n";
2805       pr "  PyObject *py_r;\n";
2806
2807       let error_code =
2808         match fst style with
2809         | RErr -> pr "  int r;\n"; "-1"
2810         | RErrDispose -> pr "  int r;\n"; "-1"
2811         | RHive -> pr "  hive_h *r;\n"; "NULL"
2812         | RNode -> pr "  hive_node_h r;\n"; "0"
2813         | RNodeNotFound ->
2814             pr "  errno = 0;\n";
2815             pr "  hive_node_h r;\n";
2816             "0 && errno != 0"
2817         | RNodeList -> pr "  hive_node_h *r;\n"; "NULL"
2818         | RValue -> pr "  hive_value_h r;\n"; "0"
2819         | RValueList -> pr "  hive_value_h *r;\n"; "NULL"
2820         | RString -> pr "  char *r;\n"; "NULL"
2821         | RStringList -> pr "  char **r;\n"; "NULL"
2822         | RLenType ->
2823             pr "  int r;\n";
2824             pr "  size_t len;\n";
2825             pr "  hive_type t;\n";
2826             "-1"
2827         | RLenTypeVal ->
2828             pr "  char *r;\n";
2829             pr "  size_t len;\n";
2830             pr "  hive_type t;\n";
2831             "NULL"
2832         | RInt32 ->
2833             pr "  errno = 0;\n";
2834             pr "  int32_t r;\n";
2835             "-1 && errno != 0"
2836         | RInt64 ->
2837             pr "  errno = 0;\n";
2838             pr "  int64_t r;\n";
2839             "-1 && errno != 0" in
2840
2841       (* Call and arguments. *)
2842       let c_params =
2843         List.map (function
2844                   | AUnusedFlags -> "0"
2845                   | ASetValues -> "values.nr_values, values.values"
2846                   | ASetValue -> "&val"
2847                   | arg -> name_of_argt arg) (snd style) in
2848       let c_params =
2849         match fst style with
2850         | RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"]
2851         | _ -> c_params in
2852
2853       List.iter (
2854         function
2855         | AHive ->
2856             pr "  hive_h *h;\n";
2857             pr "  PyObject *py_h;\n"
2858         | ANode n
2859         | AValue n ->
2860             pr "  long %s;\n" n
2861         | AString n
2862         | AStringNullable n ->
2863             pr "  char *%s;\n" n
2864         | AOpenFlags ->
2865             pr "  int flags;\n"
2866         | AUnusedFlags -> ()
2867         | ASetValues ->
2868             pr "  py_set_values values;\n";
2869             pr "  PyObject *py_values;\n"
2870         | ASetValue ->
2871             pr "  hive_set_value val;\n";
2872             pr "  PyObject *py_val;\n"
2873       ) (snd style);
2874
2875       pr "\n";
2876
2877       (* Convert the required parameters. *)
2878       pr "  if (!PyArg_ParseTuple (args, (char *) \"";
2879       List.iter (
2880         function
2881         | AHive ->
2882             pr "O"
2883         | ANode n
2884         | AValue n ->
2885             pr "l"
2886         | AString n ->
2887             pr "s"
2888         | AStringNullable n ->
2889             pr "z"
2890         | AOpenFlags ->
2891             pr "i"
2892         | AUnusedFlags -> ()
2893         | ASetValues
2894         | ASetValue ->
2895             pr "O"
2896       ) (snd style);
2897
2898       pr ":hivex_%s\"" name;
2899
2900       List.iter (
2901         function
2902         | AHive ->
2903             pr ", &py_h"
2904         | ANode n
2905         | AValue n ->
2906             pr ", &%s" n
2907         | AString n
2908         | AStringNullable n ->
2909             pr ", &%s" n
2910         | AOpenFlags ->
2911             pr ", &flags"
2912         | AUnusedFlags -> ()
2913         | ASetValues ->
2914             pr ", &py_values"
2915         | ASetValue ->
2916             pr ", &py_val"
2917         ) (snd style);
2918
2919       pr "))\n";
2920       pr "    return NULL;\n";
2921
2922       (* Convert some Python argument types to C. *)
2923       List.iter (
2924         function
2925         | AHive ->
2926             pr "  h = get_handle (py_h);\n"
2927         | ANode _
2928         | AValue _
2929         | AString _
2930         | AStringNullable _
2931         | AOpenFlags
2932         | AUnusedFlags -> ()
2933         | ASetValues ->
2934             pr "  if (get_values (py_values, &values) == -1)\n";
2935             pr "    return NULL;\n"
2936         | ASetValue ->
2937             pr "  if (get_value (py_val, &val) == -1)\n";
2938             pr "    return NULL;\n"
2939       ) (snd style);
2940
2941       (* Call the C function. *)
2942       pr "  r = hivex_%s (%s);\n" name (String.concat ", " c_params);
2943
2944       (* Free up arguments. *)
2945       List.iter (
2946         function
2947         | AHive | ANode _ | AValue _
2948         | AString _ | AStringNullable _
2949         | AOpenFlags | AUnusedFlags -> ()
2950         | ASetValues ->
2951             pr "  free (values.values);\n"
2952         | ASetValue -> ()
2953       ) (snd style);
2954
2955       (* Check for errors from C library. *)
2956       pr "  if (r == %s) {\n" error_code;
2957       pr "    PyErr_SetString (PyExc_RuntimeError,\n";
2958       pr "                     strerror (errno));\n";
2959       pr "    return NULL;\n";
2960       pr "  }\n";
2961       pr "\n";
2962
2963       (* Convert return value to Python. *)
2964       (match fst style with
2965        | RErr
2966        | RErrDispose ->
2967            pr "  Py_INCREF (Py_None);\n";
2968            pr "  py_r = Py_None;\n"
2969        | RHive ->
2970            pr "  py_r = put_handle (r);\n"
2971        | RNode ->
2972            pr "  py_r = PyLong_FromLongLong (r);\n"
2973        | RNodeNotFound ->
2974            pr "  if (r)\n";
2975            pr "    py_r = PyLong_FromLongLong (r);\n";
2976            pr "  else {\n";
2977            pr "    Py_INCREF (Py_None);\n";
2978            pr "    py_r = Py_None;\n";
2979            pr "  }\n";
2980        | RNodeList
2981        | RValueList ->
2982            pr "  py_r = put_node_list (r);\n";
2983            pr "  free (r);\n"
2984        | RValue ->
2985            pr "  py_r = PyLong_FromLongLong (r);\n"
2986        | RString ->
2987            pr "  py_r = PyString_FromString (r);\n";
2988            pr "  free (r);"
2989        | RStringList ->
2990            pr "  py_r = put_string_list (r);\n";
2991            pr "  free_strings (r);\n"
2992        | RLenType ->
2993            pr "  py_r = put_len_type (len, t);\n"
2994        | RLenTypeVal ->
2995            pr "  py_r = put_val_type (r, len, t);\n";
2996            pr "  free (r);\n"
2997        | RInt32 ->
2998            pr "  py_r = PyInt_FromLong ((long) r);\n"
2999        | RInt64 ->
3000            pr "  py_r = PyLong_FromLongLong (r);\n"
3001       );
3002       pr "  return py_r;\n";
3003       pr "}\n";
3004       pr "\n"
3005   ) functions;
3006
3007   (* Table of functions. *)
3008   pr "static PyMethodDef methods[] = {\n";
3009   List.iter (
3010     fun (name, _, _, _) ->
3011       pr "  { (char *) \"%s\", py_hivex_%s, METH_VARARGS, NULL },\n"
3012         name name
3013   ) functions;
3014   pr "  { NULL, NULL, 0, NULL }\n";
3015   pr "};\n";
3016   pr "\n";
3017
3018   (* Init function. *)
3019   pr "\
3020 void
3021 initlibhivexmod (void)
3022 {
3023   static int initialized = 0;
3024
3025   if (initialized) return;
3026   Py_InitModule ((char *) \"libhivexmod\", methods);
3027   initialized = 1;
3028 }
3029 "
3030   
3031 and generate_python_py () =
3032   generate_header HashStyle LGPLv2plus;
3033
3034   pr "\
3035 u\"\"\"Python bindings for hivex
3036
3037 import hivex
3038 h = hivex.Hivex (filename)
3039
3040 The hivex module provides Python bindings to the hivex API for
3041 examining and modifying Windows Registry 'hive' files.
3042
3043 Read the hivex(3) man page to find out how to use the API.
3044 \"\"\"
3045
3046 import libhivexmod
3047
3048 class Hivex:
3049     \"\"\"Instances of this class are hivex API handles.\"\"\"
3050
3051     def __init__ (self, filename";
3052
3053   List.iter (
3054     fun (_, flag, _) -> pr ", %s = False" (String.lowercase flag)
3055   ) open_flags;
3056
3057   pr "):
3058         \"\"\"Create a new hivex handle.\"\"\"
3059         flags = 0
3060 ";
3061
3062   List.iter (
3063     fun (n, flag, description) ->
3064       pr "        # %s\n" description;
3065       pr "        if %s: flags += %d\n" (String.lowercase flag) n
3066   ) open_flags;
3067
3068   pr "        self._o = libhivexmod.open (filename, flags)
3069
3070     def __del__ (self):
3071         libhivexmod.close (self._o)
3072
3073 ";
3074
3075   List.iter (
3076     fun (name, style, shortdesc, _) ->
3077       (* The close and open calls are handled specially above. *)
3078       if fst style <> RErrDispose && List.hd (snd style) = AHive then (
3079         let args = List.tl (snd style) in
3080         let args = List.filter (
3081           function AOpenFlags | AUnusedFlags -> false
3082           | _ -> true
3083         ) args in
3084
3085         pr "    def %s (self" name;
3086         List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
3087         pr "):\n";
3088         pr "        u\"\"\"%s\"\"\"\n" shortdesc;
3089         pr "        return libhivexmod.%s (self._o" name;
3090         List.iter (
3091           fun arg ->
3092             pr ", ";
3093             match arg with
3094             | AHive -> assert false
3095             | ANode n | AValue n
3096             | AString n | AStringNullable n -> pr "%s" n
3097             | AOpenFlags
3098             | AUnusedFlags -> assert false
3099             | ASetValues -> pr "values"
3100             | ASetValue -> pr "val"
3101         ) args;
3102         pr ")\n";
3103         pr "\n"
3104       )
3105   ) functions
3106
3107 let output_to filename k =
3108   let filename_new = filename ^ ".new" in
3109   chan := open_out filename_new;
3110   k ();
3111   close_out !chan;
3112   chan := Pervasives.stdout;
3113
3114   (* Is the new file different from the current file? *)
3115   if Sys.file_exists filename && files_equal filename filename_new then
3116     unlink filename_new                 (* same, so skip it *)
3117   else (
3118     (* different, overwrite old one *)
3119     (try chmod filename 0o644 with Unix_error _ -> ());
3120     rename filename_new filename;
3121     chmod filename 0o444;
3122     printf "written %s\n%!" filename;
3123   )
3124
3125 let perror msg = function
3126   | Unix_error (err, _, _) ->
3127       eprintf "%s: %s\n" msg (error_message err)
3128   | exn ->
3129       eprintf "%s: %s\n" msg (Printexc.to_string exn)
3130
3131 (* Main program. *)
3132 let () =
3133   let lock_fd =
3134     try openfile "configure.ac" [O_RDWR] 0
3135     with
3136     | Unix_error (ENOENT, _, _) ->
3137         eprintf "\
3138 You are probably running this from the wrong directory.
3139 Run it from the top source directory using the command
3140   generator/generator.ml
3141 ";
3142         exit 1
3143     | exn ->
3144         perror "open: configure.ac" exn;
3145         exit 1 in
3146
3147   (* Acquire a lock so parallel builds won't try to run the generator
3148    * twice at the same time.  Subsequent builds will wait for the first
3149    * one to finish.  Note the lock is released implicitly when the
3150    * program exits.
3151    *)
3152   (try lockf lock_fd F_LOCK 1
3153    with exn ->
3154      perror "lock: configure.ac" exn;
3155      exit 1);
3156
3157   check_functions ();
3158
3159   output_to "lib/hivex.h" generate_c_header;
3160   output_to "lib/hivex.pod" generate_c_pod;
3161
3162   output_to "lib/hivex.syms" generate_linker_script;
3163
3164   output_to "ocaml/hivex.mli" generate_ocaml_interface;
3165   output_to "ocaml/hivex.ml" generate_ocaml_implementation;
3166   output_to "ocaml/hivex_c.c" generate_ocaml_c;
3167
3168   output_to "perl/lib/Win/Hivex.pm" generate_perl_pm;
3169   output_to "perl/Hivex.xs" generate_perl_xs;
3170
3171   output_to "python/hivex.py" generate_python_py;
3172   output_to "python/hivex-py.c" generate_python_c;
3173
3174   (* Always generate this file last, and unconditionally.  It's used
3175    * by the Makefile to know when we must re-run the generator.
3176    *)
3177   let chan = open_out "generator/stamp-generator" in
3178   fprintf chan "1\n";
3179   close_out chan;
3180
3181   printf "generated %d lines of code\n" !lines