Coverage Report

Created: 2026-01-25 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupd/fwupd-bios-setting.c
Line
Count
Source
1
/*
2
 * Copyright 2022 Mario Limonciello <mario.limonciello@amd.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include "fwupd-bios-setting.h"
10
#include "fwupd-codec.h"
11
#include "fwupd-enums-private.h"
12
#include "fwupd-error.h"
13
#include "fwupd-json-array.h"
14
#include "fwupd-json-object.h"
15
16
/**
17
 * FwupdBiosSetting:
18
 *
19
 * A BIOS setting that represents a setting in the firmware.
20
 */
21
22
static void
23
fwupd_bios_setting_finalize(GObject *object);
24
25
typedef struct {
26
  FwupdBiosSettingKind kind;
27
  gchar *id;
28
  gchar *name;
29
  gchar *description;
30
  gchar *path;
31
  gchar *current_value;
32
  guint64 lower_bound;
33
  guint64 upper_bound;
34
  guint64 scalar_increment;
35
  gboolean read_only;
36
  GPtrArray *possible_values;
37
} FwupdBiosSettingPrivate;
38
39
static void
40
fwupd_bios_setting_codec_iface_init(FwupdCodecInterface *iface);
41
42
0
G_DEFINE_TYPE_EXTENDED(FwupdBiosSetting,
43
0
           fwupd_bios_setting,
44
0
           G_TYPE_OBJECT,
45
0
           0,
46
0
           G_ADD_PRIVATE(FwupdBiosSetting)
47
0
         G_IMPLEMENT_INTERFACE(FWUPD_TYPE_CODEC,
48
0
             fwupd_bios_setting_codec_iface_init));
49
0
50
0
#define GET_PRIVATE(o) (fwupd_bios_setting_get_instance_private(o))
51
52
/**
53
 * fwupd_bios_setting_get_id
54
 * @self: a #FwupdBiosSetting
55
 *
56
 * Gets the unique attribute identifier for this attribute/driver
57
 *
58
 * Returns: attribute ID if set otherwise NULL
59
 *
60
 * Since: 1.8.4
61
 **/
62
const gchar *
63
fwupd_bios_setting_get_id(FwupdBiosSetting *self)
64
0
{
65
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
66
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
67
0
  return priv->id;
68
0
}
69
70
/**
71
 * fwupd_bios_setting_set_id
72
 * @self: a #FwupdBiosSetting
73
 *
74
 * Sets the unique attribute identifier for this attribute
75
 *
76
 * Since: 1.8.4
77
 **/
78
void
79
fwupd_bios_setting_set_id(FwupdBiosSetting *self, const gchar *id)
80
0
{
81
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
82
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
83
84
  /* not changed */
85
0
  if (g_strcmp0(priv->id, id) == 0)
86
0
    return;
87
88
0
  g_free(priv->id);
89
0
  priv->id = g_strdup(id);
90
0
}
91
92
/**
93
 * fwupd_bios_setting_get_read_only:
94
 * @self: a #FwupdBiosSetting
95
 *
96
 * Determines if a BIOS setting is read only
97
 *
98
 * Returns: gboolean
99
 *
100
 * Since: 1.8.4
101
 **/
102
gboolean
103
fwupd_bios_setting_get_read_only(FwupdBiosSetting *self)
104
0
{
105
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
106
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), FALSE);
107
0
  return priv->read_only;
108
0
}
109
110
/**
111
 * fwupd_bios_setting_set_read_only:
112
 * @self: a #FwupdBiosSetting
113
 *
114
 * Configures whether an attribute is read only
115
 * maximum length for string attributes.
116
 *
117
 *
118
 * Since: 1.8.4
119
 **/
120
void
121
fwupd_bios_setting_set_read_only(FwupdBiosSetting *self, gboolean val)
122
0
{
123
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
124
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
125
0
  priv->read_only = val;
126
0
}
127
128
/**
129
 * fwupd_bios_setting_get_lower_bound:
130
 * @self: a #FwupdBiosSetting
131
 *
132
 * Gets the lower bound for integer attributes or
133
 * minimum length for string attributes.
134
 *
135
 * Returns: guint64
136
 *
137
 * Since: 1.8.4
138
 **/
139
guint64
140
fwupd_bios_setting_get_lower_bound(FwupdBiosSetting *self)
141
0
{
142
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
143
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), 0);
144
0
  return priv->lower_bound;
145
0
}
146
147
/**
148
 * fwupd_bios_setting_get_upper_bound:
149
 * @self: a #FwupdBiosSetting
150
 *
151
 * Gets the upper bound for integer attributes or
152
 * maximum length for string attributes.
153
 *
154
 * Returns: guint64
155
 *
156
 * Since: 1.8.4
157
 **/
158
guint64
159
fwupd_bios_setting_get_upper_bound(FwupdBiosSetting *self)
160
0
{
161
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
162
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), 0);
163
0
  return priv->upper_bound;
164
0
}
165
166
/**
167
 * fwupd_bios_setting_get_scalar_increment:
168
 * @self: a #FwupdBiosSetting
169
 *
170
 * Gets the scalar increment used for integer attributes.
171
 *
172
 * Returns: guint64
173
 *
174
 * Since: 1.8.4
175
 **/
176
guint64
177
fwupd_bios_setting_get_scalar_increment(FwupdBiosSetting *self)
178
0
{
179
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
180
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), 0);
181
0
  return priv->scalar_increment;
