[PATCH 1/3] ntdll: Factor out SMBIOS table creation.
Brendan Shanks
bshanks at codeweavers.com
Mon Sep 13 17:07:25 CDT 2021
Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
---
dlls/ntdll/unix/system.c | 374 +++++++++++++++++++++------------------
1 file changed, 202 insertions(+), 172 deletions(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 2cdc6278f3d..145cb0810cd 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -1264,13 +1264,200 @@ static NTSTATUS create_cpuset_info(SYSTEM_CPU_SET_INFORMATION *info)
#ifdef linux
-static void copy_smbios_string( char **buffer, char *s, size_t len )
+static void copy_smbios_string( char **buffer, const char *s, size_t len )
{
if (!len) return;
memcpy(*buffer, s, len + 1);
*buffer += len + 1;
}
+#define S(s) const char * s, size_t s ## _len
+static NTSTATUS create_smbios_tables( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
+ ULONG *required_len,
+ S(bios_vendor), S(bios_version), S(bios_date),
+ S(system_vendor), S(system_product), S(system_version),
+ S(system_serial), const GUID *system_uuid, S(system_sku),
+ S(system_family),
+ S(board_vendor), S(board_product), S(board_version),
+ S(board_serial), S(board_asset_tag),
+ S(chassis_vendor), BYTE chassis_type, S(chassis_version),
+ S(chassis_serial), S(chassis_asset_tag) )
+#undef S
+{
+ char *buffer = (char*)sfti->TableBuffer;
+ BYTE string_count;
+ BYTE handle_count = 0;
+ struct smbios_prologue *prologue;
+ struct smbios_bios *bios;
+ struct smbios_system *system;
+ struct smbios_board *board;
+ struct smbios_chassis *chassis;
+ struct smbios_boot_info *boot_info;
+ struct smbios_header *end_of_table;
+
+ *required_len = sizeof(struct smbios_prologue);
+
+#define L(l) (l + (l ? 1 : 0))
+ *required_len += sizeof(struct smbios_bios);
+ *required_len += max(L(bios_vendor_len) + L(bios_version_len) + L(bios_date_len) + 1, 2);
+
+ *required_len += sizeof(struct smbios_system);
+ *required_len += max(L(system_vendor_len) + L(system_product_len) + L(system_version_len) +
+ L(system_serial_len) + L(system_sku_len) + L(system_family_len) + 1, 2);
+
+ *required_len += sizeof(struct smbios_board);
+ *required_len += max(L(board_vendor_len) + L(board_product_len) + L(board_version_len) +
+ L(board_serial_len) + L(board_asset_tag_len) + 1, 2);
+
+ *required_len += sizeof(struct smbios_chassis);
+ *required_len += max(L(chassis_vendor_len) + L(chassis_version_len) + L(chassis_serial_len) +
+ L(chassis_asset_tag_len) + 1, 2);
+
+ *required_len += sizeof(struct smbios_boot_info);
+ *required_len += 2;
+
+ *required_len += sizeof(struct smbios_header);
+ *required_len += 2;
+#undef L
+
+ sfti->TableBufferLength = *required_len;
+
+ *required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+
+ if (available_len < *required_len)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ prologue = (struct smbios_prologue*)buffer;
+ prologue->calling_method = 0;
+ prologue->major_version = 2;
+ prologue->minor_version = 4;
+ prologue->revision = 0;
+ prologue->length = sfti->TableBufferLength - sizeof(struct smbios_prologue);
+ buffer += sizeof(struct smbios_prologue);
+
+ string_count = 0;
+ bios = (struct smbios_bios*)buffer;
+ bios->hdr.type = 0;
+ bios->hdr.length = sizeof(struct smbios_bios);
+ bios->hdr.handle = handle_count++;
+ bios->vendor = bios_vendor_len ? ++string_count : 0;
+ bios->version = bios_version_len ? ++string_count : 0;
+ bios->start = 0;
+ bios->date = bios_date_len ? ++string_count : 0;
+ bios->size = 0;
+ bios->characteristics = 0x4; /* not supported */
+ bios->characteristics_ext[0] = 0;
+ bios->characteristics_ext[1] = 0;
+ bios->system_bios_major_release = 0xFF; /* not supported */
+ bios->system_bios_minor_release = 0xFF; /* not supported */
+ bios->ec_firmware_major_release = 0xFF; /* not supported */
+ bios->ec_firmware_minor_release = 0xFF; /* not supported */
+ buffer += sizeof(struct smbios_bios);
+
+ copy_smbios_string(&buffer, bios_vendor, bios_vendor_len);
+ copy_smbios_string(&buffer, bios_version, bios_version_len);
+ copy_smbios_string(&buffer, bios_date, bios_date_len);
+ if (!string_count) *buffer++ = 0;
+ *buffer++ = 0;
+
+ string_count = 0;
+ system = (struct smbios_system*)buffer;
+ system->hdr.type = 1;
+ system->hdr.length = sizeof(struct smbios_system);
+ system->hdr.handle = handle_count++;
+ system->vendor = system_vendor_len ? ++string_count : 0;
+ system->product = system_product_len ? ++string_count : 0;
+ system->version = system_version_len ? ++string_count : 0;
+ system->serial = system_serial_len ? ++string_count : 0;
+ memcpy( system->uuid, system_uuid, sizeof(GUID) );
+ system->wake_up_type = 0x02; /* unknown */
+ system->sku_number = system_sku_len ? ++string_count : 0;
+ system->family = system_family_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_system);
+
+ copy_smbios_string(&buffer, system_vendor, system_vendor_len);
+ copy_smbios_string(&buffer, system_product, system_product_len);
+ copy_smbios_string(&buffer, system_version, system_version_len);
+ copy_smbios_string(&buffer, system_serial, system_serial_len);
+ copy_smbios_string(&buffer, system_sku, system_sku_len);
+ copy_smbios_string(&buffer, system_family, system_family_len);
+ if (!string_count) *buffer++ = 0;
+ *buffer++ = 0;
+
+ string_count = 0;
+ chassis = (struct smbios_chassis*)buffer;
+ chassis->hdr.type = 3;
+ chassis->hdr.length = sizeof(struct smbios_chassis);
+ chassis->hdr.handle = handle_count++;
+ chassis->vendor = chassis_vendor_len ? ++string_count : 0;
+ chassis->type = chassis_type;
+ chassis->version = chassis_version_len ? ++string_count : 0;
+ chassis->serial = chassis_serial_len ? ++string_count : 0;
+ chassis->asset_tag = chassis_asset_tag_len ? ++string_count : 0;
+ chassis->boot_state = 0x02; /* unknown */
+ chassis->power_supply_state = 0x02; /* unknown */
+ chassis->thermal_state = 0x02; /* unknown */
+ chassis->security_status = 0x02; /* unknown */
+ chassis->oem_defined = 0;
+ chassis->height = 0; /* undefined */
+ chassis->num_power_cords = 0; /* unspecified */
+ chassis->num_contained_elements = 0;
+ chassis->contained_element_rec_length = 3;
+ buffer += sizeof(struct smbios_chassis);
+
+ copy_smbios_string(&buffer, chassis_vendor, chassis_vendor_len);
+ copy_smbios_string(&buffer, chassis_version, chassis_version_len);
+ copy_smbios_string(&buffer, chassis_serial, chassis_serial_len);
+ copy_smbios_string(&buffer, chassis_asset_tag, chassis_asset_tag_len);
+ if (!string_count) *buffer++ = 0;
+ *buffer++ = 0;
+
+ string_count = 0;
+ board = (struct smbios_board*)buffer;
+ board->hdr.type = 2;
+ board->hdr.length = sizeof(struct smbios_board);
+ board->hdr.handle = handle_count++;
+ board->vendor = board_vendor_len ? ++string_count : 0;
+ board->product = board_product_len ? ++string_count : 0;
+ board->version = board_version_len ? ++string_count : 0;
+ board->serial = board_serial_len ? ++string_count : 0;
+ board->asset_tag = board_asset_tag_len ? ++string_count : 0;
+ board->feature_flags = 0x5; /* hosting board, removable */
+ board->location = 0;
+ board->chassis_handle = chassis->hdr.handle;
+ board->board_type = 0xa; /* motherboard */
+ board->num_contained_handles = 0;
+ buffer += sizeof(struct smbios_board);
+
+ copy_smbios_string(&buffer, board_vendor, board_vendor_len);
+ copy_smbios_string(&buffer, board_product, board_product_len);
+ copy_smbios_string(&buffer, board_version, board_version_len);
+ copy_smbios_string(&buffer, board_serial, board_serial_len);
+ copy_smbios_string(&buffer, board_asset_tag, board_asset_tag_len);
+ if (!string_count) *buffer++ = 0;
+ *buffer++ = 0;
+
+ boot_info = (struct smbios_boot_info*)buffer;
+ boot_info->hdr.type = 32;
+ boot_info->hdr.length = sizeof(struct smbios_boot_info);
+ boot_info->hdr.handle = handle_count++;
+ memset(boot_info->reserved, 0, sizeof(boot_info->reserved));
+ memset(boot_info->boot_status, 0, sizeof(boot_info->boot_status)); /* no errors detected */
+ buffer += sizeof(struct smbios_boot_info);
+ *buffer++ = 0;
+ *buffer++ = 0;
+
+ end_of_table = (struct smbios_header*)buffer;
+ end_of_table->type = 127;
+ end_of_table->length = sizeof(struct smbios_header);
+ end_of_table->handle = handle_count++;
+ buffer += sizeof(struct smbios_header);
+ *buffer++ = 0;
+ *buffer++ = 0;
+
+ return STATUS_SUCCESS;
+}
+
static size_t get_smbios_string( const char *path, char *str, size_t size )
{
FILE *file;
@@ -1343,16 +1530,7 @@ static NTSTATUS get_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULON
char chassis_vendor[128], chassis_version[128], chassis_serial[128], chassis_asset_tag[128];
char chassis_type[11] = "2"; /* unknown */
size_t chassis_vendor_len, chassis_version_len, chassis_serial_len, chassis_asset_tag_len;
- char *buffer = (char*)sfti->TableBuffer;
- BYTE string_count;
- BYTE handle_count = 0;
- struct smbios_prologue *prologue;
- struct smbios_bios *bios;
- struct smbios_system *system;
- struct smbios_board *board;
- struct smbios_chassis *chassis;
- struct smbios_boot_info *boot_info;
- struct smbios_header *end_of_table;
+ GUID system_uuid;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
@@ -1376,167 +1554,19 @@ static NTSTATUS get_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULON
get_smbios_string("/sys/class/dmi/id/chassis_type", S(chassis_type));
#undef S
- *required_len = sizeof(struct smbios_prologue);
-
-#define L(l) (l + (l ? 1 : 0))
- *required_len += sizeof(struct smbios_bios);
- *required_len += max(L(bios_vendor_len) + L(bios_version_len) + L(bios_date_len) + 1, 2);
-
- *required_len += sizeof(struct smbios_system);
- *required_len += max(L(system_vendor_len) + L(system_product_len) + L(system_version_len) +
- L(system_serial_len) + L(system_sku_len) + L(system_family_len) + 1, 2);
-
- *required_len += sizeof(struct smbios_board);
- *required_len += max(L(board_vendor_len) + L(board_product_len) + L(board_version_len) +
- L(board_serial_len) + L(board_asset_tag_len) + 1, 2);
-
- *required_len += sizeof(struct smbios_chassis);
- *required_len += max(L(chassis_vendor_len) + L(chassis_version_len) + L(chassis_serial_len) +
- L(chassis_asset_tag_len) + 1, 2);
-
- *required_len += sizeof(struct smbios_boot_info);
- *required_len += 2;
-
- *required_len += sizeof(struct smbios_header);
- *required_len += 2;
-#undef L
-
- sfti->TableBufferLength = *required_len;
-
- *required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
-
- if (available_len < *required_len)
- return STATUS_BUFFER_TOO_SMALL;
-
- prologue = (struct smbios_prologue*)buffer;
- prologue->calling_method = 0;
- prologue->major_version = 2;
- prologue->minor_version = 4;
- prologue->revision = 0;
- prologue->length = sfti->TableBufferLength - sizeof(struct smbios_prologue);
- buffer += sizeof(struct smbios_prologue);
-
- string_count = 0;
- bios = (struct smbios_bios*)buffer;
- bios->hdr.type = 0;
- bios->hdr.length = sizeof(struct smbios_bios);
- bios->hdr.handle = handle_count++;
- bios->vendor = bios_vendor_len ? ++string_count : 0;
- bios->version = bios_version_len ? ++string_count : 0;
- bios->start = 0;
- bios->date = bios_date_len ? ++string_count : 0;
- bios->size = 0;
- bios->characteristics = 0x4; /* not supported */
- bios->characteristics_ext[0] = 0;
- bios->characteristics_ext[1] = 0;
- bios->system_bios_major_release = 0xFF; /* not supported */
- bios->system_bios_minor_release = 0xFF; /* not supported */
- bios->ec_firmware_major_release = 0xFF; /* not supported */
- bios->ec_firmware_minor_release = 0xFF; /* not supported */
- buffer += sizeof(struct smbios_bios);
-
- copy_smbios_string(&buffer, bios_vendor, bios_vendor_len);
- copy_smbios_string(&buffer, bios_version, bios_version_len);
- copy_smbios_string(&buffer, bios_date, bios_date_len);
- if (!string_count) *buffer++ = 0;
- *buffer++ = 0;
-
- string_count = 0;
- system = (struct smbios_system*)buffer;
- system->hdr.type = 1;
- system->hdr.length = sizeof(struct smbios_system);
- system->hdr.handle = handle_count++;
- system->vendor = system_vendor_len ? ++string_count : 0;
- system->product = system_product_len ? ++string_count : 0;
- system->version = system_version_len ? ++string_count : 0;
- system->serial = system_serial_len ? ++string_count : 0;
- get_system_uuid( (GUID *)system->uuid );
- system->wake_up_type = 0x02; /* unknown */
- system->sku_number = system_sku_len ? ++string_count : 0;
- system->family = system_family_len ? ++string_count : 0;
- buffer += sizeof(struct smbios_system);
-
- copy_smbios_string(&buffer, system_vendor, system_vendor_len);
- copy_smbios_string(&buffer, system_product, system_product_len);
- copy_smbios_string(&buffer, system_version, system_version_len);
- copy_smbios_string(&buffer, system_serial, system_serial_len);
- copy_smbios_string(&buffer, system_sku, system_sku_len);
- copy_smbios_string(&buffer, system_family, system_family_len);
- if (!string_count) *buffer++ = 0;
- *buffer++ = 0;
-
- string_count = 0;
- chassis = (struct smbios_chassis*)buffer;
- chassis->hdr.type = 3;
- chassis->hdr.length = sizeof(struct smbios_chassis);
- chassis->hdr.handle = handle_count++;
- chassis->vendor = chassis_vendor_len ? ++string_count : 0;
- chassis->type = atoi(chassis_type);
- chassis->version = chassis_version_len ? ++string_count : 0;
- chassis->serial = chassis_serial_len ? ++string_count : 0;
- chassis->asset_tag = chassis_asset_tag_len ? ++string_count : 0;
- chassis->boot_state = 0x02; /* unknown */
- chassis->power_supply_state = 0x02; /* unknown */
- chassis->thermal_state = 0x02; /* unknown */
- chassis->security_status = 0x02; /* unknown */
- chassis->oem_defined = 0;
- chassis->height = 0; /* undefined */
- chassis->num_power_cords = 0; /* unspecified */
- chassis->num_contained_elements = 0;
- chassis->contained_element_rec_length = 3;
- buffer += sizeof(struct smbios_chassis);
-
- copy_smbios_string(&buffer, chassis_vendor, chassis_vendor_len);
- copy_smbios_string(&buffer, chassis_version, chassis_version_len);
- copy_smbios_string(&buffer, chassis_serial, chassis_serial_len);
- copy_smbios_string(&buffer, chassis_asset_tag, chassis_asset_tag_len);
- if (!string_count) *buffer++ = 0;
- *buffer++ = 0;
-
- string_count = 0;
- board = (struct smbios_board*)buffer;
- board->hdr.type = 2;
- board->hdr.length = sizeof(struct smbios_board);
- board->hdr.handle = handle_count++;
- board->vendor = board_vendor_len ? ++string_count : 0;
- board->product = board_product_len ? ++string_count : 0;
- board->version = board_version_len ? ++string_count : 0;
- board->serial = board_serial_len ? ++string_count : 0;
- board->asset_tag = board_asset_tag_len ? ++string_count : 0;
- board->feature_flags = 0x5; /* hosting board, removable */
- board->location = 0;
- board->chassis_handle = chassis->hdr.handle;
- board->board_type = 0xa; /* motherboard */
- board->num_contained_handles = 0;
- buffer += sizeof(struct smbios_board);
-
- copy_smbios_string(&buffer, board_vendor, board_vendor_len);
- copy_smbios_string(&buffer, board_product, board_product_len);
- copy_smbios_string(&buffer, board_version, board_version_len);
- copy_smbios_string(&buffer, board_serial, board_serial_len);
- copy_smbios_string(&buffer, board_asset_tag, board_asset_tag_len);
- if (!string_count) *buffer++ = 0;
- *buffer++ = 0;
-
- boot_info = (struct smbios_boot_info*)buffer;
- boot_info->hdr.type = 32;
- boot_info->hdr.length = sizeof(struct smbios_boot_info);
- boot_info->hdr.handle = handle_count++;
- memset(boot_info->reserved, 0, sizeof(boot_info->reserved));
- memset(boot_info->boot_status, 0, sizeof(boot_info->boot_status)); /* no errors detected */
- buffer += sizeof(struct smbios_boot_info);
- *buffer++ = 0;
- *buffer++ = 0;
-
- end_of_table = (struct smbios_header*)buffer;
- end_of_table->type = 127;
- end_of_table->length = sizeof(struct smbios_header);
- end_of_table->handle = handle_count++;
- buffer += sizeof(struct smbios_header);
- *buffer++ = 0;
- *buffer++ = 0;
-
- return STATUS_SUCCESS;
+ get_system_uuid(&system_uuid);
+
+#define S(s) s, s ## _len
+ return create_smbios_tables( sfti, available_len, required_len,
+ S(bios_vendor), S(bios_version), S(bios_date),
+ S(system_vendor), S(system_product), S(system_version),
+ S(system_serial), &system_uuid, S(system_sku),
+ S(system_family),
+ S(board_vendor), S(board_product), S(board_version),
+ S(board_serial), S(board_asset_tag),
+ S(chassis_vendor), atoi(chassis_type), S(chassis_version),
+ S(chassis_serial), S(chassis_asset_tag) );
+#undef S
}
default:
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION provider %08x\n", sfti->ProviderSignature);
--
2.30.1 (Apple Git-130)
More information about the wine-devel
mailing list