X-Git-Url: http://git.annexia.org/?p=hivex.git;a=blobdiff_plain;f=generator%2Fgenerator.ml;h=b0c10eb42621d17d72518c68d8330e9b2fad49ad;hp=b6fb8b3af52793af32a96c7daa9a865c8f3a0d60;hb=HEAD;hpb=e85b1eaa268caea316f6aa8e02738b3d94297250 diff --git a/generator/generator.ml b/generator/generator.ml index b6fb8b3..b0c10eb 100755 --- a/generator/generator.ml +++ b/generator/generator.ml @@ -51,6 +51,7 @@ and ret = | RNodeList (* Returns hive_node_h* or NULL. *) | RValue (* Returns hive_value_h or 0. *) | RValueList (* Returns hive_value_h* or NULL. *) + | RLenValue (* Returns offset and length of value. *) | RString (* Returns char* or NULL. *) | RStringList (* Returns char** or NULL. *) | RLenType (* See hivex_value_type. *) @@ -265,14 +266,26 @@ you know the type in advance."; "node_struct_length", (RSize, [AHive; ANode "node"]), "return the length of a node", "\ -Return the length of the node data structure. Returns 0 -and sets errno on error."; +Return the length of the node data structure."; "value_struct_length", (RSize, [AHive; AValue "val"]), "return the length of a value data structure", "\ -Return the length of the value data structure. Returns 0 -and sets errno on error."; +Return the length of the value data structure."; + + "value_data_cell_offset", (RLenValue, [AHive; AValue "val"]), + "return the offset and length of a value data cell", + "\ +Return the offset and length of the value's data cell. + +The data cell is a registry structure that contains the length +(a 4 byte, little endian integer) followed by the data. + +If the length of the value is less than or equal to 4 bytes +then the offset and length returned by this function is zero +as the data is inlined in the value. + +Returns 0 and sets errno on error."; "value_value", (RLenTypeVal, [AHive; AValue "val"]), "return data length, data type and data of a value", @@ -890,6 +903,7 @@ and generate_c_prototype ?(extern = false) name style = | RValueList -> pr "hive_value_h *" | RString -> pr "char *" | RStringList -> pr "char **" + | RLenValue -> pr "hive_value_h " | RLenType -> pr "int " | RLenTypeVal -> pr "char *" | RInt32 -> pr "int32_t " @@ -911,6 +925,7 @@ and generate_c_prototype ?(extern = false) name style = ) (snd style); (match fst style with | RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len" + | RLenValue -> pr ", size_t *len" | _ -> () ); pr ");\n" @@ -1113,6 +1128,10 @@ On error this returns NULL and sets errno.\n\n" pr "\ Returns 0 on success. On error this returns -1 and sets errno.\n\n" + | RLenValue -> + pr "\ +Returns a value handle. +On error this returns 0 and sets errno.\n\n" | RLenTypeVal -> pr "\ The value is returned as an array of bytes (of length C). @@ -1624,6 +1643,7 @@ and generate_ocaml_prototype ?(is_external = false) name style = | RString -> pr "string" | RStringList -> pr "string array" | RLenType -> pr "hive_type * int" + | RLenValue -> pr "int * value" | RLenTypeVal -> pr "hive_type * string" | RInt32 -> pr "int32" | RInt64 -> pr "int64" @@ -1687,6 +1707,7 @@ static hive_type HiveType_val (value); static value Val_hive_type (hive_type); static value copy_int_array (size_t *); static value copy_type_len (size_t, hive_type); +static value copy_len_value (size_t, hive_value_h); static value copy_type_value (const char *, size_t, hive_type); static void raise_error (const char *) Noreturn; static void raise_closed (const char *) Noreturn; @@ -1709,6 +1730,7 @@ static void raise_closed (const char *) Noreturn; let c_params = match fst style with | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]] + | RLenValue -> c_params @ [["&len"]] | _ -> c_params in let c_params = List.concat c_params in @@ -1781,6 +1803,11 @@ static void raise_closed (const char *) Noreturn; pr " size_t len;\n"; pr " hive_type t;\n"; "-1" + | RLenValue -> + pr " errno = 0;"; + pr " hive_value_h r;\n"; + pr " size_t len;\n"; + "0 && errno != 0" | RLenTypeVal -> pr " char *r;\n"; pr " size_t len;\n"; @@ -1861,6 +1888,7 @@ static void raise_closed (const char *) Noreturn; pr " for (int i = 0; r[i] != NULL; ++i) free (r[i]);\n"; pr " free (r);\n" | RLenType -> pr " rv = copy_type_len (len, t);\n" + | RLenValue -> pr " rv = copy_len_value (len, r);\n" | RLenTypeVal -> pr " rv = copy_type_value (r, len, t);\n"; pr " free (r);\n" @@ -1983,6 +2011,20 @@ copy_type_len (size_t len, hive_type t) } static value +copy_len_value (size_t len, hive_value_h r) +{ + CAMLparam0 (); + CAMLlocal2 (v, rv); + + rv = caml_alloc (2, 0); + v = Val_int (len); + Store_field (rv, 0, v); + v = Val_int (r); + Store_field (rv, 1, v); + CAMLreturn (rv); +} + +static value copy_type_value (const char *r, size_t len, hive_type t) { CAMLparam0 (); @@ -2172,6 +2214,7 @@ sub open { | RString | RStringList | RLenType + | RLenValue | RLenTypeVal | RInt32 | RInt64 -> () @@ -2246,6 +2289,7 @@ and generate_perl_prototype name style = | RString -> pr "$string = " | RStringList -> pr "@strings = " | RLenType -> pr "($type, $len) = " + | RLenValue -> pr "($len, $value) = " | RLenTypeVal -> pr "($type, $data) = " | RInt32 -> pr "$int32 = " | RInt64 -> pr "$int64 = " @@ -2469,6 +2513,7 @@ DESTROY (h) | RValueList | RStringList | RLenType + | RLenValue | RLenTypeVal -> pr "void\n" | RInt32 -> pr "SV *\n" | RInt64 -> pr "SV *\n" @@ -2641,6 +2686,22 @@ DESTROY (h) pr " PUSHs (sv_2mortal (newSViv (type)));\n"; pr " PUSHs (sv_2mortal (newSViv (len)));\n"; + | RLenValue -> + pr "PREINIT:\n"; + pr " hive_value_h r;\n"; + pr " size_t len;\n"; + pr " PPCODE:\n"; + pr " errno = 0;\n"; + pr " r = hivex_%s (%s, &len);\n" + name (String.concat ", " c_params); + free_args (); + pr " if (r == 0 && errno)\n"; + pr " croak (\"%%s: \", \"%s\", strerror (errno));\n" + name; + pr " EXTEND (SP, 2);\n"; + pr " PUSHs (sv_2mortal (newSViv (len)));\n"; + pr " PUSHs (sv_2mortal (newSViv (r)));\n"; + | RLenTypeVal -> pr "PREINIT:\n"; pr " char *r;\n"; @@ -2696,6 +2757,8 @@ and generate_python_c () = generate_header CStyle LGPLv2plus; pr "\ +#include + #define PY_SSIZE_T_CLEAN 1 #include @@ -2749,40 +2812,42 @@ static int get_value (PyObject *v, hive_set_value *ret) { PyObject *obj; +#ifndef HAVE_PYSTRING_ASSTRING + PyObject *bytes; +#endif obj = PyDict_GetItemString (v, \"key\"); if (!obj) { PyErr_SetString (PyExc_RuntimeError, \"no 'key' element in dictionary\"); return -1; } - if (!PyString_Check (obj)) { - PyErr_SetString (PyExc_RuntimeError, \"'key' element is not a string\"); - return -1; - } +#ifdef HAVE_PYSTRING_ASSTRING ret->key = PyString_AsString (obj); +#else + bytes = PyUnicode_AsUTF8String (obj); + ret->key = PyBytes_AS_STRING (bytes); +#endif obj = PyDict_GetItemString (v, \"t\"); if (!obj) { PyErr_SetString (PyExc_RuntimeError, \"no 't' element in dictionary\"); return -1; } - if (!PyInt_Check (obj)) { - PyErr_SetString (PyExc_RuntimeError, \"'t' element is not an integer\"); - return -1; - } - ret->t = PyInt_AsLong (obj); + ret->t = PyLong_AsLong (obj); obj = PyDict_GetItemString (v, \"value\"); if (!obj) { PyErr_SetString (PyExc_RuntimeError, \"no 'value' element in dictionary\"); return -1; } - if (!PyString_Check (obj)) { - PyErr_SetString (PyExc_RuntimeError, \"'value' element is not a string\"); - return -1; - } +#ifdef HAVE_PYSTRING_ASSTRING ret->value = PyString_AsString (obj); ret->len = PyString_Size (obj); +#else + bytes = PyUnicode_AsUTF8String (obj); + ret->value = PyBytes_AS_STRING (bytes); + ret->len = PyBytes_GET_SIZE (bytes); +#endif return 0; } @@ -2836,8 +2901,13 @@ put_string_list (char * const * const argv) ; list = PyList_New (argc); - for (i = 0; i < argc; ++i) + for (i = 0; i < argc; ++i) { +#ifdef HAVE_PYSTRING_ASSTRING PyList_SetItem (list, i, PyString_FromString (argv[i])); +#else + PyList_SetItem (list, i, PyUnicode_FromString (argv[i])); +#endif + } return list; } @@ -2873,17 +2943,30 @@ static PyObject * put_len_type (size_t len, hive_type t) { PyObject *r = PyTuple_New (2); - PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t)); + PyTuple_SetItem (r, 0, PyLong_FromLong ((long) t)); PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) len)); return r; } static PyObject * +put_len_val (size_t len, hive_value_h value) +{ + PyObject *r = PyTuple_New (2); + PyTuple_SetItem (r, 0, PyLong_FromLongLong ((long) len)); + PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) value)); + return r; +} + +static PyObject * put_val_type (char *val, size_t len, hive_type t) { PyObject *r = PyTuple_New (2); - PyTuple_SetItem (r, 0, PyInt_FromLong ((long) t)); + PyTuple_SetItem (r, 0, PyLong_FromLong ((long) t)); +#ifdef HAVE_PYSTRING_ASSTRING PyTuple_SetItem (r, 1, PyString_FromStringAndSize (val, len)); +#else + PyTuple_SetItem (r, 1, PyBytes_FromStringAndSize (val, len)); +#endif return r; } @@ -2918,6 +3001,11 @@ put_val_type (char *val, size_t len, hive_type t) pr " size_t len;\n"; pr " hive_type t;\n"; "-1" + | RLenValue -> + pr " errno = 0;\n"; + pr " int r;\n"; + pr " size_t len;\n"; + "0 && errno != 0" | RLenTypeVal -> pr " char *r;\n"; pr " size_t len;\n"; @@ -2942,6 +3030,7 @@ put_val_type (char *val, size_t len, hive_type t) let c_params = match fst style with | RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"] + | RLenValue -> c_params @ ["&len"] | _ -> c_params in List.iter ( @@ -3079,18 +3168,24 @@ put_val_type (char *val, size_t len, hive_type t) | RValue -> pr " py_r = PyLong_FromLongLong (r);\n" | RString -> + pr "#ifdef HAVE_PYSTRING_ASSTRING\n"; pr " py_r = PyString_FromString (r);\n"; + pr "#else\n"; + pr " py_r = PyUnicode_FromString (r);\n"; + pr "#endif\n"; pr " free (r);" | RStringList -> pr " py_r = put_string_list (r);\n"; pr " free_strings (r);\n" | RLenType -> pr " py_r = put_len_type (len, t);\n" + | RLenValue -> + pr " py_r = put_len_val (len, r);\n" | RLenTypeVal -> pr " py_r = put_val_type (r, len, t);\n"; pr " free (r);\n" | RInt32 -> - pr " py_r = PyInt_FromLong ((long) r);\n" + pr " py_r = PyLong_FromLong ((long) r);\n" | RInt64 -> pr " py_r = PyLong_FromLongLong (r);\n" ); @@ -3112,22 +3207,54 @@ put_val_type (char *val, size_t len, hive_type t) (* Init function. *) pr "\ +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + \"libhivexmod\", /* m_name */ + \"hivex module\", /* m_doc */ + -1, /* m_size */ + methods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; +#endif + +static PyObject * +moduleinit (void) +{ + PyObject *m; + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create (&moduledef); +#else + m = Py_InitModule ((char *) \"libhivexmod\", methods); +#endif + + return m; /* m might be NULL if module init failed */ +} + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC +PyInit_libhivexmod (void) +{ + return moduleinit (); +} +#else void initlibhivexmod (void) { - static int initialized = 0; - - if (initialized) return; - Py_InitModule ((char *) \"libhivexmod\", methods); - initialized = 1; + (void) moduleinit (); } +#endif " and generate_python_py () = generate_header HashStyle LGPLv2plus; pr "\ -u\"\"\"Python bindings for hivex +\"\"\"Python bindings for hivex import hivex h = hivex.Hivex (filename) @@ -3180,7 +3307,7 @@ class Hivex: pr " def %s (self" name; List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args; pr "):\n"; - pr " u\"\"\"%s\"\"\"\n" shortdesc; + pr " \"\"\"%s\"\"\"\n" shortdesc; pr " return libhivexmod.%s (self._o" name; List.iter ( fun arg -> @@ -3218,6 +3345,14 @@ and generate_ruby_c () = #define RARRAY_LEN(r) (RARRAY((r))->len) #endif +#ifndef RSTRING_LEN +#define RSTRING_LEN(r) (RSTRING((r))->len) +#endif + +#ifndef RSTRING_PTR +#define RSTRING_PTR(r) (RSTRING((r))->ptr) +#endif + static VALUE m_hivex; /* hivex module */ static VALUE c_hivex; /* hive_h handle */ static VALUE e_Error; /* used for all errors */ @@ -3240,8 +3375,8 @@ get_value (VALUE valv, hive_set_value *val) val->key = StringValueCStr (key); val->t = NUM2ULL (type); - val->len = RSTRING (value)->len; - val->value = RSTRING (value)->ptr; + val->len = RSTRING_LEN (value); + val->value = RSTRING_PTR (value); } static hive_set_value * @@ -3296,6 +3431,7 @@ get_values (VALUE valuesv, size_t *nr_values) | RString -> "string" | RStringList -> "list" | RLenType -> "hash" + | RLenValue -> "integer" | RLenTypeVal -> "hash" | RInt32 -> "integer" | RInt64 -> "integer" in @@ -3394,6 +3530,11 @@ get_values (VALUE valuesv, size_t *nr_values) pr " size_t len;\n"; pr " hive_type t;\n"; "-1" + | RLenValue -> + pr " errno = 0;\n"; + pr " hive_value_h r;\n"; + pr " size_t len;\n"; + "0 && errno != 0" | RLenTypeVal -> pr " char *r;\n"; pr " size_t len;\n"; @@ -3418,6 +3559,7 @@ get_values (VALUE valuesv, size_t *nr_values) let c_params = match ret with | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]] + | RLenValue -> c_params @ [["&len"]] | _ -> c_params in let c_params = List.concat c_params in @@ -3499,6 +3641,11 @@ get_values (VALUE valuesv, size_t *nr_values) pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n"; pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"type\")), INT2NUM (t));\n"; pr " return rv;\n" + | RLenValue -> + pr " VALUE rv = rb_hash_new ();\n"; + pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n"; + pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"off\")), ULL2NUM (r));\n"; + pr " return rv;\n" | RLenTypeVal -> pr " VALUE rv = rb_hash_new ();\n"; pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n";