182
0
}
183
184
/**
185
 * fwupd_bios_setting_set_upper_bound:
186
 * @self: a #FwupdBiosSetting
187
 * @val: a guint64 value to set bound to
188
 *
189
 * Sets the upper bound used for BIOS integer attributes or max
190
 * length for string attributes.
191
 *
192
 * Since: 1.8.4
193
 **/
194
void
195
fwupd_bios_setting_set_upper_bound(FwupdBiosSetting *self, guint64 val)
196
0
{
197
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
198
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
199
0
  priv->upper_bound = val;
200
0
}
201
202
/**
203
 * fwupd_bios_setting_set_lower_bound:
204
 * @self: a #FwupdBiosSetting
205
 * @val: a guint64 value to set bound to
206
 *
207
 * Sets the lower bound used for BIOS integer attributes or max
208
 * length for string attributes.
209
 *
210
 * Since: 1.8.4
211
 **/
212
void
213
fwupd_bios_setting_set_lower_bound(FwupdBiosSetting *self, guint64 val)
214
0
{
215
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
216
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
217
0
  priv->lower_bound = val;
218
0
}
219
220
/**
221
 * fwupd_bios_setting_set_scalar_increment:
222
 * @self: a #FwupdBiosSetting
223
 * @val: a guint64 value to set increment to
224
 *
225
 * Sets the scalar increment used for BIOS integer attributes.
226
 *
227
 * Since: 1.8.4
228
 **/
229
void
230
fwupd_bios_setting_set_scalar_increment(FwupdBiosSetting *self, guint64 val)
231
0
{
232
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
233
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
234
0
  priv->scalar_increment = val;
235
0
}
236
237
/**
238
 * fwupd_bios_setting_get_kind:
239
 * @self: a #FwupdBiosSetting
240
 *
241
 * Gets the BIOS setting type used by the kernel interface.
242
 *
243
 * Returns: the bios setting type, or %FWUPD_BIOS_SETTING_KIND_UNKNOWN if unset.
244
 *
245
 * Since: 1.8.4
246
 **/
247
FwupdBiosSettingKind
248
fwupd_bios_setting_get_kind(FwupdBiosSetting *self)
249
0
{
250
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
251
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), 0);
252
0
  return priv->kind;
253
0
}
254
255
/**
256
 * fwupd_bios_setting_set_kind:
257
 * @self: a #FwupdBiosSetting
258
 * @type: a bios setting type, e.g. %FWUPD_BIOS_SETTING_KIND_ENUMERATION
259
 *
260
 * Sets the BIOS setting type used by the kernel interface.
261
 *
262
 * Since: 1.8.4
263
 **/
264
void
265
fwupd_bios_setting_set_kind(FwupdBiosSetting *self, FwupdBiosSettingKind type)
266
0
{
267
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
268
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
269
0
  priv->kind = type;
270
0
}
271
272
/**
273
 * fwupd_bios_setting_set_name:
274
 * @self: a #FwupdBiosSetting
275
 * @name: (nullable): the attribute name
276
 *
277
 * Sets the attribute name provided by a kernel driver.
278
 *
279
 * Since: 1.8.4
280
 **/
281
void
282
fwupd_bios_setting_set_name(FwupdBiosSetting *self, const gchar *name)
283
0
{
284
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
285
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
286
287
  /* not changed */
288
0
  if (g_strcmp0(priv->name, name) == 0)
289
0
    return;
290
291
0
  g_free(priv->name);
292
0
  priv->name = g_strdup(name);
293
0
}
294
295
/**
296
 * fwupd_bios_setting_set_path:
297
 * @self: a #FwupdBiosSetting
298
 * @path: (nullable): the path the driver providing the attribute uses
299
 *
300
 * Sets path to the attribute.
301
 *
302
 * Since: 1.8.4
303
 **/
304
void
305
fwupd_bios_setting_set_path(FwupdBiosSetting *self, const gchar *path)
306
0
{
307
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
308
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
309
310
  /* not changed */
311
0
  if (g_strcmp0(priv->path, path) == 0)
312
0
    return;
313
314
0
  g_free(priv->path);
315
0
  priv->path = g_strdup(path);
316
0
}
317
318
/**
319
 * fwupd_bios_setting_set_description:
320
 * @self: a #FwupdBiosSetting
321
 * @description: (nullable): the attribute description
322
 *
323
 * Sets the attribute description.
324
 *
325
 * Since: 1.8.4
326
 **/
327
void
328
fwupd_bios_setting_set_description(FwupdBiosSetting *self, const gchar *description)
329
0
{
330
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
331
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
332
333
  /* not changed */
334
0
  if (g_strcmp0(priv->description, description) == 0)
335
0
    return;
336
337
0
  g_free(priv->description);
338
0
  priv->description = g_strdup(description);
339
0
}
340
341
/* determine if key is supposed to be positive */
342
static gboolean
343
fwupd_bios_setting_key_is_positive(const gchar *key)
344
0
{
345
0
  if (g_strrstr(key, "enable"))
346
0
    return TRUE;
347
0
  if (g_strcmp0(key, "true") == 0)
348
0
    return TRUE;
349
0
  if (g_strcmp0(key, "1") == 0)
350
0
    return TRUE;
351
0
  if (g_strcmp0(key, "on") == 0)
352
0
    return TRUE;
353
0
  return FALSE;
354
0
}
355
356
/* determine if key is supposed to be negative */
357
static gboolean
358
fwupd_bios_setting_key_is_negative(const gchar *key)
359
0
{
360
0
  if (g_strrstr(key, "disable"))
361
0
    return TRUE;
362
0
  if (g_strcmp0(key, "false") == 0)
363
0
    return TRUE;
364
0
  if (g_strcmp0(key, "0") == 0)
365
0
    return TRUE;
366
0
  if (g_strcmp0(key, "off") == 0)
367
0
    return TRUE;
368
0
  return FALSE;
369
0
}
370
371
/**
372
 * fwupd_bios_setting_map_possible_value:
373
 * @self: a #FwupdBiosSetting
374
 * @key: the string to try to map
375
 * @error: (nullable): optional return location for an error
376
 *
377
 * Attempts to map a user provided string into strings that a #FwupdBiosSetting can
378
 * support.  The following heuristics are used:
379
 * - Ignore case sensitivity
380
 * - Map obviously "positive" phrases into a value that turns on the #FwupdBiosSetting
381
 * - Map obviously "negative" phrases into a value that turns off the #FwupdBiosSetting
382
 *
383
 * Returns: (transfer none): the possible value that maps or NULL if none if found
384
 *
385
 * Since: 1.8.4
386
 **/
