Coverage Report

Created: 2025-08-28 07:10

/src/libfwevt/libfwevt/libfwevt_task.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Task functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "libfwevt_debug.h"
31
#include "libfwevt_libcerror.h"
32
#include "libfwevt_libcnotify.h"
33
#include "libfwevt_libfguid.h"
34
#include "libfwevt_libuna.h"
35
#include "libfwevt_task.h"
36
#include "libfwevt_types.h"
37
38
#include "fwevt_template.h"
39
40
/* Creates a task
41
 * Make sure the value task is referencing, is set to NULL
42
 * Returns 1 if successful or -1 on error
43
 */
44
int libfwevt_task_initialize(
45
     libfwevt_task_t **task,
46
     libcerror_error_t **error )
47
40.7k
{
48
40.7k
  libfwevt_internal_task_t *internal_task = NULL;
49
40.7k
  static char *function                   = "libfwevt_task_initialize";
50
51
40.7k
  if( task == NULL )
52
0
  {
53
0
    libcerror_error_set(
54
0
     error,
55
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
56
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
57
0
     "%s: invalid task.",
58
0
     function );
59
60
0
    return( -1 );
61
0
  }
62
40.7k
  if( *task != NULL )
63
0
  {
64
0
    libcerror_error_set(
65
0
     error,
66
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
67
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
68
0
     "%s: invalid task value already set.",
69
0
     function );
70
71
0
    return( -1 );
72
0
  }
73
40.7k
  internal_task = memory_allocate_structure(
74
40.7k
                   libfwevt_internal_task_t );
75
76
40.7k
  if( internal_task == NULL )
77
0
  {
78
0
    libcerror_error_set(
79
0
     error,
80
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
81
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
82
0
     "%s: unable to create task.",
83
0
     function );
84
85
0
    goto on_error;
86
0
  }
87
40.7k
  if( memory_set(
88
40.7k
       internal_task,
89
40.7k
       0,
90
40.7k
       sizeof( libfwevt_internal_task_t ) ) == NULL )
91
0
  {
92
0
    libcerror_error_set(
93
0
     error,
94
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
95
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
96
0
     "%s: unable to clear task.",
97
0
     function );
98
99
0
    goto on_error;
100
0
  }
101
40.7k
  *task = (libfwevt_task_t *) internal_task;
102
103
40.7k
  return( 1 );
104
105
0
on_error:
106
0
  if( internal_task != NULL )
107
0
  {
108
0
    memory_free(
109
0
     internal_task );
110
0
  }
111
0
  return( -1 );
112
40.7k
}
113
114
/* Frees a task
115
 * Returns 1 if successful or -1 on error
116
 */
117
int libfwevt_task_free(
118
     libfwevt_task_t **task,
119
     libcerror_error_t **error )
120
0
{
121
0
  static char *function = "libfwevt_task_free";
122
123
0
  if( task == NULL )
124
0
  {
125
0
    libcerror_error_set(
126
0
     error,
127
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
128
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
129
0
     "%s: invalid task.",
130
0
     function );
131
132
0
    return( -1 );
133
0
  }
134
0
  if( *task != NULL )
135
0
  {
136
0
    *task = NULL;
137
0
  }
138
0
  return( 1 );
139
0
}
140
141
/* Frees a task
142
 * Returns 1 if successful or -1 on error
143
 */
144
int libfwevt_internal_task_free(
145
     libfwevt_internal_task_t **internal_task,
146
     libcerror_error_t **error )
147
40.7k
{
148
40.7k
  static char *function = "libfwevt_internal_task_free";
149
150
40.7k
  if( internal_task == NULL )
151
0
  {
152
0
    libcerror_error_set(
153
0
     error,
154
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
155
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
156
0
     "%s: invalid task.",
157
0
     function );
158
159
0
    return( -1 );
160
0
  }
161
40.7k
  if( *internal_task != NULL )
162
40.7k
  {
163
40.7k
    memory_free(
164
40.7k
     *internal_task );
165
166
40.7k
    *internal_task = NULL;
167
40.7k
  }
168
40.7k
  return( 1 );
169
40.7k
}
170
171
/* Reads the task
172
 * Returns 1 if successful or -1 on error
173
 */
174
int libfwevt_task_read_data(
175
     libfwevt_task_t *task,
176
     const uint8_t *data,
177
     size_t data_size,
178
     size_t data_offset,
179
     libcerror_error_t **error )
180
40.7k
{
181
40.7k
  libfwevt_internal_task_t *internal_task = NULL;
182
40.7k
  fwevt_template_task_t *wevt_task        = NULL;
183
40.7k
  static char *function                   = "libfwevt_task_read_data";
184
40.7k
  uint32_t task_data_offset               = 0;
185
40.7k
  uint32_t task_data_size                 = 0;
186
187
#if defined( HAVE_DEBUG_OUTPUT )
188
  uint32_t value_32bit                    = 0;
189
#endif
190
191
40.7k
  if( task == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
197
0
     "%s: invalid task.",
198
0
     function );
199
200
0
    return( -1 );
201
0
  }
202
40.7k
  internal_task = (libfwevt_internal_task_t *) task;
203
204
40.7k
  if( data == NULL )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
209
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
210
0
     "%s: invalid data.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
40.7k
  if( data_size > (size_t) SSIZE_MAX )
