libesedb(3)

πŸ“¦
this version Β· 2 versions
, in debian trixie, epel 10, fedora 43, fedora 44, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– libesedb β€” NAME πŸ’–

okay bestie, gather round 🫢 this is libesedb, and the header you're gonna #include is libesedb.h β€” it's the library that lets you access the Extensible Storage Engine (ESE) Database File (EDB) format. yes, that ESE, the one living inside your Windows search index and your mailbox files. she's iconic, she's complicated, and we're gonna be besties with her. periodt. πŸ’…


✨ SYNOPSIS ✨

first things first, you gotta invite her in:

#include <libesedb.h>

and then, bestie, it's a whole menu of functions. let's go group by group, no skipping, no cap πŸŽ€

🌸 Support functions

the little helpers that hold the whole vibe together:

const char *
libesedb_get_version(void);

int
libesedb_get_access_flags_read(void);

int
libesedb_get_codepage(int *codepage, libesedb_error_t **error);

int
libesedb_set_codepage(int codepage, libesedb_error_t **error);

int
libesedb_check_file_signature(const char *filename,
    libesedb_error_t **error);

and here's the tea β€” some of these only exist if your build said yes to certain things πŸ‘‘

Available when compiled with wide character string support:

int
libesedb_check_file_signature_wide(const wchar_t *filename,
    libesedb_error_t **error);

Available when compiled with libbfio support:

int
libesedb_check_file_signature_file_io_handle(libbfio_handle_t *bfio_handle,
    libesedb_error_t **error);

πŸ”” Notify functions

the ones that tell you what's going on behind the scenes. gossip girl energy, but for your library 🌈

void
libesedb_notify_set_verbose(int verbose);

int
libesedb_notify_set_stream(FILE *stream, libesedb_error_t **error);

int
libesedb_notify_stream_open(const char *filename,
    libesedb_error_t **error);

int
libesedb_notify_stream_close(libesedb_error_t **error);

😭 Error functions

because bestie, things will go wrong, and when they do you deserve a full explanation, not a cryptic -1. these are your emotional support error handlers πŸ’œ

void
libesedb_error_free(libesedb_error_t **error);

int
libesedb_error_fprint(libesedb_error_t *error, FILE *stream);

int
libesedb_error_sprint(libesedb_error_t *error, char *string,
    size_t size);

int
libesedb_error_backtrace_fprint(libesedb_error_t *error, FILE *stream);

int
libesedb_error_backtrace_sprint(libesedb_error_t *error, char *string,
    size_t size);

πŸ“ File functions

this is where the actual EDB file comes into the chat. open her, inspect her, ask her about her tables β€” main character energy fr fr πŸ‘‘

int
libesedb_file_initialize(libesedb_file_t **file,
    libesedb_error_t **error);

int
libesedb_file_free(libesedb_file_t **file, libesedb_error_t **error);

int
libesedb_file_signal_abort(libesedb_file_t *file,
    libesedb_error_t **error);

int
libesedb_file_open(libesedb_file_t *file, const char *filename,
    int access_flags, libesedb_error_t **error);

int
libesedb_file_close(libesedb_file_t *file, libesedb_error_t **error);

int
libesedb_file_get_type(libesedb_file_t *file, uint32_t *type,
    libesedb_error_t **error);

int
libesedb_file_get_format_version(libesedb_file_t *file,
    uint32_t *format_version, uint32_t *format_revision,
    libesedb_error_t **error);

int
libesedb_file_get_creation_format_version(libesedb_file_t *file,
    uint32_t *format_version, uint32_t *format_revision,
    libesedb_error_t **error);

int
libesedb_file_get_page_size(libesedb_file_t *file, uint32_t *page_size,
    libesedb_error_t **error);

int
libesedb_file_get_number_of_tables(libesedb_file_t *file,
    int *number_of_tables, libesedb_error_t **error);

int
libesedb_file_get_table(libesedb_file_t *file, int table_entry,
    libesedb_table_t **table, libesedb_error_t **error);

int
libesedb_file_get_table_by_utf8_name(libesedb_file_t *file,
    const uint8_t *utf8_string, size_t utf8_string_length,
    libesedb_table_t **table, libesedb_error_t **error);