387
const gchar *
388
fwupd_bios_setting_map_possible_value(FwupdBiosSetting *self, const gchar *key, GError **error)
389
0
{
390
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
391
0
  gboolean positive_key = FALSE;
392
0
  gboolean negative_key = FALSE;
393
0
  g_autofree gchar *lower_key = NULL;
394
395
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
396
0
  g_return_val_if_fail(priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION, NULL);
397
398
0
  if (priv->possible_values->len == 0) {
399
0
    g_set_error(error,
400
0
          FWUPD_ERROR,
401
0
          FWUPD_ERROR_NOT_SUPPORTED,
402
0
          "%s doesn't contain any possible values",
403
0
          priv->name);
404
0
    return NULL;
405
0
  }
406
407
0
  lower_key = g_utf8_strdown(key, -1);
408
0
  positive_key = fwupd_bios_setting_key_is_positive(lower_key);
409
0
  negative_key = fwupd_bios_setting_key_is_negative(lower_key);
410
0
  for (guint i = 0; i < priv->possible_values->len; i++) {
411
0
    const gchar *possible = g_ptr_array_index(priv->possible_values, i);
412
0
    g_autofree gchar *lower_possible = g_utf8_strdown(possible, -1);
413
0
    gboolean positive_possible;
414
0
    gboolean negative_possible;
415
416
    /* perfect match */
417
0
    if (g_strcmp0(lower_possible, lower_key) == 0)
418
0
      return possible;
419
    /* fuzzy match */
420
0
    positive_possible = fwupd_bios_setting_key_is_positive(lower_possible);
421
0
    negative_possible = fwupd_bios_setting_key_is_negative(lower_possible);
422
0
    if ((positive_possible && positive_key) || (negative_possible && negative_key))
423
0
      return possible;
424
0
  }
425
0
  g_set_error(error,
426
0
        FWUPD_ERROR,
427
0
        FWUPD_ERROR_NOT_SUPPORTED,
428
0
        "%s doesn't map to any possible values for %s",
429
0
        key,
430
0
        priv->name);
431
0
  return NULL;
432
0
}
433
434
/**
435
 * fwupd_bios_setting_has_possible_value:
436
 * @self: a #FwupdBiosSetting
437
 * @val: the possible value string
438
 *
439
 * Finds out if a specific possible value was added to the attribute.
440
 *
441
 * Returns: %TRUE if the self matches.
442
 *
443
 * Since: 1.8.4
444
 **/
445
gboolean
446
fwupd_bios_setting_has_possible_value(FwupdBiosSetting *self, const gchar *val)
447
0
{
448
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
449
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), FALSE);
450
0
  g_return_val_if_fail(val != NULL, FALSE);
451
452
0
  if (priv->possible_values->len == 0)
453
0
    return TRUE;
454
455
0
  for (guint i = 0; i < priv->possible_values->len; i++) {
456
0
    const gchar *tmp = g_ptr_array_index(priv->possible_values, i);
457
0
    if (g_strcmp0(tmp, val) == 0)
458
0
      return TRUE;
459
0
  }
460
0
  return FALSE;
461
0
}
462
463
/**
464
 * fwupd_bios_setting_add_possible_value:
465
 * @self: a #FwupdBiosSetting
466
 * @possible_value: the possible
467
 *
468
 * Adds a possible value to the attribute.  This indicates one of the values the
469
 * kernel driver will accept from userspace.
470
 *
471
 * Since: 1.8.4
472
 **/
473
void
474
fwupd_bios_setting_add_possible_value(FwupdBiosSetting *self, const gchar *possible_value)
475
0
{
476
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
477
0
  g_return_if_fail(FWUPD_IS_BIOS_SETTING(self));
478
0
  if (priv->possible_values->len > 0 &&
479
0
      fwupd_bios_setting_has_possible_value(self, possible_value))
480
0
    return;
481
0
  g_ptr_array_add(priv->possible_values, g_strdup(possible_value));
482
0
}
483
484
/**
485
 * fwupd_bios_setting_get_possible_values:
486
 * @self: a #FwupdBiosSetting
487
 *
488
 * Find all possible values for an enumeration attribute.
489
 *
490
 * Returns: (transfer container) (element-type gchar*): all possible values.
491
 *
492
 * Since: 1.8.4
493
 **/