216
0
  {
217
0
    libcerror_error_set(
218
0
     error,
219
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
220
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
221
0
     "%s: invalid data size value exceeds maximum.",
222
0
     function );
223
224
0
    return( -1 );
225
0
  }
226
40.7k
  if( data_offset >= data_size )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
231
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
232
0
     "%s: invalid data offset value out of bounds.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
40.7k
  if( ( data_size < sizeof( fwevt_template_task_t ) )
238
40.7k
   || ( data_offset > ( data_size - sizeof( fwevt_template_task_t ) ) ) )
239
0
  {
240
0
    libcerror_error_set(
241
0
     error,
242
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
243
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
244
0
     "%s: invalid data value too small.",
245
0
     function );
246
247
0
    return( -1 );
248
0
  }
249
40.7k
  wevt_task = (fwevt_template_task_t *) &( data[ data_offset ] );
250
251
#if defined( HAVE_DEBUG_OUTPUT )
252
  if( libcnotify_verbose != 0 )
253
  {
254
    libcnotify_printf(
255
     "%s: task data:\n",
256
     function );
257
    libcnotify_print_data(
258
     (uint8_t *) wevt_task,
259
     sizeof( fwevt_template_task_t ),
260
     0 );
261
  }
262
#endif
263
40.7k
  byte_stream_copy_to_uint32_little_endian(
264
40.7k
   wevt_task->identifier,
265
40.7k
   internal_task->identifier );
266
267
40.7k
  byte_stream_copy_to_uint32_little_endian(
268
40.7k
   wevt_task->data_offset,
269
40.7k
   task_data_offset );
270
271
#if defined( HAVE_DEBUG_OUTPUT )
272
  if( libcnotify_verbose != 0 )
273
  {
274
    libcnotify_printf(
275
     "%s: identifier\t\t\t\t\t: %" PRIu32 "\n",
276
     function,
277
     internal_task->identifier );
278
279
    byte_stream_copy_to_uint32_little_endian(
280
     wevt_task->message_identifier,
281
     value_32bit );
282
    libcnotify_printf(
283
     "%s: message identifier\t\t\t\t: 0x%08" PRIx32 "\n",
284
     function,
285
     value_32bit );
286
287
    if( libfwevt_debug_print_guid_value(
288
         function,
289
         "unknown1\t\t\t\t\t",
290
         wevt_task->unknown1,
291
         16,
292
         LIBFGUID_ENDIAN_LITTLE,
293
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
294
         error ) != 1 )
295
    {
296
      libcerror_error_set(
297
       error,
298
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
299
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
300
       "%s: unable to print GUID value.",
301
       function );
302
303
      return( -1 );
304
    }
305
    libcnotify_printf(
306
     "%s: data offset\t\t\t\t\t: 0x%08" PRIx32 "\n",
307
     function,
308
     task_data_offset );
309
  }
310
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
311
312
40.7k
  if( task_data_offset > 0 )
313
675
  {
314
675
    if( task_data_offset >= ( data_size - 4 ) )
315
105
    {
316
105
      libcerror_error_set(
317
105
       error,
318
105
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
319
105
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
320
105
       "%s: invalid task data offset value out of bounds.",
321
105
       function );
322
323
105
      return( -1 );
324
105
    }
325
570
    byte_stream_copy_to_uint32_little_endian(
326
570
     &( data[ task_data_offset ] ),
327
570
     task_data_size );
328
329
570
    if( ( data_size < task_data_size )
330
570
     || ( task_data_offset > ( data_size - task_data_size ) ) )
331
99
    {
332
99
      libcerror_error_set(
333
99
       error,
334
99
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
335
99
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
336
99
       "%s: invalid task data size value out of bounds.",
337
99
       function );
338
339
99
      return( -1 );
340
99
    }
341
#if defined( HAVE_DEBUG_OUTPUT )
342
    if( libcnotify_verbose != 0 )
343
    {
344
      libcnotify_printf(
345
       "%s: data:\n",
346
       function );
347
      libcnotify_print_data(
348
       &( data[ task_data_offset ] ),
349
       task_data_size,
350
       0 );
351
    }
352
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
353
354
#if defined( HAVE_DEBUG_OUTPUT )
355
    if( libcnotify_verbose != 0 )
356
    {
357
      libcnotify_printf(
358
       "%s: data size\t\t\t\t\t: %" PRIu32 "\n",
359
       function,
360
       task_data_size );
361
    }
362
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
363
364
471
    if( task_data_size >= 4 )
365
116
    {
366
116
      task_data_offset += 4;
367
116
      task_data_size   -= 4;
368
369
#if defined( HAVE_DEBUG_OUTPUT )
370
      if( libcnotify_verbose != 0 )
371
      {
372
        if( libfwevt_debug_print_utf16_string_value(
373
             function,
374
             "name\t\t\t\t\t\t",
375
             &( data[ task_data_offset ] ),
376
             task_data_size,
377
             LIBUNA_ENDIAN_LITTLE,
378
             error ) != 1 )
379
        {
380
          libcerror_error_set(
381
           error,
382
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
383
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
384
           "%s: unable to print UTF-16 string value.",
385
           function );
386
387
          return( -1 );
388
        }
389
      }
390
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
391
116
    }
392
471
  }
393
#if defined( HAVE_DEBUG_OUTPUT )
394
  if( libcnotify_verbose != 0 )
395
  {
396
    libcnotify_printf(
397
     "\n" );
398
  }
399
#endif
400
40.5k
  return( 1 );
401
40.7k
}
402