int
libesedb_file_get_table_by_utf16_name(libesedb_file_t *file,
    const uint16_t *utf16_string, size_t utf16_string_length,
    libesedb_table_t **table, libesedb_error_t **error);

and again, the conditional girlies πŸ’«

Available when compiled with wide character string support:

int
libesedb_file_open_wide(libesedb_file_t *file, const wchar_t *filename,
    int access_flags, libesedb_error_t **error);

Available when compiled with libbfio support:

int
libesedb_file_open_file_io_handle(libesedb_file_t *file,
    libbfio_handle_t *file_io_handle, int access_flags,
    libesedb_error_t **error);

πŸ—‚οΈ Table functions

tables!! the whole point, honestly. names, identifiers, columns, indexes, records β€” she has layers, and we love that for her πŸ¦‹

int
libesedb_table_free(libesedb_table_t **table, libesedb_error_t **error);

int
libesedb_table_get_identifier(libesedb_table_t *table,
    uint32_t *identifier, libesedb_error_t **error);

int
libesedb_table_get_utf8_name_size(libesedb_table_t *table,
    size_t *utf8_string_size, libesedb_error_t **error);

int
libesedb_table_get_utf8_name(libesedb_table_t *table,
    uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_table_get_utf16_name_size(libesedb_table_t *table,
    size_t *utf16_string_size, libesedb_error_t **error);

int
libesedb_table_get_utf16_name(libesedb_table_t *table,
    uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

int
libesedb_table_get_utf8_template_name_size(libesedb_table_t *table,
    size_t *utf8_string_size, libesedb_error_t **error);

int
libesedb_table_get_utf8_template_name(libesedb_table_t *table,
    uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_table_get_utf16_template_name_size(libesedb_table_t *table,
    size_t *utf16_string_size, libesedb_error_t **error);

int
libesedb_table_get_utf16_template_name(libesedb_table_t *table,
    uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

int
libesedb_table_get_number_of_columns(libesedb_table_t *table,
    int *number_of_columns, uint8_t flags, libesedb_error_t **error);

int
libesedb_table_get_column(libesedb_table_t *table, int column_entry,
    libesedb_column_t **column, uint8_t flags,
    libesedb_error_t **error);

int
libesedb_table_get_number_of_indexes(libesedb_table_t *table,
    int *number_of_indexes, libesedb_error_t **error);

int
libesedb_table_get_index(libesedb_table_t *table, int index_entry,
    libesedb_index_t **index, libesedb_error_t **error);

int
libesedb_table_get_number_of_records(libesedb_table_t *table,
    int *number_of_records, libesedb_error_t **error);

int
libesedb_table_get_record(libesedb_table_t *table, int record_entry,
    libesedb_record_t **record, libesedb_error_t **error);

🌷 Column functions

the individual columns. she's giving detail-oriented, she's giving structured data, she's giving organization 🌸

int
libesedb_column_free(libesedb_column_t **column,
    libesedb_error_t **error);

int
libesedb_column_get_identifier(libesedb_column_t *column,
    uint32_t *identifier, libesedb_error_t **error);

int
libesedb_column_get_type(libesedb_column_t *column, uint32_t *type,
    libesedb_error_t **error);

int
libesedb_column_get_utf8_name_size(libesedb_column_t *column,
    size_t *utf8_string_size, libesedb_error_t **error);

int
libesedb_column_get_utf8_name(libesedb_column_t *column,
    uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_column_get_utf16_name_size(libesedb_column_t *column,
    size_t *utf16_string_size, libesedb_error_t **error);

int
libesedb_column_get_utf16_name(libesedb_column_t *column,
    uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

πŸŽ€ Index functions

indexes, bestie. the shortcuts. the little lookup queens. they ate and left no crumbs ✨

int
libesedb_index_free(libesedb_index_t **index, libesedb_error_t **error);

int
libesedb_index_get_identifier(libesedb_index_t *index,
    uint32_t *identifier, libesedb_error_t **error);

int
libesedb_index_get_utf8_name_size(libesedb_index_t *index,
    size_t *utf8_string_size, libesedb_error_t **error);

int
libesedb_index_get_utf8_name(libesedb_index_t *index,
    uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_index_get_utf16_name_size(libesedb_index_t *index,
    size_t *utf16_string_size, libesedb_error_t **error);

int
libesedb_index_get_utf16_name(libesedb_index_t *index,
    uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

int
libesedb_index_get_number_of_records(libesedb_index_t *index,
    int *number_of_records, libesedb_error_t **error);

int
libesedb_index_get_record(libesedb_index_t *index, int record_entry,
    libesedb_record_t **record, libesedb_error_t **error);

πŸ“ Record (row) functions

and here she is β€” the rows themselves. the actual data. this is the part where you get to pull out values in every flavor: booleans, 8bit, 16bit, 32bit, 64bit, filetime, floating point… she has range, and honestly? obsessed πŸ”₯

int
libesedb_record_free(libesedb_record_t **record,
    libesedb_error_t **error);

int
libesedb_record_get_number_of_values(libesedb_record_t *record,
    int *number_of_values, libesedb_error_t **error);

int
libesedb_record_get_column_identifier(libesedb_record_t *record,
    int value_entry, uint32_t *column_identifier,
    libesedb_error_t **error);

int
libesedb_record_get_column_type(libesedb_record_t *record,
    int value_entry, uint32_t *column_type, libesedb_error_t **error);

int
libesedb_record_get_utf8_column_name_size(libesedb_record_t *record,
    int value_entry, size_t *utf8_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_utf8_column_name(libesedb_record_t *record,
    int value_entry, uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_utf16_column_name_size(libesedb_record_t *record,
    int value_entry, size_t *utf16_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_utf16_column_name(libesedb_record_t *record,
    int value_entry, uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_data_size(libesedb_record_t *record,
    int value_entry, size_t *value_data_size, libesedb_error_t **error);

int
libesedb_record_get_value_data(libesedb_record_t *record,
    int value_entry, uint8_t *value_data, size_t value_data_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_data_flags(libesedb_record_t *record,
    int value_entry, uint8_t *value_data_flags,
    libesedb_error_t **error);

int
libesedb_record_get_value_boolean(libesedb_record_t *record,
    int value_entry, uint8_t *value_boolean, libesedb_error_t **error);

int
libesedb_record_get_value_8bit(libesedb_record_t *record,
    int value_entry, uint8_t *value_8bit, libesedb_error_t **error);

int
libesedb_record_get_value_16bit(libesedb_record_t *record,
    int value_entry, uint16_t *value_16bit, libesedb_error_t **error);

int
libesedb_record_get_value_32bit(libesedb_record_t *record,
    int value_entry, uint32_t *value_32bit, libesedb_error_t **error);

int
libesedb_record_get_value_64bit(libesedb_record_t *record,
    int value_entry, uint64_t *value_64bit, libesedb_error_t **error);

int
libesedb_record_get_value_filetime(libesedb_record_t *record,
    int value_entry, uint64_t *value_filetime,
    libesedb_error_t **error);

int
libesedb_record_get_value_floating_point_32bit(libesedb_record_t *record,
    int value_entry, float *value_floating_point_32bit,
    libesedb_error_t **error);

bestie we are SO not done yet, this page keeps going and going and honestly? we love a thorough queen πŸ‘‘ more coming πŸ’–

okay bestie, picking up right where we left off β€” the prototype parade continues and it does NOT stop πŸ’…

int
libesedb_record_get_value_floating_point_64bit(libesedb_record_t *record,
    int value_entry, double *value_floating_point_64bit,
    libesedb_error_t **error);

int
libesedb_record_get_value_utf8_string_size(libesedb_record_t *record,
    int value_entry, size_t *utf8_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_utf8_string(libesedb_record_t *record,
    int value_entry, uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_utf16_string_size(libesedb_record_t *record,
    int value_entry, size_t *utf16_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_utf16_string(libesedb_record_t *record,
    int value_entry, uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_binary_data_size(libesedb_record_t *record,
    int value_entry, size_t *binary_data_size,
    libesedb_error_t **error);

int
libesedb_record_get_value_binary_data(libesedb_record_t *record,
    int value_entry, uint8_t *binary_data, size_t binary_data_size,
    libesedb_error_t **error);

so these are the record-side value grabbers πŸ’œ you've got your 64-bit floating point value, your UTF-8 string size and string, your UTF-16 string size and string, and your binary data size and binary data. Note the pattern, bestie: the _size versions hand you back a size so you can allocate, and the non-_size versions want a buffer you already sized. That's the whole game.

And then there's the ✨special✨ squad β€” the ones that check whether a value is a long value or a multi value, and the ones that go get the actual libesedb_long_value_t or libesedb_multi_value_t for you:

int
libesedb_record_is_long_value(libesedb_record_t *record,
    int value_entry, libesedb_error_t **error);

int
libesedb_record_is_multi_value(libesedb_record_t *record,
    int value_entry, libesedb_error_t **error);

int
libesedb_record_get_long_value(libesedb_record_t *record,
    int value_entry, libesedb_long_value_t **long_value,
    libesedb_error_t **error);

int
libesedb_record_get_multi_value(libesedb_record_t *record,
    int value_entry, libesedb_multi_value_t **multi_value,
    libesedb_error_t **error);

it's giving "vibe check, then fetch" 🫢


🌈 Long value functions 🌈

Long values get their own little world, and honestly? deserved. First up: freeing one, asking how big its data is, and pulling the raw data out.

int
libesedb_long_value_free(libesedb_long_value_t **long_value,
    libesedb_error_t **error);

int
libesedb_long_value_get_data_size(libesedb_long_value_t *long_value,
    size64_t *data_size, libesedb_error_t **error);

int
libesedb_long_value_get_data(libesedb_long_value_t *long_value,
    uint8_t *data, size_t data_size, libesedb_error_t **error);

Then the segment era 😭 β€” long values can be split into data segments, so you can count them, get the size of one by data_segment_index, and get the segment itself.

int
libesedb_long_value_get_number_of_data_segments(libesedb_long_value_t *long_value,
    int *number_of_data_segments, libesedb_error_t **error);

int
libesedb_long_value_get_data_segment_size(libesedb_long_value_t *long_value,
    int data_segment_index, size_t *data_size,
    libesedb_error_t **error);

int
libesedb_long_value_get_data_segment(libesedb_long_value_t *long_value,
    int data_segment_index, uint8_t *data_segment, size_t data_size,
    libesedb_error_t **error);

And of course, because strings are the main character, UTF-8 and UTF-16 size + value getters:

int
libesedb_long_value_get_utf8_string_size(libesedb_long_value_t *long_value,
    size_t *utf8_string_size, libesedb_error_t **error);

int
libesedb_long_value_get_utf8_string(libesedb_long_value_t *long_value,
    uint8_t *utf8_string, size_t utf8_string_size,
    libesedb_error_t **error);

int
libesedb_long_value_get_utf16_string_size(libesedb_long_value_t *long_value,
    size_t *utf16_string_size, libesedb_error_t **error);

int
libesedb_long_value_get_utf16_string(libesedb_long_value_t *long_value,
    uint16_t *utf16_string, size_t utf16_string_size,
    libesedb_error_t **error);

see the symmetry?? it's so satisfying, I'm obsessed πŸ’–


πŸ¦‹ Multi value functions πŸ¦‹

okay multi values, your turn, no cap. Free one, find out what column type it is, count how many values are inside, and grab the size + raw data of a specific value_entry:

int
libesedb_multi_value_free(libesedb_multi_value_t **multi_value,
    libesedb_error_t **error);

int
libesedb_multi_value_get_column_type(libesedb_multi_value_t *multi_value,
    uint32_t *column_type, libesedb_error_t **error);

int
libesedb_multi_value_get_number_of_values(libesedb_multi_value_t *multi_value,
    int *number_of_values, libesedb_error_t **error);

int
libesedb_multi_value_get_value_data_size(libesedb_multi_value_t *multi_value,
    int value_entry, size_t *value_data_size, libesedb_error_t **error);

int
libesedb_multi_value_get_value_data(libesedb_multi_value_t *multi_value,
    int value_entry, uint8_t *value_data, size_t value_data_size,
    libesedb_error_t **error);

Then the typed getters β€” and bestie, there are SO many. Every width of int, both floats, and filetime, all indexed by multi_value_index:

int
libesedb_multi_value_get_value_8bit(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint8_t *value_8bit,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_16bit(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint16_t *value_16bit,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_32bit(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint32_t *value_32bit,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_64bit(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint64_t *value_64bit,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_floating_point_32bit(libesedb_multi_value_t *multi_value,
    int multi_value_index, float *value_32bit,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_floating_point_64bit(libesedb_multi_value_t *multi_value,
    int multi_value_index, double *value_64bit,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_filetime(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint64_t *value_filetime,
    libesedb_error_t **error);

filetime walked so your timestamps could run πŸ•°οΈβœ¨ (and yes it takes a uint64_t *, note that).

Finally the string + binary crew β€” UTF-8 size/string, UTF-16 size/string, binary data size/data, all with multi_value_index:

int
libesedb_multi_value_get_value_utf8_string_size(libesedb_multi_value_t *multi_value,
    int multi_value_index, size_t *utf8_string_size,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_utf8_string(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint8_t *utf8_string,
    size_t utf8_string_size, libesedb_error_t **error);

int
libesedb_multi_value_get_value_utf16_string_size(libesedb_multi_value_t *multi_value,
    int multi_value_index, size_t *utf16_string_size,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_utf16_string(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint16_t *utf16_string,
    size_t utf16_string_size, libesedb_error_t **error);

int
libesedb_multi_value_get_value_binary_data_size(libesedb_multi_value_t *multi_value,
    int multi_value_index, size_t *binary_data_size,
    libesedb_error_t **error);

int
libesedb_multi_value_get_value_binary_data(libesedb_multi_value_t *multi_value,
    int multi_value_index, uint8_t *binary_data,
    size_t binary_data_size, libesedb_error_t **error);

slay, that's the whole synopsis. no crumbs left πŸ’…


πŸ’œ DESCRIPTION πŸ’œ

okay so there's basically one function living here and it's the vibe-setter:

The libesedb_get_version() function is used to retrieve the library version.

that's it. that's the description. it's short but it's honest 🫢


🫢 RETURN VALUES 🫢

Most of the functions return NULL or -1 on error, dependent on the return type. For the actual return values see "libesedb.h".

fr fr, go read "libesedb.h" β€” the real receipts are in there, don't guess 😭

🌈 ENVIRONMENT 🌈

None

nothing. zero. the environment section is on do-not-disturb. ✨


🌸 FILES 🌸

None


⭐ NOTES ⭐

okay important lore incoming, bestie πŸ“£

libesedb can be compiled with wide character support (wchar_t).

To compile libesedb with wide character support use: ./configure --enable-wide-character-type=yes or define: _UNICODE or UNICODE during compilation.

LIBESEDB_WIDE_CHARACTER_TYPE in libesedb/features.h can be used to determine if libesedb was compiled with wide character support.

so if you're ever like "wait, was this thing built with wide character support??" β€” that macro in libesedb/features.h is your answer. iykyk πŸ’–

πŸ’€ BUGS πŸ’€

Please report bugs of any kind on the project issue tracker:

https://github.com/libyal/libesedb/issues

any kind, bestie. ANY kind. don't be shy, the maintainers want to know πŸ™ˆ

πŸ‘‘ AUTHOR πŸ‘‘

These man pages are generated from "libesedb.h".

iconic β€” the header is the source of truth, the man pages are just the glow-up ✨


Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>.

This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

NO warranty β€” not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. say it with me: no warranty, periodt. πŸ’€

πŸ”₯ SEE ALSO πŸ”₯

  • the libesedb.h include file

one single see-also, and honestly? it's the right one. that header has everything. go look at it. πŸ¦‹


and that's a wrap on libesedb(3), bestie πŸ’– this page is libesedb, stamped April 1, 2019, and it lives in the man section as libesedb(3). go forth, read your values, free your long values and multi values, and remember: if it's NULL or -1, that's the error talking. mwah πŸŽ€βœ¨