494
GPtrArray *
495
fwupd_bios_setting_get_possible_values(FwupdBiosSetting *self)
496
0
{
497
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
498
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
499
0
  g_return_val_if_fail(priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION, NULL);
500
0
  return priv->possible_values;
501
0
}
502
503
/**
504
 * fwupd_bios_setting_get_name:
505
 * @self: a #FwupdBiosSetting
506
 *
507
 * Gets the attribute name.
508
 *
509
 * Returns: the attribute name, or %NULL if unset.
510
 *
511
 * Since: 1.8.4
512
 **/
513
const gchar *
514
fwupd_bios_setting_get_name(FwupdBiosSetting *self)
515
0
{
516
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
517
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
518
0
  return priv->name;
519
0
}
520
521
/**
522
 * fwupd_bios_setting_get_path:
523
 * @self: a #FwupdBiosSetting
524
 *
525
 * Gets the path for the driver providing the attribute.
526
 *
527
 * Returns: (nullable): the driver, or %NULL if unfound.
528
 *
529
 * Since: 1.8.4
530
 **/
531
const gchar *
532
fwupd_bios_setting_get_path(FwupdBiosSetting *self)
533
0
{
534
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
535
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
536
0
  return priv->path;
537
0
}
538
539
/**
540
 * fwupd_bios_setting_get_description:
541
 * @self: a #FwupdBiosSetting
542
 *
543
 * Gets the attribute description which is provided by some drivers to explain
544
 * what they change.
545
 *
546
 * Returns: the attribute description, or %NULL if unset.
547
 *
548
 * Since: 1.8.4
549
 **/
550
const gchar *
551
fwupd_bios_setting_get_description(FwupdBiosSetting *self)
552
0
{
553
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
554
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
555
0
  return priv->description;
556
0
}
557
558
/**
559
 * fwupd_bios_setting_get_current_value:
560
 * @self: a #FwupdBiosSetting
561
 *
562
 * Gets the string representation of the current_value stored in an attribute
563
 * from the kernel.  This value is cached; so changing it outside of fwupd may
564
 * may put it out of sync.
565
 *
566
 * Returns: the current value of the attribute.
567
 *
568
 * Since: 1.8.4
569
 **/
570
const gchar *
571
fwupd_bios_setting_get_current_value(FwupdBiosSetting *self)
572
0
{
573
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
574
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), NULL);
575
0
  return priv->current_value;
576
0
}
577
578
/**
579
 * fwupd_bios_setting_set_current_value:
580
 * @self: a #FwupdBiosSetting
581
 * @value: (nullable): The string to set an attribute to
582
 *
583
 * Sets the string stored in an attribute.
584
 * This doesn't change the representation in the kernel.
585
 *
586
 * Since: 1.8.4
587
 **/
588
void
589
fwupd_bios_setting_set_current_value(FwupdBiosSetting *self, const gchar *value)
590
0
{
591
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
592
593
  /* not changed */
594
0
  if (g_strcmp0(priv->current_value, value) == 0)
595
0
    return;
596
597
0
  g_free(priv->current_value);
598
0
  priv->current_value = g_strdup(value);
599
0
}
600
601
static gboolean
602
_fu_strtoull_simple(const gchar *str, guint64 *value, GError **error)
603
0
{
604
0
  gchar *endptr = NULL;
605
0
  guint base = 10;
606
607
  /* convert */
608
0
  if (g_str_has_prefix(str, "0x")) {
609
0
    str += 2;
610
0
    base = 16;
611
0
  }
612
0
  *value = g_ascii_strtoull(str, &endptr, base); /* nocheck:blocked */
613
0
  if ((gsize)(endptr - str) != strlen(str) && *endptr != '\n') {
614
0
    g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_DATA, "cannot parse %s", str);
615
0
    return FALSE;
616
0
  }
617
0
  return TRUE;
618
0
}
619
620
static gboolean
621
fwupd_bios_setting_validate_value(FwupdBiosSetting *self, const gchar *value, GError **error)
622
0
{
623
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
624
625
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER) {
626
0
    guint64 tmp = 0;
627
0
    if (!_fu_strtoull_simple(value, &tmp, error))
628
0
      return FALSE;
629
0
    if (tmp < priv->lower_bound) {
630
0
      g_set_error(error, /* nocheck:error */
631
0
            FWUPD_ERROR,
632
0
            FWUPD_ERROR_NOT_SUPPORTED,
633
0
            "%s is too small (%" G_GUINT64_FORMAT
634
0
            ") expected at least %" G_GUINT64_FORMAT,
635
0
            value,
636
0
            tmp,
637
0
            priv->lower_bound);
638
0
      return FALSE;
639
0
    }
640
0
    if (tmp > priv->upper_bound) {
641
0
      g_set_error(error, /* nocheck:error */
642
0
            FWUPD_ERROR,
643
0
            FWUPD_ERROR_NOT_SUPPORTED,
644
0
            "%s is too big (%" G_GUINT64_FORMAT
645
0
            ") expected no more than %" G_GUINT64_FORMAT,
646
0
            value,
647
0
            tmp,
648
0
            priv->upper_bound);
649
0
      return FALSE;
650
0
    }
651
0
    return TRUE;
652
0
  }
