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