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