653
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_STRING) {
654
0
    gsize tmp = strlen(value);
655
0
    if (tmp < priv->lower_bound) {
656
0
      g_set_error(error, /* nocheck:error */
657
0
            FWUPD_ERROR,
658
0
            FWUPD_ERROR_NOT_SUPPORTED,
659
0
            "%s is too short (%" G_GSIZE_FORMAT
660
0
            ") expected at least %" G_GUINT64_FORMAT,
661
0
            value,
662
0
            tmp,
663
0
            priv->lower_bound);
664
0
      return FALSE;
665
0
    }
666
0
    if (tmp > priv->upper_bound) {
667
0
      g_set_error(error, /* nocheck:error */
668
0
            FWUPD_ERROR,
669
0
            FWUPD_ERROR_NOT_SUPPORTED,
670
0
            "%s is too long (%" G_GSIZE_FORMAT
671
0
            ") expected no more than %" G_GUINT64_FORMAT,
672
0
            value,
673
0
            tmp,
674
0
            priv->upper_bound);
675
0
      return FALSE;
676
0
    }
677
0
    return TRUE;
678
0
  }
679
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION)
680
0
    return TRUE;
681
682
  /* not supported */
683
0
  g_set_error_literal(error,
684
0
          FWUPD_ERROR,
685
0
          FWUPD_ERROR_NOT_SUPPORTED,
686
0
          "unknown attribute type");
687
0
  return FALSE;
688
0
}
689
690
/**
691
 * fwupd_bios_setting_write_value:
692
 * @self: a #FwupdBiosSetting
693
 * @value: (not nullable): The string to write
694
 * @error: (nullable): optional return location for an error
695
 *
696
 * Writes a new value into the setting if it is different from the current value.
697
 *
698
 * NOTE: A subclass should handle the `->write_value()` vfunc and actually write the value to the
699
 * firmware.
700
 *
701
 * Returns: %TRUE for success
702
 *
703
 * Since: 1.9.4
704
 **/
705
gboolean
706
fwupd_bios_setting_write_value(FwupdBiosSetting *self, const gchar *value, GError **error)
707
0
{
708
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
709
0
  FwupdBiosSettingClass *klass = FWUPD_BIOS_SETTING_GET_CLASS(self);
710
711
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), FALSE);
712
0
  g_return_val_if_fail(value != NULL, FALSE);
713
0
  g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
714
715
  /* not changed */
716
0
  if (g_strcmp0(priv->current_value, value) == 0) {
717
0
    g_set_error(error,
718
0
          FWUPD_ERROR,
719
0
          FWUPD_ERROR_NOTHING_TO_DO,
720
0
          "%s is already set to %s",
721
0
          priv->id,
722
0
          value);
723
0
    return FALSE;
724
0
  }
725
726
  /* sanity check */
727
0
  if (fwupd_bios_setting_get_read_only(self)) {
728
0
    g_set_error(error,
729
0
          FWUPD_ERROR,
730
0
          FWUPD_ERROR_NOT_SUPPORTED,
731
0
          "%s is read only",
732
0
          priv->name);
733
0
    return FALSE;
734
0
  }
735
736
  /* convert the value */
737
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION) {
738
0
    value = fwupd_bios_setting_map_possible_value(self, value, error);
739
0
    if (value == NULL)
740
0
      return FALSE;
741
0
  }
742
743
  /* also done by the kernel or firmware, doing it here too allows for better errors */
744
0
  if (!fwupd_bios_setting_validate_value(self, value, error))
745
0
    return FALSE;
746
747
  /* not implemented */
748
0
  if (klass->write_value == NULL) {
749
0
    g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported");
750
0
    return FALSE;
751
0
  }
752
753
  /* proxy */
754
0
  return klass->write_value(self, value, error);
755
0
}
756
757
static gboolean
758
fwupd_bios_setting_trusted(FwupdBiosSetting *self, gboolean trusted)
759
0
{
760
0
  g_return_val_if_fail(FWUPD_IS_BIOS_SETTING(self), FALSE);
761
762
0
  if (trusted)
763
0
    return TRUE;
764
0
  if (g_strcmp0(fwupd_bios_setting_get_name(self), "pending_reboot") == 0)
765
0
    return TRUE;
766
0
  return FALSE;
767
0
}
768
769
static void
770
fwupd_bios_setting_add_variant(FwupdCodec *codec, GVariantBuilder *builder, FwupdCodecFlags flags)
771
0
{
772
0
  FwupdBiosSetting *self = FWUPD_BIOS_SETTING(codec);
773
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
774
775
0
  g_variant_builder_add(builder,
776
0
            "{sv}",
777
0
            FWUPD_RESULT_KEY_BIOS_SETTING_TYPE,
778
0
            g_variant_new_uint64(priv->kind));
779
0
  if (priv->id != NULL) {
780
0
    g_variant_builder_add(builder,
781
0
              "{sv}",
782
0
              FWUPD_RESULT_KEY_BIOS_SETTING_ID,
783
0
              g_variant_new_string(priv->id));
784
0
  }
785
0
  if (priv->name != NULL) {
786
0
    g_variant_builder_add(builder,
787
0
              "{sv}",
788
0
              FWUPD_RESULT_KEY_NAME,
789
0
              g_variant_new_string(priv->name));
790
0
  }
791
0
  if (priv->path != NULL) {
792
0
    g_variant_builder_add(builder,
793
0
              "{sv}",
794
0
              FWUPD_RESULT_KEY_FILENAME,
795
0
              g_variant_new_string(priv->path));
796
0
  }
797
0
  if (priv->description != NULL) {
798
0
    g_variant_builder_add(builder,
799
0
              "{sv}",
800
0
              FWUPD_RESULT_KEY_DESCRIPTION,
801
0
              g_variant_new_string(priv->description));
802
0
  }
803
0
  g_variant_builder_add(builder,
804
0
            "{sv}",
805
0
            FWUPD_RESULT_KEY_BIOS_SETTING_READ_ONLY,
806
0
            g_variant_new_boolean(priv->read_only));
807
0
  if (priv->current_value != NULL &&
808
0
      fwupd_bios_setting_trusted(self, flags & FWUPD_CODEC_FLAG_TRUSTED)) {
809
0
    g_variant_builder_add(builder,
810
0
              "{sv}",
811
0
              FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
812
0
              g_variant_new_string(priv->current_value));
813
0
  }
814
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER ||
815
0
      priv->kind == FWUPD_BIOS_SETTING_KIND_STRING) {
816
0
    g_variant_builder_add(builder,
817
0
              "{sv}",
818
0
              FWUPD_RESULT_KEY_BIOS_SETTING_LOWER_BOUND,
819
0
              g_variant_new_uint64(priv->lower_bound));
820
0
    g_variant_builder_add(builder,
821
0
              "{sv}",
822
0
              FWUPD_RESULT_KEY_BIOS_SETTING_UPPER_BOUND,
823
0
              g_variant_new_uint64(priv->upper_bound));
824
0
    if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER) {
825
0
      g_variant_builder_add(builder,
826
0
                "{sv}",
827
0
                FWUPD_RESULT_KEY_BIOS_SETTING_SCALAR_INCREMENT,
828
0
                g_variant_new_uint64(priv->scalar_increment));
829
0
    }
