From 7bec8b3ecc350da98dd8519ba8face2444a70d0f Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sat, 30 Dec 2023 06:17:32 +0100 Subject: [PATCH] Worked on format support --- ...dows Event manifest binary format.asciidoc | 18 +- include/libfwevt.h.in | 93 ++- libfwevt/fwevt_template.h | 4 +- libfwevt/libfwevt_channel.c | 54 +- libfwevt/libfwevt_template.c | 193 ++++-- libfwevt/libfwevt_template.h | 19 +- libfwevt/libfwevt_template_item.c | 452 +++++++++++--- libfwevt/libfwevt_template_item.h | 40 +- manuals/libfwevt.3 | 24 +- msvscpp/pyfwevt/pyfwevt.vcproj | 16 + pyfwevt/Makefile.am | 2 + pyfwevt/pyfwevt.c | 36 ++ pyfwevt/pyfwevt_template.c | 247 ++++++++ pyfwevt/pyfwevt_template.h | 17 + pyfwevt/pyfwevt_template_item.c | 566 ++++++++++++++++++ pyfwevt/pyfwevt_template_item.h | 84 +++ pyfwevt/pyfwevt_template_items.c | 460 ++++++++++++++ pyfwevt/pyfwevt_template_items.h | 97 +++ 18 files changed, 2251 insertions(+), 171 deletions(-) create mode 100644 pyfwevt/pyfwevt_template_item.c create mode 100644 pyfwevt/pyfwevt_template_item.h create mode 100644 pyfwevt/pyfwevt_template_items.c create mode 100644 pyfwevt/pyfwevt_template_items.h diff --git a/documentation/Windows Event manifest binary format.asciidoc b/documentation/Windows Event manifest binary format.asciidoc index 8d40873..4556460 100644 --- a/documentation/Windows Event manifest binary format.asciidoc +++ b/documentation/Windows Event manifest binary format.asciidoc @@ -305,7 +305,7 @@ The channel definitions are of variable size and consist of: Including the channel definitions header | 8 | 4 | | Number of channel definitions | 12 | ... | | Array of channel definitions -| ... | ... | | Channel data +| ... | ... | | Channel name |=== === Channel definition @@ -334,9 +334,9 @@ or 0xffffffff (-1) if not set | | | Operational |=== -=== Channel data +=== Channel name -The channel data is of variable size and consists of: +The channel name is of variable size and consists of: [cols="1,1,1,5",options="header"] |=== @@ -552,21 +552,21 @@ A template definition is of variable size and consists of: | 0 | 4 | "TEMP" | Signature | 4 | 4 | | Size + Including the template header -| 8 | 4 | | Number of variable descriptors -| 12 | 4 | | Number of variable names +| 8 | 4 | | Number of item descriptors +| 12 | 4 | | Number of item names | 16 | 4 | | Template items offset + The offset is relative to the start of the instrumentation manifest | 20 | 4 | [yellow-background]*1* | [yellow-background]*Unknown (number of BinXML fragments?)* | 24 | 16 | | Identifier + Contains a GUID | 40 | ... | | Binary XML fragment -| ... | ... | | Template variables descriptors -| ... | ... | | Template variables names +| ... | ... | | Template item descriptors +| ... | ... | | Template item names |=== [NOTE] -If the number of variable descriptors (and number of variable names) the -template items offset is either 0 or contains the template size. +If the number of item descriptors (and number of item names) the template items +offset is either 0 or contains the template size. === Template binary XML fragment diff --git a/include/libfwevt.h.in b/include/libfwevt.h.in index e1f0d78..19c0c69 100644 --- a/include/libfwevt.h.in +++ b/include/libfwevt.h.in @@ -260,7 +260,7 @@ int libfwevt_level_free( * ------------------------------------------------------------------------- */ /* Creates a manifest - * Make sure the value channel is referencing, is set to NULL + * Make sure the value manifest is referencing, is set to NULL * Returns 1 if successful or -1 on error */ LIBFWEVT_EXTERN \ @@ -650,17 +650,104 @@ int libfwevt_template_get_size( */ LIBFWEVT_EXTERN \ int libfwevt_template_get_identifier( - libfwevt_template_t *template, + libfwevt_template_t *wevt_template, uint8_t *guid_data, size_t guid_data_size, libfwevt_error_t **error ); +/* Retrieves the number of items + * Returns 1 if successful or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_get_number_of_items( + libfwevt_template_t *wevt_template, + int *number_of_items, + libfwevt_error_t **error ); + +/* Retrieves a specific item + * Returns 1 if successful or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_get_item_by_index( + libfwevt_template_t *wevt_template, + int item_index, + libfwevt_template_item_t **item, + libfwevt_error_t **error ); + +/* ------------------------------------------------------------------------- + * Template item functions + * ------------------------------------------------------------------------- */ + +/* Frees a template item + * Returns 1 if successful or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_free( + libfwevt_template_item_t **template_item, + libfwevt_error_t **error ); + +/* Retrieves the input data type + * Returns 1 if successful or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_input_data_type( + libfwevt_template_item_t *template_item, + uint8_t *input_data_type, + libfwevt_error_t **error ); + +/* Retrieves the output data type + * Returns 1 if successful or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_output_data_type( + libfwevt_template_item_t *template_item, + uint8_t *output_data_type, + libfwevt_error_t **error ); + +/* Retrieves the size of the UTF-8 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf8_name_size( + libfwevt_template_item_t *template_item, + size_t *utf8_string_size, + libfwevt_error_t **error ); + +/* Retrieves the UTF-8 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf8_name( + libfwevt_template_item_t *template_item, + uint8_t *utf8_string, + size_t utf8_string_size, + libfwevt_error_t **error ); + +/* Retrieves the size of the UTF-16 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf16_name_size( + libfwevt_template_item_t *template_item, + size_t *utf16_string_size, + libfwevt_error_t **error ); + +/* Retrieves the UTF-16 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf16_name( + libfwevt_template_item_t *template_item, + uint16_t *utf16_string, + size_t utf16_string_size, + libfwevt_error_t **error ); + /* ------------------------------------------------------------------------- * XML document functions * ------------------------------------------------------------------------- */ /* Creates an XML document - * Make sure the value channel is referencing, is set to NULL + * Make sure the value xml_document is referencing, is set to NULL * Returns 1 if successful or -1 on error */ LIBFWEVT_EXTERN \ diff --git a/libfwevt/fwevt_template.h b/libfwevt/fwevt_template.h index 1ae34c2..d73ce0c 100644 --- a/libfwevt/fwevt_template.h +++ b/libfwevt/fwevt_template.h @@ -137,10 +137,10 @@ struct fwevt_template_channel */ uint8_t identifier[ 4 ]; - /* The data offset + /* The name offset * Consists of 4 bytes */ - uint8_t data_offset[ 4 ]; + uint8_t name_offset[ 4 ]; /* Unknown * Consists of 4 bytes diff --git a/libfwevt/libfwevt_channel.c b/libfwevt/libfwevt_channel.c index f53dbbb..adaf4d5 100644 --- a/libfwevt/libfwevt_channel.c +++ b/libfwevt/libfwevt_channel.c @@ -185,8 +185,8 @@ int libfwevt_channel_read_data( libfwevt_internal_channel_t *internal_channel = NULL; fwevt_template_channel_t *wevt_channel = NULL; static char *function = "libfwevt_channel_read_data"; - uint32_t channel_data_offset = 0; - uint32_t channel_data_size = 0; + uint32_t name_offset = 0; + uint32_t name_size = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint32_t value_32bit = 0; @@ -281,8 +281,8 @@ int libfwevt_channel_read_data( internal_channel->identifier ); byte_stream_copy_to_uint32_little_endian( - wevt_channel->data_offset, - channel_data_offset ); + wevt_channel->name_offset, + name_offset ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) @@ -293,9 +293,9 @@ int libfwevt_channel_read_data( internal_channel->identifier ); libcnotify_printf( - "%s: data offset\t\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: name offset\t\t\t\t\t: 0x%08" PRIx32 "\n", function, - channel_data_offset ); + name_offset ); byte_stream_copy_to_uint32_little_endian( wevt_channel->unknown1, @@ -315,31 +315,31 @@ int libfwevt_channel_read_data( } #endif /* defined( HAVE_DEBUG_OUTPUT ) */ - if( channel_data_offset > 0 ) + if( name_offset > 0 ) { - if( channel_data_offset >= ( data_size - 4 ) ) + if( name_offset >= ( data_size - 4 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid channel data offset value out of bounds.", + "%s: invalid name offset value out of bounds.", function ); goto on_error; } byte_stream_copy_to_uint32_little_endian( - &( data[ channel_data_offset ] ), - channel_data_size ); + &( data[ name_offset ] ), + name_size ); - if( ( data_size < channel_data_size ) - || ( channel_data_offset > ( data_size - channel_data_size ) ) ) + if( ( data_size < name_size ) + || ( name_offset > ( data_size - name_size ) ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid channel data size value out of bounds.", + "%s: invalid name size value out of bounds.", function ); goto on_error; @@ -351,8 +351,8 @@ int libfwevt_channel_read_data( "%s: data:\n", function ); libcnotify_print_data( - &( data[ channel_data_offset ] ), - channel_data_size, + &( data[ name_offset ] ), + name_size, 0 ); } #endif /* defined( HAVE_DEBUG_OUTPUT ) */ @@ -361,19 +361,19 @@ int libfwevt_channel_read_data( if( libcnotify_verbose != 0 ) { libcnotify_printf( - "%s: data size\t\t\t\t\t: %" PRIu32 "\n", + "%s: name size\t\t\t\t\t: %" PRIu32 "\n", function, - channel_data_size ); + name_size ); } #endif /* defined( HAVE_DEBUG_OUTPUT ) */ - if( channel_data_size >= 4 ) + if( name_size >= 4 ) { - channel_data_offset += 4; - channel_data_size -= 4; + name_offset += 4; + name_size -= 4; - if( ( channel_data_size == 0 ) - || ( channel_data_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( uint8_t ) ) ) ) + if( ( name_size == 0 ) + || ( name_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( uint8_t ) ) ) ) { libcerror_error_set( error, @@ -385,7 +385,7 @@ int libfwevt_channel_read_data( goto on_error; } internal_channel->name = (uint8_t *) memory_allocate( - sizeof( uint8_t ) * channel_data_size ); + sizeof( uint8_t ) * name_size ); if( internal_channel->name == NULL ) { @@ -398,12 +398,12 @@ int libfwevt_channel_read_data( goto on_error; } - internal_channel->name_size = channel_data_size; + internal_channel->name_size = (size_t) name_size; if( memory_copy( internal_channel->name, - &( data[ channel_data_offset ] ), - channel_data_size ) == NULL ) + &( data[ name_offset ] ), + (size_t) name_size ) == NULL ) { libcerror_error_set( error, diff --git a/libfwevt/libfwevt_template.c b/libfwevt/libfwevt_template.c index 694a953..bf9b376 100644 --- a/libfwevt/libfwevt_template.c +++ b/libfwevt/libfwevt_template.c @@ -99,6 +99,20 @@ int libfwevt_template_initialize( goto on_error; } + if( libcdata_array_initialize( + &( internal_template->items_array ), + 0, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create items array.", + function ); + + goto on_error; + } if( libcdata_array_initialize( &( internal_template->values_array ), 0, @@ -122,6 +136,13 @@ int libfwevt_template_initialize( on_error: if( internal_template != NULL ) { + if( internal_template->items_array != NULL ) + { + libcdata_array_free( + &( internal_template->items_array ), + (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_item_free, + NULL ); + } memory_free( internal_template ); } @@ -203,6 +224,20 @@ int libfwevt_internal_template_free( memory_free( ( *internal_template )->data ); } + if( libcdata_array_free( + &( ( *internal_template )->items_array ), + (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_item_free, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to free items array.", + function ); + + result = -1; + } if( libcdata_array_free( &( ( *internal_template )->values_array ), (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free, @@ -761,6 +796,7 @@ int libfwevt_template_read_template_items( data, data_size, (size_t) template_items_data_offset, + internal_template->offset, error ) != 1 ) { libcerror_error_set( @@ -775,57 +811,32 @@ int libfwevt_template_read_template_items( } template_items_data_offset += 20; - input_data_type = ( (libfwevt_internal_template_item_t *) template_item )->input_data_type; template_item_name_offset = ( (libfwevt_internal_template_item_t *) template_item )->name_offset; - if( template_item_name_offset < internal_template->offset ) + if( first_template_item_name_offset == 0 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid template item: %d name offset value out of bounds.", - function, - template_value_index ); - - goto on_error; + first_template_item_name_offset = template_item_name_offset; } - template_item_name_offset -= internal_template->offset; + input_data_type = ( (libfwevt_internal_template_item_t *) template_item )->input_data_type; - if( libfwevt_template_item_read_name( - template_item, - data, - data_size, - (size_t) template_item_name_offset, + if( libcdata_array_append_entry( + internal_template->items_array, + &entry_index, + (intptr_t *) template_item, error ) != 1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_IO, - LIBCERROR_IO_ERROR_READ_FAILED, - "%s: unable to read template item: %d name.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to append template item: %d to array.", function, template_value_index ); goto on_error; } - if( first_template_item_name_offset == 0 ) - { - first_template_item_name_offset = template_item_name_offset; - } - if( libfwevt_template_item_free( - &template_item, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free template item.", - function ); + template_item = NULL; - goto on_error; - } if( libfwevt_xml_template_value_initialize( &template_value, error ) != 1 ) @@ -915,28 +926,33 @@ int libfwevt_template_read_template_items( template_value_index++; } - while( template_items_data_offset < first_template_item_name_offset ); + while( ( internal_template->offset + template_items_data_offset ) < first_template_item_name_offset ); return( 1 ); on_error: - if( template_item != NULL ) - { - libfwevt_template_item_free( - &template_item, - NULL ); - } if( template_value != NULL ) { libfwevt_xml_template_value_free( &template_value, NULL ); } + if( template_item != NULL ) + { + libfwevt_template_item_free( + &template_item, + NULL ); + } libcdata_array_empty( internal_template->values_array, (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free, NULL ); + libcdata_array_empty( + internal_template->items_array, + (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_item_free, + NULL ); + return( -1 ); } @@ -1420,7 +1436,7 @@ int libfwevt_template_get_size( * Returns 1 if successful, 0 if value is not available or -1 on error */ int libfwevt_template_get_identifier( - libfwevt_template_t *template, + libfwevt_template_t *wevt_template, uint8_t *guid_data, size_t guid_data_size, libcerror_error_t **error ) @@ -1428,7 +1444,7 @@ int libfwevt_template_get_identifier( libfwevt_internal_template_t *internal_template = NULL; static char *function = "libfwevt_template_get_identifier"; - if( template == NULL ) + if( wevt_template == NULL ) { libcerror_error_set( error, @@ -1439,7 +1455,7 @@ int libfwevt_template_get_identifier( return( -1 ); } - internal_template = (libfwevt_internal_template_t *) template; + internal_template = (libfwevt_internal_template_t *) wevt_template; if( guid_data == NULL ) { @@ -1481,3 +1497,88 @@ int libfwevt_template_get_identifier( return( 1 ); } +/* Retrieves the number of items + * Returns 1 if successful or -1 on error + */ +int libfwevt_template_get_number_of_items( + libfwevt_template_t *wevt_template, + int *number_of_items, + libcerror_error_t **error ) +{ + libfwevt_internal_template_t *internal_template = NULL; + static char *function = "libfwevt_template_get_number_of_items"; + + if( wevt_template == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template.", + function ); + + return( -1 ); + } + internal_template = (libfwevt_internal_template_t *) wevt_template; + + if( libcdata_array_get_number_of_entries( + internal_template->items_array, + number_of_items, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Retrieves a specific item + * Returns 1 if successful or -1 on error + */ +int libfwevt_template_get_item_by_index( + libfwevt_template_t *wevt_template, + int item_index, + libfwevt_template_item_t **item, + libcerror_error_t **error ) +{ + libfwevt_internal_template_t *internal_template = NULL; + static char *function = "libfwevt_template_get_item_by_index"; + + if( wevt_template == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template.", + function ); + + return( -1 ); + } + internal_template = (libfwevt_internal_template_t *) wevt_template; + + if( libcdata_array_get_entry_by_index( + internal_template->items_array, + item_index, + (intptr_t **) item, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve entry: %d.", + function, + item_index ); + + return( -1 ); + } + return( 1 ); +} + diff --git a/libfwevt/libfwevt_template.h b/libfwevt/libfwevt_template.h index 7c1f6cd..5e20726 100644 --- a/libfwevt/libfwevt_template.h +++ b/libfwevt/libfwevt_template.h @@ -71,6 +71,10 @@ struct libfwevt_internal_template */ uint8_t identifier[ 16 ]; + /* The items array + */ + libcdata_array_t *items_array; + /* The values array */ libcdata_array_t *values_array; @@ -164,11 +168,24 @@ int libfwevt_template_get_size( LIBFWEVT_EXTERN \ int libfwevt_template_get_identifier( - libfwevt_template_t *template, + libfwevt_template_t *wevt_template, uint8_t *guid_data, size_t guid_data_size, libcerror_error_t **error ); +LIBFWEVT_EXTERN \ +int libfwevt_template_get_number_of_items( + libfwevt_template_t *wevt_template, + int *number_of_items, + libcerror_error_t **error ); + +LIBFWEVT_EXTERN \ +int libfwevt_template_get_item_by_index( + libfwevt_template_t *wevt_template, + int item_index, + libfwevt_template_item_t **item, + libcerror_error_t **error ); + #if defined( __cplusplus ) } #endif diff --git a/libfwevt/libfwevt_template_item.c b/libfwevt/libfwevt_template_item.c index ba44e1d..7dbdbf2 100644 --- a/libfwevt/libfwevt_template_item.c +++ b/libfwevt/libfwevt_template_item.c @@ -157,6 +157,11 @@ int libfwevt_internal_template_item_free( } if( *internal_template_item != NULL ) { + if( ( *internal_template_item )->name != NULL ) + { + memory_free( + ( *internal_template_item )->name ); + } memory_free( *internal_template_item ); @@ -173,10 +178,13 @@ int libfwevt_template_item_read_data( const uint8_t *data, size_t data_size, size_t data_offset, + size_t template_data_offset, libcerror_error_t **error ) { libfwevt_internal_template_item_t *internal_template_item = NULL; static char *function = "libfwevt_template_item_read_data"; + uint32_t name_offset = 0; + uint32_t name_size = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint32_t value_32bit = 0; @@ -196,6 +204,17 @@ int libfwevt_template_item_read_data( } internal_template_item = (libfwevt_internal_template_item_t *) template_item; + if( internal_template_item->name != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid template item - name value already set.", + function ); + + return( -1 ); + } if( data == NULL ) { libcerror_error_set( @@ -260,7 +279,7 @@ int libfwevt_template_item_read_data( byte_stream_copy_to_uint32_little_endian( &( data[ data_offset + 16 ] ), - internal_template_item->name_offset ); + name_offset ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) @@ -318,26 +337,180 @@ int libfwevt_template_item_read_data( libcnotify_printf( "%s: name offset\t\t\t\t: 0x%08" PRIx32 "\n", function, - internal_template_item->name_offset ); + name_offset ); } #endif /* defined( HAVE_DEBUG_OUTPUT ) */ + internal_template_item->name_offset = name_offset; + + if( name_offset > 0 ) + { + if( name_offset < template_data_offset ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid name offset value out of bounds.", + function ); + + goto on_error; + } + name_offset -= template_data_offset; + + if( name_offset >= ( data_size - 4 ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid name offset value out of bounds.", + function ); + + goto on_error; + } + byte_stream_copy_to_uint32_little_endian( + &( data[ name_offset ] ), + name_size ); + + if( ( data_size < name_size ) + || ( name_offset > ( data_size - name_size ) ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid name size value out of bounds.", + function ); + + goto on_error; + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: data:\n", + function ); + libcnotify_print_data( + &( data[ name_offset ] ), + name_size, + 0 ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: name size\t\t\t\t: %" PRIu32 "\n", + function, + name_size ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + + if( name_size >= 4 ) + { + name_offset += 4; + name_size -= 4; + + if( ( name_size == 0 ) + || ( name_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( uint8_t ) ) ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid name size value out of bounds.", + function ); + + goto on_error; + } + internal_template_item->name = (uint8_t *) memory_allocate( + sizeof( uint8_t ) * name_size ); + + if( internal_template_item->name == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create name.", + function ); + + goto on_error; + } + internal_template_item->name_size = (size_t) name_size; + + if( memory_copy( + internal_template_item->name, + &( data[ name_offset ] ), + (size_t) name_size ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy name.", + function ); + + goto on_error; + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + if( libfwevt_debug_print_utf16_string_value( + function, + "name\t\t\t\t\t", + internal_template_item->name, + internal_template_item->name_size, + LIBUNA_ENDIAN_LITTLE, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, + "%s: unable to print UTF-16 string value.", + function ); + + goto on_error; + } + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + } + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "\n" ); + } +#endif return( 1 ); + +on_error: + if( internal_template_item->name != NULL ) + { + memory_free( + internal_template_item->name ); + + internal_template_item->name = NULL; + } + internal_template_item->name_size = 0; + + return( -1 ); } -/* Reads the template item +/* Retrieves the input data type * Returns 1 if successful or -1 on error */ -int libfwevt_template_item_read_name( +int libfwevt_template_item_get_input_data_type( libfwevt_template_item_t *template_item, - const uint8_t *data, - size_t data_size, - size_t data_offset, + uint8_t *input_data_type, libcerror_error_t **error ) { libfwevt_internal_template_item_t *internal_template_item = NULL; - static char *function = "libfwevt_template_item_read_name"; - uint16_t name_size = 0; + static char *function = "libfwevt_template_item_get_input_data_type"; if( template_item == NULL ) { @@ -352,130 +525,255 @@ int libfwevt_template_item_read_name( } internal_template_item = (libfwevt_internal_template_item_t *) template_item; - if( data == NULL ) + if( input_data_type == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid data.", + "%s: invalid input data type.", function ); return( -1 ); } - if( data_size > (size_t) SSIZE_MAX ) + *input_data_type = internal_template_item->input_data_type; + + return( 1 ); +} + +/* Retrieves the output data type + * Returns 1 if successful or -1 on error + */ +int libfwevt_template_item_get_output_data_type( + libfwevt_template_item_t *template_item, + uint8_t *output_data_type, + libcerror_error_t **error ) +{ + libfwevt_internal_template_item_t *internal_template_item = NULL; + static char *function = "libfwevt_template_item_get_output_data_type"; + + if( template_item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid data size value exceeds maximum.", + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template item.", function ); return( -1 ); } - if( data_offset >= data_size ) + internal_template_item = (libfwevt_internal_template_item_t *) template_item; + + if( output_data_type == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid data offset value out of bounds.", + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid output data type.", function ); return( -1 ); } - if( ( data_size < 4 ) - || ( data_offset > ( data_size - 4 ) ) ) + *output_data_type = internal_template_item->output_data_type; + + return( 1 ); +} + +/* Retrieves the size of the UTF-8 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +int libfwevt_template_item_get_utf8_name_size( + libfwevt_template_item_t *template_item, + size_t *utf8_string_size, + libcerror_error_t **error ) +{ + libfwevt_internal_template_item_t *internal_template_item = NULL; + static char *function = "libfwevt_template_item_get_utf8_name_size"; + + if( template_item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid data value too small.", + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template item.", function ); return( -1 ); } -#if defined( HAVE_DEBUG_OUTPUT ) - if( libcnotify_verbose != 0 ) + internal_template_item = (libfwevt_internal_template_item_t *) template_item; + + if( ( internal_template_item->name == NULL ) + || ( internal_template_item->name_size == 0 ) ) { - libcnotify_printf( - "%s: template item name data:\n", + return( 0 ); + } + if( libuna_utf8_string_size_from_utf16_stream( + internal_template_item->name, + internal_template_item->name_size, + LIBUNA_ENDIAN_LITTLE, + utf8_string_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve UTF-8 string size.", function ); - libcnotify_print_data( - &( data[ data_offset ] ), - 20, - 0 ); + + return( -1 ); } -#endif - byte_stream_copy_to_uint32_little_endian( - &( data[ data_offset ] ), - name_size ); + return( 1 ); +} + +/* Retrieves the UTF-8 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +int libfwevt_template_item_get_utf8_name( + libfwevt_template_item_t *template_item, + uint8_t *utf8_string, + size_t utf8_string_size, + libcerror_error_t **error ) +{ + libfwevt_internal_template_item_t *internal_template_item = NULL; + static char *function = "libfwevt_template_item_get_utf8_name"; - if( name_size > ( data_size - data_offset ) ) + if( template_item == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid template - data too small.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template item.", function ); - goto on_error; + return( -1 ); } -#if defined( HAVE_DEBUG_OUTPUT ) - if( libcnotify_verbose != 0 ) + internal_template_item = (libfwevt_internal_template_item_t *) template_item; + + if( ( internal_template_item->name == NULL ) + || ( internal_template_item->name_size == 0 ) ) { - libcnotify_printf( - "%s: name data:\n", + return( 0 ); + } + if( libuna_utf8_string_copy_from_utf16_stream( + utf8_string, + utf8_string_size, + internal_template_item->name, + internal_template_item->name_size, + LIBUNA_ENDIAN_LITTLE, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve UTF-8 string.", function ); - libcnotify_print_data( - &( data[ data_offset ] ), - name_size, - 0 ); + + return( -1 ); } -#endif - if( name_size > 0 ) + return( 1 ); +} + +/* Retrieves the size of the UTF-16 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +int libfwevt_template_item_get_utf16_name_size( + libfwevt_template_item_t *template_item, + size_t *utf16_string_size, + libcerror_error_t **error ) +{ + libfwevt_internal_template_item_t *internal_template_item = NULL; + static char *function = "libfwevt_template_item_get_utf16_name_size"; + + if( template_item == NULL ) { - if( name_size < 4 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid name size value out of bounds.", - function ); + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template item.", + function ); - goto on_error; - } - name_size -= 4; + return( -1 ); } - data_offset += 4; + internal_template_item = (libfwevt_internal_template_item_t *) template_item; -#if defined( HAVE_DEBUG_OUTPUT ) - if( libcnotify_verbose != 0 ) + if( ( internal_template_item->name == NULL ) + || ( internal_template_item->name_size == 0 ) ) { - libcnotify_printf( - "%s: name size\t\t\t\t: %" PRIu32 "\n", - function, - name_size ); + return( 0 ); + } + if( libuna_utf16_string_size_from_utf16_stream( + internal_template_item->name, + internal_template_item->name_size, + LIBUNA_ENDIAN_LITTLE, + utf16_string_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve UTF-16 string size.", + function ); - libcnotify_printf( - "%s: name data:\n", + return( -1 ); + } + return( 1 ); +} + +/* Retrieves the UTF-16 formatted name + * Returns 1 if successful, 0 if not available or -1 on error + */ +int libfwevt_template_item_get_utf16_name( + libfwevt_template_item_t *template_item, + uint16_t *utf16_string, + size_t utf16_string_size, + libcerror_error_t **error ) +{ + libfwevt_internal_template_item_t *internal_template_item = NULL; + static char *function = "libfwevt_template_item_get_utf16_name"; + + if( template_item == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid template item.", function ); - libcnotify_print_data( - &( data[ data_offset ] ), - name_size, - 0 ); + + return( -1 ); } -#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + internal_template_item = (libfwevt_internal_template_item_t *) template_item; - internal_template_item->name_size = name_size; + if( ( internal_template_item->name == NULL ) + || ( internal_template_item->name_size == 0 ) ) + { + return( 0 ); + } + if( libuna_utf16_string_copy_from_utf16_stream( + utf16_string, + utf16_string_size, + internal_template_item->name, + internal_template_item->name_size, + LIBUNA_ENDIAN_LITTLE, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve UTF-8 string.", + function ); + return( -1 ); + } return( 1 ); - -on_error: - return( -1 ); } diff --git a/libfwevt/libfwevt_template_item.h b/libfwevt/libfwevt_template_item.h index 46651f5..47098c5 100644 --- a/libfwevt/libfwevt_template_item.h +++ b/libfwevt/libfwevt_template_item.h @@ -76,13 +76,45 @@ int libfwevt_template_item_read_data( const uint8_t *data, size_t data_size, size_t data_offset, + size_t template_data_offset, libcerror_error_t **error ); -int libfwevt_template_item_read_name( +LIBFWEVT_EXTERN \ +int libfwevt_tempalte_item_get_input_data_type( libfwevt_template_item_t *template_item, - const uint8_t *data, - size_t data_size, - size_t data_offset, + uint8_t *input_data_type, + libcerror_error_t **error ); + +LIBFWEVT_EXTERN \ +int libfwevt_tempalte_item_get_output_data_type( + libfwevt_template_item_t *template_item, + uint8_t *output_data_type, + libcerror_error_t **error ); + +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf8_name_size( + libfwevt_template_item_t *template_item, + size_t *utf8_string_size, + libcerror_error_t **error ); + +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf8_name( + libfwevt_template_item_t *template_item, + uint8_t *utf8_string, + size_t utf8_string_size, + libcerror_error_t **error ); + +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf16_name_size( + libfwevt_template_item_t *template_item, + size_t *utf16_string_size, + libcerror_error_t **error ); + +LIBFWEVT_EXTERN \ +int libfwevt_template_item_get_utf16_name( + libfwevt_template_item_t *template_item, + uint16_t *utf16_string, + size_t utf16_string_size, libcerror_error_t **error ); #if defined( __cplusplus ) diff --git a/manuals/libfwevt.3 b/manuals/libfwevt.3 index 936f063..ad95d95 100644 --- a/manuals/libfwevt.3 +++ b/manuals/libfwevt.3 @@ -1,4 +1,4 @@ -.Dd December 29, 2023 +.Dd December 30, 2023 .Dt libfwevt 3 .Os libfwevt .Sh NAME @@ -157,7 +157,27 @@ Template functions .Ft int .Fn libfwevt_template_get_size "libfwevt_template_t *wevt_template" "uint32_t *size" "libfwevt_error_t **error" .Ft int -.Fn libfwevt_template_get_identifier "libfwevt_template_t *template" "uint8_t *guid_data" "size_t guid_data_size" "libfwevt_error_t **error" +.Fn libfwevt_template_get_identifier "libfwevt_template_t *wevt_template" "uint8_t *guid_data" "size_t guid_data_size" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_get_number_of_items "libfwevt_template_t *wevt_template" "int *number_of_items" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_get_item_by_index "libfwevt_template_t *wevt_template" "int item_index" "libfwevt_template_item_t **item" "libfwevt_error_t **error" +.Pp +Template item functions +.Ft int +.Fn libfwevt_template_item_free "libfwevt_template_item_t **template_item" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_item_get_input_data_type "libfwevt_template_item_t *template_item" "uint8_t *input_data_type" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_item_get_output_data_type "libfwevt_template_item_t *template_item" "uint8_t *output_data_type" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_item_get_utf8_name_size "libfwevt_template_item_t *template_item" "size_t *utf8_string_size" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_item_get_utf8_name "libfwevt_template_item_t *template_item" "uint8_t *utf8_string" "size_t utf8_string_size" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_item_get_utf16_name_size "libfwevt_template_item_t *template_item" "size_t *utf16_string_size" "libfwevt_error_t **error" +.Ft int +.Fn libfwevt_template_item_get_utf16_name "libfwevt_template_item_t *template_item" "uint16_t *utf16_string" "size_t utf16_string_size" "libfwevt_error_t **error" .Pp XML document functions .Ft int diff --git a/msvscpp/pyfwevt/pyfwevt.vcproj b/msvscpp/pyfwevt/pyfwevt.vcproj index 4f836c3..516c1fc 100644 --- a/msvscpp/pyfwevt/pyfwevt.vcproj +++ b/msvscpp/pyfwevt/pyfwevt.vcproj @@ -257,6 +257,14 @@ RelativePath="..\..\pyfwevt\pyfwevt_template.c" > + + + + @@ -371,6 +379,14 @@ RelativePath="..\..\pyfwevt\pyfwevt_template.h" > + + + + diff --git a/pyfwevt/Makefile.am b/pyfwevt/Makefile.am index 9f683dd..7c3bda7 100644 --- a/pyfwevt/Makefile.am +++ b/pyfwevt/Makefile.am @@ -36,6 +36,8 @@ pyfwevt_la_SOURCES = \ pyfwevt_task.c pyfwevt_task.h \ pyfwevt_tasks.c pyfwevt_tasks.h \ pyfwevt_template.c pyfwevt_template.h \ + pyfwevt_template_item.c pyfwevt_template_item.h \ + pyfwevt_template_items.c pyfwevt_template_items.h \ pyfwevt_templates.c pyfwevt_templates.h \ pyfwevt_unused.h diff --git a/pyfwevt/pyfwevt.c b/pyfwevt/pyfwevt.c index c101aad..1fb17ba 100644 --- a/pyfwevt/pyfwevt.c +++ b/pyfwevt/pyfwevt.c @@ -50,6 +50,8 @@ #include "pyfwevt_task.h" #include "pyfwevt_tasks.h" #include "pyfwevt_template.h" +#include "pyfwevt_template_item.h" +#include "pyfwevt_template_items.h" #include "pyfwevt_templates.h" #include "pyfwevt_unused.h" @@ -479,6 +481,40 @@ PyMODINIT_FUNC initpyfwevt( "template", (PyObject *) &pyfwevt_template_type_object ); + /* Setup the template item type object + */ + pyfwevt_template_item_type_object.tp_new = PyType_GenericNew; + + if( PyType_Ready( + &pyfwevt_template_item_type_object ) < 0 ) + { + goto on_error; + } + Py_IncRef( + (PyObject *) &pyfwevt_template_item_type_object ); + + PyModule_AddObject( + module, + "template_item", + (PyObject *) &pyfwevt_template_item_type_object ); + + /* Setup the template items type object + */ + pyfwevt_template_items_type_object.tp_new = PyType_GenericNew; + + if( PyType_Ready( + &pyfwevt_template_items_type_object ) < 0 ) + { + goto on_error; + } + Py_IncRef( + (PyObject *) &pyfwevt_template_items_type_object ); + + PyModule_AddObject( + module, + "template_items", + (PyObject *) &pyfwevt_template_items_type_object ); + /* Setup the templates type object */ pyfwevt_templates_type_object.tp_new = PyType_GenericNew; diff --git a/pyfwevt/pyfwevt_template.c b/pyfwevt/pyfwevt_template.c index 5084821..944f6e4 100644 --- a/pyfwevt/pyfwevt_template.c +++ b/pyfwevt/pyfwevt_template.c @@ -32,6 +32,8 @@ #include "pyfwevt_libfwevt.h" #include "pyfwevt_python.h" #include "pyfwevt_template.h" +#include "pyfwevt_template_item.h" +#include "pyfwevt_template_items.h" #include "pyfwevt_unused.h" PyMethodDef pyfwevt_template_object_methods[] = { @@ -43,6 +45,20 @@ PyMethodDef pyfwevt_template_object_methods[] = { "\n" "Retrieves the identifier." }, + { "get_number_of_items", + (PyCFunction) pyfwevt_template_get_number_of_items, + METH_NOARGS, + "get_number_of_items() -> Integer\n" + "\n" + "Retrieves the number of items." }, + + { "get_item", + (PyCFunction) pyfwevt_template_get_item, + METH_VARARGS | METH_KEYWORDS, + "get_item(item_index) -> Object\n" + "\n" + "Retrieves the item specified by the index." }, + /* Sentinel */ { NULL, NULL, 0, NULL } }; @@ -55,6 +71,18 @@ PyGetSetDef pyfwevt_template_object_get_set_definitions[] = { "The identifier.", NULL }, + { "number_of_items", + (getter) pyfwevt_template_get_number_of_items, + (setter) 0, + "The number of items.", + NULL }, + + { "items", + (getter) pyfwevt_template_get_items, + (setter) 0, + "The items.", + NULL }, + /* Sentinel */ { NULL, NULL, NULL, NULL, NULL } }; @@ -378,3 +406,222 @@ PyObject *pyfwevt_template_get_identifier( return( string_object ); } +/* Retrieves the number of items + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_get_number_of_items( + pyfwevt_template_t *pyfwevt_template, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfwevt_template_get_number_of_items"; + int number_of_items = 0; + int result = 0; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + + if( pyfwevt_template == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_get_number_of_items( + pyfwevt_template->template, + &number_of_items, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve number of items.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } +#if PY_MAJOR_VERSION >= 3 + integer_object = PyLong_FromLong( + (long) number_of_items ); +#else + integer_object = PyInt_FromLong( + (long) number_of_items ); +#endif + return( integer_object ); +} + +/* Retrieves a specific item by index + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_get_item_by_index( + PyObject *pyfwevt_template, + int item_index ) +{ + PyObject *item_object = NULL; + libcerror_error_t *error = NULL; + libfwevt_template_item_t *item = NULL; + static char *function = "pyfwevt_template_get_item_by_index"; + int result = 0; + + if( pyfwevt_template == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_get_item_by_index( + ( (pyfwevt_template_t *) pyfwevt_template )->template, + item_index, + &item, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve item: %d.", + function, + item_index ); + + libcerror_error_free( + &error ); + + goto on_error; + } + item_object = pyfwevt_template_item_new( + item, + pyfwevt_template ); + + if( item_object == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create item object.", + function ); + + goto on_error; + } + return( item_object ); + +on_error: + if( item != NULL ) + { + libfwevt_template_item_free( + &item, + NULL ); + } + return( NULL ); +} + +/* Retrieves a specific item + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_get_item( + PyObject *pyfwevt_template, + PyObject *arguments, + PyObject *keywords ) +{ + PyObject *item_object = NULL; + static char *keyword_list[] = { "item_index", NULL }; + int item_index = 0; + + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "i", + keyword_list, + &item_index ) == 0 ) + { + return( NULL ); + } + item_object = pyfwevt_template_get_item_by_index( + pyfwevt_template, + item_index ); + + return( item_object ); +} + +/* Retrieves a sequence and iterator object for the items + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_get_items( + pyfwevt_template_t *pyfwevt_template, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED ) +{ + PyObject *sequence_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfwevt_template_get_items"; + int number_of_items = 0; + int result = 0; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + + if( pyfwevt_template == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_get_number_of_items( + pyfwevt_template->template, + &number_of_items, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve number of items.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + sequence_object = pyfwevt_template_items_new( + (PyObject *) pyfwevt_template, + &pyfwevt_template_get_item_by_index, + number_of_items ); + + if( sequence_object == NULL ) + { + pyfwevt_error_raise( + error, + PyExc_MemoryError, + "%s: unable to create sequence object.", + function ); + + return( NULL ); + } + return( sequence_object ); +} + diff --git a/pyfwevt/pyfwevt_template.h b/pyfwevt/pyfwevt_template.h index fa20ab2..4034c1d 100644 --- a/pyfwevt/pyfwevt_template.h +++ b/pyfwevt/pyfwevt_template.h @@ -68,6 +68,23 @@ PyObject *pyfwevt_template_get_identifier( pyfwevt_template_t *pyfwevt_template, PyObject *arguments ); +PyObject *pyfwevt_template_get_number_of_items( + pyfwevt_template_t *pyfwevt_template, + PyObject *arguments ); + +PyObject *pyfwevt_template_get_item_by_index( + PyObject *pyfwevt_template, + int item_index ); + +PyObject *pyfwevt_template_get_item( + PyObject *pyfwevt_template, + PyObject *arguments, + PyObject *keywords ); + +PyObject *pyfwevt_template_get_items( + pyfwevt_template_t *pyfwevt_template, + PyObject *arguments ); + #if defined( __cplusplus ) } #endif diff --git a/pyfwevt/pyfwevt_template_item.c b/pyfwevt/pyfwevt_template_item.c new file mode 100644 index 0000000..8482958 --- /dev/null +++ b/pyfwevt/pyfwevt_template_item.c @@ -0,0 +1,566 @@ +/* + * Python object wrapper of libfwevt_template_item_t + * + * Copyright (C) 2011-2023, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI ) +#include +#endif + +#include "pyfwevt_template_item.h" +#include "pyfwevt_error.h" +#include "pyfwevt_libcerror.h" +#include "pyfwevt_libfwevt.h" +#include "pyfwevt_python.h" +#include "pyfwevt_unused.h" + +PyMethodDef pyfwevt_template_item_object_methods[] = { + + { "get_input_data_type", + (PyCFunction) pyfwevt_template_item_get_input_data_type, + METH_NOARGS, + "get_input_data_type() -> Integer\n" + "\n" + "Retrieves the input data type." }, + + { "get_output_data_type", + (PyCFunction) pyfwevt_template_item_get_output_data_type, + METH_NOARGS, + "get_output_data_type() -> Integer\n" + "\n" + "Retrieves the output data type." }, + + { "get_name", + (PyCFunction) pyfwevt_template_item_get_name, + METH_NOARGS, + "get_name() -> Unicode string or None\n" + "\n" + "Retrieves the name." }, + + /* Sentinel */ + { NULL, NULL, 0, NULL } +}; + +PyGetSetDef pyfwevt_template_item_object_get_set_definitions[] = { + + { "input_data_type", + (getter) pyfwevt_template_item_get_input_data_type, + (setter) 0, + "The input data type.", + NULL }, + + { "output_data_type", + (getter) pyfwevt_template_item_get_output_data_type, + (setter) 0, + "The output data type.", + NULL }, + + { "name", + (getter) pyfwevt_template_item_get_name, + (setter) 0, + "The name.", + NULL }, + + /* Sentinel */ + { NULL, NULL, NULL, NULL, NULL } +}; + +PyTypeObject pyfwevt_template_item_type_object = { + PyVarObject_HEAD_INIT( NULL, 0 ) + + /* tp_name */ + "pyfwevt.template_item", + /* tp_basicsize */ + sizeof( pyfwevt_template_item_t ), + /* tp_itemsize */ + 0, + /* tp_dealloc */ + (destructor) pyfwevt_template_item_free, + /* tp_print */ + 0, + /* tp_getattr */ + 0, + /* tp_setattr */ + 0, + /* tp_compare */ + 0, + /* tp_repr */ + 0, + /* tp_as_number */ + 0, + /* tp_as_sequence */ + 0, + /* tp_as_mapping */ + 0, + /* tp_hash */ + 0, + /* tp_call */ + 0, + /* tp_str */ + 0, + /* tp_getattro */ + 0, + /* tp_setattro */ + 0, + /* tp_as_buffer */ + 0, + /* tp_flags */ + Py_TPFLAGS_DEFAULT, + /* tp_doc */ + "pyfwevt template_item object (wraps libfwevt_template_item_t)", + /* tp_traverse */ + 0, + /* tp_clear */ + 0, + /* tp_richcompare */ + 0, + /* tp_weaklistoffset */ + 0, + /* tp_iter */ + 0, + /* tp_iternext */ + 0, + /* tp_methods */ + pyfwevt_template_item_object_methods, + /* tp_members */ + 0, + /* tp_getset */ + pyfwevt_template_item_object_get_set_definitions, + /* tp_base */ + 0, + /* tp_dict */ + 0, + /* tp_descr_get */ + 0, + /* tp_descr_set */ + 0, + /* tp_dictoffset */ + 0, + /* tp_init */ + (initproc) pyfwevt_template_item_init, + /* tp_alloc */ + 0, + /* tp_new */ + 0, + /* tp_free */ + 0, + /* tp_is_gc */ + 0, + /* tp_bases */ + NULL, + /* tp_mro */ + NULL, + /* tp_cache */ + NULL, + /* tp_subclasses */ + NULL, + /* tp_weaklist */ + NULL, + /* tp_del */ + 0, + /* tp_version_tag */ + 0 +}; + +/* Creates a new template_item object + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_item_new( + libfwevt_template_item_t *template_item, + PyObject *parent_object ) +{ + pyfwevt_template_item_t *pyfwevt_template_item = NULL; + static char *function = "pyfwevt_template_item_new"; + + if( template_item == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template item.", + function ); + + return( NULL ); + } + /* PyObject_New does not invoke tp_init + */ + pyfwevt_template_item = PyObject_New( + struct pyfwevt_template_item, + &pyfwevt_template_item_type_object ); + + if( pyfwevt_template_item == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to initialize template item.", + function ); + + goto on_error; + } + pyfwevt_template_item->template_item = template_item; + pyfwevt_template_item->parent_object = parent_object; + + if( pyfwevt_template_item->parent_object != NULL ) + { + Py_IncRef( + pyfwevt_template_item->parent_object ); + } + return( (PyObject *) pyfwevt_template_item ); + +on_error: + if( pyfwevt_template_item != NULL ) + { + Py_DecRef( + (PyObject *) pyfwevt_template_item ); + } + return( NULL ); +} + +/* Initializes a template_item object + * Returns 0 if successful or -1 on error + */ +int pyfwevt_template_item_init( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED, + PyObject *keywords PYFWEVT_ATTRIBUTE_UNUSED ) +{ + static char *function = "pyfwevt_template_item_init"; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + PYFWEVT_UNREFERENCED_PARAMETER( keywords ) + + if( pyfwevt_template_item == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template item.", + function ); + + return( -1 ); + } + /* Make sure libfwevt template_item is set to NULL + */ + pyfwevt_template_item->template_item = NULL; + + PyErr_Format( + PyExc_NotImplementedError, + "%s: initialize of template_item not supported.", + function ); + + return( -1 ); +} + +/* Frees a template_item object + */ +void pyfwevt_template_item_free( + pyfwevt_template_item_t *pyfwevt_template_item ) +{ + struct _typeobject *ob_type = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfwevt_template_item_free"; + int result = 0; + + if( pyfwevt_template_item == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template item.", + function ); + + return; + } + ob_type = Py_TYPE( + pyfwevt_template_item ); + + if( ob_type == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: missing ob_type.", + function ); + + return; + } + if( ob_type->tp_free == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid ob_type - missing tp_free.", + function ); + + return; + } + if( pyfwevt_template_item->template_item != NULL ) + { + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_item_free( + &( pyfwevt_template_item->template_item ), + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_MemoryError, + "%s: unable to free libfwevt template item.", + function ); + + libcerror_error_free( + &error ); + } + } + if( pyfwevt_template_item->parent_object != NULL ) + { + Py_DecRef( + pyfwevt_template_item->parent_object ); + } + ob_type->tp_free( + (PyObject*) pyfwevt_template_item ); +} + +/* Retrieves the input data type + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_item_get_input_data_type( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfwevt_template_item_get_input_data_type"; + uint8_t value_8bit = 0; + int result = 0; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + + if( pyfwevt_template_item == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template item.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_item_get_input_data_type( + pyfwevt_template_item->template_item, + &value_8bit, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve input data type.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + integer_object = PyLong_FromUnsignedLong( + (unsigned long) value_8bit ); + + return( integer_object ); +} + +/* Retrieves the output data type + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_item_get_output_data_type( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfwevt_template_item_get_output_data_type"; + uint8_t value_8bit = 0; + int result = 0; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + + if( pyfwevt_template_item == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template item.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_item_get_output_data_type( + pyfwevt_template_item->template_item, + &value_8bit, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve output data type.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + integer_object = PyLong_FromUnsignedLong( + (unsigned long) value_8bit ); + + return( integer_object ); +} + +/* Retrieves the name + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_item_get_name( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED ) +{ + PyObject *string_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfwevt_template_item_get_name"; + char *utf8_string = NULL; + size_t utf8_string_size = 0; + int result = 0; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + + if( pyfwevt_template_item == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid template item.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_item_get_utf8_name_size( + pyfwevt_template_item->template_item, + &utf8_string_size, + &error ); + + Py_END_ALLOW_THREADS + + if( result == -1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to determine size of name as UTF-8 string.", + function ); + + libcerror_error_free( + &error ); + + goto on_error; + } + else if( ( result == 0 ) + || ( utf8_string_size == 0 ) ) + { + Py_IncRef( + Py_None ); + + return( Py_None ); + } + utf8_string = (char *) PyMem_Malloc( + sizeof( char ) * utf8_string_size ); + + if( utf8_string == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create UTF-8 string.", + function ); + + goto on_error; + } + Py_BEGIN_ALLOW_THREADS + + result = libfwevt_template_item_get_utf8_name( + pyfwevt_template_item->template_item, + (uint8_t *) utf8_string, + utf8_string_size, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfwevt_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve name as UTF-8 string.", + function ); + + libcerror_error_free( + &error ); + + goto on_error; + } + /* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes + * the end of string character is part of the string + */ + string_object = PyUnicode_DecodeUTF8( + utf8_string, + (Py_ssize_t) utf8_string_size - 1, + NULL ); + + if( string_object == NULL ) + { + PyErr_Format( + PyExc_IOError, + "%s: unable to convert UTF-8 string into Unicode object.", + function ); + + goto on_error; + } + PyMem_Free( + utf8_string ); + + return( string_object ); + +on_error: + if( utf8_string != NULL ) + { + PyMem_Free( + utf8_string ); + } + return( NULL ); +} + diff --git a/pyfwevt/pyfwevt_template_item.h b/pyfwevt/pyfwevt_template_item.h new file mode 100644 index 0000000..ed49fee --- /dev/null +++ b/pyfwevt/pyfwevt_template_item.h @@ -0,0 +1,84 @@ +/* + * Python object wrapper of libfwevt_template_item_t + * + * Copyright (C) 2011-2023, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#if !defined( _PYFWEVT_TEMPLATE_ITEM_H ) +#define _PYFWEVT_TEMPLATE_ITEM_H + +#include +#include + +#include "pyfwevt_libfwevt.h" +#include "pyfwevt_python.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct pyfwevt_template_item pyfwevt_template_item_t; + +struct pyfwevt_template_item +{ + /* Python object initialization + */ + PyObject_HEAD + + /* The libfwevt template_item + */ + libfwevt_template_item_t *template_item; + + /* The parent object + */ + PyObject *parent_object; +}; + +extern PyMethodDef pyfwevt_template_item_object_methods[]; +extern PyTypeObject pyfwevt_template_item_type_object; + +PyObject *pyfwevt_template_item_new( + libfwevt_template_item_t *template_item, + PyObject *parent_object ); + +int pyfwevt_template_item_init( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments, + PyObject *keywords ); + +void pyfwevt_template_item_free( + pyfwevt_template_item_t *pyfwevt_template_item ); + +PyObject *pyfwevt_template_item_get_input_data_type( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments ); + +PyObject *pyfwevt_template_item_get_output_data_type( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments ); + +PyObject *pyfwevt_template_item_get_name( + pyfwevt_template_item_t *pyfwevt_template_item, + PyObject *arguments ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _PYFWEVT_TEMPLATE_ITEM_H ) */ + diff --git a/pyfwevt/pyfwevt_template_items.c b/pyfwevt/pyfwevt_template_items.c new file mode 100644 index 0000000..c90aecb --- /dev/null +++ b/pyfwevt/pyfwevt_template_items.c @@ -0,0 +1,460 @@ +/* + * Python object definition of the sequence and iterator object of template_items + * + * Copyright (C) 2011-2023, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI ) +#include +#endif + +#include "pyfwevt_template_item.h" +#include "pyfwevt_template_items.h" +#include "pyfwevt_libcerror.h" +#include "pyfwevt_libfwevt.h" +#include "pyfwevt_python.h" +#include "pyfwevt_unused.h" + +PySequenceMethods pyfwevt_template_items_sequence_methods = { + /* sq_length */ + (lenfunc) pyfwevt_template_items_len, + /* sq_concat */ + 0, + /* sq_repeat */ + 0, + /* sq_item */ + (ssizeargfunc) pyfwevt_template_items_getitem, + /* sq_slice */ + 0, + /* sq_ass_item */ + 0, + /* sq_ass_slice */ + 0, + /* sq_contains */ + 0, + /* sq_inplace_concat */ + 0, + /* sq_inplace_repeat */ + 0 +}; + +PyTypeObject pyfwevt_template_items_type_object = { + PyVarObject_HEAD_INIT( NULL, 0 ) + + /* tp_name */ + "pyfwevt.template_items", + /* tp_basicsize */ + sizeof( pyfwevt_template_items_t ), + /* tp_itemsize */ + 0, + /* tp_dealloc */ + (destructor) pyfwevt_template_items_free, + /* tp_print */ + 0, + /* tp_getattr */ + 0, + /* tp_setattr */ + 0, + /* tp_compare */ + 0, + /* tp_repr */ + 0, + /* tp_as_number */ + 0, + /* tp_as_sequence */ + &pyfwevt_template_items_sequence_methods, + /* tp_as_mapping */ + 0, + /* tp_hash */ + 0, + /* tp_call */ + 0, + /* tp_str */ + 0, + /* tp_getattro */ + 0, + /* tp_setattro */ + 0, + /* tp_as_buffer */ + 0, + /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, + /* tp_doc */ + "pyfwevt sequence and iterator object of template items", + /* tp_traverse */ + 0, + /* tp_clear */ + 0, + /* tp_richcompare */ + 0, + /* tp_weaklistoffset */ + 0, + /* tp_iter */ + (getiterfunc) pyfwevt_template_items_iter, + /* tp_iternext */ + (iternextfunc) pyfwevt_template_items_iternext, + /* tp_methods */ + 0, + /* tp_members */ + 0, + /* tp_getset */ + 0, + /* tp_base */ + 0, + /* tp_dict */ + 0, + /* tp_descr_get */ + 0, + /* tp_descr_set */ + 0, + /* tp_dictoffset */ + 0, + /* tp_init */ + (initproc) pyfwevt_template_items_init, + /* tp_alloc */ + 0, + /* tp_new */ + 0, + /* tp_free */ + 0, + /* tp_is_gc */ + 0, + /* tp_bases */ + NULL, + /* tp_mro */ + NULL, + /* tp_cache */ + NULL, + /* tp_subclasses */ + NULL, + /* tp_weaklist */ + NULL, + /* tp_del */ + 0, + /* tp_version_tag */ + 0 +}; + +/* Creates a new template_items sequence and iterator object + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfwevt_template_items_new( + PyObject *parent_object, + PyObject* (*get_item_by_index)( + PyObject *parent_object, + int index ), + int number_of_items ) +{ + pyfwevt_template_items_t *sequence_object = NULL; + static char *function = "pyfwevt_template_items_new"; + + if( parent_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid parent object.", + function ); + + return( NULL ); + } + if( get_item_by_index == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid get item by index function.", + function ); + + return( NULL ); + } + /* Make sure the template_items values are initialized + */ + sequence_object = PyObject_New( + struct pyfwevt_template_items, + &pyfwevt_template_items_type_object ); + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create sequence object.", + function ); + + goto on_error; + } + sequence_object->parent_object = parent_object; + sequence_object->get_item_by_index = get_item_by_index; + sequence_object->current_index = 0; + sequence_object->number_of_items = number_of_items; + + Py_IncRef( + (PyObject *) sequence_object->parent_object ); + + return( (PyObject *) sequence_object ); + +on_error: + if( sequence_object != NULL ) + { + Py_DecRef( + (PyObject *) sequence_object ); + } + return( NULL ); +} + +/* Initializes a template_items sequence and iterator object + * Returns 0 if successful or -1 on error + */ +int pyfwevt_template_items_init( + pyfwevt_template_items_t *sequence_object, + PyObject *arguments PYFWEVT_ATTRIBUTE_UNUSED, + PyObject *keywords PYFWEVT_ATTRIBUTE_UNUSED ) +{ + static char *function = "pyfwevt_template_items_init"; + + PYFWEVT_UNREFERENCED_PARAMETER( arguments ) + PYFWEVT_UNREFERENCED_PARAMETER( keywords ) + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( -1 ); + } + /* Make sure the template_items values are initialized + */ + sequence_object->parent_object = NULL; + sequence_object->get_item_by_index = NULL; + sequence_object->current_index = 0; + sequence_object->number_of_items = 0; + + PyErr_Format( + PyExc_NotImplementedError, + "%s: initialize of template_items not supported.", + function ); + + return( -1 ); +} + +/* Frees a template_items sequence object + */ +void pyfwevt_template_items_free( + pyfwevt_template_items_t *sequence_object ) +{ + struct _typeobject *ob_type = NULL; + static char *function = "pyfwevt_template_items_free"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return; + } + ob_type = Py_TYPE( + sequence_object ); + + if( ob_type == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: missing ob_type.", + function ); + + return; + } + if( ob_type->tp_free == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid ob_type - missing tp_free.", + function ); + + return; + } + if( sequence_object->parent_object != NULL ) + { + Py_DecRef( + (PyObject *) sequence_object->parent_object ); + } + ob_type->tp_free( + (PyObject*) sequence_object ); +} + +/* The template_items len() function + */ +Py_ssize_t pyfwevt_template_items_len( + pyfwevt_template_items_t *sequence_object ) +{ + static char *function = "pyfwevt_template_items_len"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( -1 ); + } + return( (Py_ssize_t) sequence_object->number_of_items ); +} + +/* The template_items getitem() function + */ +PyObject *pyfwevt_template_items_getitem( + pyfwevt_template_items_t *sequence_object, + Py_ssize_t item_index ) +{ + PyObject *template_item_object = NULL; + static char *function = "pyfwevt_template_items_getitem"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( NULL ); + } + if( sequence_object->get_item_by_index == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - missing get item by index function.", + function ); + + return( NULL ); + } + if( sequence_object->number_of_items < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - invalid number of items.", + function ); + + return( NULL ); + } + if( ( item_index < 0 ) + || ( item_index >= (Py_ssize_t) sequence_object->number_of_items ) ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid invalid item index value out of bounds.", + function ); + + return( NULL ); + } + template_item_object = sequence_object->get_item_by_index( + sequence_object->parent_object, + (int) item_index ); + + return( template_item_object ); +} + +/* The template_items iter() function + */ +PyObject *pyfwevt_template_items_iter( + pyfwevt_template_items_t *sequence_object ) +{ + static char *function = "pyfwevt_template_items_iter"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( NULL ); + } + Py_IncRef( + (PyObject *) sequence_object ); + + return( (PyObject *) sequence_object ); +} + +/* The template_items iternext() function + */ +PyObject *pyfwevt_template_items_iternext( + pyfwevt_template_items_t *sequence_object ) +{ + PyObject *template_item_object = NULL; + static char *function = "pyfwevt_template_items_iternext"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( NULL ); + } + if( sequence_object->get_item_by_index == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - missing get item by index function.", + function ); + + return( NULL ); + } + if( sequence_object->current_index < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - invalid current index.", + function ); + + return( NULL ); + } + if( sequence_object->number_of_items < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - invalid number of items.", + function ); + + return( NULL ); + } + if( sequence_object->current_index >= sequence_object->number_of_items ) + { + PyErr_SetNone( + PyExc_StopIteration ); + + return( NULL ); + } + template_item_object = sequence_object->get_item_by_index( + sequence_object->parent_object, + sequence_object->current_index ); + + if( template_item_object != NULL ) + { + sequence_object->current_index++; + } + return( template_item_object ); +} + diff --git a/pyfwevt/pyfwevt_template_items.h b/pyfwevt/pyfwevt_template_items.h new file mode 100644 index 0000000..c47db10 --- /dev/null +++ b/pyfwevt/pyfwevt_template_items.h @@ -0,0 +1,97 @@ +/* + * Python object definition of the sequence and iterator object of template items + * + * Copyright (C) 2011-2023, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#if !defined( _PYFWEVT_TEMPLATE_ITEMS_H ) +#define _PYFWEVT_TEMPLATE_ITEMS_H + +#include +#include + +#include "pyfwevt_libfwevt.h" +#include "pyfwevt_python.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct pyfwevt_template_items pyfwevt_template_items_t; + +struct pyfwevt_template_items +{ + /* Python object initialization + */ + PyObject_HEAD + + /* The parent object + */ + PyObject *parent_object; + + /* The get item by index callback function + */ + PyObject* (*get_item_by_index)( + PyObject *parent_object, + int index ); + + /* The current index + */ + int current_index; + + /* The number of items + */ + int number_of_items; +}; + +extern PyTypeObject pyfwevt_template_items_type_object; + +PyObject *pyfwevt_template_items_new( + PyObject *parent_object, + PyObject* (*get_item_by_index)( + PyObject *parent_object, + int index ), + int number_of_items ); + +int pyfwevt_template_items_init( + pyfwevt_template_items_t *sequence_object, + PyObject *arguments, + PyObject *keywords ); + +void pyfwevt_template_items_free( + pyfwevt_template_items_t *sequence_object ); + +Py_ssize_t pyfwevt_template_items_len( + pyfwevt_template_items_t *sequence_object ); + +PyObject *pyfwevt_template_items_getitem( + pyfwevt_template_items_t *sequence_object, + Py_ssize_t item_index ); + +PyObject *pyfwevt_template_items_iter( + pyfwevt_template_items_t *sequence_object ); + +PyObject *pyfwevt_template_items_iternext( + pyfwevt_template_items_t *sequence_object ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _PYFWEVT_TEMPLATE_ITEMS_H ) */ +