830
0
  } else if (priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION) {
831
0
    if (priv->possible_values->len > 0) {
832
0
      g_autofree const gchar **strv =
833
0
          g_new0(const gchar *, priv->possible_values->len + 1);
834
0
      for (guint i = 0; i < priv->possible_values->len; i++)
835
0
        strv[i] =
836
0
            (const gchar *)g_ptr_array_index(priv->possible_values, i);
837
0
      g_variant_builder_add(builder,
838
0
                "{sv}",
839
0
                FWUPD_RESULT_KEY_BIOS_SETTING_POSSIBLE_VALUES,
840
0
                g_variant_new_strv(strv, -1));
841
0
    }
842
0
  }
843
0
}
844
845
static void
846
fwupd_bios_setting_from_key_value(FwupdBiosSetting *self, const gchar *key, GVariant *value)
847
0
{
848
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_TYPE) == 0) {
849
0
    fwupd_bios_setting_set_kind(self, g_variant_get_uint64(value));
850
0
    return;
851
0
  }
852
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_ID) == 0) {
853
0
    fwupd_bios_setting_set_id(self, g_variant_get_string(value, NULL));
854
0
    return;
855
0
  }
856
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_NAME) == 0) {
857
0
    fwupd_bios_setting_set_name(self, g_variant_get_string(value, NULL));
858
0
    return;
859
0
  }
860
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_FILENAME) == 0) {
861
0
    fwupd_bios_setting_set_path(self, g_variant_get_string(value, NULL));
862
0
    return;
863
0
  }
864
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE) == 0) {
865
0
    fwupd_bios_setting_set_current_value(self, g_variant_get_string(value, NULL));
866
0
    return;
867
0
  }
868
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) {
869
0
    fwupd_bios_setting_set_description(self, g_variant_get_string(value, NULL));
870
0
    return;
871
0
  }
872
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_POSSIBLE_VALUES) == 0) {
873
0
    g_autofree const gchar **strv = g_variant_get_strv(value, NULL);
874
0
    for (guint i = 0; strv[i] != NULL; i++)
875
0
      fwupd_bios_setting_add_possible_value(self, strv[i]);
876
0
    return;
877
0
  }
878
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_LOWER_BOUND) == 0) {
879
0
    fwupd_bios_setting_set_lower_bound(self, g_variant_get_uint64(value));
880
0
    return;
881
0
  }
882
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_UPPER_BOUND) == 0) {
883
0
    fwupd_bios_setting_set_upper_bound(self, g_variant_get_uint64(value));
884
0
    return;
885
0
  }
886
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_SCALAR_INCREMENT) == 0) {
887
0
    fwupd_bios_setting_set_scalar_increment(self, g_variant_get_uint64(value));
888
0
    return;
889
0
  }
890
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_READ_ONLY) == 0) {
891
0
    fwupd_bios_setting_set_read_only(self, g_variant_get_boolean(value));
892
0
    return;
893
0
  }
894
0
}
895
896
static gboolean
897
fwupd_bios_setting_from_json(FwupdCodec *codec, FwupdJsonObject *json_obj, GError **error)
898
0
{
899
0
  FwupdBiosSetting *self = FWUPD_BIOS_SETTING(codec);
900
0
  gboolean tmpb = FALSE;
901
0
  gint64 tmpi = 0;
902
0
  g_autoptr(FwupdJsonArray) json_arr = NULL;
903
904
0
  if (!fwupd_json_object_get_integer_with_default(json_obj,
905
0
              FWUPD_RESULT_KEY_BIOS_SETTING_TYPE,
906
0
              &tmpi,
907
0
              0,
908
0
              error))
909
0
    return FALSE;
910
0
  fwupd_bios_setting_set_kind(self, tmpi);
911
0
  fwupd_bios_setting_set_id(
912
0
      self,
913
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_BIOS_SETTING_ID, NULL));
914
915
0
  fwupd_bios_setting_set_name(
916
0
      self,
917
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_NAME, NULL));
918
0
  fwupd_bios_setting_set_description(
919
0
      self,
920
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_DESCRIPTION, NULL));
921
0
  fwupd_bios_setting_set_path(
922
0
      self,
923
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_FILENAME, NULL));
924
0
  fwupd_bios_setting_set_current_value(
925
0
      self,
926
0
      fwupd_json_object_get_string(json_obj,
927
0
           FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
928
0
           NULL));
929
0
  json_arr = fwupd_json_object_get_array(json_obj,
930
0
                 FWUPD_RESULT_KEY_BIOS_SETTING_POSSIBLE_VALUES,
931
0
                 NULL);
932
0
  if (json_arr != NULL) {
933
0
    for (guint i = 0; i < fwupd_json_array_get_size(json_arr); i++) {
934
0
      const gchar *tmp = fwupd_json_array_get_string(json_arr, i, NULL);
935
0
      fwupd_bios_setting_add_possible_value(self, tmp);
936
0
    }
937
0
  }
938
0
  if (!fwupd_json_object_get_integer_with_default(json_obj,
939
0
              FWUPD_RESULT_KEY_BIOS_SETTING_LOWER_BOUND,
940
0
              &tmpi,
941
0
              0,
942
0
              error))
943
0
    return FALSE;
944
0
  fwupd_bios_setting_set_lower_bound(self, tmpi);
945
0
  if (!fwupd_json_object_get_integer_with_default(json_obj,
946
0
              FWUPD_RESULT_KEY_BIOS_SETTING_UPPER_BOUND,
947
0
              &tmpi,
948
0
              0,
949
0
              error))
950
0
    return FALSE;
951
0
  fwupd_bios_setting_set_upper_bound(self, tmpi);
952
0
  if (!fwupd_json_object_get_integer_with_default(
953
0
    json_obj,
954
0
    FWUPD_RESULT_KEY_BIOS_SETTING_SCALAR_INCREMENT,
955
0
    &tmpi,
956
0
    0,
957
0
    error))
958
0
    return FALSE;
959
0
  fwupd_bios_setting_set_scalar_increment(self, tmpi);
960
0
  if (!fwupd_json_object_get_boolean_with_default(json_obj,
961
0
              FWUPD_RESULT_KEY_BIOS_SETTING_READ_ONLY,
962
0
              &tmpb,
963
0
              FALSE,
964
0
              error))
965
0
    return FALSE;
966
0
  fwupd_bios_setting_set_read_only(self, tmpb);
967
  /* success */
968
0
  return TRUE;
969
0
}
970
971
static void
972
fwupd_bios_setting_add_json(FwupdCodec *codec, FwupdJsonObject *json_obj, FwupdCodecFlags flags)
973
0
{
974
0
  FwupdBiosSetting *self = FWUPD_BIOS_SETTING(codec);
975
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
976
977
0
  if (priv->name != NULL)
978
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_NAME, priv->name);
979
0
  if (priv->description != NULL)
980
0
    fwupd_json_object_add_string(json_obj,
981
0
               FWUPD_RESULT_KEY_DESCRIPTION,
982
0
               priv->description);
983
0
  if (priv->path != NULL)
984
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_FILENAME, priv->path);
985
0
  if (priv->id != NULL)
986
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_BIOS_SETTING_ID, priv->id);
987
0
  if (priv->current_value != NULL) {
988
0
    fwupd_json_object_add_string(json_obj,
989
0
               FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
990
0
               priv->current_value);
991
0
  }
992
0
  fwupd_json_object_add_boolean(json_obj,
993
0
              FWUPD_RESULT_KEY_BIOS_SETTING_READ_ONLY,
994
0
              priv->read_only);
995
0
  fwupd_json_object_add_integer(json_obj, FWUPD_RESULT_KEY_BIOS_SETTING_TYPE, priv->kind);
996
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION) {
997
0
    if (priv->possible_values->len > 0) {
998
0
      g_autoptr(FwupdJsonArray) json_arr = fwupd_json_array_new();
999
0
      for (guint i = 0; i < priv->possible_values->len; i++) {
1000
0
        const gchar *tmp = g_ptr_array_index(priv->possible_values, i);
1001
0
        fwupd_json_array_add_string(json_arr, tmp);
1002
0
      }
1003
0
      fwupd_json_object_add_array(json_obj,
1004
0
                FWUPD_RESULT_KEY_BIOS_SETTING_POSSIBLE_VALUES,
1005
0
                json_arr);
1006
0
    }
1007
0
  }
1008
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER ||
1009
0
      priv->kind == FWUPD_BIOS_SETTING_KIND_STRING) {
1010
0
    fwupd_json_object_add_integer(json_obj,
1011
0
                FWUPD_RESULT_KEY_BIOS_SETTING_LOWER_BOUND,
1012
0
                priv->lower_bound);
1013
0
    fwupd_json_object_add_integer(json_obj,
1014
0
                FWUPD_RESULT_KEY_BIOS_SETTING_UPPER_BOUND,
1015
0
                priv->upper_bound);
1016
0
    if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER) {
1017
0
      fwupd_json_object_add_integer(
1018
0
          json_obj,
1019
0
          FWUPD_RESULT_KEY_BIOS_SETTING_SCALAR_INCREMENT,
1020
0
          priv->scalar_increment);
1021
0
    }
1022
0
  }
1023
0
}
1024
1025
static void
1026
fwupd_bios_setting_add_string(FwupdCodec *codec, guint idt, GString *str)
1027
0
{
1028
0
  FwupdBiosSetting *self = FWUPD_BIOS_SETTING(codec);
1029
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
1030
1031
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_NAME, priv->name);
1032
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_BIOS_SETTING_ID, priv->id);
1033
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
1034
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_FILENAME, priv->path);
1035
0
  fwupd_codec_string_append_int(str, idt, FWUPD_RESULT_KEY_BIOS_SETTING_TYPE, priv->kind);
1036
0
  fwupd_codec_string_append(str,
1037
0
          idt,
1038
0
          FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
1039
0
          priv->current_value);
1040
0
  fwupd_codec_string_append(str,
1041
0
          idt,
1042
0
          FWUPD_RESULT_KEY_BIOS_SETTING_READ_ONLY,
1043
0
          priv->read_only ? "True" : "False");
1044
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_ENUMERATION) {
1045
0
    for (guint i = 0; i < priv->possible_values->len; i++) {
1046
0
      const gchar *tmp = g_ptr_array_index(priv->possible_values, i);
1047
0
      fwupd_codec_string_append(str,
1048
0
              idt,
1049
0
              FWUPD_RESULT_KEY_BIOS_SETTING_POSSIBLE_VALUES,
1050
0
              tmp);
1051
0
    }
1052
0
  }
1053
0
  if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER ||
1054
0
      priv->kind == FWUPD_BIOS_SETTING_KIND_STRING) {
1055
0
    fwupd_codec_string_append_int(str,
1056
0
                idt,
1057
0
                FWUPD_RESULT_KEY_BIOS_SETTING_LOWER_BOUND,
1058
0
                priv->lower_bound);
1059
0
    fwupd_codec_string_append_int(str,
1060
0
                idt,
1061
0
                FWUPD_RESULT_KEY_BIOS_SETTING_UPPER_BOUND,
1062
0
                priv->upper_bound);
1063
0
    if (priv->kind == FWUPD_BIOS_SETTING_KIND_INTEGER) {
1064
0
      fwupd_codec_string_append_int(
1065
0
          str,
1066
0
          idt,
1067
0
          FWUPD_RESULT_KEY_BIOS_SETTING_SCALAR_INCREMENT,
1068
0
          priv->scalar_increment);
1069
0
    }
1070
0
  }
1071
0
}
1072
1073
static void
1074
fwupd_bios_setting_class_init(FwupdBiosSettingClass *klass)
1075
0
{
1076
0
  GObjectClass *object_class = G_OBJECT_CLASS(klass);
1077
0
  object_class->finalize = fwupd_bios_setting_finalize;
1078
0
}
1079
1080
static void
1081
fwupd_bios_setting_init(FwupdBiosSetting *self)
1082
0
{
1083
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
1084
0
  priv->possible_values = g_ptr_array_new_with_free_func(g_free);
1085
0
}
1086
1087
static void
1088
fwupd_bios_setting_finalize(GObject *object)
1089
0
{
1090
0
  FwupdBiosSetting *self = FWUPD_BIOS_SETTING(object);
1091
0
  FwupdBiosSettingPrivate *priv = GET_PRIVATE(self);
1092
1093
0
  g_free(priv->current_value);
1094
0
  g_free(priv->id);
1095
0
  g_free(priv->name);
1096
0
  g_free(priv->description);
1097
0
  g_free(priv->path);
1098
0
  g_ptr_array_unref(priv->possible_values);
1099
1100
0
  G_OBJECT_CLASS(fwupd_bios_setting_parent_class)->finalize(object);
1101
0
}
1102
1103
static void
1104
fwupd_bios_setting_from_variant_iter(FwupdCodec *codec, GVariantIter *iter)
1105
0
{
1106
0
  FwupdBiosSetting *self = FWUPD_BIOS_SETTING(codec);
1107
0
  GVariant *value;
1108
0
  const gchar *key;
1109
0
  while (g_variant_iter_next(iter, "{&sv}", &key, &value)) {
1110
0
    fwupd_bios_setting_from_key_value(self, key, value);
1111
0
    g_variant_unref(value);
1112
0
  }
1113
0
}
1114
1115
static void
1116
fwupd_bios_setting_codec_iface_init(FwupdCodecInterface *iface)
1117
0
{
1118
0
  iface->add_string = fwupd_bios_setting_add_string;
1119
0
  iface->add_json = fwupd_bios_setting_add_json;
1120
0
  iface->from_json = fwupd_bios_setting_from_json;
1121
0
  iface->add_variant = fwupd_bios_setting_add_variant;
1122
0
  iface->from_variant_iter = fwupd_bios_setting_from_variant_iter;
1123
0
}
1124
1125
/**
1126
 * fwupd_bios_setting_new:
1127
 * @name: (nullable): the attribute name
1128
 * @path: (nullable): the path the driver providing this attribute uses
1129
 *
1130
 * Creates a new bios setting.
1131
 *
1132
 * Returns: a new #FwupdBiosSetting.
1133
 *
1134
 * Since: 1.8.4
1135
 **/
1136
FwupdBiosSetting *
1137
fwupd_bios_setting_new(const gchar *name, const gchar *path)
1138
0
{
1139
0
  FwupdBiosSetting *self;
1140
1141
0
  self = g_object_new(FWUPD_TYPE_BIOS_SETTING, NULL);
1142
0
  if (name != NULL)
1143
0
    fwupd_bios_setting_set_name(self, name);
1144
0
  if (path != NULL)
1145
0
    fwupd_bios_setting_set_path(self, path);
1146
1147
0
  return FWUPD_BIOS_SETTING(self);
1148
0
}