From 805dced32cbb2eef1f2b639100faef3bb0482e29 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 1 Apr 2009 16:10:55 +0200 Subject: Added indenting tool for C code and reindented *.[ch] files --- src/config.h | 1 + src/dmidecode.c | 9007 ++++++++++++++++++++++++++----------------------- src/dmidecode.h | 31 +- src/dmidecodemodule.c | 574 ++-- src/dmidecodemodule.h | 38 +- src/dmihelper.c | 24 +- src/dmihelper.h | 151 +- src/dmioem.c | 125 +- src/dmioem.h | 1 + src/types.h | 20 +- src/util.c | 234 +- src/util.h | 3 +- 12 files changed, 5433 insertions(+), 4776 deletions(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index c1d7d03..713ac5d 100644 --- a/src/config.h +++ b/src/config.h @@ -1,3 +1,4 @@ + /* * Configuration */ diff --git a/src/dmidecode.c b/src/dmidecode.c index 40cb861..d687c81 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1,3 +1,4 @@ + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DMI Decode @@ -84,6 +85,7 @@ static const char *out_of_spec = ""; static const char *bad_index = ""; + #define BAD_INDEX PyString_FromString("") #define OUT_OF_SPEC PyString_FromString("") @@ -91,292 +93,330 @@ static const char *bad_index = ""; ** Type-independant Stuff */ -static PyObject *dmi_string_py(const struct dmi_header *dm, u8 s) { - char *bp=(char *)dm->data; - size_t i, len; - - PyObject *data; - - if(s==0) data = PyString_FromString("Not Specified"); - else { - bp += dm->length; - while(s>1 && *bp) { bp += strlen(bp); bp++; s--; } - - if(!*bp) data = BAD_INDEX; - else { - /* ASCII filtering */ - len=strlen(bp); - for(i=0; idata; - size_t i, len; - - if(s == 0) return "Not Specified"; - - bp += dm->length; - while(s>1 && *bp) { - bp+=strlen(bp); - bp++; - s--; - } - - if(!*bp) return bad_index; - - /* ASCII filtering */ - len = strlen(bp); - for(i=0; i0x99 || (value&0x0F)>0x09) return 0; - if(valuehigh) return 0; - return 1; -} - -PyObject* dmi_dump(struct dmi_header *h) { - int row, i; - const char *s; - - PyObject *data = PyDict_New(); - PyObject *data1 = PyList_New(0); - for(row=0; row<((h->length-1)>>4)+1; row++) { - for(i=0; i<16 && ilength-(row<<4); i++) - PyList_Append(data1, PyString_FromFormat("0x%02x", (h->data)[(row<<4)+i])); - } - PyDict_SetItemString(data, "Header and Data", data1); - - if((h->data)[h->length] || (h->data)[h->length+1]) { - i=1; - PyObject *data2 = PyList_New(0); - while((s=dmi_string(h, i++))!=bad_index) { - //. FIXME: DUMP - /* - if(opt.flags & FLAG_DUMP) { - int j, l = strlen(s)+1; - for(row=0; row<((l-1)>>4)+1; row++) { - for(j=0; j<16 && jdata; + size_t i, len; + + PyObject *data; + + if(s == 0) + data = PyString_FromString("Not Specified"); + else { + bp += dm->length; + while(s > 1 && *bp) { + bp += strlen(bp); + bp++; + s--; + } + + if(!*bp) + data = BAD_INDEX; + else { + /* ASCII filtering */ + len = strlen(bp); + for(i = 0; i < len; i++) + if(bp[i] < 32 || bp[i] == 127) + bp[i] = '.'; + data = PyString_FromString(bp); + } + } + return data; +} + +const char *dmi_string(const struct dmi_header *dm, u8 s) +{ + char *bp = (char *)dm->data; + size_t i, len; + + if(s == 0) + return "Not Specified"; + + bp += dm->length; + while(s > 1 && *bp) { + bp += strlen(bp); + bp++; + s--; + } + + if(!*bp) + return bad_index; + + /* ASCII filtering */ + len = strlen(bp); + for(i = 0; i < len; i++) + if(bp[i] < 32 || bp[i] == 127) + bp[i] = '.'; + + return bp; +} + +static const char *dmi_smbios_structure_type(u8 code) +{ + static const char *type[] = { + "BIOS", /* 0 */ + "System", + "Base Board", + "Chassis", + "Processor", + "Memory Controller", + "Memory Module", + "Cache", + "Port Connector", + "System Slots", + "On Board Devices", + "OEM Strings", + "System Configuration Options", + "BIOS Language", + "Group Associations", + "System Event Log", + "Physical Memory Array", + "Memory Device", + "32-bit Memory Error", + "Memory Array Mapped Address", + "Memory Device Mapped Address", + "Built-in Pointing Device", + "Portable Battery", + "System Reset", + "Hardware Security", + "System Power Controls", + "Voltage Probe", + "Cooling Device", + "Temperature Probe", + "Electrical Current Probe", + "Out-of-band Remote Access", + "Boot Integrity Services", + "System Boot", + "64-bit Memory Error", + "Management Device", + "Management Device Component", + "Management Device Threshold Data", + "Memory Channel", + "IPMI Device", + "Power Supply" /* 39 */ + }; + + if(code <= 39) + return (type[code]); + return out_of_spec; +} + +static int dmi_bcd_range(u8 value, u8 low, u8 high) +{ + if(value > 0x99 || (value & 0x0F) > 0x09) + return 0; + if(value < low || value > high) + return 0; + return 1; +} + +PyObject *dmi_dump(struct dmi_header * h) +{ + int row, i; + const char *s; + + PyObject *data = PyDict_New(); + PyObject *data1 = PyList_New(0); + + for(row = 0; row < ((h->length - 1) >> 4) + 1; row++) { + for(i = 0; i < 16 && i < h->length - (row << 4); i++) + PyList_Append(data1, + PyString_FromFormat("0x%02x", (h->data)[(row << 4) + i])); } - fprintf(stderr, "\"%s\"|", s); - } - else fprintf(stderr, "%s|", s); - */ - PyList_Append(data1, PyString_FromFormat("%s", s)); - } - PyDict_SetItemString(data, "Strings", data2); - } - return data; + PyDict_SetItemString(data, "Header and Data", data1); + + if((h->data)[h->length] || (h->data)[h->length + 1]) { + i = 1; + PyObject *data2 = PyList_New(0); + + while((s = dmi_string(h, i++)) != bad_index) { + //. FIXME: DUMP + /* + * if(opt.flags & FLAG_DUMP) { + * int j, l = strlen(s)+1; + * for(row=0; row<((l-1)>>4)+1; row++) { + * for(j=0; j<16 && j>10); +static PyObject *dmi_bios_runtime_size(u32 code) +{ + if(code & 0x000003FF) + return PyString_FromFormat("%i bytes", code); + else + return PyString_FromFormat("%i kB", code >> 10); } /* 3.3.1.1 */ -static PyObject* dmi_bios_characteristics(u64 code) { - static const char *characteristics[] = { - "BIOS characteristics not supported", /* 3 */ - "ISA is supported", - "MCA is supported", - "EISA is supported", - "PCI is supported", - "PC Card (PCMCIA) is supported", - "PNP is supported", - "APM is supported", - "BIOS is upgradeable", - "BIOS shadowing is allowed", - "VLB is supported", - "ESCD support is available", - "Boot from CD is supported", - "Selectable boot is supported", - "BIOS ROM is socketed", - "Boot from PC Card (PCMCIA) is supported", - "EDD is supported", - "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)", - "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)", - "5.25\"/360 KB floppy services are supported (int 13h)", - "5.25\"/1.2 MB floppy services are supported (int 13h)", - "3.5\"/720 KB floppy services are supported (int 13h)", - "3.5\"/2.88 MB floppy services are supported (int 13h)", - "Print screen service is supported (int 5h)", - "8042 keyboard services are supported (int 9h)", - "Serial services are supported (int 14h)", - "Printer services are supported (int 17h)", - "CGA/mono video services are supported (int 10h)", - "NEC PC-98" /* 31 */ - }; - - PyObject *data; - if(code.l&(1<<3)) { - data = PyString_FromString(characteristics[0]); - } else { - int i; - data = PyDict_New(); - for(i=4; i<=31; i++) - PyDict_SetItemString(data, characteristics[i-3], code.l&(1<= 0x0206) - return PyString_FromFormat("%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] - ); - else - return PyString_FromFormat("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] - ); +PyObject *dmi_system_uuid_py(const u8 * p, u16 ver) +{ + int only0xFF = 1, only0x00 = 1; + int i; + + for(i = 0; i < 16 && (only0x00 || only0xFF); i++) { + if(p[i] != 0x00) + only0x00 = 0; + if(p[i] != 0xFF) + only0xFF = 0; + } + + if(only0xFF) + return PyString_FromString("Not Present"); + + if(only0x00) + return PyString_FromString("Not Settable"); + + /* + * As off version 2.6 of the SMBIOS specification, the first 3 + * fields of the UUID are supposed to be encoded on little-endian. + * The specification says that this is the defacto standard, + * however I've seen systems following RFC 4122 instead and use + * network byte order, so I am reluctant to apply the byte-swapping + * for older versions. + */ + if(ver >= 0x0206) + return + PyString_FromFormat + ("%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", p[3], + p[2], p[1], p[0], p[5], p[4], p[7], p[6], p[8], p[9], p[10], p[11], p[12], + p[13], p[14], p[15] + ); + else + return + PyString_FromFormat + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p[0], + p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], + p[13], p[14], p[15] + ); } /* 3.3.2.1 */ -static PyObject *dmi_system_wake_up_type(u8 code) { - static const char *type[]={ - "Reserved", /* 0x00 */ - "Other", - "Unknown", - "APM Timer", - "Modem Ring", - "LAN Remote", - "Power Switch", - "PCI PME#", - "AC Power Restored" /* 0x08 */ - }; - - if(code<=0x08) return PyString_FromString(type[code]); - return OUT_OF_SPEC; +static PyObject *dmi_system_wake_up_type(u8 code) +{ + static const char *type[] = { + "Reserved", /* 0x00 */ + "Other", + "Unknown", + "APM Timer", + "Modem Ring", + "LAN Remote", + "Power Switch", + "PCI PME#", + "AC Power Restored" /* 0x08 */ + }; + + if(code <= 0x08) + return PyString_FromString(type[code]); + return OUT_OF_SPEC; } /******************************************************************************* @@ -384,64 +424,72 @@ static PyObject *dmi_system_wake_up_type(u8 code) { */ /* 3.3.3.1 */ -static PyObject *dmi_base_board_features(u8 code) { - static const char *features[] = { - "Board is a hosting board", /* 0 */ - "Board requires at least one daughter board", - "Board is removable", - "Board is replaceable", - "Board is hot swappable" /* 4 */ - }; - - PyObject *data; - if((code&0x1F)==0) data = Py_None; - else { - int i; - data = PyList_New(5); - for(i=0; i<=4; i++) { - if(code&(1<=0x01 && code<=0x0D) - return PyString_FromString(type[code-0x01]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_base_board_handles(u8 count, const u8 *p) { - int i; - - PyObject *dict = PyDict_New(); - PyObject *list = PyList_New(count); - - for(i=0; i= 0x01 && code <= 0x0D) + return PyString_FromString(type[code - 0x01]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_base_board_handles(u8 count, const u8 * p) +{ + int i; + + PyObject *dict = PyDict_New(); + PyObject *list = PyList_New(count); + + for(i = 0; i < count; i++) + PyList_SET_ITEM(list, i, PyString_FromFormat("0x%04x", WORD(p + sizeof(u16) * i))); + + PyDict_SetItemString(dict, "Contained Object Handles", list); + Py_DECREF(list); + + return dict; } /******************************************************************************* @@ -449,732 +497,796 @@ static PyObject *dmi_base_board_handles(u8 count, const u8 *p) { */ /* 3.3.4.1 */ -const char *dmi_chassis_type(u8 code) { - static const char *type[] = { - "Other", /* 0x01 */ - "Unknown", - "Desktop", - "Low Profile Desktop", - "Pizza Box", - "Mini Tower", - "Tower", - "Portable", - "Laptop", - "Notebook", - "Hand Held", - "Docking Station", - "All In One", - "Sub Notebook", - "Space-saving", - "Lunch Box", - "Main Server Chassis", /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */ - "Expansion Chassis", - "Sub Chassis", - "Bus Expansion Chassis", - "Peripheral Chassis", - "RAID Chassis", - "Rack Mount Chassis", - "Sealed-case PC", - "Multi-system", - "CompactPCI", - "AdvancedTCA", /* 0x1B */ - "Blade", - "Blade Enclosing" /* 0x1D */ - }; - - if(code>=0x01 && code<=0x1B) - return type[code-0x01]; - return out_of_spec; -} - -static PyObject *dmi_chassis_type_py(u8 code) { - return PyString_FromString(dmi_chassis_type(code)); -} - -static PyObject *dmi_chassis_lock(u8 code) { - static const char *lock[] = { - "Not Present", /* 0x00 */ - "Present" /* 0x01 */ - }; - - return PyString_FromString(lock[code]); +const char *dmi_chassis_type(u8 code) +{ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "Desktop", + "Low Profile Desktop", + "Pizza Box", + "Mini Tower", + "Tower", + "Portable", + "Laptop", + "Notebook", + "Hand Held", + "Docking Station", + "All In One", + "Sub Notebook", + "Space-saving", + "Lunch Box", + "Main Server Chassis", /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */ + "Expansion Chassis", + "Sub Chassis", + "Bus Expansion Chassis", + "Peripheral Chassis", + "RAID Chassis", + "Rack Mount Chassis", + "Sealed-case PC", + "Multi-system", + "CompactPCI", + "AdvancedTCA", /* 0x1B */ + "Blade", + "Blade Enclosing" /* 0x1D */ + }; + + if(code >= 0x01 && code <= 0x1B) + return type[code - 0x01]; + return out_of_spec; +} + +static PyObject *dmi_chassis_type_py(u8 code) +{ + return PyString_FromString(dmi_chassis_type(code)); +} + +static PyObject *dmi_chassis_lock(u8 code) +{ + static const char *lock[] = { + "Not Present", /* 0x00 */ + "Present" /* 0x01 */ + }; + + return PyString_FromString(lock[code]); } /* 3.3.4.2 */ -static PyObject *dmi_chassis_state(u8 code) { - static const char *state[]={ - "Other", /* 0x01 */ - "Unknown", - "Safe", /* master.mif says OK */ - "Warning", - "Critical", - "Non-recoverable" /* 0x06 */ - }; +static PyObject *dmi_chassis_state(u8 code) +{ + static const char *state[] = { + "Other", /* 0x01 */ + "Unknown", + "Safe", /* master.mif says OK */ + "Warning", + "Critical", + "Non-recoverable" /* 0x06 */ + }; - if(code>=0x01 && code<=0x06) - return PyString_FromString(state[code-0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x06) + return PyString_FromString(state[code - 0x01]); + return OUT_OF_SPEC; } /* 3.3.4.3 */ -static const char *dmi_chassis_security_status(u8 code) { - static const char *status[]={ - "Other", /* 0x01 */ - "Unknown", - "None", - "External Interface Locked Out", - "External Interface Enabled" /* 0x05 */ - }; +static const char *dmi_chassis_security_status(u8 code) +{ + static const char *status[] = { + "Other", /* 0x01 */ + "Unknown", + "None", + "External Interface Locked Out", + "External Interface Enabled" /* 0x05 */ + }; - if(code>=0x01 && code<=0x05) - return(status[code-0x01]); - return out_of_spec; + if(code >= 0x01 && code <= 0x05) + return (status[code - 0x01]); + return out_of_spec; } -static PyObject *dmi_chassis_height(u8 code) { - if(code==0x00) return PyString_FromString("Unspecified"); - else return PyString_FromFormat("%i U", code); +static PyObject *dmi_chassis_height(u8 code) +{ + if(code == 0x00) + return PyString_FromString("Unspecified"); + else + return PyString_FromFormat("%i U", code); } -static PyObject *dmi_chassis_power_cords(u8 code) { - if(code==0x00) return PyString_FromString("Unspecified"); - else return PyString_FromFormat("%i", code); +static PyObject *dmi_chassis_power_cords(u8 code) +{ + if(code == 0x00) + return PyString_FromString("Unspecified"); + else + return PyString_FromFormat("%i", code); } -static PyObject *dmi_chassis_elements(u8 count, u8 len, const u8 *p) { - int i; +static PyObject *dmi_chassis_elements(u8 count, u8 len, const u8 * p) +{ + int i; + + PyObject *data = PyDict_New(); + + PyDict_SetItemString(data, "Contained Elements", PyInt_FromLong(count)); - PyObject *data = PyDict_New(); - PyDict_SetItemString(data, "Contained Elements", PyInt_FromLong(count)); + PyObject *_key, *_val; - PyObject *_key, *_val; - for(i=0; i=0x03) { + for(i = 0; i < count; i++) { + if(len >= 0x03) { - _key = PyString_FromFormat("%s", - p[i*len]&0x80? - dmi_smbios_structure_type(p[i*len]&0x7F): - PyString_AS_STRING(dmi_base_board_type(p[i*len]&0x7F)) - ); + _key = PyString_FromFormat("%s", + p[i * len] & 0x80 ? + dmi_smbios_structure_type(p[i * len] & 0x7F) : + PyString_AS_STRING(dmi_base_board_type + (p[i * len] & 0x7F)) + ); - if (p[1+i*len]==p[2+i*len]) _val = PyString_FromFormat("%i", p[1+i*len]); - else _val = PyString_FromFormat("%i-%i", p[1+i*len], p[2+i*len]); + if(p[1 + i * len] == p[2 + i * len]) + _val = PyString_FromFormat("%i", p[1 + i * len]); + else + _val = PyString_FromFormat("%i-%i", p[1 + i * len], p[2 + i * len]); - PyDict_SetItem(data, _key, _val); + PyDict_SetItem(data, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - } - } + Py_DECREF(_key); + Py_DECREF(_val); + } + } - return data; + return data; } /******************************************************************************* ** 3.3.5 Processor Information (Type 4) */ -static PyObject *dmi_processor_type(u8 code) { - /* 3.3.5.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Central Processor", - "Math Processor", - "DSP Processor", - "Video Processor" /* 0x06 */ - }; - - if(code>=0x01 && code<=0x06) return PyString_FromString(type[code-0x01]); - return OUT_OF_SPEC; -} - -static const char *dmi_processor_family(const struct dmi_header *h) { - const u8 *data = h->data; - unsigned int i, low, high; - u16 code; - - /* 3.3.5.2 */ - static struct { - int value; - const char *name; - } family2[] = { - { 0x01, "Other" }, - { 0x02, "Unknown" }, - { 0x03, "8086" }, - { 0x04, "80286" }, - { 0x05, "80386" }, - { 0x06, "80486" }, - { 0x07, "8087" }, - { 0x08, "80287" }, - { 0x09, "80387" }, - { 0x0A, "80487" }, - { 0x0B, "Pentium" }, - { 0x0C, "Pentium Pro" }, - { 0x0D, "Pentium II" }, - { 0x0E, "Pentium MMX" }, - { 0x0F, "Celeron" }, - { 0x10, "Pentium II Xeon" }, - { 0x11, "Pentium III" }, - { 0x12, "M1" }, - { 0x13, "M2" }, - { 0x14, "Celeron M" }, /* From CIM_Processor.Family */ - { 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */ - - { 0x18, "Duron" }, - { 0x19, "K5" }, - { 0x1A, "K6" }, - { 0x1B, "K6-2" }, - { 0x1C, "K6-3" }, - { 0x1D, "Athlon" }, - { 0x1E, "AMD29000" }, - { 0x1F, "K6-2+" }, - { 0x20, "Power PC" }, - { 0x21, "Power PC 601" }, - { 0x22, "Power PC 603" }, - { 0x23, "Power PC 603+" }, - { 0x24, "Power PC 604" }, - { 0x25, "Power PC 620" }, - { 0x26, "Power PC x704" }, - { 0x27, "Power PC 750" }, - { 0x28, "Core Duo" }, /* From CIM_Processor.Family */ - { 0x29, "Core Duo Mobile" }, /* From CIM_Processor.Family */ - { 0x2A, "Core Solo Mobile" }, /* From CIM_Processor.Family */ - { 0x2B, "Atom" }, /* From CIM_Processor.Family */ - - { 0x30, "Alpha" }, - { 0x31, "Alpha 21064" }, - { 0x32, "Alpha 21066" }, - { 0x33, "Alpha 21164" }, - { 0x34, "Alpha 21164PC" }, - { 0x35, "Alpha 21164a" }, - { 0x36, "Alpha 21264" }, - { 0x37, "Alpha 21364" }, - - { 0x40, "MIPS" }, - { 0x41, "MIPS R4000" }, - { 0x42, "MIPS R4200" }, - { 0x43, "MIPS R4400" }, - { 0x44, "MIPS R4600" }, - { 0x45, "MIPS R10000" }, - - { 0x50, "SPARC" }, - { 0x51, "SuperSPARC" }, - { 0x52, "MicroSPARC II" }, - { 0x53, "MicroSPARC IIep" }, - { 0x54, "UltraSPARC" }, - { 0x55, "UltraSPARC II" }, - { 0x56, "UltraSPARC IIi" }, - { 0x57, "UltraSPARC III" }, - { 0x58, "UltraSPARC IIIi" }, - - { 0x60, "68040" }, - { 0x61, "68xxx" }, - { 0x62, "68000" }, - { 0x63, "68010" }, - { 0x64, "68020" }, - { 0x65, "68030" }, - - { 0x70, "Hobbit" }, - - { 0x78, "Crusoe TM5000" }, - { 0x79, "Crusoe TM3000" }, - { 0x7A, "Efficeon TM8000" }, - - { 0x80, "Weitek" }, - - { 0x82, "Itanium" }, - { 0x83, "Athlon 64" }, - { 0x84, "Opteron" }, - { 0x85, "Sempron" }, - { 0x86, "Turion 64" }, - { 0x87, "Dual-Core Opteron" }, - { 0x88, "Athlon 64 X2" }, - { 0x89, "Turion 64 X2" }, - { 0x8A, "Quad-Core Opteron" }, /* From CIM_Processor.Family */ - { 0x8B, "Third-Generation Opteron" }, /* From CIM_Processor.Family */ - { 0x8C, "Phenom FX" }, /* From CIM_Processor.Family */ - { 0x8D, "Phenom X4" }, /* From CIM_Processor.Family */ - { 0x8E, "Phenom X2" }, /* From CIM_Processor.Family */ - { 0x8F, "Athlon X2" }, /* From CIM_Processor.Family */ - { 0x90, "PA-RISC" }, - { 0x91, "PA-RISC 8500" }, - { 0x92, "PA-RISC 8000" }, - { 0x93, "PA-RISC 7300LC" }, - { 0x94, "PA-RISC 7200" }, - { 0x95, "PA-RISC 7100LC" }, - { 0x96, "PA-RISC 7100" }, - - { 0xA0, "V30" }, - { 0xA1, "Quad-Core Xeon 3200" }, /* From CIM_Processor.Family */ - { 0xA2, "Dual-Core Xeon 3000" }, /* From CIM_Processor.Family */ - { 0xA3, "Quad-Core Xeon 5300" }, /* From CIM_Processor.Family */ - { 0xA4, "Dual-Core Xeon 5100" }, /* From CIM_Processor.Family */ - { 0xA5, "Dual-Core Xeon 5000" }, /* From CIM_Processor.Family */ - { 0xA6, "Dual-Core Xeon LV" }, /* From CIM_Processor.Family */ - { 0xA7, "Dual-Core Xeon ULV" }, /* From CIM_Processor.Family */ - { 0xA8, "Dual-Core Xeon 7100" }, /* From CIM_Processor.Family */ - { 0xA9, "Quad-Core Xeon 5400" }, /* From CIM_Processor.Family */ - { 0xAA, "Quad-Core Xeon" }, /* From CIM_Processor.Family */ - - { 0xB0, "Pentium III Xeon" }, - { 0xB1, "Pentium III Speedstep" }, - { 0xB2, "Pentium 4" }, - { 0xB3, "Xeon" }, - { 0xB4, "AS400" }, - { 0xB5, "Xeon MP" }, - { 0xB6, "Athlon XP" }, - { 0xB7, "Athlon MP" }, - { 0xB8, "Itanium 2" }, - { 0xB9, "Pentium M" }, - { 0xBA, "Celeron D" }, - { 0xBB, "Pentium D" }, - { 0xBC, "Pentium EE" }, - { 0xBD, "Core Solo" }, - /* 0xBE handled as a special case */ - { 0xBF, "Core 2 Duo" }, - { 0xC0, "Core 2 Solo" }, /* From CIM_Processor.Family */ - { 0xC1, "Core 2 Extreme" }, /* From CIM_Processor.Family */ - { 0xC2, "Core 2 Quad" }, /* From CIM_Processor.Family */ - { 0xC3, "Core 2 Extreme Mobile" }, /* From CIM_Processor.Family */ - { 0xC4, "Core 2 Duo Mobile" }, /* From CIM_Processor.Family */ - { 0xC5, "Core 2 Solo Mobile" }, /* From CIM_Processor.Family */ - - { 0xC8, "IBM390" }, - { 0xC9, "G4" }, - { 0xCA, "G5" }, - { 0xCB, "ESA/390 G6" }, - { 0xCC, "z/Architectur" }, - - { 0xD2, "C7-M" }, - { 0xD3, "C7-D" }, - { 0xD4, "C7" }, - { 0xD5, "Eden" }, - - { 0xFA, "i860" }, - { 0xFB, "i960" }, - - { 0x104, "SH-3" }, - { 0x105, "SH-4" }, - - { 0x118, "ARM" }, - { 0x119, "StrongARM" }, - - { 0x12C, "6x86" }, - { 0x12D, "MediaGX" }, - { 0x12E, "MII" }, - - { 0x140, "WinChip" }, - - { 0x15E, "DSP" }, - - { 0x1F4, "Video Processor" }, - }; - - /* Linear Search - Slow - for(i=0; ilength>=0x2A)?WORD(data+0x28):data[0x06]; - - /* Special case for ambiguous value 0xBE */ - if(code == 0xBE) { - const char *manufacturer = dmi_string(h, data[0x07]); - - /* Best bet based on manufacturer string */ - if(strstr(manufacturer, "Intel") != NULL || strncasecmp(manufacturer, "Intel", 5) == 0) - return "Core 2"; - if(strstr(manufacturer, "AMD") != NULL || strncasecmp(manufacturer, "AMD", 3) == 0) - return "K7"; - return "Core 2 or K7"; - } - - /* Perform a binary search */ - low = 0; - high = ARRAY_SIZE(family2) - 1; - while(1) { - i = (low + high) / 2; - if (family2[i].value == code) return family2[i].name; - if (low == high) /* Not found */ return out_of_spec; - if (code < family2[i].value) high = i; - else low = i + 1; - } - - return out_of_spec; -} - -static PyObject *dmi_processor_id(u8 type, const u8 *p, const char *version) { - PyObject *data = PyDict_New(); - - /* Intel AP-485 revision 31, table 3-4 */ - static const char *flags[32]={ - "FPU (Floating-point unit on-chip)", /* 0 */ - "VME (Virtual mode extension)", - "DE (Debugging extension)", - "PSE (Page size extension)", - "TSC (Time stamp counter)", - "MSR (Model specific registers)", - "PAE (Physical address extension)", - "MCE (Machine check exception)", - "CX8 (CMPXCHG8 instruction supported)", - "APIC (On-chip APIC hardware supported)", - NULL, /* 10 */ - "SEP (Fast system call)", - "MTRR (Memory type range registers)", - "PGE (Page global enable)", - "MCA (Machine check architecture)", - "CMOV (Conditional move instruction supported)", - "PAT (Page attribute table)", - "PSE-36 (36-bit page size extension)", - "PSN (Processor serial number present and enabled)", - "CLFSH (CLFLUSH instruction supported)", - NULL, /* 20 */ - "DS (Debug store)", - "ACPI (ACPI supported)", - "MMX (MMX technology supported)", - "FXSR (Fast floating-point save and restore)", - "SSE (Streaming SIMD extensions)", - "SSE2 (Streaming SIMD extensions 2)", - "SS (Self-snoop)", - "HTT (Hyper-threading technology)", - "TM (Thermal monitor supported)", - "IA64 (IA64 capabilities)", - "PBE (Pending break enabled)" /* 31 */ - }; - /* - ** Extra flags are now returned in the ECX register when one calls - ** the CPUID instruction. Their meaning is explained in table 3-5, but - ** DMI doesn't support this yet. - */ - u32 eax, edx; - int sig=0; - - /* - ** This might help learn about new processors supporting the - ** CPUID instruction or another form of identification. - */ - - //. TODO: PyString_FromFormat does not support %x (yet?)... - PyDict_SetItemString(data, "ID", - PyString_FromFormat("%02x %02x %02x %02x %02x %02x %02x %02x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] - ) - ); - - if(type==0x05) /* 80386 */ { - u16 dx=WORD(p); - /* - ** 80386 have a different signature. - */ - PyDict_SetItemString(data, "Signature", - PyString_FromFormat( - "Type %i, Family %i, Major Stepping %i, Minor Stepping %i", - dx>>12, (dx>>8)&0xF, (dx>>4)&0xF, dx&0xF - ) - ); - return data; - } - - if(type==0x06) /* 80486 */ { - u16 dx=WORD(p); - /* - ** Not all 80486 CPU support the CPUID instruction, we have to find - ** wether the one we have here does or not. Note that this trick - ** works only because we know that 80486 must be little-endian. - */ - if((dx&0x0F00)==0x0400 - &&((dx&0x00F0)==0x0040 || (dx&0x00F0)>=0x0070) - &&((dx&0x000F)>=0x0003)) sig=1; - else { - PyDict_SetItemString(data, "Signature", - PyString_FromFormat( - "Type %i, Family %i, Model %i, Stepping %i", - (dx>>12)&0x3, (dx>>8)&0xF, (dx>>4)&0xF, dx&0xF - ) - ); - return data; - } - } else if( - ( - type >= 0x0B && type <= 0x15) /* Intel, Cyrix */ - || (type >= 0x28 && type <= 0x2B) /* Intel */ - || (type >= 0xA1 && type <= 0xAA) /* Intel */ - || (type >= 0xB0 && type <= 0xB3) /* Intel */ - || type == 0xB5 /* Intel */ - || (type >= 0xB9 && type <= 0xC5) /* Intel */ - || (type >= 0xD2 && type <= 0xD5) /* VIA */ - ) sig=1; - else if( - ( - type >= 0x18 && type <= 0x1D) /* AMD */ - || type == 0x1F /* AMD */ - || (type >= 0x83 && type <= 0x8F) /* AMD */ - || (type >= 0xB6 && type <= 0xB7) /* AMD */ - || (type >= 0xE6 && type <= 0xEB) /* AMD */ - ) sig=2; - else if(type==0x01 || type==0x02) { - /* - ** Some X86-class CPU have family "Other" or "Unknown". In this case, - ** we use the version string to determine if they are known to - ** support the CPUID instruction. - */ - if( - strncmp(version, "Pentium III MMX", 15) == 0 - || strncmp(version, "Intel(R) Core(TM)2", 18) == 0 - || strncmp(version, "Intel(R) Pentium(R)", 19) == 0 - || strcmp(version, "Genuine Intel(R) CPU U1400") == 0 - ) sig = 1; - else if( - strncmp(version, "AMD Athlon(TM)", 14) == 0 - || strncmp(version, "AMD Opteron(tm)", 15) == 0 - || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0 - ) sig = 2; - else return data; - } else /* not X86-class */ return data; - - eax=DWORD(p); - edx=DWORD(p+4); - switch(sig) { - case 1: /* Intel */ - PyDict_SetItemString(data, "Signature", - PyString_FromFormat( - "Type %i, Family %i, Model %i, Stepping %i", - (eax>>12)&0x3, ((eax>>20)&0xFF)+((eax>>8)&0x0F), - ((eax>>12)&0xF0)+((eax>>4)&0x0F), eax&0xF - ) - ); - break; - case 2: /* AMD, publication #25481 revision 2.28 */ - PyDict_SetItemString(data, "Signature", - PyString_FromFormat( - "Family %i, Model %i, Stepping %i", - ((eax>>8)&0xF)+(((eax>>8)&0xF)==0xF?(eax>>20)&0xFF:0), - ((eax>>4)&0xF)|(((eax>>8)&0xF)==0xF?(eax>>12)&0xF0:0), - eax&0xF - ) - ); - break; - } - - edx=DWORD(p+4); - if((edx&0xFFEFFBFF)==0) PyDict_SetItemString(data, "Flags", Py_None); - else { - int i; - PyObject *subdata = PyDict_New(); - for(i=0; i<=31; i++) - if(flags[i]!=NULL) - PyDict_SetItemString(subdata, flags[i], (edx&(1<= 0x01 && code <= 0x06) + return PyString_FromString(type[code - 0x01]); + return OUT_OF_SPEC; +} + +static const char *dmi_processor_family(const struct dmi_header *h) +{ + const u8 *data = h->data; + unsigned int i, low, high; + u16 code; + + /* 3.3.5.2 */ + static struct { + int value; + const char *name; + } family2[] = { + /* *INDENT-OFF* */ + { 0x01, "Other" }, + { 0x02, "Unknown" }, + { 0x03, "8086" }, + { 0x04, "80286" }, + { 0x05, "80386" }, + { 0x06, "80486" }, + { 0x07, "8087" }, + { 0x08, "80287" }, + { 0x09, "80387" }, + { 0x0A, "80487" }, + { 0x0B, "Pentium" }, + { 0x0C, "Pentium Pro" }, + { 0x0D, "Pentium II" }, + { 0x0E, "Pentium MMX" }, + { 0x0F, "Celeron" }, + { 0x10, "Pentium II Xeon" }, + { 0x11, "Pentium III" }, + { 0x12, "M1" }, + { 0x13, "M2" }, + { 0x14, "Celeron M" }, /* From CIM_Processor.Family */ + { 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */ + + { 0x18, "Duron" }, + { 0x19, "K5" }, + { 0x1A, "K6" }, + { 0x1B, "K6-2" }, + { 0x1C, "K6-3" }, + { 0x1D, "Athlon" }, + { 0x1E, "AMD29000" }, + { 0x1F, "K6-2+" }, + { 0x20, "Power PC" }, + { 0x21, "Power PC 601" }, + { 0x22, "Power PC 603" }, + { 0x23, "Power PC 603+" }, + { 0x24, "Power PC 604" }, + { 0x25, "Power PC 620" }, + { 0x26, "Power PC x704" }, + { 0x27, "Power PC 750" }, + { 0x28, "Core Duo" }, /* From CIM_Processor.Family */ + { 0x29, "Core Duo Mobile" }, /* From CIM_Processor.Family */ + { 0x2A, "Core Solo Mobile" }, /* From CIM_Processor.Family */ + { 0x2B, "Atom" }, /* From CIM_Processor.Family */ + + { 0x30, "Alpha" }, + { 0x31, "Alpha 21064" }, + { 0x32, "Alpha 21066" }, + { 0x33, "Alpha 21164" }, + { 0x34, "Alpha 21164PC" }, + { 0x35, "Alpha 21164a" }, + { 0x36, "Alpha 21264" }, + { 0x37, "Alpha 21364" }, + + { 0x40, "MIPS" }, + { 0x41, "MIPS R4000" }, + { 0x42, "MIPS R4200" }, + { 0x43, "MIPS R4400" }, + { 0x44, "MIPS R4600" }, + { 0x45, "MIPS R10000" }, + + { 0x50, "SPARC" }, + { 0x51, "SuperSPARC" }, + { 0x52, "MicroSPARC II" }, + { 0x53, "MicroSPARC IIep" }, + { 0x54, "UltraSPARC" }, + { 0x55, "UltraSPARC II" }, + { 0x56, "UltraSPARC IIi" }, + { 0x57, "UltraSPARC III" }, + { 0x58, "UltraSPARC IIIi" }, + + { 0x60, "68040" }, + { 0x61, "68xxx" }, + { 0x62, "68000" }, + { 0x63, "68010" }, + { 0x64, "68020" }, + { 0x65, "68030" }, + + { 0x70, "Hobbit" }, + + { 0x78, "Crusoe TM5000" }, + { 0x79, "Crusoe TM3000" }, + { 0x7A, "Efficeon TM8000" }, + + { 0x80, "Weitek" }, + + { 0x82, "Itanium" }, + { 0x83, "Athlon 64" }, + { 0x84, "Opteron" }, + { 0x85, "Sempron" }, + { 0x86, "Turion 64" }, + { 0x87, "Dual-Core Opteron" }, + { 0x88, "Athlon 64 X2" }, + { 0x89, "Turion 64 X2" }, + { 0x8A, "Quad-Core Opteron" }, /* From CIM_Processor.Family */ + { 0x8B, "Third-Generation Opteron" }, /* From CIM_Processor.Family */ + { 0x8C, "Phenom FX" }, /* From CIM_Processor.Family */ + { 0x8D, "Phenom X4" }, /* From CIM_Processor.Family */ + { 0x8E, "Phenom X2" }, /* From CIM_Processor.Family */ + { 0x8F, "Athlon X2" }, /* From CIM_Processor.Family */ + { 0x90, "PA-RISC" }, + { 0x91, "PA-RISC 8500" }, + { 0x92, "PA-RISC 8000" }, + { 0x93, "PA-RISC 7300LC" }, + { 0x94, "PA-RISC 7200" }, + { 0x95, "PA-RISC 7100LC" }, + { 0x96, "PA-RISC 7100" }, + + { 0xA0, "V30" }, + { 0xA1, "Quad-Core Xeon 3200" }, /* From CIM_Processor.Family */ + { 0xA2, "Dual-Core Xeon 3000" }, /* From CIM_Processor.Family */ + { 0xA3, "Quad-Core Xeon 5300" }, /* From CIM_Processor.Family */ + { 0xA4, "Dual-Core Xeon 5100" }, /* From CIM_Processor.Family */ + { 0xA5, "Dual-Core Xeon 5000" }, /* From CIM_Processor.Family */ + { 0xA6, "Dual-Core Xeon LV" }, /* From CIM_Processor.Family */ + { 0xA7, "Dual-Core Xeon ULV" }, /* From CIM_Processor.Family */ + { 0xA8, "Dual-Core Xeon 7100" }, /* From CIM_Processor.Family */ + { 0xA9, "Quad-Core Xeon 5400" }, /* From CIM_Processor.Family */ + { 0xAA, "Quad-Core Xeon" }, /* From CIM_Processor.Family */ + + { 0xB0, "Pentium III Xeon" }, + { 0xB1, "Pentium III Speedstep" }, + { 0xB2, "Pentium 4" }, + { 0xB3, "Xeon" }, + { 0xB4, "AS400" }, + { 0xB5, "Xeon MP" }, + { 0xB6, "Athlon XP" }, + { 0xB7, "Athlon MP" }, + { 0xB8, "Itanium 2" }, + { 0xB9, "Pentium M" }, + { 0xBA, "Celeron D" }, + { 0xBB, "Pentium D" }, + { 0xBC, "Pentium EE" }, + { 0xBD, "Core Solo" }, + /* 0xBE handled as a special case */ + { 0xBF, "Core 2 Duo" }, + { 0xC0, "Core 2 Solo" }, /* From CIM_Processor.Family */ + { 0xC1, "Core 2 Extreme" }, /* From CIM_Processor.Family */ + { 0xC2, "Core 2 Quad" }, /* From CIM_Processor.Family */ + { 0xC3, "Core 2 Extreme Mobile" }, /* From CIM_Processor.Family */ + { 0xC4, "Core 2 Duo Mobile" }, /* From CIM_Processor.Family */ + { 0xC5, "Core 2 Solo Mobile" }, /* From CIM_Processor.Family */ + + { 0xC8, "IBM390" }, + { 0xC9, "G4" }, + { 0xCA, "G5" }, + { 0xCB, "ESA/390 G6" }, + { 0xCC, "z/Architectur" }, + + { 0xD2, "C7-M" }, + { 0xD3, "C7-D" }, + { 0xD4, "C7" }, + { 0xD5, "Eden" }, + + { 0xFA, "i860" }, + { 0xFB, "i960" }, + + { 0x104, "SH-3" }, + { 0x105, "SH-4" }, + + { 0x118, "ARM" }, + { 0x119, "StrongARM" }, + + { 0x12C, "6x86" }, + { 0x12D, "MediaGX" }, + { 0x12E, "MII" }, + + { 0x140, "WinChip" }, + + { 0x15E, "DSP" }, + + { 0x1F4, "Video Processor" }, + /* *INDENT-ON* */ + }; + + /* Linear Search - Slow + * for(i=0; ilength >= 0x2A) ? WORD(data + 0x28) : data[0x06]; + + /* Special case for ambiguous value 0xBE */ + if(code == 0xBE) { + const char *manufacturer = dmi_string(h, data[0x07]); + + /* Best bet based on manufacturer string */ + if(strstr(manufacturer, "Intel") != NULL || + strncasecmp(manufacturer, "Intel", 5) == 0) + return "Core 2"; + if(strstr(manufacturer, "AMD") != NULL || strncasecmp(manufacturer, "AMD", 3) == 0) + return "K7"; + return "Core 2 or K7"; + } + + /* Perform a binary search */ + low = 0; + high = ARRAY_SIZE(family2) - 1; + while(1) { + i = (low + high) / 2; + if(family2[i].value == code) + return family2[i].name; + if(low == high) /* Not found */ + return out_of_spec; + if(code < family2[i].value) + high = i; + else + low = i + 1; + } + + return out_of_spec; +} + +static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) +{ + PyObject *data = PyDict_New(); + + /* Intel AP-485 revision 31, table 3-4 */ + static const char *flags[32] = { + "FPU (Floating-point unit on-chip)", /* 0 */ + "VME (Virtual mode extension)", + "DE (Debugging extension)", + "PSE (Page size extension)", + "TSC (Time stamp counter)", + "MSR (Model specific registers)", + "PAE (Physical address extension)", + "MCE (Machine check exception)", + "CX8 (CMPXCHG8 instruction supported)", + "APIC (On-chip APIC hardware supported)", + NULL, /* 10 */ + "SEP (Fast system call)", + "MTRR (Memory type range registers)", + "PGE (Page global enable)", + "MCA (Machine check architecture)", + "CMOV (Conditional move instruction supported)", + "PAT (Page attribute table)", + "PSE-36 (36-bit page size extension)", + "PSN (Processor serial number present and enabled)", + "CLFSH (CLFLUSH instruction supported)", + NULL, /* 20 */ + "DS (Debug store)", + "ACPI (ACPI supported)", + "MMX (MMX technology supported)", + "FXSR (Fast floating-point save and restore)", + "SSE (Streaming SIMD extensions)", + "SSE2 (Streaming SIMD extensions 2)", + "SS (Self-snoop)", + "HTT (Hyper-threading technology)", + "TM (Thermal monitor supported)", + "IA64 (IA64 capabilities)", + "PBE (Pending break enabled)" /* 31 */ + }; + /* + ** Extra flags are now returned in the ECX register when one calls + ** the CPUID instruction. Their meaning is explained in table 3-5, but + ** DMI doesn't support this yet. + */ + u32 eax, edx; + int sig = 0; + + /* + ** This might help learn about new processors supporting the + ** CPUID instruction or another form of identification. + */ + + //. TODO: PyString_FromFormat does not support %x (yet?)... + PyDict_SetItemString(data, "ID", + PyString_FromFormat("%02x %02x %02x %02x %02x %02x %02x %02x", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] + ) + ); + + if(type == 0x05) { /* 80386 */ + u16 dx = WORD(p); + + /* + ** 80386 have a different signature. + */ + PyDict_SetItemString(data, "Signature", + PyString_FromFormat + ("Type %i, Family %i, Major Stepping %i, Minor Stepping %i", + dx >> 12, (dx >> 8) & 0xF, (dx >> 4) & 0xF, dx & 0xF) + ); + return data; + } + + if(type == 0x06) { /* 80486 */ + u16 dx = WORD(p); + + /* + ** Not all 80486 CPU support the CPUID instruction, we have to find + ** wether the one we have here does or not. Note that this trick + ** works only because we know that 80486 must be little-endian. + */ + if((dx & 0x0F00) == 0x0400 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070) + && ((dx & 0x000F) >= 0x0003)) + sig = 1; + else { + PyDict_SetItemString(data, "Signature", + PyString_FromFormat + ("Type %i, Family %i, Model %i, Stepping %i", + (dx >> 12) & 0x3, (dx >> 8) & 0xF, (dx >> 4) & 0xF, + dx & 0xF) + ); + return data; + } + } else if((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */ + ||(type >= 0x28 && type <= 0x2B) /* Intel */ + ||(type >= 0xA1 && type <= 0xAA) /* Intel */ + ||(type >= 0xB0 && type <= 0xB3) /* Intel */ + ||type == 0xB5 /* Intel */ + || (type >= 0xB9 && type <= 0xC5) /* Intel */ + ||(type >= 0xD2 && type <= 0xD5) /* VIA */ + ) + sig = 1; + else if((type >= 0x18 && type <= 0x1D) /* AMD */ + ||type == 0x1F /* AMD */ + || (type >= 0x83 && type <= 0x8F) /* AMD */ + ||(type >= 0xB6 && type <= 0xB7) /* AMD */ + ||(type >= 0xE6 && type <= 0xEB) /* AMD */ + ) + sig = 2; + else if(type == 0x01 || type == 0x02) { + /* + ** Some X86-class CPU have family "Other" or "Unknown". In this case, + ** we use the version string to determine if they are known to + ** support the CPUID instruction. + */ + if(strncmp(version, "Pentium III MMX", 15) == 0 + || strncmp(version, "Intel(R) Core(TM)2", 18) == 0 + || strncmp(version, "Intel(R) Pentium(R)", 19) == 0 + || strcmp(version, "Genuine Intel(R) CPU U1400") == 0) + sig = 1; + else if(strncmp(version, "AMD Athlon(TM)", 14) == 0 + || strncmp(version, "AMD Opteron(tm)", 15) == 0 + || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0) + sig = 2; + else + return data; + } else /* not X86-class */ + return data; + + eax = DWORD(p); + edx = DWORD(p + 4); + switch (sig) { + case 1: /* Intel */ + PyDict_SetItemString(data, "Signature", + PyString_FromFormat + ("Type %i, Family %i, Model %i, Stepping %i", + (eax >> 12) & 0x3, ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F), + ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), eax & 0xF) + ); + break; + case 2: /* AMD, publication #25481 revision 2.28 */ + PyDict_SetItemString(data, "Signature", + PyString_FromFormat("Family %i, Model %i, Stepping %i", + ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == + 0xF ? (eax >> 20) & + 0xFF : 0), + ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == + 0xF ? (eax >> 12) & + 0xF0 : 0), eax & 0xF) + ); + break; + } + + edx = DWORD(p + 4); + if((edx & 0xFFEFFBFF) == 0) + PyDict_SetItemString(data, "Flags", Py_None); + else { + int i; + PyObject *subdata = PyDict_New(); + + for(i = 0; i <= 31; i++) + if(flags[i] != NULL) + PyDict_SetItemString(subdata, flags[i], + (edx & (1 << i)) ? Py_True : Py_False); + PyDict_SetItemString(data, "Flags", subdata); + Py_DECREF(subdata); + } + + return data; } /* 3.3.5.4 */ -static PyObject *dmi_processor_voltage(u8 code) { - static const char *voltage[]={ - "5.0 V", /* 0 */ - "3.3 V", - "2.9 V" /* 2 */ - }; - int i; - - PyObject *data; - if(code&0x80) data = PyString_FromFormat("%.1f V", (float)(code&0x7f)/10); - else { - data = PyDict_New(); - for(i=0; i<=2; i++) - PyDict_SetItemString(data, voltage[i], (code&(1<=0x01 && code<=0x15) return PyString_FromString(upgrade[code-0x01]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_processor_cache(u16 code, const char *level, u16 ver) { - PyObject *data; - if(code==0xFFFF) { - if(ver>=0x0203) data = PyString_FromString("Not Provided"); - else data = PyString_FromFormat("No %s Cache", level); - } else data = PyString_FromFormat("0x%04x", code); - return data; +static PyObject *dmi_processor_voltage(u8 code) +{ + static const char *voltage[] = { + "5.0 V", /* 0 */ + "3.3 V", + "2.9 V" /* 2 */ + }; + int i; + + PyObject *data; + + if(code & 0x80) + data = PyString_FromFormat("%.1f V", (float)(code & 0x7f) / 10); + else { + data = PyDict_New(); + for(i = 0; i <= 2; i++) + PyDict_SetItemString(data, voltage[i], + (code & (1 << i) ? Py_True : Py_False)); + if(code == 0x00) + PyDict_SetItemString(data, "VOLTAGE", PyString_FromString("Unknown")); + } + return data; +} + +int dmi_processor_frequency(const u8 * p) +{ + u16 code = WORD(p); + + if(code) + return code; //. Value measured in MHz + else + return -1; //. Unknown +} +static PyObject *dmi_processor_frequency_py(const u8 * p) +{ + return PyInt_FromLong(dmi_processor_frequency(p)); +} + +static const char *dmi_processor_status(u8 code) +{ + static const char *status[] = { + "Unknown", /* 0x00 */ + "Enabled", + "Disabled By User", + "Disabled By BIOS", + "Idle", /* 0x04 */ + "Other" /* 0x07 */ + }; + + if(code <= 0x04) + return status[code]; + if(code == 0x07) + return status[0x05]; + return out_of_spec; +} + +static PyObject *dmi_processor_upgrade(u8 code) +{ + /* 3.3.5.5 */ + static const char *upgrade[] = { + "Other", /* 0x01 */ + "Unknown", + "Daughter Board", + "ZIF Socket", + "Replaceable Piggy Back", + "None", + "LIF Socket", + "Slot 1", + "Slot 2", + "370-pin Socket", + "Slot A", + "Slot M", + "Socket 423", + "Socket A (Socket 462)", + "Socket 478", + "Socket 754", + "Socket 940", + "Socket 939", + "Socket mPGA604", + "Socket LGA771", + "Socket LGA775", /* 0x15 */ + "Socket S1", + "Socket AM2", + "Socket F (1207)" /* 0x18 */ + }; + + if(code >= 0x01 && code <= 0x15) + return PyString_FromString(upgrade[code - 0x01]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_processor_cache(u16 code, const char *level, u16 ver) +{ + PyObject *data; + + if(code == 0xFFFF) { + if(ver >= 0x0203) + data = PyString_FromString("Not Provided"); + else + data = PyString_FromFormat("No %s Cache", level); + } else + data = PyString_FromFormat("0x%04x", code); + return data; } /* 3.3.5.9 */ -static PyObject *dmi_processor_characteristics(u16 code) { - static const char *characteristics[]={ - "64-bit capable" /* 2 */ - }; - - PyObject *data; - if((code&0x0004)==0) { - data = Py_None; - } else { - data = PyList_New(1); - int i; - for(i=2; i<=2; i++) - if(code&(1<=0x01 && code<=0x08) return(PyString_FromString(method[code-0x01])); - return OUT_OF_SPEC; +static PyObject *dmi_memory_controller_ed_method(u8 code) +{ + /* 3.3.6.1 */ + static const char *method[] = { + "Other", /* 0x01 */ + "Unknown", + "None", + "8-bit Parity", + "32-bit ECC", + "64-bit ECC", + "128-bit ECC", + "CRC" /* 0x08 */ + }; + + if(code >= 0x01 && code <= 0x08) + return (PyString_FromString(method[code - 0x01])); + return OUT_OF_SPEC; } /* 3.3.6.2 */ -static PyObject *dmi_memory_controller_ec_capabilities(u8 code) { - static const char *capabilities[]={ - "Other", /* 0 */ - "Unknown", - "None", - "Single-bit Error Correcting", - "Double-bit Error Correcting", - "Error Scrubbing" /* 5 */ - }; - - PyObject *data = Py_None; - if((code&0x3F)==0) return Py_None; - else { - int i; - - data = PyList_New(6); - for(i=0; i<=5; i++) - if(code&(1<=0x01 && code<=0x07) return PyString_FromString(interleave[code-0x01]); - return OUT_OF_SPEC; +static PyObject *dmi_memory_controller_ec_capabilities(u8 code) +{ + static const char *capabilities[] = { + "Other", /* 0 */ + "Unknown", + "None", + "Single-bit Error Correcting", + "Double-bit Error Correcting", + "Error Scrubbing" /* 5 */ + }; + + PyObject *data = Py_None; + + if((code & 0x3F) == 0) + return Py_None; + else { + int i; + + data = PyList_New(6); + for(i = 0; i <= 5; i++) + if(code & (1 << i)) + PyList_SET_ITEM(data, i, PyString_FromString(capabilities[i])); + else + PyList_SET_ITEM(data, i, Py_None); + } + return data; +} + +static PyObject *dmi_memory_controller_interleave(u8 code) +{ + /* 3.3.6.3 */ + static const char *interleave[] = { + "Other", /* 0x01 */ + "Unknown", + "One-way Interleave", + "Two-way Interleave", + "Four-way Interleave", + "Eight-way Interleave", + "Sixteen-way Interleave" /* 0x07 */ + }; + + if(code >= 0x01 && code <= 0x07) + return PyString_FromString(interleave[code - 0x01]); + return OUT_OF_SPEC; } /* 3.3.6.4 */ -static PyObject *dmi_memory_controller_speeds(u16 code) { - const char *speeds[]={ - "Other", /* 0 */ - "Unknown", - "70 ns", - "60 ns", - "50 ns" /* 4 */ - }; - - PyObject *data; - if((code&0x001F)!=0) data = Py_None; - else { - int i; - - data = PyList_New(5); - for(i=0; i<=4; i++) - if(code&(1<>4)); - if((code&0x0F)!=0x0F) PyList_Append(data, PyInt_FromLong(code&0x0F)); - } - return data; -} - -static PyObject *dmi_memory_module_speed(u8 code) { - if(code==0) return PyString_FromString("Unknown"); - else return PyString_FromFormat("%i ns", code); +static PyObject *dmi_memory_module_types(u16 code) +{ + static const char *types[] = { + "Other", /* 0 */ + "Unknown", + "Standard", + "FPM", + "EDO", + "Parity", + "ECC", + "SIMM", + "DIMM", + "Burst EDO", + "SDRAM" /* 10 */ + }; + + PyObject *data; + + if((code & 0x07FF) == 0) + data = Py_None; + else { + int i; + + data = PyList_New(11); + for(i = 0; i <= 10; i++) + if(code & (1 << i)) + PyList_SET_ITEM(data, i, PyString_FromString(types[i])); + else + PyList_SET_ITEM(data, i, Py_None); + } + return data; +} + +static PyObject *dmi_memory_module_connections(u8 code) +{ + PyObject *data; + + if(code == 0xFF) + data = Py_None; + else { + data = PyList_New(0); + if((code & 0xF0) != 0xF0) + PyList_Append(data, PyInt_FromLong(code >> 4)); + if((code & 0x0F) != 0x0F) + PyList_Append(data, PyInt_FromLong(code & 0x0F)); + } + return data; +} + +static PyObject *dmi_memory_module_speed(u8 code) +{ + if(code == 0) + return PyString_FromString("Unknown"); + else + return PyString_FromFormat("%i ns", code); } /* 3.3.7.2 */ -static PyObject *dmi_memory_module_size(u8 code) { - PyObject *data = PyDict_New(); - int check_conn = 1; - - switch(code&0x7F) { - case 0x7D: - PyDict_SetItemString(data, "Size", PyString_FromString("Not Determinable")); - break; - case 0x7E: - PyDict_SetItemString(data, "Size", PyString_FromString("Disabled")); - break; - case 0x7F: - PyDict_SetItemString(data, "Size", PyString_FromString("Not Installed")); - check_conn = 0; - default: - PyDict_SetItemString(data, "Size", PyString_FromFormat("%i MB", 1<<(code&0x7F))); - } - - if(check_conn) { - if(code&0x80) PyDict_SetItemString(data, "Connection", PyString_FromString("Double-bank")); - else PyDict_SetItemString(data, "Connection", PyString_FromString("Single-bank")); - } - return data; -} - -static PyObject *dmi_memory_module_error(u8 code) { - PyObject *data = NULL; - if(code&(1<<2)) data = Py_None; //. TODO: sprintf(_, "See Event Log"); - else { - if((code&0x03)==0) data = Py_True; - if(code&(1<<0)) data = PyString_FromString("Uncorrectable Errors"); - if(code&(1<<1)) data = PyString_FromString("Correctable Errors"); - } - return data; +static PyObject *dmi_memory_module_size(u8 code) +{ + PyObject *data = PyDict_New(); + int check_conn = 1; + + switch (code & 0x7F) { + case 0x7D: + PyDict_SetItemString(data, "Size", PyString_FromString("Not Determinable")); + break; + case 0x7E: + PyDict_SetItemString(data, "Size", PyString_FromString("Disabled")); + break; + case 0x7F: + PyDict_SetItemString(data, "Size", PyString_FromString("Not Installed")); + check_conn = 0; + default: + PyDict_SetItemString(data, "Size", + PyString_FromFormat("%i MB", 1 << (code & 0x7F))); + } + + if(check_conn) { + if(code & 0x80) + PyDict_SetItemString(data, "Connection", + PyString_FromString("Double-bank")); + else + PyDict_SetItemString(data, "Connection", + PyString_FromString("Single-bank")); + } + return data; +} + +static PyObject *dmi_memory_module_error(u8 code) +{ + PyObject *data = NULL; + + if(code & (1 << 2)) + data = Py_None; //. TODO: sprintf(_, "See Event Log"); + else { + if((code & 0x03) == 0) + data = Py_True; + if(code & (1 << 0)) + data = PyString_FromString("Uncorrectable Errors"); + if(code & (1 << 1)) + data = PyString_FromString("Correctable Errors"); + } + return data; } /******************************************************************************* ** 3.3.8 Cache Information (Type 7) */ -static PyObject *dmi_cache_mode(u8 code) { - static const char *mode[]={ - "Write Through", /* 0x00 */ - "Write Back", - "Varies With Memory Address", - "Unknown" /* 0x03 */ - }; +static PyObject *dmi_cache_mode(u8 code) +{ + static const char *mode[] = { + "Write Through", /* 0x00 */ + "Write Back", + "Varies With Memory Address", + "Unknown" /* 0x03 */ + }; - return PyString_FromString(mode[code]); + return PyString_FromString(mode[code]); } -static PyObject *dmi_cache_location(u8 code) { - static const char *location[4]={ - "Internal", /* 0x00 */ - "External", - NULL, /* 0x02 */ - "Unknown" /* 0x03 */ - }; +static PyObject *dmi_cache_location(u8 code) +{ + static const char *location[4] = { + "Internal", /* 0x00 */ + "External", + NULL, /* 0x02 */ + "Unknown" /* 0x03 */ + }; + + PyObject *data; - PyObject *data; - if(location[code]!=NULL) data = PyString_FromString(location[code]); - else data = OUT_OF_SPEC; - return data; + if(location[code] != NULL) + data = PyString_FromString(location[code]); + else + data = OUT_OF_SPEC; + return data; } -static PyObject *dmi_cache_size(u16 code) { - PyObject *data; - if(code&0x8000) data = PyString_FromFormat("%i KB", (code&0x7FFF)<<6); - else data = PyString_FromFormat("%i KB", code); - return data; +static PyObject *dmi_cache_size(u16 code) +{ + PyObject *data; + + if(code & 0x8000) + data = PyString_FromFormat("%i KB", (code & 0x7FFF) << 6); + else + data = PyString_FromFormat("%i KB", code); + return data; } /* 3.3.8.2 */ -static PyObject *dmi_cache_types(u16 code) { - static const char *types[] = { - "Other", /* 0 */ - "Unknown", - "Non-burst", - "Burst", - "Pipeline Burst", - "Synchronous", - "Asynchronous" /* 6 */ - }; - PyObject *data; - - if((code&0x007F)==0) data = Py_None; - else { - int i; - - data = PyList_New(7); - for(i=0; i<=6; i++) - if(code&(1<=0x01 && code<=0x06) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_cache_type(u8 code) { - /* 3.3.8.4 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Instruction", - "Data", - "Unified" /* 0x05 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x05) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_cache_associativity(u8 code) { - /* 3.3.8.5 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Direct Mapped", - "2-way Set-associative", - "4-way Set-associative", - "Fully Associative", - "8-way Set-associative", - "16-way Set-associative" /* 0x08 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x08) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; +static PyObject *dmi_cache_types(u16 code) +{ + static const char *types[] = { + "Other", /* 0 */ + "Unknown", + "Non-burst", + "Burst", + "Pipeline Burst", + "Synchronous", + "Asynchronous" /* 6 */ + }; + PyObject *data; + + if((code & 0x007F) == 0) + data = Py_None; + else { + int i; + + data = PyList_New(7); + for(i = 0; i <= 6; i++) + if(code & (1 << i)) + PyList_SET_ITEM(data, i, PyString_FromString(types[i])); + else + PyList_SET_ITEM(data, i, Py_None); + } + return data; +} + +static PyObject *dmi_cache_ec_type(u8 code) +{ + /* 3.3.8.3 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "None", + "Parity", + "Single-bit ECC", + "Multi-bit ECC" /* 0x06 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x06) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_cache_type(u8 code) +{ + /* 3.3.8.4 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "Instruction", + "Data", + "Unified" /* 0x05 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x05) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_cache_associativity(u8 code) +{ + /* 3.3.8.5 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "Direct Mapped", + "2-way Set-associative", + "4-way Set-associative", + "Fully Associative", + "8-way Set-associative", + "16-way Set-associative" /* 0x08 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x08) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; } /******************************************************************************* ** 3.3.9 Port Connector Information (Type 8) */ -static PyObject *dmi_port_connector_type(u8 code) { - /* 3.3.9.2 */ - static const char *type[] = { - "None", /* 0x00 */ - "Centronics", - "Mini Centronics", - "Proprietary", - "DB-25 male", - "DB-25 female", - "DB-15 male", - "DB-15 female", - "DB-9 male", - "DB-9 female", - "RJ-11", - "RJ-45", - "50 Pin MiniSCSI", - "Mini DIN", - "Micro DIN", - "PS/2", - "Infrared", - "HP-HIL", - "Access Bus (USB)", - "SSA SCSI", - "Circular DIN-8 male", - "Circular DIN-8 female", - "On Board IDE", - "On Board Floppy", - "9 Pin Dual Inline (pin 10 cut)", - "25 Pin Dual Inline (pin 26 cut)", - "50 Pin Dual Inline", - "68 Pin Dual Inline", - "On Board Sound Input From CD-ROM", - "Mini Centronics Type-14", - "Mini Centronics Type-26", - "Mini Jack (headphones)", - "BNC", - "IEEE 1394", - "SAS/SATA Plug Receptacle" /* 0x22 */ - }; - static const char *type_0xA0[]={ - "PC-98", /* 0xA0 */ - "PC-98 Hireso", - "PC-H98", - "PC-98 Note", - "PC-98 Full" /* 0xA4 */ - }; - - if(code<=0x22) return PyString_FromString(type[code]); - if(code>=0xA0 && code<=0xA4) return PyString_FromString(type_0xA0[code-0xA0]); - if(code==0xFF) return PyString_FromString("Other"); - return OUT_OF_SPEC; -} - -static PyObject *dmi_port_type(u8 code) { - /* 3.3.9.3 */ - static const char *type[] = { - "None", /* 0x00 */ - "Parallel Port XT/AT Compatible", - "Parallel Port PS/2", - "Parallel Port ECP", - "Parallel Port EPP", - "Parallel Port ECP/EPP", - "Serial Port XT/AT Compatible", - "Serial Port 16450 Compatible", - "Serial Port 16550 Compatible", - "Serial Port 16550A Compatible", - "SCSI Port", - "MIDI Port", - "Joystick Port", - "Keyboard Port", - "Mouse Port", - "SSA SCSI", - "USB", - "Firewire (IEEE P1394)", - "PCMCIA Type I", - "PCMCIA Type II", - "PCMCIA Type III", - "Cardbus", - "Access Bus Port", - "SCSI II", - "SCSI Wide", - "PC-98", - "PC-98 Hireso", - "PC-H98", - "Video Port", - "Audio Port", - "Modem Port", - "Network Port", - "SATA", - "SAS" /* 0x21 */ - }; - static const char *type_0xA0[]={ - "8251 Compatible", /* 0xA0 */ - "8251 FIFO Compatible" /* 0xA1 */ - }; - - if(code<=0x21) return PyString_FromString(type[code]); - if(code>=0xA0 && code<=0xA1) return PyString_FromString(type_0xA0[code-0xA0]); - if(code==0xFF) return PyString_FromString("Other"); - return OUT_OF_SPEC; +static PyObject *dmi_port_connector_type(u8 code) +{ + /* 3.3.9.2 */ + static const char *type[] = { + "None", /* 0x00 */ + "Centronics", + "Mini Centronics", + "Proprietary", + "DB-25 male", + "DB-25 female", + "DB-15 male", + "DB-15 female", + "DB-9 male", + "DB-9 female", + "RJ-11", + "RJ-45", + "50 Pin MiniSCSI", + "Mini DIN", + "Micro DIN", + "PS/2", + "Infrared", + "HP-HIL", + "Access Bus (USB)", + "SSA SCSI", + "Circular DIN-8 male", + "Circular DIN-8 female", + "On Board IDE", + "On Board Floppy", + "9 Pin Dual Inline (pin 10 cut)", + "25 Pin Dual Inline (pin 26 cut)", + "50 Pin Dual Inline", + "68 Pin Dual Inline", + "On Board Sound Input From CD-ROM", + "Mini Centronics Type-14", + "Mini Centronics Type-26", + "Mini Jack (headphones)", + "BNC", + "IEEE 1394", + "SAS/SATA Plug Receptacle" /* 0x22 */ + }; + static const char *type_0xA0[] = { + "PC-98", /* 0xA0 */ + "PC-98 Hireso", + "PC-H98", + "PC-98 Note", + "PC-98 Full" /* 0xA4 */ + }; + + if(code <= 0x22) + return PyString_FromString(type[code]); + if(code >= 0xA0 && code <= 0xA4) + return PyString_FromString(type_0xA0[code - 0xA0]); + if(code == 0xFF) + return PyString_FromString("Other"); + return OUT_OF_SPEC; +} + +static PyObject *dmi_port_type(u8 code) +{ + /* 3.3.9.3 */ + static const char *type[] = { + "None", /* 0x00 */ + "Parallel Port XT/AT Compatible", + "Parallel Port PS/2", + "Parallel Port ECP", + "Parallel Port EPP", + "Parallel Port ECP/EPP", + "Serial Port XT/AT Compatible", + "Serial Port 16450 Compatible", + "Serial Port 16550 Compatible", + "Serial Port 16550A Compatible", + "SCSI Port", + "MIDI Port", + "Joystick Port", + "Keyboard Port", + "Mouse Port", + "SSA SCSI", + "USB", + "Firewire (IEEE P1394)", + "PCMCIA Type I", + "PCMCIA Type II", + "PCMCIA Type III", + "Cardbus", + "Access Bus Port", + "SCSI II", + "SCSI Wide", + "PC-98", + "PC-98 Hireso", + "PC-H98", + "Video Port", + "Audio Port", + "Modem Port", + "Network Port", + "SATA", + "SAS" /* 0x21 */ + }; + static const char *type_0xA0[] = { + "8251 Compatible", /* 0xA0 */ + "8251 FIFO Compatible" /* 0xA1 */ + }; + + if(code <= 0x21) + return PyString_FromString(type[code]); + if(code >= 0xA0 && code <= 0xA1) + return PyString_FromString(type_0xA0[code - 0xA0]); + if(code == 0xFF) + return PyString_FromString("Other"); + return OUT_OF_SPEC; } /******************************************************************************* ** 3.3.10 System Slots (Type 9) */ -static PyObject *dmi_slot_type(u8 code) { - /* 3.3.10.1 */ - static const char *type[] = { - "Other", /* 0x01 */ - "Unknown", - "ISA", - "MCA", - "EISA", - "PCI", - "PC Card (PCMCIA)", - "VLB", - "Proprietary", - "Processor Card", - "Proprietary Memory Card", - "I/O Riser Card", - "NuBus", - "PCI-66", - "AGP", - "AGP 2x", - "AGP 4x", - "PCI-X", - "AGP 8x" /* 0x13 */ - }; - static const char *type_0xA0[]={ - "PC-98/C20", /* 0xA0 */ - "PC-98/C24", - "PC-98/E", - "PC-98/Local Bus", - "PC-98/Card", - "PCI Express", - "PCI Express x1", - "PCI Express x2", - "PCI Express x4", - "PCI Express x8", - "PCI Express x16" /* 0xAA */ - }; - - if(code>=0x01 && code<=0x13) return PyString_FromString(type[code-0x01]); - if(code>=0xA0 && code<=0xAA) return PyString_FromString(type_0xA0[code-0xA0]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_slot_bus_width(u8 code) { - /* 3.3.10.2 */ - static const char *width[]={ - "", /* 0x01, "Other" */ - "", /* "Unknown" */ - "8-bit ", - "16-bit ", - "32-bit ", - "64-bit ", - "128-bit ", - "x1 ", - "x2 ", - "x4 ", - "x8 ", - "x12 ", - "x16 ", - "x32 " /* 0x0E */ - }; - - if(code>=0x01 && code<=0x0E) return PyString_FromString(width[code-0x01]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_slot_current_usage(u8 code) { - /* 3.3.10.3 */ - static const char *usage[]={ - "Other", /* 0x01 */ - "Unknown", - "Available", - "In Use" /* 0x04 */ - }; - - if(code>=0x01 && code<=0x04) return PyString_FromString(usage[code-0x01]); - return OUT_OF_SPEC; +static PyObject *dmi_slot_type(u8 code) +{ + /* 3.3.10.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "ISA", + "MCA", + "EISA", + "PCI", + "PC Card (PCMCIA)", + "VLB", + "Proprietary", + "Processor Card", + "Proprietary Memory Card", + "I/O Riser Card", + "NuBus", + "PCI-66", + "AGP", + "AGP 2x", + "AGP 4x", + "PCI-X", + "AGP 8x" /* 0x13 */ + }; + static const char *type_0xA0[] = { + "PC-98/C20", /* 0xA0 */ + "PC-98/C24", + "PC-98/E", + "PC-98/Local Bus", + "PC-98/Card", + "PCI Express", + "PCI Express x1", + "PCI Express x2", + "PCI Express x4", + "PCI Express x8", + "PCI Express x16" /* 0xAA */ + }; + + if(code >= 0x01 && code <= 0x13) + return PyString_FromString(type[code - 0x01]); + if(code >= 0xA0 && code <= 0xAA) + return PyString_FromString(type_0xA0[code - 0xA0]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_slot_bus_width(u8 code) +{ + /* 3.3.10.2 */ + static const char *width[] = { + "", /* 0x01, "Other" */ + "", /* "Unknown" */ + "8-bit ", + "16-bit ", + "32-bit ", + "64-bit ", + "128-bit ", + "x1 ", + "x2 ", + "x4 ", + "x8 ", + "x12 ", + "x16 ", + "x32 " /* 0x0E */ + }; + + if(code >= 0x01 && code <= 0x0E) + return PyString_FromString(width[code - 0x01]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_slot_current_usage(u8 code) +{ + /* 3.3.10.3 */ + static const char *usage[] = { + "Other", /* 0x01 */ + "Unknown", + "Available", + "In Use" /* 0x04 */ + }; + + if(code >= 0x01 && code <= 0x04) + return PyString_FromString(usage[code - 0x01]); + return OUT_OF_SPEC; } /* 3.3.1O.4 */ -static PyObject *dmi_slot_length(u8 code) { - static const char *length[]={ - "Other", /* 0x01 */ - "Unknown", - "Short", - "Long" /* 0x04 */ - }; +static PyObject *dmi_slot_length(u8 code) +{ + static const char *length[] = { + "Other", /* 0x01 */ + "Unknown", + "Short", + "Long" /* 0x04 */ + }; - if(code>=0x01 && code<=0x04) - return PyString_FromString(length[code-0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x04) + return PyString_FromString(length[code - 0x01]); + return OUT_OF_SPEC; } /* 3.3.10.5 */ -static PyObject *dmi_slot_id(u8 code1, u8 code2, u8 type) { - PyObject *data; - switch(type) { - case 0x04: /* MCA */ - data = PyString_FromFormat("%i", code1); - break; - case 0x05: /* EISA */ - data = PyString_FromFormat("%i", code1); - break; - case 0x06: /* PCI */ - case 0x0E: /* PCI */ - case 0x0F: /* AGP */ - case 0x10: /* AGP */ - case 0x11: /* AGP */ - case 0x12: /* PCI-X */ - case 0x13: /* AGP */ - case 0xA5: /* PCI Express */ - data = PyString_FromFormat("%i", code1); - break; - case 0x07: /* PCMCIA */ - data = PyString_FromFormat("Adapter %i, Socket %i", code1, code2); - break; - default: - data = Py_None; - } - return data; -} - -static PyObject *dmi_slot_characteristics(u8 code1, u8 code2) { - /* 3.3.10.6 */ - static const char *characteristics1[]={ - "5.0 V is provided", /* 1 */ - "3.3 V is provided", - "Opening is shared", - "PC Card-16 is supported", - "Cardbus is supported", - "Zoom Video is supported", - "Modem ring resume is supported" /* 7 */ - }; - - /* 3.3.10.7 */ - static const char *characteristics2[]={ - "PME signal is supported", /* 0 */ - "Hot-plug devices are supported", - "SMBus signal is supported" /* 2 */ - }; - - PyObject *data; - if(code1&(1<<0)) data = PyString_FromString("Unknown"); - else if((code1&0xFE)==0 && (code2&0x07)==0) data = Py_None; - else { - int i; - - data = PyList_New(7+3); - for(i=1; i<=7; i++) { - if(code1&(1<> 3, code3 & 0x7); - else data = Py_None; - return data; +static PyObject *dmi_slot_id(u8 code1, u8 code2, u8 type) +{ + PyObject *data; + + switch (type) { + case 0x04: /* MCA */ + data = PyString_FromFormat("%i", code1); + break; + case 0x05: /* EISA */ + data = PyString_FromFormat("%i", code1); + break; + case 0x06: /* PCI */ + case 0x0E: /* PCI */ + case 0x0F: /* AGP */ + case 0x10: /* AGP */ + case 0x11: /* AGP */ + case 0x12: /* PCI-X */ + case 0x13: /* AGP */ + case 0xA5: /* PCI Express */ + data = PyString_FromFormat("%i", code1); + break; + case 0x07: /* PCMCIA */ + data = PyString_FromFormat("Adapter %i, Socket %i", code1, code2); + break; + default: + data = Py_None; + } + return data; +} + +static PyObject *dmi_slot_characteristics(u8 code1, u8 code2) +{ + /* 3.3.10.6 */ + static const char *characteristics1[] = { + "5.0 V is provided", /* 1 */ + "3.3 V is provided", + "Opening is shared", + "PC Card-16 is supported", + "Cardbus is supported", + "Zoom Video is supported", + "Modem ring resume is supported" /* 7 */ + }; + + /* 3.3.10.7 */ + static const char *characteristics2[] = { + "PME signal is supported", /* 0 */ + "Hot-plug devices are supported", + "SMBus signal is supported" /* 2 */ + }; + + PyObject *data; + + if(code1 & (1 << 0)) + data = PyString_FromString("Unknown"); + else if((code1 & 0xFE) == 0 && (code2 & 0x07) == 0) + data = Py_None; + else { + int i; + + data = PyList_New(7 + 3); + for(i = 1; i <= 7; i++) { + if(code1 & (1 << i)) + PyList_SET_ITEM(data, i - 1, + PyString_FromString(characteristics1[i - 1])); + else + PyList_SET_ITEM(data, i - 1, Py_None); + } + for(i = 0; i <= 2; i++) { + if(code2 & (1 << i)) + PyList_SET_ITEM(data, 7 + i, + PyString_FromString(characteristics2[i])); + else + PyList_SET_ITEM(data, 7 + i, Py_None); + } + } + return data; +} + +static PyObject *dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) +{ + /* 3.3.10.8 */ + PyObject *data; + + if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) + data = + PyString_FromFormat("%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7); + else + data = Py_None; + return data; } /******************************************************************************* ** 3.3.11 On Board Devices Information (Type 10) */ -static const char *dmi_on_board_devices_type(u8 code) { - /* 3.3.11.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Video", - "SCSI Controller", - "Ethernet", - "Token Ring", - "Sound", - "PATA Controller", - "SATA Controller", - "SAS Controller" /* 0x0A */ - }; - - if(code>=0x01 && code<=0x0A) return type[code-0x01]; - return out_of_spec; -} - -static PyObject *dmi_on_board_devices(struct dmi_header *h) { - PyObject *data = NULL; - u8 *p = h->data+4; - u8 count = (h->length-0x04)/2; - int i; - - if((data = PyList_New(count))) { - PyObject *_pydict; - PyObject *_val; - for(i=0; i= 0x01 && code <= 0x0A) + return type[code - 0x01]; + return out_of_spec; +} + +static PyObject *dmi_on_board_devices(struct dmi_header *h) +{ + PyObject *data = NULL; + u8 *p = h->data + 4; + u8 count = (h->length - 0x04) / 2; + int i; + + if((data = PyList_New(count))) { + PyObject *_pydict; + PyObject *_val; + + for(i = 0; i < count; i++) { + _pydict = PyDict_New(); + + _val = PyString_FromString(dmi_on_board_devices_type(p[2 * i] & 0x7F)); + PyDict_SetItemString(_pydict, "Type", _val); + Py_DECREF(_val); + + _val = p[2 * i] & 0x80 ? Py_True : Py_False; + PyDict_SetItemString(_pydict, "Enabled", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, p[2 * i + 1]); + PyDict_SetItemString(_pydict, "Description", _val); + Py_DECREF(_val); + + PyList_SET_ITEM(data, i, _pydict); + } + } + + assert(data != NULL); + Py_INCREF(data); + return data; } /******************************************************************************* * 3.3.12 OEM Strings (Type 11) */ -static PyObject *dmi_oem_strings(struct dmi_header *h) { - u8 *p=h->data+4; - u8 count=p[0x00]; - int i; +static PyObject *dmi_oem_strings(struct dmi_header *h) +{ + u8 *p = h->data + 4; + u8 count = p[0x00]; + int i; - PyObject *data = PyDict_New(); - PyObject *val; + PyObject *data = PyDict_New(); + PyObject *val; - for(i=1; i<=count; i++) { - val = dmi_string_py(h, i); - PyDict_SetItem(data, PyInt_FromLong(i), val); - Py_DECREF(val); - } + for(i = 1; i <= count; i++) { + val = dmi_string_py(h, i); + PyDict_SetItem(data, PyInt_FromLong(i), val); + Py_DECREF(val); + } - return data; + return data; } /******************************************************************************* ** 3.3.13 System Configuration Options (Type 12) */ -static PyObject *dmi_system_configuration_options(struct dmi_header *h) { - u8 *p=h->data+4; - u8 count=p[0x00]; - int i; +static PyObject *dmi_system_configuration_options(struct dmi_header *h) +{ + u8 *p = h->data + 4; + u8 count = p[0x00]; + int i; + + PyObject *data = PyDict_New(); + PyObject *val; - PyObject *data = PyDict_New(); - PyObject *val; - for(i=1; i<=count; i++) { - val = dmi_string_py(h, i); - PyDict_SetItem(data, PyInt_FromLong(i), val); - Py_DECREF(val); - } + for(i = 1; i <= count; i++) { + val = dmi_string_py(h, i); + PyDict_SetItem(data, PyInt_FromLong(i), val); + Py_DECREF(val); + } - return data; + return data; } /******************************************************************************* ** 3.3.14 BIOS Language Information (Type 13) */ -static PyObject *dmi_bios_languages(struct dmi_header *h) { - u8 *p = h->data+4; - u8 count = p[0x00]; - int i; +static PyObject *dmi_bios_languages(struct dmi_header *h) +{ + u8 *p = h->data + 4; + u8 count = p[0x00]; + int i; + + PyObject *data = PyList_New(count + 1); - PyObject *data = PyList_New(count + 1); - for(i=1; i<=count; i++) - PyList_SET_ITEM(data, i, dmi_string_py(h, i)); + for(i = 1; i <= count; i++) + PyList_SET_ITEM(data, i, dmi_string_py(h, i)); - return data; + return data; } /******************************************************************************* ** 3.3.15 Group Associations (Type 14) */ -static PyObject *dmi_group_associations_items(u8 count, const u8 *p) { - int i; +static PyObject *dmi_group_associations_items(u8 count, const u8 * p) +{ + int i; + + PyObject *data = PyList_New(count); + PyObject *val; - PyObject *data = PyList_New(count); - PyObject *val; - for(i=0; i=0x80) return "OEM-specific"; - return out_of_spec; -} - -static PyObject *dmi_event_log_status_py(u8 code) { - static const char *valid[]={ - "Invalid", /* 0 */ - "Valid" /* 1 */ - }; - static const char *full[]={ - "Not Full", /* 0 */ - "Full" /* 1 */ - }; - - return PyString_FromFormat("%s, %s", valid[(code>>0)&1], full[(code>>1)&1]); -} - -static PyObject *dmi_event_log_address_py(u8 method, const u8 *p) { - /* 3.3.16.3 */ - switch(method) { - case 0x00: - case 0x01: - case 0x02: - return PyString_FromFormat("Index 0x%04x, Data 0x%04x", WORD(p), WORD(p+2)); - break; - case 0x03: - return PyString_FromFormat("0x%08x", DWORD(p)); - break; - case 0x04: - return PyString_FromFormat("0x%04x", WORD(p)); - break; - default: - return PyString_FromString("Unknown"); - } -} - -static const char *dmi_event_log_header_type(u8 code) { - static const char *type[]={ - "No Header", /* 0x00 */ - "Type 1" /* 0x01 */ - }; - - if(code<=0x01) return type[code]; - if(code>=0x80) return "OEM-specific"; - return out_of_spec; -} - -static PyObject *dmi_event_log_descriptor_type(u8 code) { - /* 3.3.16.6.1 */ - static const char *type[]={ - NULL, /* 0x00 */ - "Single-bit ECC memory error", - "Multi-bit ECC memory error", - "Parity memory error", - "Bus timeout", - "I/O channel block", - "Software NMI", - "POST memory resize", - "POST error", - "PCI parity error", - "PCI system error", - "CPU failure", - "EISA failsafe timer timeout", - "Correctable memory log disabled", - "Logging disabled", - NULL, /* 0x0F */ - "System limit exceeded", - "Asynchronous hardware timer expired", - "System configuration information", - "Hard disk information", - "System reconfigured", - "Uncorrectable CPU-complex error", - "Log area reset/cleared", - "System boot" /* 0x17 */ - }; - - const char *data; - if(code<=0x17 && type[code]!=NULL) data = type[code]; - else if(code>=0x80 && code<=0xFE) data = "OEM-specific"; - else if(code==0xFF) data = "End of log"; - else data = out_of_spec; - return PyString_FromString(data); -} - -static PyObject *dmi_event_log_descriptor_format(u8 code) { - /* 3.3.16.6.2 */ - static const char *format[]={ - "None", /* 0x00 */ - "Handle", - "Multiple-event", - "Multiple-event handle", - "POST results bitmap", - "System management", - "Multiple-event system management" /* 0x06 */ - }; - - const char *data; - if(code<=0x06) data = format[code]; - else if(code>=0x80) data = "OEM-specific"; - else data = out_of_spec; - return PyString_FromString(data); -} - -static PyObject *dmi_event_log_descriptors(u8 count, const u8 len, const u8 *p) { - /* 3.3.16.1 */ - int i; - - PyObject* data; - data = PyList_New(count); - for(i=0; i=0x02) { - PyObject *subdata = PyDict_New(); - PyDict_SetItemString(subdata, "Descriptor", dmi_event_log_descriptor_type(p[i*len])); - PyDict_SetItemString(subdata, "Data Format", dmi_event_log_descriptor_format(p[i*len+1])); - PyList_SET_ITEM(data, i, subdata); - } - } - return data; +static const char *dmi_event_log_method(u8 code) +{ + static const char *method[] = { + "Indexed I/O, one 8-bit index port, one 8-bit data port", /* 0x00 */ + "Indexed I/O, two 8-bit index ports, one 8-bit data port", + "Indexed I/O, one 16-bit index port, one 8-bit data port", + "Memory-mapped physical 32-bit address", + "General-purpose non-volatile data functions" /* 0x04 */ + }; + + if(code <= 0x04) + return method[code]; + if(code >= 0x80) + return "OEM-specific"; + return out_of_spec; +} + +static PyObject *dmi_event_log_status_py(u8 code) +{ + static const char *valid[] = { + "Invalid", /* 0 */ + "Valid" /* 1 */ + }; + static const char *full[] = { + "Not Full", /* 0 */ + "Full" /* 1 */ + }; + + return PyString_FromFormat("%s, %s", valid[(code >> 0) & 1], full[(code >> 1) & 1]); +} + +static PyObject *dmi_event_log_address_py(u8 method, const u8 * p) +{ + /* 3.3.16.3 */ + switch (method) { + case 0x00: + case 0x01: + case 0x02: + return PyString_FromFormat("Index 0x%04x, Data 0x%04x", WORD(p), WORD(p + 2)); + break; + case 0x03: + return PyString_FromFormat("0x%08x", DWORD(p)); + break; + case 0x04: + return PyString_FromFormat("0x%04x", WORD(p)); + break; + default: + return PyString_FromString("Unknown"); + } +} + +static const char *dmi_event_log_header_type(u8 code) +{ + static const char *type[] = { + "No Header", /* 0x00 */ + "Type 1" /* 0x01 */ + }; + + if(code <= 0x01) + return type[code]; + if(code >= 0x80) + return "OEM-specific"; + return out_of_spec; +} + +static PyObject *dmi_event_log_descriptor_type(u8 code) +{ + /* 3.3.16.6.1 */ + static const char *type[] = { + NULL, /* 0x00 */ + "Single-bit ECC memory error", + "Multi-bit ECC memory error", + "Parity memory error", + "Bus timeout", + "I/O channel block", + "Software NMI", + "POST memory resize", + "POST error", + "PCI parity error", + "PCI system error", + "CPU failure", + "EISA failsafe timer timeout", + "Correctable memory log disabled", + "Logging disabled", + NULL, /* 0x0F */ + "System limit exceeded", + "Asynchronous hardware timer expired", + "System configuration information", + "Hard disk information", + "System reconfigured", + "Uncorrectable CPU-complex error", + "Log area reset/cleared", + "System boot" /* 0x17 */ + }; + + const char *data; + + if(code <= 0x17 && type[code] != NULL) + data = type[code]; + else if(code >= 0x80 && code <= 0xFE) + data = "OEM-specific"; + else if(code == 0xFF) + data = "End of log"; + else + data = out_of_spec; + return PyString_FromString(data); +} + +static PyObject *dmi_event_log_descriptor_format(u8 code) +{ + /* 3.3.16.6.2 */ + static const char *format[] = { + "None", /* 0x00 */ + "Handle", + "Multiple-event", + "Multiple-event handle", + "POST results bitmap", + "System management", + "Multiple-event system management" /* 0x06 */ + }; + + const char *data; + + if(code <= 0x06) + data = format[code]; + else if(code >= 0x80) + data = "OEM-specific"; + else + data = out_of_spec; + return PyString_FromString(data); +} + +static PyObject *dmi_event_log_descriptors(u8 count, const u8 len, const u8 * p) +{ + /* 3.3.16.1 */ + int i; + + PyObject *data; + + data = PyList_New(count); + for(i = 0; i < count; i++) { + if(len >= 0x02) { + PyObject *subdata = PyDict_New(); + + PyDict_SetItemString(subdata, "Descriptor", + dmi_event_log_descriptor_type(p[i * len])); + PyDict_SetItemString(subdata, "Data Format", + dmi_event_log_descriptor_format(p[i * len + 1])); + PyList_SET_ITEM(data, i, subdata); + } + } + return data; } /******************************************************************************* ** 3.3.17 Physical Memory Array (Type 16) */ -static PyObject *dmi_memory_array_location(u8 code) { - /* 3.3.17.1 */ - static const char *location[]={ - "Other", /* 0x01 */ - "Unknown", - "System Board Or Motherboard", - "ISA Add-on Card", - "EISA Add-on Card", - "PCI Add-on Card", - "MCA Add-on Card", - "PCMCIA Add-on Card", - "Proprietary Add-on Card", - "NuBus" /* 0x0A, master.mif says 16 */ - }; - static const char *location_0xA0[]={ - "PC-98/C20 Add-on Card", /* 0xA0 */ - "PC-98/C24 Add-on Card", - "PC-98/E Add-on Card", - "PC-98/Local Bus Add-on Card", - "PC-98/Card Slot Add-on Card" /* 0xA4, from master.mif */ - }; - - if(code>=0x01 && code<=0x0A) return PyString_FromString(location[code-0x01]); - if(code>=0xA0 && code<=0xA4) return PyString_FromString(location_0xA0[code-0xA0]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_memory_array_use(u8 code) { - /* 3.3.17.2 */ - static const char *use[]={ - "Other", /* 0x01 */ - "Unknown", - "System Memory", - "Video Memory", - "Flash Memory", - "Non-volatile RAM", - "Cache Memory" /* 0x07 */ - }; - - if(code>=0x01 && code<=0x07) return PyString_FromString(use[code-0x01]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_memory_array_ec_type(u8 code) { - /* 3.3.17.3 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "None", - "Parity", - "Single-bit ECC", - "Multi-bit ECC", - "CRC" /* 0x07 */ - }; - - if(code>=0x01 && code<=0x07) return PyString_FromString(type[code-0x01]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_memory_array_capacity(u32 code) { - PyObject *data; - if(code==0x8000000) data = PyString_FromString("Unknown"); - else { - if((code&0x000FFFFF)==0) data = PyString_FromFormat("%i GB", code>>20); - else if((code&0x000003FF)==0) data = PyString_FromFormat("%i MB", code>>10); - else data = PyString_FromFormat("%i kB", code); - } - return data; -} - -static PyObject *dmi_memory_array_error_handle(u16 code) { - PyObject *data; - if(code==0xFFFE) data = PyString_FromString("Not Provided"); - else if(code==0xFFFF) data = PyString_FromString("No Error"); - else data = PyString_FromFormat("0x%04x", code); - return data; +static PyObject *dmi_memory_array_location(u8 code) +{ + /* 3.3.17.1 */ + static const char *location[] = { + "Other", /* 0x01 */ + "Unknown", + "System Board Or Motherboard", + "ISA Add-on Card", + "EISA Add-on Card", + "PCI Add-on Card", + "MCA Add-on Card", + "PCMCIA Add-on Card", + "Proprietary Add-on Card", + "NuBus" /* 0x0A, master.mif says 16 */ + }; + static const char *location_0xA0[] = { + "PC-98/C20 Add-on Card", /* 0xA0 */ + "PC-98/C24 Add-on Card", + "PC-98/E Add-on Card", + "PC-98/Local Bus Add-on Card", + "PC-98/Card Slot Add-on Card" /* 0xA4, from master.mif */ + }; + + if(code >= 0x01 && code <= 0x0A) + return PyString_FromString(location[code - 0x01]); + if(code >= 0xA0 && code <= 0xA4) + return PyString_FromString(location_0xA0[code - 0xA0]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_memory_array_use(u8 code) +{ + /* 3.3.17.2 */ + static const char *use[] = { + "Other", /* 0x01 */ + "Unknown", + "System Memory", + "Video Memory", + "Flash Memory", + "Non-volatile RAM", + "Cache Memory" /* 0x07 */ + }; + + if(code >= 0x01 && code <= 0x07) + return PyString_FromString(use[code - 0x01]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_memory_array_ec_type(u8 code) +{ + /* 3.3.17.3 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "None", + "Parity", + "Single-bit ECC", + "Multi-bit ECC", + "CRC" /* 0x07 */ + }; + + if(code >= 0x01 && code <= 0x07) + return PyString_FromString(type[code - 0x01]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_memory_array_capacity(u32 code) +{ + PyObject *data; + + if(code == 0x8000000) + data = PyString_FromString("Unknown"); + else { + if((code & 0x000FFFFF) == 0) + data = PyString_FromFormat("%i GB", code >> 20); + else if((code & 0x000003FF) == 0) + data = PyString_FromFormat("%i MB", code >> 10); + else + data = PyString_FromFormat("%i kB", code); + } + return data; +} + +static PyObject *dmi_memory_array_error_handle(u16 code) +{ + PyObject *data; + + if(code == 0xFFFE) + data = PyString_FromString("Not Provided"); + else if(code == 0xFFFF) + data = PyString_FromString("No Error"); + else + data = PyString_FromFormat("0x%04x", code); + return data; } /******************************************************************************* ** 3.3.18 Memory Device (Type 17) */ -static PyObject *dmi_memory_device_width(u16 code) { - /* - ** If no memory module is present, width may be 0 - */ - PyObject *data; - if(code==0xFFFF || code==0) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%i bits", code); - return data; -} - -static PyObject *dmi_memory_device_size(u16 code) { - PyObject *data = NULL; - if(code==0) data = Py_None; //. No Module Installed - else if(code==0xFFFF) data = PyString_FromString("Unknown"); //. Unknown - else { - //. Keeping this as String rather than Int as it has KB and MB representations... - if(code&0x8000) data = PyString_FromFormat("%d KB", code&0x7FFF); - else data = PyString_FromFormat("%d MB", code); - } - return data; -} - -static PyObject *dmi_memory_device_form_factor(u8 code) { - /* 3.3.18.1 */ - static const char *form_factor[]={ - "Other", /* 0x01 */ - "Unknown", - "SIMM", - "SIP", - "Chip", - "DIP", - "ZIP", - "Proprietary Card", - "DIMM", - "TSOP", - "Row Of Chips", - "RIMM", - "SODIMM", - "SRIMM", - "FB-DIMM" /* 0x0F */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x0F) return data = PyString_FromString(form_factor[code-0x01]); - return data = OUT_OF_SPEC; -} - -static PyObject *dmi_memory_device_set(u8 code) { - PyObject *data; - if(code==0) data = Py_None; - else if(code==0xFF) data = PyString_FromString("Unknown"); - else data = PyInt_FromLong(code); - return data; -} - -static PyObject *dmi_memory_device_type(u8 code) { - /* 3.3.18.2 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "DRAM", - "EDRAM", - "VRAM", - "SRAM", - "RAM", - "ROM", - "Flash", - "EEPROM", - "FEPROM", - "EPROM", - "CDRAM", - "3DRAM", - "SDRAM", - "SGRAM", - "RDRAM", - "DDR", - "DDR2", - "DDR2 FB-DIMM" /* 0x14 */ - }; - - if(code>=0x01 && code<=0x14) return PyString_FromString(type[code-0x01]); - return OUT_OF_SPEC; -} - -static PyObject *dmi_memory_device_type_detail(u16 code) { - /* 3.3.18.3 */ - static const char *detail[]={ - "Other", /* 1 */ - "Unknown", - "Fast-paged", - "Static Column", - "Pseudo-static", - "RAMBus", - "Synchronous", - "CMOS", - "EDO", - "Window DRAM", - "Cache DRAM", - "Non-Volatile" /* 12 */ - }; - - PyObject *data; - if((code&0x1FFE)==0) data = Py_None; - else { - int i; - - data = PyList_New(12); - for(i=1; i<=12; i++) - if(code&(1<= 0x01 && code <= 0x0F) + return data = PyString_FromString(form_factor[code - 0x01]); + return data = OUT_OF_SPEC; +} + +static PyObject *dmi_memory_device_set(u8 code) +{ + PyObject *data; + + if(code == 0) + data = Py_None; + else if(code == 0xFF) + data = PyString_FromString("Unknown"); + else + data = PyInt_FromLong(code); + return data; +} + +static PyObject *dmi_memory_device_type(u8 code) +{ + /* 3.3.18.2 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "DRAM", + "EDRAM", + "VRAM", + "SRAM", + "RAM", + "ROM", + "Flash", + "EEPROM", + "FEPROM", + "EPROM", + "CDRAM", + "3DRAM", + "SDRAM", + "SGRAM", + "RDRAM", + "DDR", + "DDR2", + "DDR2 FB-DIMM" /* 0x14 */ + }; + + if(code >= 0x01 && code <= 0x14) + return PyString_FromString(type[code - 0x01]); + return OUT_OF_SPEC; +} + +static PyObject *dmi_memory_device_type_detail(u16 code) +{ + /* 3.3.18.3 */ + static const char *detail[] = { + "Other", /* 1 */ + "Unknown", + "Fast-paged", + "Static Column", + "Pseudo-static", + "RAMBus", + "Synchronous", + "CMOS", + "EDO", + "Window DRAM", + "Cache DRAM", + "Non-Volatile" /* 12 */ + }; + + PyObject *data; + + if((code & 0x1FFE) == 0) + data = Py_None; + else { + int i; + + data = PyList_New(12); + for(i = 1; i <= 12; i++) + if(code & (1 << i)) + PyList_SET_ITEM(data, i - 1, PyString_FromString(detail[i - 1])); + else + PyList_SET_ITEM(data, i - 1, Py_None); + } + return data; +} + +static PyObject *dmi_memory_device_speed(u16 code) +{ + PyObject *data; + + if(code == 0) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%i MHz (%.1f ns)", code, (float)1000 / code); + return data; } /******************************************************************************* * 3.3.19 32-bit Memory Error Information (Type 18) */ -static PyObject *dmi_memory_error_type(u8 code) { - /* 3.3.19.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "OK", - "Bad Read", - "Parity Error", - "Single-bit Error", - "Double-bit Error", - "Multi-bit Error", - "Nibble Error", - "Checksum Error", - "CRC Error", - "Corrected Single-bit Error", - "Corrected Error", - "Uncorrectable Error" /* 0x0E */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x0E) data = PyString_FromString(type[code-0x01]); - data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_memory_error_granularity(u8 code) { - /* 3.3.19.2 */ - static const char *granularity[]={ - "Other", /* 0x01 */ - "Unknown", - "Device Level", - "Memory Partition Level" /* 0x04 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x04) data = PyString_FromString(granularity[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_memory_error_operation(u8 code) { - /* 3.3.19.3 */ - static const char *operation[]={ - "Other", /* 0x01 */ - "Unknown", - "Read", - "Write", - "Partial Write" /* 0x05 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x05) data = PyString_FromString(operation[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_memory_error_syndrome(u32 code) { - PyObject *data; - if(code==0x00000000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("0x%08x", code); - return data; -} - -static PyObject *dmi_32bit_memory_error_address(u32 code) { - PyObject *data; - if(code==0x80000000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("0x%08x", code); - return data; +static PyObject *dmi_memory_error_type(u8 code) +{ + /* 3.3.19.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "OK", + "Bad Read", + "Parity Error", + "Single-bit Error", + "Double-bit Error", + "Multi-bit Error", + "Nibble Error", + "Checksum Error", + "CRC Error", + "Corrected Single-bit Error", + "Corrected Error", + "Uncorrectable Error" /* 0x0E */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x0E) + data = PyString_FromString(type[code - 0x01]); + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_memory_error_granularity(u8 code) +{ + /* 3.3.19.2 */ + static const char *granularity[] = { + "Other", /* 0x01 */ + "Unknown", + "Device Level", + "Memory Partition Level" /* 0x04 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x04) + data = PyString_FromString(granularity[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_memory_error_operation(u8 code) +{ + /* 3.3.19.3 */ + static const char *operation[] = { + "Other", /* 0x01 */ + "Unknown", + "Read", + "Write", + "Partial Write" /* 0x05 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x05) + data = PyString_FromString(operation[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_memory_error_syndrome(u32 code) +{ + PyObject *data; + + if(code == 0x00000000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("0x%08x", code); + return data; +} + +static PyObject *dmi_32bit_memory_error_address(u32 code) +{ + PyObject *data; + + if(code == 0x80000000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("0x%08x", code); + return data; } /******************************************************************************* ** 3.3.20 Memory Array Mapped Address (Type 19) */ -static PyObject *dmi_mapped_address_size(u32 code) { - PyObject *data; - if(code==0) data = PyString_FromString("Invalid"); - else if((code&0x000FFFFF)==0) data = PyString_FromFormat("%i GB", code>>20); - else if((code&0x000003FF)==0) data = PyString_FromFormat("%i MB", code>>10); - else data = PyString_FromFormat("%i kB", code); - return data; +static PyObject *dmi_mapped_address_size(u32 code) +{ + PyObject *data; + + if(code == 0) + data = PyString_FromString("Invalid"); + else if((code & 0x000FFFFF) == 0) + data = PyString_FromFormat("%i GB", code >> 20); + else if((code & 0x000003FF) == 0) + data = PyString_FromFormat("%i MB", code >> 10); + else + data = PyString_FromFormat("%i kB", code); + return data; } /******************************************************************************* ** 3.3.21 Memory Device Mapped Address (Type 20) */ -static PyObject *dmi_mapped_address_row_position(u8 code) { - PyObject *data; - if(code==0) data = OUT_OF_SPEC; - else if(code==0xFF) data = PyString_FromString("Unknown"); - else data = PyInt_FromLong(code); - return data; +static PyObject *dmi_mapped_address_row_position(u8 code) +{ + PyObject *data; + + if(code == 0) + data = OUT_OF_SPEC; + else if(code == 0xFF) + data = PyString_FromString("Unknown"); + else + data = PyInt_FromLong(code); + return data; } -static PyObject *dmi_mapped_address_interleave_position(u8 code) { - PyObject *data; - if(code!=0) { - data = PyDict_New(); - PyDict_SetItemString(data, "Interleave Position", (code==0xFF)?PyString_FromString("Unknown"):PyInt_FromLong(code)); - } else data = Py_None; - return data; +static PyObject *dmi_mapped_address_interleave_position(u8 code) +{ + PyObject *data; + + if(code != 0) { + data = PyDict_New(); + PyDict_SetItemString(data, "Interleave Position", + (code == + 0xFF) ? PyString_FromString("Unknown") : + PyInt_FromLong(code)); + } else + data = Py_None; + return data; } -static PyObject *dmi_mapped_address_interleaved_data_depth(u8 code) { - PyObject *data; - if(code!=0) { - data = PyDict_New(); - PyDict_SetItemString(data, "Interleave Data Depth", (code==0xFF)?PyString_FromString("Unknown"):PyInt_FromLong(code)); - } else data = Py_None; - return data; +static PyObject *dmi_mapped_address_interleaved_data_depth(u8 code) +{ + PyObject *data; + + if(code != 0) { + data = PyDict_New(); + PyDict_SetItemString(data, "Interleave Data Depth", + (code == + 0xFF) ? PyString_FromString("Unknown") : + PyInt_FromLong(code)); + } else + data = Py_None; + return data; } /******************************************************************************* ** 3.3.22 Built-in Pointing Device (Type 21) */ -static PyObject *dmi_pointing_device_type(u8 code) { - /* 3.3.22.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Mouse", - "Track Ball", - "Track Point", - "Glide Point", - "Touch Pad", - "Touch Screen", - "Optical Sensor" /* 0x09 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x09) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_pointing_device_interface(u8 code) { - /* 3.3.22.2 */ - static const char *interface[]={ - "Other", /* 0x01 */ - "Unknown", - "Serial", - "PS/2", - "Infrared", - "HIP-HIL", - "Bus Mouse", - "ADB (Apple Desktop Bus)" /* 0x08 */ - }; - static const char *interface_0xA0[]={ - "Bus Mouse DB-9", /* 0xA0 */ - "Bus Mouse Micro DIN", - "USB" /* 0xA2 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x08) data = PyString_FromString(interface[code-0x01]); - else if(code>=0xA0 && code<=0xA2) data = PyString_FromString(interface_0xA0[code-0xA0]); - else data = OUT_OF_SPEC; - return data; +static PyObject *dmi_pointing_device_type(u8 code) +{ + /* 3.3.22.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "Mouse", + "Track Ball", + "Track Point", + "Glide Point", + "Touch Pad", + "Touch Screen", + "Optical Sensor" /* 0x09 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x09) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_pointing_device_interface(u8 code) +{ + /* 3.3.22.2 */ + static const char *interface[] = { + "Other", /* 0x01 */ + "Unknown", + "Serial", + "PS/2", + "Infrared", + "HIP-HIL", + "Bus Mouse", + "ADB (Apple Desktop Bus)" /* 0x08 */ + }; + static const char *interface_0xA0[] = { + "Bus Mouse DB-9", /* 0xA0 */ + "Bus Mouse Micro DIN", + "USB" /* 0xA2 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x08) + data = PyString_FromString(interface[code - 0x01]); + else if(code >= 0xA0 && code <= 0xA2) + data = PyString_FromString(interface_0xA0[code - 0xA0]); + else + data = OUT_OF_SPEC; + return data; } /******************************************************************************* ** 3.3.23 Portable Battery (Type 22) */ -static PyObject *dmi_battery_chemistry(u8 code) { - /* 3.3.23.1 */ - static const char *chemistry[]={ - "Other", /* 0x01 */ - "Unknown", - "Lead Acid", - "Nickel Cadmium", - "Nickel Metal Hydride", - "Lithium Ion", - "Zinc Air", - "Lithium Polymer" /* 0x08 */ - }; - PyObject *data; +static PyObject *dmi_battery_chemistry(u8 code) +{ + /* 3.3.23.1 */ + static const char *chemistry[] = { + "Other", /* 0x01 */ + "Unknown", + "Lead Acid", + "Nickel Cadmium", + "Nickel Metal Hydride", + "Lithium Ion", + "Zinc Air", + "Lithium Polymer" /* 0x08 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x08) + data = PyString_FromString(chemistry[code - 0x01]); + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_battery_capacity(u16 code, u8 multiplier) +{ + PyObject *data; - if(code>=0x01 && code<=0x08) data = PyString_FromString(chemistry[code-0x01]); - data = OUT_OF_SPEC; - return data; + if(code == 0) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%i mWh", code * multiplier); + return data; } -static PyObject *dmi_battery_capacity(u16 code, u8 multiplier) { - PyObject *data; - if(code==0) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%i mWh", code*multiplier); - return data; -} +static PyObject *dmi_battery_voltage(u16 code) +{ + PyObject *data; -static PyObject *dmi_battery_voltage(u16 code) { - PyObject *data; - if(code==0) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%i mV", code); - return data; + if(code == 0) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%i mV", code); + return data; } -static PyObject *dmi_battery_maximum_error(u8 code) { - PyObject *data; - if(code==0xFF) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%i%%", code); - return data; +static PyObject *dmi_battery_maximum_error(u8 code) +{ + PyObject *data; + + if(code == 0xFF) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%i%%", code); + return data; } /******************************************************************************* ** 3.3.24 System Reset (Type 23) */ -static PyObject *dmi_system_reset_boot_option(u8 code) { - static const char *option[]={ - "Operating System", /* 0x1 */ - "System Utilities", - "Do Not Reboot" /* 0x3 */ - }; - PyObject *data; +static PyObject *dmi_system_reset_boot_option(u8 code) +{ + static const char *option[] = { + "Operating System", /* 0x1 */ + "System Utilities", + "Do Not Reboot" /* 0x3 */ + }; + PyObject *data; - if(code>=0x1) data = PyString_FromString(option[code-0x1]); - else data = OUT_OF_SPEC; - return data; + if(code >= 0x1) + data = PyString_FromString(option[code - 0x1]); + else + data = OUT_OF_SPEC; + return data; } -static PyObject *dmi_system_reset_count(u16 code) { - PyObject *data; - if(code==0xFFFF) data = PyString_FromString("Unknown"); - else data = PyInt_FromLong(code); - return data; +static PyObject *dmi_system_reset_count(u16 code) +{ + PyObject *data; + + if(code == 0xFFFF) + data = PyString_FromString("Unknown"); + else + data = PyInt_FromLong(code); + return data; } -static PyObject *dmi_system_reset_timer(u16 code) { - PyObject *data; - if(code==0xFFFF) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%i min", code); - return data; +static PyObject *dmi_system_reset_timer(u16 code) +{ + PyObject *data; + + if(code == 0xFFFF) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%i min", code); + return data; } /******************************************************************************* * 3.3.25 Hardware Security (Type 24) */ -static PyObject *dmi_hardware_security_status(u8 code) { - static const char *status[]={ - "Disabled", /* 0x00 */ - "Enabled", - "Not Implemented", - "Unknown" /* 0x03 */ - }; +static PyObject *dmi_hardware_security_status(u8 code) +{ + static const char *status[] = { + "Disabled", /* 0x00 */ + "Enabled", + "Not Implemented", + "Unknown" /* 0x03 */ + }; - return PyString_FromString(status[code]); + return PyString_FromString(status[code]); } /******************************************************************************* ** 3.3.26 System Power Controls (Type 25) */ -static PyObject *dmi_power_controls_power_on(const u8 *p) { - /* 3.3.26.1 */ - PyObject *data = PyList_New(5); - - PyList_SET_ITEM(data, 0, dmi_bcd_range(p[0], 0x01, 0x12)?PyString_FromFormat(" %02x", p[0]):PyString_FromString(" *")); - PyList_SET_ITEM(data, 1, dmi_bcd_range(p[1], 0x01, 0x31)?PyString_FromFormat("-%02x", p[1]):PyString_FromString("-*")); - PyList_SET_ITEM(data, 2, dmi_bcd_range(p[2], 0x00, 0x23)?PyString_FromFormat(" %02x", p[2]):PyString_FromString(" *")); - PyList_SET_ITEM(data, 3, dmi_bcd_range(p[3], 0x00, 0x59)?PyString_FromFormat(":%02x", p[3]):PyString_FromString(":*")); - PyList_SET_ITEM(data, 4, dmi_bcd_range(p[4], 0x00, 0x59)?PyString_FromFormat(":%02x", p[4]):PyString_FromString(":*")); - - return data; +static PyObject *dmi_power_controls_power_on(const u8 * p) +{ + /* 3.3.26.1 */ + PyObject *data = PyList_New(5); + + PyList_SET_ITEM(data, 0, + dmi_bcd_range(p[0], 0x01, 0x12) ? PyString_FromFormat(" %02x", + p[0]) : + PyString_FromString(" *")); + PyList_SET_ITEM(data, 1, + dmi_bcd_range(p[1], 0x01, 0x31) ? PyString_FromFormat("-%02x", + p[1]) : + PyString_FromString("-*")); + PyList_SET_ITEM(data, 2, + dmi_bcd_range(p[2], 0x00, 0x23) ? PyString_FromFormat(" %02x", + p[2]) : + PyString_FromString(" *")); + PyList_SET_ITEM(data, 3, + dmi_bcd_range(p[3], 0x00, 0x59) ? PyString_FromFormat(":%02x", + p[3]) : + PyString_FromString(":*")); + PyList_SET_ITEM(data, 4, + dmi_bcd_range(p[4], 0x00, 0x59) ? PyString_FromFormat(":%02x", + p[4]) : + PyString_FromString(":*")); + + return data; } /******************************************************************************* * 3.3.27 Voltage Probe (Type 26) */ -static PyObject *dmi_voltage_probe_location(u8 code) { - /* 3.3.27.1 */ - static const char *location[]={ - "Other", /* 0x01 */ - "Unknown", - "Processor", - "Disk", - "Peripheral Bay", - "System Management Module", - "Motherboard", - "Memory Module", - "Processor Module", - "Power Unit", - "Add-in Card" /* 0x0B */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x0B) data = PyString_FromString(location[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_probe_status(u8 code) { - /* 3.3.27.1 */ - static const char *status[]={ - "Other", /* 0x01 */ - "Unknown", - "OK", - "Non-critical", - "Critical", - "Non-recoverable" /* 0x06 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x06) data = PyString_FromString(status[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_voltage_probe_value(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.3f V", (float)(i16)code/1000); - return data; -} - -static PyObject *dmi_voltage_probe_resolution(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.1f mV", (float)code/10); - return data; -} - -static PyObject *dmi_probe_accuracy(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.2f%%", (float)code/100); - return data; +static PyObject *dmi_voltage_probe_location(u8 code) +{ + /* 3.3.27.1 */ + static const char *location[] = { + "Other", /* 0x01 */ + "Unknown", + "Processor", + "Disk", + "Peripheral Bay", + "System Management Module", + "Motherboard", + "Memory Module", + "Processor Module", + "Power Unit", + "Add-in Card" /* 0x0B */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x0B) + data = PyString_FromString(location[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_probe_status(u8 code) +{ + /* 3.3.27.1 */ + static const char *status[] = { + "Other", /* 0x01 */ + "Unknown", + "OK", + "Non-critical", + "Critical", + "Non-recoverable" /* 0x06 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x06) + data = PyString_FromString(status[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_voltage_probe_value(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.3f V", (float)(i16) code / 1000); + return data; +} + +static PyObject *dmi_voltage_probe_resolution(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.1f mV", (float)code / 10); + return data; +} + +static PyObject *dmi_probe_accuracy(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.2f%%", (float)code / 100); + return data; } /******************************************************************************* ** 3.3.28 Cooling Device (Type 27) */ -static PyObject *dmi_cooling_device_type(u8 code) { - /* 3.3.28.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Fan", - "Centrifugal Blower", - "Chip Fan", - "Cabinet Fan", - "Power Supply Fan", - "Heat Pipe", - "Integrated Refrigeration" /* 0x09 */ - }; - static const char *type_0x10[]={ - "Active Cooling", /* 0x10, master.mif says 32 */ - "Passive Cooling" /* 0x11, master.mif says 33 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x09) data = PyString_FromString(type[code-0x01]); - else if(code>=0x10 && code<=0x11) data = PyString_FromString(type_0x10[code-0x10]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_cooling_device_speed(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown Or Non-rotating"); - else data = PyString_FromFormat("%i rpm", code); - return data; +static PyObject *dmi_cooling_device_type(u8 code) +{ + /* 3.3.28.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "Fan", + "Centrifugal Blower", + "Chip Fan", + "Cabinet Fan", + "Power Supply Fan", + "Heat Pipe", + "Integrated Refrigeration" /* 0x09 */ + }; + static const char *type_0x10[] = { + "Active Cooling", /* 0x10, master.mif says 32 */ + "Passive Cooling" /* 0x11, master.mif says 33 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x09) + data = PyString_FromString(type[code - 0x01]); + else if(code >= 0x10 && code <= 0x11) + data = PyString_FromString(type_0x10[code - 0x10]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_cooling_device_speed(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown Or Non-rotating"); + else + data = PyString_FromFormat("%i rpm", code); + return data; } /******************************************************************************* ** 3.3.29 Temperature Probe (Type 28) */ -static PyObject *dmi_temperature_probe_location(u8 code) { - /* 3.3.29.1 */ - static const char *location[]={ - "Other", /* 0x01 */ - "Unknown", - "Processor", - "Disk", - "Peripheral Bay", - "System Management Module", /* master.mif says SMB Master */ - "Motherboard", - "Memory Module", - "Processor Module", - "Power Unit", - "Add-in Card", - "Front Panel Board", - "Back Panel Board", - "Power System Board", - "Drive Back Plane" /* 0x0F */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x0F) data = PyString_FromString(location[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_temperature_probe_value(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.1f deg C", (float)(i16)code/10); - return data; -} - -static PyObject *dmi_temperature_probe_resolution(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.3f deg C", (float)code/1000); - return data; +static PyObject *dmi_temperature_probe_location(u8 code) +{ + /* 3.3.29.1 */ + static const char *location[] = { + "Other", /* 0x01 */ + "Unknown", + "Processor", + "Disk", + "Peripheral Bay", + "System Management Module", /* master.mif says SMB Master */ + "Motherboard", + "Memory Module", + "Processor Module", + "Power Unit", + "Add-in Card", + "Front Panel Board", + "Back Panel Board", + "Power System Board", + "Drive Back Plane" /* 0x0F */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x0F) + data = PyString_FromString(location[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_temperature_probe_value(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.1f deg C", (float)(i16) code / 10); + return data; +} + +static PyObject *dmi_temperature_probe_resolution(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.3f deg C", (float)code / 1000); + return data; } /******************************************************************************* ** 3.3.30 Electrical Current Probe (Type 29) */ -static PyObject *dmi_current_probe_value(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.3f A", (float)(i16)code/1000); - return data; +static PyObject *dmi_current_probe_value(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.3f A", (float)(i16) code / 1000); + return data; } -static PyObject *dmi_current_probe_resolution(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.1f mA", (float)code/10); - return data; +static PyObject *dmi_current_probe_resolution(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.1f mA", (float)code / 10); + return data; } /******************************************************************************* ** 3.3.33 System Boot Information (Type 32) */ -static PyObject *dmi_system_boot_status(u8 code) { - static const char *status[]={ - "No errors detected", /* 0 */ - "No bootable media", - "Operating system failed to load", - "Firmware-detected hardware failure", - "Operating system-detected hardware failure", - "User-requested boot", - "System security violation", - "Previously-requested image", - "System watchdog timer expired" /* 8 */ - }; - PyObject *data; - - if(code<=8) data = PyString_FromString(status[code]); - else if(code>=128 && code<=191) data = PyString_FromString("OEM-specific"); - else if(code>=192) data = PyString_FromString("Product-specific"); - else data = OUT_OF_SPEC; - return data; +static PyObject *dmi_system_boot_status(u8 code) +{ + static const char *status[] = { + "No errors detected", /* 0 */ + "No bootable media", + "Operating system failed to load", + "Firmware-detected hardware failure", + "Operating system-detected hardware failure", + "User-requested boot", + "System security violation", + "Previously-requested image", + "System watchdog timer expired" /* 8 */ + }; + PyObject *data; + + if(code <= 8) + data = PyString_FromString(status[code]); + else if(code >= 128 && code <= 191) + data = PyString_FromString("OEM-specific"); + else if(code >= 192) + data = PyString_FromString("Product-specific"); + else + data = OUT_OF_SPEC; + return data; } /******************************************************************************* ** 3.3.34 64-bit Memory Error Information (Type 33) */ -static PyObject *dmi_64bit_memory_error_address(u64 code) { - PyObject *data; - if(code.h==0x80000000 && code.l==0x00000000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("0x%08x%08x", code.h, code.l); - return data; +static PyObject *dmi_64bit_memory_error_address(u64 code) +{ + PyObject *data; + + if(code.h == 0x80000000 && code.l == 0x00000000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("0x%08x%08x", code.h, code.l); + return data; } /******************************************************************************* ** 3.3.35 Management Device (Type 34) */ -static PyObject *dmi_management_device_type(u8 code) { - /* 3.3.35.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "LM75", - "LM78", - "LM79", - "LM80", - "LM81", - "ADM9240", - "DS1780", - "MAX1617", - "GL518SM", - "W83781D", - "HT82H791" /* 0x0D */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x0D) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_management_device_address_type(u8 code) { - /* 3.3.35.2 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "I/O Port", - "Memory", - "SMBus" /* 0x05 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x05) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; +static PyObject *dmi_management_device_type(u8 code) +{ + /* 3.3.35.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "LM75", + "LM78", + "LM79", + "LM80", + "LM81", + "ADM9240", + "DS1780", + "MAX1617", + "GL518SM", + "W83781D", + "HT82H791" /* 0x0D */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x0D) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_management_device_address_type(u8 code) +{ + /* 3.3.35.2 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "I/O Port", + "Memory", + "SMBus" /* 0x05 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x05) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; } /******************************************************************************* ** 3.3.38 Memory Channel (Type 37) */ -static PyObject *dmi_memory_channel_type(u8 code) { - /* 3.3.38.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "RamBus", - "SyncLink" /* 0x04 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x04) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_memory_channel_devices(u8 count, const u8 *p) { - PyObject *data = PyDict_New(); - PyObject *subdata, *val; - int i; +static PyObject *dmi_memory_channel_type(u8 code) +{ + /* 3.3.38.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "RamBus", + "SyncLink" /* 0x04 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x04) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_memory_channel_devices(u8 count, const u8 * p) +{ + PyObject *data = PyDict_New(); + PyObject *subdata, *val; + int i; - for(i=1; i<=count; i++) { - subdata = PyList_New(2); + for(i = 1; i <= count; i++) { + subdata = PyList_New(2); - val = PyString_FromFormat("Load: %i", p[3*i]); - PyList_SET_ITEM(subdata, 0, val); - Py_DECREF(val); + val = PyString_FromFormat("Load: %i", p[3 * i]); + PyList_SET_ITEM(subdata, 0, val); + Py_DECREF(val); - val = PyString_FromFormat("Handle: 0x%04x", WORD(p+3*i+1)); - PyList_SET_ITEM(subdata, 1, val); - Py_DECREF(val); + val = PyString_FromFormat("Handle: 0x%04x", WORD(p + 3 * i + 1)); + PyList_SET_ITEM(subdata, 1, val); + Py_DECREF(val); - PyDict_SetItem(data, PyInt_FromLong(i), subdata); - Py_DECREF(subdata); - } - return data; + PyDict_SetItem(data, PyInt_FromLong(i), subdata); + Py_DECREF(subdata); + } + return data; } /******************************************************************************* ** 3.3.39 IPMI Device Information (Type 38) */ -static PyObject *dmi_ipmi_interface_type(u8 code) { - /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */ - static const char *type[]={ - "Unknown", /* 0x00 */ - "KCS (Keyboard Control Style)", - "SMIC (Server Management Interface Chip)", - "BT (Block Transfer)", - "SSIF (SMBus System Interface)" /* 0x04 */ - }; - PyObject *data; - - if(code<=0x04) data = PyString_FromString(type[code]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb) { - PyObject *data; - if(type==0x04) /* SSIF */ { - data = PyString_FromFormat("0x%02x (SMBus)", (*p)>>1); - } else { - u64 address=QWORD(p); - data = PyString_FromFormat("0x%08x%08x (%s)", address.h, (address.l&~1)|lsb, address.l&1?"I/O":"Memory-mapped"); - } - return data; -} - -static PyObject *dmi_ipmi_register_spacing(u8 code) { - /* IPMI 2.0, appendix C1, table C1-1 */ - static const char *spacing[]={ - "Successive Byte Boundaries", /* 0x00 */ - "32-bit Boundaries", - "16-byte Boundaries" /* 0x02 */ - }; - PyObject *data; - - if(code<=0x02) return data = PyString_FromString(spacing[code]); - return data = OUT_OF_SPEC; +static PyObject *dmi_ipmi_interface_type(u8 code) +{ + /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */ + static const char *type[] = { + "Unknown", /* 0x00 */ + "KCS (Keyboard Control Style)", + "SMIC (Server Management Interface Chip)", + "BT (Block Transfer)", + "SSIF (SMBus System Interface)" /* 0x04 */ + }; + PyObject *data; + + if(code <= 0x04) + data = PyString_FromString(type[code]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_ipmi_base_address(u8 type, const u8 * p, u8 lsb) +{ + PyObject *data; + + if(type == 0x04) { /* SSIF */ + data = PyString_FromFormat("0x%02x (SMBus)", (*p) >> 1); + } else { + u64 address = QWORD(p); + + data = + PyString_FromFormat("0x%08x%08x (%s)", address.h, (address.l & ~1) | lsb, + address.l & 1 ? "I/O" : "Memory-mapped"); + } + return data; +} + +static PyObject *dmi_ipmi_register_spacing(u8 code) +{ + /* IPMI 2.0, appendix C1, table C1-1 */ + static const char *spacing[] = { + "Successive Byte Boundaries", /* 0x00 */ + "32-bit Boundaries", + "16-byte Boundaries" /* 0x02 */ + }; + PyObject *data; + + if(code <= 0x02) + return data = PyString_FromString(spacing[code]); + return data = OUT_OF_SPEC; } /******************************************************************************* ** 3.3.40 System Power Supply (Type 39) */ -static PyObject *dmi_power_supply_power(u16 code) { - PyObject *data; - if(code==0x8000) data = PyString_FromString("Unknown"); - else data = PyString_FromFormat("%.3f W", (float)code/1000); - return data; -} - -static PyObject *dmi_power_supply_type(u8 code) { - /* 3.3.40.1 */ - static const char *type[]={ - "Other", /* 0x01 */ - "Unknown", - "Linear", - "Switching", - "Battery", - "UPS", - "Converter", - "Regulator" /* 0x08 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x08) data = PyString_FromString(type[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_power_supply_status(u8 code) { - /* 3.3.40.1 */ - static const char *status[]={ - "Other", /* 0x01 */ - "Unknown", - "OK", - "Non-critical", - "Critical" /* 0x05 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x05) data = PyString_FromString(status[code-0x01]); - else data = OUT_OF_SPEC; - return data; -} - -static PyObject *dmi_power_supply_range_switching(u8 code) { - /* 3.3.40.1 */ - static const char *switching[]={ - "Other", /* 0x01 */ - "Unknown", - "Manual", - "Auto-switch", - "Wide Range", - "N/A" /* 0x06 */ - }; - PyObject *data; - - if(code>=0x01 && code<=0x06) data = PyString_FromString(switching[code-0x01]); - else data = OUT_OF_SPEC; - return data; +static PyObject *dmi_power_supply_power(u16 code) +{ + PyObject *data; + + if(code == 0x8000) + data = PyString_FromString("Unknown"); + else + data = PyString_FromFormat("%.3f W", (float)code / 1000); + return data; +} + +static PyObject *dmi_power_supply_type(u8 code) +{ + /* 3.3.40.1 */ + static const char *type[] = { + "Other", /* 0x01 */ + "Unknown", + "Linear", + "Switching", + "Battery", + "UPS", + "Converter", + "Regulator" /* 0x08 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x08) + data = PyString_FromString(type[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_power_supply_status(u8 code) +{ + /* 3.3.40.1 */ + static const char *status[] = { + "Other", /* 0x01 */ + "Unknown", + "OK", + "Non-critical", + "Critical" /* 0x05 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x05) + data = PyString_FromString(status[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; +} + +static PyObject *dmi_power_supply_range_switching(u8 code) +{ + /* 3.3.40.1 */ + static const char *switching[] = { + "Other", /* 0x01 */ + "Unknown", + "Manual", + "Auto-switch", + "Wide Range", + "N/A" /* 0x06 */ + }; + PyObject *data; + + if(code >= 0x01 && code <= 0x06) + data = PyString_FromString(switching[code - 0x01]); + else + data = OUT_OF_SPEC; + return data; } /* @@ -2803,1638 +3243,1751 @@ static PyObject *dmi_power_supply_range_switching(u8 code) { ** whether it's worth the effort. */ -static PyObject *dmi_additional_info(const struct dmi_header *h, const char *prefix) { - u8 *p = h->data + 4; - u8 count = *p++; - u8 length; - int i, offset = 5; - PyObject *data = PyList_New(count); - - for(i=0; ilength < offset + 1) break; - length = p[0x00]; - if (length < 0x05 || h->length < offset + length) break; - - PyDict_SetItemString(subdata, - "Referenced Handle", - PyString_FromFormat("0x%04x", WORD(p + 0x01)) - ); - - PyDict_SetItemString(subdata, - "Referenced Offset", - PyString_FromFormat("0x%02x", p[0x03]) - ); - - PyDict_SetItemString(subdata, - "String", - dmi_string_py(h, p[0x04]) - ); - - PyObject *_val; - switch (length - 0x05) { - case 1: - _val = PyString_FromFormat("0x%02x", p[0x05]); - break; - case 2: - _val = PyString_FromFormat("0x%04x", WORD(p + 0x05)); - break; - case 4: - _val = PyString_FromFormat("0x%08x", DWORD(p + 0x05)); - break; - default: - _val = PyString_FromString("Unexpected size"); - break; - } - PyDict_SetItemString(subdata, "Value", _val); - Py_DECREF(_val); - - p += length; - offset += length; - PyList_SET_ITEM(data, i, subdata); - } - return data; +static PyObject *dmi_additional_info(const struct dmi_header *h, const char *prefix) +{ + u8 *p = h->data + 4; + u8 count = *p++; + u8 length; + int i, offset = 5; + PyObject *data = PyList_New(count); + + for(i = 0; i < count; i++) { + PyObject *subdata = PyDict_New(); + + /* Check for short entries */ + if(h->length < offset + 1) + break; + length = p[0x00]; + if(length < 0x05 || h->length < offset + length) + break; + + PyDict_SetItemString(subdata, + "Referenced Handle", + PyString_FromFormat("0x%04x", WORD(p + 0x01)) + ); + + PyDict_SetItemString(subdata, + "Referenced Offset", PyString_FromFormat("0x%02x", p[0x03]) + ); + + PyDict_SetItemString(subdata, "String", dmi_string_py(h, p[0x04]) + ); + + PyObject *_val; + + switch (length - 0x05) { + case 1: + _val = PyString_FromFormat("0x%02x", p[0x05]); + break; + case 2: + _val = PyString_FromFormat("0x%04x", WORD(p + 0x05)); + break; + case 4: + _val = PyString_FromFormat("0x%08x", DWORD(p + 0x05)); + break; + default: + _val = PyString_FromString("Unexpected size"); + break; + } + PyDict_SetItemString(subdata, "Value", _val); + Py_DECREF(_val); + + p += length; + offset += length; + PyList_SET_ITEM(data, i, subdata); + } + return data; } /******************************************************************************* ** Main */ -PyObject* dmi_decode(struct dmi_header *h, u16 ver) { - - const u8 *data = h->data; - - //. 0xF1 --> 0xF100 - //int minor = h->type<<8; - char _[2048]; bzero(_, 2048); - //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; - dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[h->type]; - PyObject *pylist = PyDict_New(); - PyDict_SetItemString(pylist, "id", PyString_FromString(dmiMajor->id)); - PyDict_SetItemString(pylist, "desc", PyString_FromString(dmiMajor->desc)); - PyObject *_val; //. A Temporary pointer (value) - PyObject *_key; //. Another temporary pointer (key) - PyObject *caseData = PyDict_New(); - - switch(h->type) { - - case 0: /* 3.3.1 BIOS Information */ - - if(h->length<0x12) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Vendor", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Release Date", _val); - Py_DECREF(_val); - - /* - * On IA-64, the BIOS base address will read 0 because - * there is no BIOS. Skip the base address and the - * runtime size in this case. - */ - if(WORD(data+0x06)!=0) { - _val = PyString_FromFormat("0x%04x0", WORD(data+0x06)); - PyDict_SetItemString(caseData, "Address", _val); - Py_DECREF(_val); - - _val = dmi_bios_runtime_size((0x10000-WORD(data+0x06))<<4); - PyDict_SetItemString(caseData, "Runtime Size", _val); - Py_DECREF(_val); - } - - _val = PyString_FromFormat("%i kB", (data[0x09]+1)<<6); - PyDict_SetItemString(caseData, "ROM Size", _val); - Py_DECREF(_val); - - _val = dmi_bios_characteristics(QWORD(data+0x0A)); - PyDict_SetItemString(caseData, "Characteristics", _val); - Py_DECREF(_val); - - if(h->length<0x13) break; - _val = dmi_bios_characteristics_x1(data[0x12]); - PyDict_SetItemString(caseData, "Characteristics x1", _val); - Py_DECREF(_val); - - if(h->length<0x14) break; - _val = dmi_bios_characteristics_x2(data[0x13]); - PyDict_SetItemString(caseData, "Characteristics x2", _val); - Py_DECREF(_val); - - if(h->length<0x18) break; - - if(data[0x14]!=0xFF && data[0x15]!=0xFF) { - _val = PyString_FromFormat("%i.%i", data[0x14], data[0x15]); - PyDict_SetItemString(caseData, "BIOS Revision", _val); - Py_DECREF(_val); - } - - if(data[0x16]!=0xFF && data[0x17]!=0xFF) { - _val = PyString_FromFormat("%i.%i", data[0x16], data[0x17]); - PyDict_SetItemString(caseData, "Firmware Revision", _val); - Py_DECREF(_val); - } - - break; - - case 1: /* 3.3.2 System Information */ - - if(h->length<0x08) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Product Name", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - - if(h->length<0x19) break; - _val = dmi_system_uuid_py(data+0x08, ver); - PyDict_SetItemString(caseData, "UUID", _val); - Py_DECREF(_val); - - _val = dmi_system_wake_up_type(data[0x18]); - PyDict_SetItemString(caseData, "Wake-Up Type", _val); - Py_DECREF(_val); - - if(h->length<0x1B) break; - _val = dmi_string_py(h, data[0x19]); - PyDict_SetItemString(caseData, "SKU Number", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x1A]); - PyDict_SetItemString(caseData, "Family", _val); - Py_DECREF(_val); - break; - - case 2: /* 3.3.3 Base Board Information */ - - if(h->length<0x08) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Product Name", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - - if(h->length<0x0F) break; - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - - _val = dmi_base_board_features(data[0x09]); - PyDict_SetItemString(caseData, "Features", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x0A]); - PyDict_SetItemString(caseData, "Location In Chassis", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data+0x0B)); - PyDict_SetItemString(caseData, "Chassis Handle", _val); - Py_DECREF(_val); - - _val = dmi_base_board_type(data[0x0D]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - if(h->length<0x0F+data[0x0E]*sizeof(u16)) break; - _val = dmi_base_board_handles(data[0x0E], data+0x0F); - PyDict_SetItemString(caseData, "Type ???", _val); - Py_DECREF(_val); - break; - - case 3: /* 3.3.4 Chassis Information */ - - if(h->length<0x09) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_chassis_type_py(data[0x05]&0x7F); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_chassis_lock(data[0x05]>>7); - PyDict_SetItemString(caseData, "Lock", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - - if(h->length<0x0D) break; - _val = dmi_chassis_state(data[0x09]); - PyDict_SetItemString(caseData, "Boot-Up State", _val); - Py_DECREF(_val); - - _val = dmi_chassis_state(data[0x0A]); - PyDict_SetItemString(caseData, "Power Supply State", _val); - Py_DECREF(_val); - - _val = dmi_chassis_state(data[0x0B]); - PyDict_SetItemString(caseData, "Thermal State", _val); - Py_DECREF(_val); - - _val = PyString_FromString(dmi_chassis_security_status(data[0x0C])); - PyDict_SetItemString(caseData, "Security Status", _val); - Py_DECREF(_val); - - if(h->length<0x11) break; - _val = PyString_FromFormat("0x%08x", DWORD(data+0x0D)); - PyDict_SetItemString(caseData, "OEM Information", _val); - Py_DECREF(_val); - - if(h->length<0x13) break; - _val = dmi_chassis_height(data[0x11]); - PyDict_SetItemString(caseData, "Height", _val); - Py_DECREF(_val); - - _val = dmi_chassis_power_cords(data[0x12]); - PyDict_SetItemString(caseData, "Number Of Power Cords", _val); - Py_DECREF(_val); - - if(h->length < 0x15) break; - if(h->length<0x15+data[0x13]*data[0x14]) break; - _val = dmi_chassis_elements(data[0x13], data[0x14], data+0x15); - PyDict_SetItemString(caseData, "Elements", _val); - Py_DECREF(_val); - - break; - - - case 4: /* 3.3.5 Processor Information */ - - if(h->length<0x1A) break; - - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Socket Designation", _val); - Py_DECREF(_val); - - _val = dmi_processor_type(data[0x05]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = PyString_FromString(dmi_processor_family(h)); - PyDict_SetItemString(caseData, "Family", _val); - Py_DECREF(_val); - - _val = dmi_processor_id(data[0x06], data+8, dmi_string(h, data[0x10])); - PyDict_SetItemString(_val, "Vendor", dmi_string_py(h, data[0x07])); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x10]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_processor_voltage(data[0x11]); - PyDict_SetItemString(caseData, "Voltage", _val); - Py_DECREF(_val); - - _val = dmi_processor_frequency_py(data+0x12); - PyDict_SetItemString(caseData, "External Clock", _val); - Py_DECREF(_val); - - _val = dmi_processor_frequency_py(data+0x14); - PyDict_SetItemString(caseData, "Max Speed", _val); - Py_DECREF(_val); - - _val = dmi_processor_frequency_py(data+0x16); - PyDict_SetItemString(caseData, "Current Speed", _val); - Py_DECREF(_val); - - if(data[0x18]&(1<<6)) { - _val = PyString_FromFormat("Populated:%s", dmi_processor_status(data[0x18]&0x07)); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - } else { - _val = PyString_FromString("Populated:No"); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - } - _val = dmi_processor_upgrade(data[0x19]); - PyDict_SetItemString(caseData, "Upgrade", _val); - Py_DECREF(_val); - - if(h->length<0x20) break; - _val = dmi_processor_cache(WORD(data+0x1A), "L1", ver); - PyDict_SetItemString(caseData, "L1 Cache Handle", _val); - Py_DECREF(_val); - - _val = dmi_processor_cache(WORD(data+0x1C), "L2", ver); - PyDict_SetItemString(caseData, "L2 Cache Handle", _val); - Py_DECREF(_val); - - _val = dmi_processor_cache(WORD(data+0x1E), "L3", ver); - PyDict_SetItemString(caseData, "L3 Cache Handle", _val); - Py_DECREF(_val); - - if(h->length<0x23) break; - _val = dmi_string_py(h, data[0x20]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x21]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x22]); - PyDict_SetItemString(caseData, "Part Number", _val); - Py_DECREF(_val); - - if(h->length<0x28) break; - if(data[0x23]!=0) { - _val = PyString_FromFormat("%i", data[0x23]); - PyDict_SetItemString(caseData, "Core Count", _val); - Py_DECREF(_val); - } - - if(data[0x24]!=0) { - _val = PyString_FromFormat("%i", data[0x24]); - PyDict_SetItemString(caseData, "Core Enabled", _val); - Py_DECREF(_val); - } - - if(data[0x25]!=0) { - _val = PyString_FromFormat("%i", data[0x25]); - PyDict_SetItemString(caseData, "Thread Count", _val); - Py_DECREF(_val); - } - - _val = dmi_processor_characteristics(WORD(data+0x26)); - PyDict_SetItemString(caseData, "Characteristics", _val); - Py_DECREF(_val); - break; - - case 5: /* 3.3.6 Memory Controller Information */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - if(h->length<0x0F) break; - _val = dmi_memory_controller_ed_method(data[0x04]); - PyDict_SetItemString(caseData, "Error Detecting Method", _val); - Py_DECREF(_val); - - _val = dmi_memory_controller_ec_capabilities(data[0x05]); - PyDict_SetItemString(caseData, "Error Correcting Capabilities", _val); - Py_DECREF(_val); - - _val = dmi_memory_controller_interleave(data[0x06]); - PyDict_SetItemString(caseData, "Supported Interleave", _val); - Py_DECREF(_val); - - _val = dmi_memory_controller_interleave(data[0x07]); - PyDict_SetItemString(caseData, "Current Interleave", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%i MB", 1<length<0x0F+data[0x0E]*sizeof(u16)) break; - _val = dmi_memory_controller_slots(data[0x0E], data+0x0F); - PyDict_SetItemString(caseData, "Associated Memory Sluts", _val); - Py_DECREF(_val); - - if(h->length<0x10+data[0x0E]*sizeof(u16)) break; - _val = dmi_memory_controller_ec_capabilities(data[0x0F+data[0x0E]*sizeof(u16)]); - PyDict_SetItemString(caseData, "Enabled Error Correcting Capabilities", _val); - Py_DECREF(_val); - break; - - case 6: /* 3.3.7 Memory Module Information */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - if(h->length<0x0C) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Socket Designation", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_connections(data[0x05]); - PyDict_SetItemString(caseData, "Bank Connections", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_speed(data[0x06]); - PyDict_SetItemString(caseData, "Current Speed", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_types(WORD(data+0x07)); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_size(data[0x09]); - PyDict_SetItemString(caseData, "Installed Size", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_size(data[0x0A]); - PyDict_SetItemString(caseData, "Enabled Size", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_error(data[0x0B]); - PyDict_SetItemString(caseData, "Error Status", _val); - Py_DECREF(_val); - break; - - case 7: /* 3.3.8 Cache Information */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - if(h->length<0x0F) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Socket Designation", _val); - Py_DECREF(_val); - - _val = PyDict_New(); - PyDict_SetItemString(_val, "Enabled", WORD(data+0x05)&0x0080?Py_True:Py_False); - PyDict_SetItemString(_val, "Socketed", WORD(data+0x05)&0x0008?Py_True:Py_False); - PyDict_SetItemString(_val, "Level", PyInt_FromLong((WORD(data+0x05)&0x0007)+1)); - PyDict_SetItemString(caseData, "Configuration" , _val); - Py_DECREF(_val); - - _val = dmi_cache_mode((WORD(data+0x05)>>8)&0x0003); - PyDict_SetItemString(caseData, "Operational Mode", _val); - Py_DECREF(_val); - - _val = dmi_cache_location((WORD(data+0x05)>>5)&0x0003); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_cache_size(WORD(data+0x09)); - PyDict_SetItemString(caseData, "Installed Size", _val); - Py_DECREF(_val); - - _val = dmi_cache_size(WORD(data+0x07)); - PyDict_SetItemString(caseData, "Maximum Size", _val); - Py_DECREF(_val); - - _val = dmi_cache_types(WORD(data+0x0B)); - PyDict_SetItemString(caseData, "Supported SRAM Types", _val); - Py_DECREF(_val); - - _val = dmi_cache_types(WORD(data+0x0D)); - PyDict_SetItemString(caseData, "Installed SRAM Type", _val); - Py_DECREF(_val); - - if(h->length<0x13) break; - _val = dmi_memory_module_speed(data[0x0F]); - PyDict_SetItemString(caseData, "Speed", _val); - Py_DECREF(_val); - - _val = dmi_cache_ec_type(data[0x10]); - PyDict_SetItemString(caseData, "Error Correction Type", _val); - Py_DECREF(_val); - - _val = dmi_cache_type(data[0x11]); - PyDict_SetItemString(caseData, "System Type", _val); - Py_DECREF(_val); - - _val = dmi_cache_associativity(data[0x12]); - PyDict_SetItemString(caseData, "Associativity", _val); - Py_DECREF(_val); - - break; - - case 8: /* 3.3.9 Port Connector Information */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - if(h->length<0x09) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Internal Reference Designator", _val); - Py_DECREF(_val); - - _val = dmi_port_connector_type(data[0x05]); - PyDict_SetItemString(caseData, "Internal Connector Type", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "External Reference Designator", _val); - Py_DECREF(_val); - - _val = dmi_port_connector_type(data[0x07]); - PyDict_SetItemString(caseData, "External Connector Type", _val); - Py_DECREF(_val); - - _val = dmi_port_type(data[0x08]); - PyDict_SetItemString(caseData, "Port Type", _val); - Py_DECREF(_val); - - break; - - case 9: /* 3.3.10 System Slots */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - if(h->length<0x0C) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Designation", _val); - Py_DECREF(_val); - - _val = dmi_slot_bus_width(data[0x06]); - PyDict_SetItemString(caseData, "Type:SlotBusWidth", _val); - Py_DECREF(_val); - _val = dmi_slot_type(data[0x05]); - PyDict_SetItemString(caseData, "Type:SlotType", _val); - Py_DECREF(_val); - - _val = dmi_slot_current_usage(data[0x07]); - PyDict_SetItemString(caseData, "Current Usage", _val); - Py_DECREF(_val); - - _val = dmi_slot_length(data[0x08]); - PyDict_SetItemString(caseData, "SlotLength", _val); - Py_DECREF(_val); - _val = dmi_slot_id(data[0x09], data[0x0A], data[0x05]); - PyDict_SetItemString(caseData, "SlotId", _val); - Py_DECREF(_val); - - _val = (h->length<0x0D)?dmi_slot_characteristics(data[0x0B], 0x00):dmi_slot_characteristics(data[0x0B], data[0x0C]); - PyDict_SetItemString(caseData, "Characteristics", _val); - Py_DECREF(_val); - break; - - case 10: /* 3.3.11 On Board Devices Information */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - break; - - case 11: /* 3.3.12 OEM Strings */ - - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - - if(h->length<0x05) break; - _val = dmi_oem_strings(h); - PyDict_SetItemString(caseData, "Strings", _val); - Py_DECREF(_val); - - break; - - case 12: /* 3.3.13 System Configuration Options */ - - if(h->length<0x05) break; - _val = dmi_system_configuration_options(h); - PyDict_SetItemString(caseData, "Options", _val); - Py_DECREF(_val); - - break; - - case 13: /* 3.3.14 BIOS Language Information */ - - if(h->length<0x16) break; - _val = PyString_FromFormat("%i", data[0x04]); - PyDict_SetItemString(caseData, "Installable Languages", _val); - Py_DECREF(_val); - - _val = dmi_bios_languages(h); - PyList_SET_ITEM(_val, 0, dmi_string_py(h, data[0x15])); - PyDict_SetItemString(caseData, "Currently Installed Language", _val); - Py_DECREF(_val); - - break; - - case 14: /* 3.3.15 Group Associations */ - - if(h->length<0x05) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Name", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%i", (h->length-0x05)/3); - PyDict_SetItemString(caseData, "Items", _val); - Py_DECREF(_val); - - _val = dmi_group_associations_items((h->length-0x05)/3, data+0x05); - PyDict_SetItemString(caseData, "Items2", _val); //. FIXME: Title - Py_DECREF(_val); - break; - - case 15: /* 3.3.16 System Event Log */ - - if(h->length<0x14) break; - _val = PyString_FromFormat("%i bytes", WORD(data+0x04)); - PyDict_SetItemString(caseData, "Area Length", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data+0x06)); - PyDict_SetItemString(caseData, "Header Start Offset", _val); - Py_DECREF(_val); - - if(WORD(data+0x08)-WORD(data+0x06)) { - _val = PyString_FromFormat("%i byte%s", WORD(data+0x08)-WORD(data+0x06), WORD(data+0x08)-WORD(data+0x06)>1?"s":""); - PyDict_SetItemString(caseData, "Header Length", _val); - Py_DECREF(_val); - } - - _val = PyString_FromFormat("0x%04x", WORD(data+0x08)); - PyDict_SetItemString(caseData, "Data Start Offset", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%s", dmi_event_log_method(data[0x0A])); - PyDict_SetItemString(caseData, "Access Method", _val); - Py_DECREF(_val); - - _val = dmi_event_log_address_py(data[0x0A], data+0x10); - PyDict_SetItemString(caseData, "Access Address", _val); - Py_DECREF(_val); - - _val = dmi_event_log_status_py(data[0x0B]); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%08x", DWORD(data+0x0C)); - PyDict_SetItemString(caseData, "Change Token", _val); - Py_DECREF(_val); - - if(h->length<0x17) break; - _val = PyString_FromFormat("%s", dmi_event_log_header_type(data[0x14])); - PyDict_SetItemString(caseData, "Header Format", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%i", data[0x15]); - PyDict_SetItemString(caseData, "Supported Log Type Descriptors", _val); - Py_DECREF(_val); - - if(h->length<0x17+data[0x15]*data[0x16]) break; - _val = dmi_event_log_descriptors(data[0x15], data[0x16], data+0x17); - PyDict_SetItemString(caseData, "DMI Event Log Descriptors", _val); - Py_DECREF(_val); - - break; - - case 16: /* 3.3.17 Physical Memory Array */ - - if(h->length<0x0F) break; - _val = dmi_memory_array_location(data[0x04]); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_use(data[0x05]); - PyDict_SetItemString(caseData, "Use", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_ec_type(data[0x06]); - PyDict_SetItemString(caseData, "Error Correction Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_capacity(DWORD(data+0x07)); - PyDict_SetItemString(caseData, "Maximum Capacity", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_error_handle(WORD(data+0x0B)); - PyDict_SetItemString(caseData, "Error Information Handle", _val); - Py_DECREF(_val); - - _val = PyInt_FromLong(WORD(data+0x0D)); - PyDict_SetItemString(caseData, "Number Of Devices", _val); - Py_DECREF(_val); - break; - - - case 17: /* 3.3.18 Memory Device */ - - if(h->length<0x15) break; - _val = PyString_FromFormat("0x%04x", WORD(data+0x04)); - PyDict_SetItemString(caseData, "Array Handle", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_error_handle(WORD(data+0x06)); - PyDict_SetItemString(caseData, "Error Information Handle", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_width(WORD(data+0x08)); - PyDict_SetItemString(caseData, "Total Width", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_width(WORD(data+0x0A)); - PyDict_SetItemString(caseData, "Data Width", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_size(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Size", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_form_factor(data[0x0E]); - PyDict_SetItemString(caseData, "Form Factor", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_set(data[0x0F]); - PyDict_SetItemString(caseData, "Set", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x10]); - PyDict_SetItemString(caseData, "Locator", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x11]); - PyDict_SetItemString(caseData, "Bank Locator", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_type(data[0x12]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_type_detail(WORD(data+0x13)); - PyDict_SetItemString(caseData, "Type Detail", _val); - Py_DECREF(_val); - - if(h->length<0x17) break; - _val = dmi_memory_device_speed(WORD(data+0x15)); - PyDict_SetItemString(caseData, "Speed", _val); - Py_DECREF(_val); - - if(h->length<0x1B) break; - _val = dmi_string_py(h, data[0x17]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x18]); - PyDict_SetItemString(caseData,"Serial Number" , _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x19]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x1A]); - PyDict_SetItemString(caseData, "Part Number", _val); - Py_DECREF(_val); - break; - - case 18: /* 3.3.19 32-bit Memory Error Information */ - - if(h->length<0x17) break; - _val = dmi_memory_error_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_error_granularity(data[0x05]); - PyDict_SetItemString(caseData, "Granularity", _val); - Py_DECREF(_val); - - _val = dmi_memory_error_operation(data[0x06]); - PyDict_SetItemString(caseData, "Operation", _val); - Py_DECREF(_val); - - _val = dmi_memory_error_syndrome(DWORD(data+0x07)); - PyDict_SetItemString(caseData, "Vendor Syndrome", _val); - Py_DECREF(_val); - - _val = dmi_32bit_memory_error_address(DWORD(data+0x0B)); - PyDict_SetItemString(caseData, "Memory Array Address", _val); - Py_DECREF(_val); - - _val = dmi_32bit_memory_error_address(DWORD(data+0x0F)); - PyDict_SetItemString(caseData, "Device Address", _val); - Py_DECREF(_val); - - _val = dmi_32bit_memory_error_address(DWORD(data+0x13)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); - break; - - case 19: /* 3.3.20 Memory Array Mapped Address */ - - if(h->length<0x0F) break; - _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x04)>>2, (DWORD(data+0x04)&0x3)<<10); - PyDict_SetItemString(caseData, "Starting Address", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x08)>>2, ((DWORD(data+0x08)&0x3)<<10)+0x3FF); - PyDict_SetItemString(caseData, "Ending Address", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_size(DWORD(data+0x08)-DWORD(data+0x04)+1); - PyDict_SetItemString(caseData, "Range Size", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Physical Array Handle", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%i", data[0x0F]); - PyDict_SetItemString(caseData, "Partition Width", _val); - Py_DECREF(_val); - break; - - case 20: /* 3.3.21 Memory Device Mapped Address */ - - if(h->length<0x13) break; - _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x04)>>2, (DWORD(data+0x04)&0x3)<<10); - PyDict_SetItemString(caseData, "Starting Address", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x08)>>2, ((DWORD(data+0x08)&0x3)<<10)+0x3FF); - PyDict_SetItemString(caseData, "Ending Address", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_size(DWORD(data+0x08)-DWORD(data+0x04)+1); - PyDict_SetItemString(caseData, "Range Size", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Physical Device Handle", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data+0x0E)); - PyDict_SetItemString(caseData, "Memory Array Mapped Address Handle", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_row_position(data[0x10]); - PyDict_SetItemString(caseData, "Partition Row Position", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_interleave_position(data[0x11]); - PyDict_SetItemString(caseData, ">>>", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_interleaved_data_depth(data[0x12]); - PyDict_SetItemString(caseData, ">>>", _val); - Py_DECREF(_val); - break; - - case 21: /* 3.3.22 Built-in Pointing Device */ - - if(h->length<0x07) break; - _val = dmi_pointing_device_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_pointing_device_interface(data[0x05]); - PyDict_SetItemString(caseData, "Interface", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%i", data[0x06]); - PyDict_SetItemString(caseData, "Buttons", _val); - Py_DECREF(_val); - break; - - case 22: /* 3.3.23 Portable Battery */ - - if(h->length<0x10) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - if(data[0x06] || h->length<0x1A) { - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Manufacture Date", _val); - Py_DECREF(_val); - } - - if(data[0x07] || h->length<0x1A) { - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - } - - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Name", _val); - Py_DECREF(_val); - - if(data[0x09]!=0x02 || h->length<0x1A) { - _val = dmi_battery_chemistry(data[0x09]); - PyDict_SetItemString(caseData, "Chemistry", _val); - Py_DECREF(_val); - } - _val = (h->length<0x1A)?dmi_battery_capacity(WORD(data+0x0A), 1):dmi_battery_capacity(WORD(data+0x0A), data[0x15]); - PyDict_SetItemString(caseData, "Design Capacity", _val); - Py_DECREF(_val); - - _val = dmi_battery_voltage(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Design Voltage", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x0E]); - PyDict_SetItemString(caseData, "SBDS Version", _val); - Py_DECREF(_val); - - _val = dmi_battery_maximum_error(data[0x0F]); - PyDict_SetItemString(caseData, "Maximum Error", _val); - Py_DECREF(_val); - - if(h->length<0x1A) break; - if(data[0x07]==0) { - _val = PyString_FromFormat("%04x", WORD(data+0x10)); - PyDict_SetItemString(caseData, "SBDS Serial Number", _val); - Py_DECREF(_val); - } - if(data[0x06]==0) { - _val = PyString_FromFormat("%i-%02u-%02u", 1980+(WORD(data+0x12)>>9), (WORD(data+0x12)>>5)&0x0F, WORD(data+0x12)&0x1F); - PyDict_SetItemString(caseData, "SBDS Manufacture Date", _val); - Py_DECREF(_val); - } - if(data[0x09]==0x02) { - _val = dmi_string_py(h, data[0x14]); - PyDict_SetItemString(caseData, "SBDS Chemistry", _val); - Py_DECREF(_val); - } - - _val = PyString_FromFormat("0x%08x", DWORD(data+0x16)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); - break; - - case 23: /* 3.3.24 System Reset */ - - if(h->length<0x0D) break; - _val = PyString_FromFormat("%s", data[0x04]&(1<<0)?"Enabled":"Disabled"); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%s", data[0x04]&(1<<5)?"Present":"Not Present"); - PyDict_SetItemString(caseData, "Watchdog Timer", _val); - Py_DECREF(_val); - - if(!(data[0x04]&(1<<5))) break; - _val = dmi_system_reset_boot_option((data[0x04]>>1)&0x3); - PyDict_SetItemString(caseData, "Boot Option", _val); - Py_DECREF(_val); - - _val = dmi_system_reset_boot_option((data[0x04]>>3)&0x3); - PyDict_SetItemString(caseData, "Boot Option On Limit", _val); - Py_DECREF(_val); - - _val = dmi_system_reset_count(WORD(data+0x05)); - PyDict_SetItemString(caseData, "Reset Count", _val); - Py_DECREF(_val); - - _val = dmi_system_reset_count(WORD(data+0x07)); - PyDict_SetItemString(caseData, "Reset Limit", _val); - Py_DECREF(_val); - - _val = dmi_system_reset_timer(WORD(data+0x09)); - PyDict_SetItemString(caseData, "Timer Interval", _val); - Py_DECREF(_val); - - _val = dmi_system_reset_timer(WORD(data+0x0B)); - PyDict_SetItemString(caseData, "Timeout", _val); - Py_DECREF(_val); - - break; - - case 24: /* 3.3.25 Hardware Security */ - - if(h->length<0x05) break; - _val = dmi_hardware_security_status(data[0x04]>>6); - PyDict_SetItemString(caseData, "Power-On Password Status", _val); - Py_DECREF(_val); - - _val = dmi_hardware_security_status((data[0x04]>>4)&0x3); - PyDict_SetItemString(caseData, "Keyboard Password Status", _val); - Py_DECREF(_val); - - _val = dmi_hardware_security_status((data[0x04]>>2)&0x3); - PyDict_SetItemString(caseData, "Administrator Password Status", _val); - Py_DECREF(_val); - - _val = dmi_hardware_security_status(data[0x04]&0x3); - PyDict_SetItemString(caseData, "Front Panel Reset Status", _val); - Py_DECREF(_val); +PyObject *dmi_decode(struct dmi_header * h, u16 ver) +{ - break; + const u8 *data = h->data; + + //. 0xF1 --> 0xF100 + //int minor = h->type<<8; + char _[2048]; + + bzero(_, 2048); + //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; + dmi_codes_major *dmiMajor = (dmi_codes_major *) & dmiCodesMajor[h->type]; + PyObject *pylist = PyDict_New(); + + PyDict_SetItemString(pylist, "id", PyString_FromString(dmiMajor->id)); + PyDict_SetItemString(pylist, "desc", PyString_FromString(dmiMajor->desc)); + PyObject *_val; //. A Temporary pointer (value) + PyObject *_key; //. Another temporary pointer (key) + PyObject *caseData = PyDict_New(); + + switch (h->type) { + + case 0: /* 3.3.1 BIOS Information */ + + if(h->length < 0x12) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Vendor", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x05]); + PyDict_SetItemString(caseData, "Version", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x08]); + PyDict_SetItemString(caseData, "Release Date", _val); + Py_DECREF(_val); + + /* + * On IA-64, the BIOS base address will read 0 because + * there is no BIOS. Skip the base address and the + * runtime size in this case. + */ + if(WORD(data + 0x06) != 0) { + _val = PyString_FromFormat("0x%04x0", WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Address", _val); + Py_DECREF(_val); + + _val = dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4); + PyDict_SetItemString(caseData, "Runtime Size", _val); + Py_DECREF(_val); + } + + _val = PyString_FromFormat("%i kB", (data[0x09] + 1) << 6); + PyDict_SetItemString(caseData, "ROM Size", _val); + Py_DECREF(_val); + + _val = dmi_bios_characteristics(QWORD(data + 0x0A)); + PyDict_SetItemString(caseData, "Characteristics", _val); + Py_DECREF(_val); + + if(h->length < 0x13) + break; + _val = dmi_bios_characteristics_x1(data[0x12]); + PyDict_SetItemString(caseData, "Characteristics x1", _val); + Py_DECREF(_val); + + if(h->length < 0x14) + break; + _val = dmi_bios_characteristics_x2(data[0x13]); + PyDict_SetItemString(caseData, "Characteristics x2", _val); + Py_DECREF(_val); + + if(h->length < 0x18) + break; + + if(data[0x14] != 0xFF && data[0x15] != 0xFF) { + _val = PyString_FromFormat("%i.%i", data[0x14], data[0x15]); + PyDict_SetItemString(caseData, "BIOS Revision", _val); + Py_DECREF(_val); + } + + if(data[0x16] != 0xFF && data[0x17] != 0xFF) { + _val = PyString_FromFormat("%i.%i", data[0x16], data[0x17]); + PyDict_SetItemString(caseData, "Firmware Revision", _val); + Py_DECREF(_val); + } + + break; + + case 1: /* 3.3.2 System Information */ + + if(h->length < 0x08) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x05]); + PyDict_SetItemString(caseData, "Product Name", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x06]); + PyDict_SetItemString(caseData, "Version", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x07]); + PyDict_SetItemString(caseData, "Serial Number", _val); + Py_DECREF(_val); + + if(h->length < 0x19) + break; + _val = dmi_system_uuid_py(data + 0x08, ver); + PyDict_SetItemString(caseData, "UUID", _val); + Py_DECREF(_val); + + _val = dmi_system_wake_up_type(data[0x18]); + PyDict_SetItemString(caseData, "Wake-Up Type", _val); + Py_DECREF(_val); + + if(h->length < 0x1B) + break; + _val = dmi_string_py(h, data[0x19]); + PyDict_SetItemString(caseData, "SKU Number", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x1A]); + PyDict_SetItemString(caseData, "Family", _val); + Py_DECREF(_val); + break; + + case 2: /* 3.3.3 Base Board Information */ + + if(h->length < 0x08) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x05]); + PyDict_SetItemString(caseData, "Product Name", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x06]); + PyDict_SetItemString(caseData, "Version", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x07]); + PyDict_SetItemString(caseData, "Serial Number", _val); + Py_DECREF(_val); + + if(h->length < 0x0F) + break; + _val = dmi_string_py(h, data[0x08]); + PyDict_SetItemString(caseData, "Asset Tag", _val); + Py_DECREF(_val); + + _val = dmi_base_board_features(data[0x09]); + PyDict_SetItemString(caseData, "Features", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x0A]); + PyDict_SetItemString(caseData, "Location In Chassis", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Chassis Handle", _val); + Py_DECREF(_val); + + _val = dmi_base_board_type(data[0x0D]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + if(h->length < 0x0F + data[0x0E] * sizeof(u16)) + break; + _val = dmi_base_board_handles(data[0x0E], data + 0x0F); + PyDict_SetItemString(caseData, "Type ???", _val); + Py_DECREF(_val); + break; + + case 3: /* 3.3.4 Chassis Information */ + + if(h->length < 0x09) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + _val = dmi_chassis_type_py(data[0x05] & 0x7F); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_chassis_lock(data[0x05] >> 7); + PyDict_SetItemString(caseData, "Lock", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x06]); + PyDict_SetItemString(caseData, "Version", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x07]); + PyDict_SetItemString(caseData, "Serial Number", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x08]); + PyDict_SetItemString(caseData, "Asset Tag", _val); + Py_DECREF(_val); + + if(h->length < 0x0D) + break; + _val = dmi_chassis_state(data[0x09]); + PyDict_SetItemString(caseData, "Boot-Up State", _val); + Py_DECREF(_val); + + _val = dmi_chassis_state(data[0x0A]); + PyDict_SetItemString(caseData, "Power Supply State", _val); + Py_DECREF(_val); + + _val = dmi_chassis_state(data[0x0B]); + PyDict_SetItemString(caseData, "Thermal State", _val); + Py_DECREF(_val); + + _val = PyString_FromString(dmi_chassis_security_status(data[0x0C])); + PyDict_SetItemString(caseData, "Security Status", _val); + Py_DECREF(_val); + + if(h->length < 0x11) + break; + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x0D)); + PyDict_SetItemString(caseData, "OEM Information", _val); + Py_DECREF(_val); + + if(h->length < 0x13) + break; + _val = dmi_chassis_height(data[0x11]); + PyDict_SetItemString(caseData, "Height", _val); + Py_DECREF(_val); + + _val = dmi_chassis_power_cords(data[0x12]); + PyDict_SetItemString(caseData, "Number Of Power Cords", _val); + Py_DECREF(_val); + + if(h->length < 0x15) + break; + if(h->length < 0x15 + data[0x13] * data[0x14]) + break; + _val = dmi_chassis_elements(data[0x13], data[0x14], data + 0x15); + PyDict_SetItemString(caseData, "Elements", _val); + Py_DECREF(_val); + + break; + + case 4: /* 3.3.5 Processor Information */ + + if(h->length < 0x1A) + break; + + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Socket Designation", _val); + Py_DECREF(_val); + + _val = dmi_processor_type(data[0x05]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = PyString_FromString(dmi_processor_family(h)); + PyDict_SetItemString(caseData, "Family", _val); + Py_DECREF(_val); + + _val = dmi_processor_id(data[0x06], data + 8, dmi_string(h, data[0x10])); + PyDict_SetItemString(_val, "Vendor", dmi_string_py(h, data[0x07])); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x10]); + PyDict_SetItemString(caseData, "Version", _val); + Py_DECREF(_val); + + _val = dmi_processor_voltage(data[0x11]); + PyDict_SetItemString(caseData, "Voltage", _val); + Py_DECREF(_val); + + _val = dmi_processor_frequency_py(data + 0x12); + PyDict_SetItemString(caseData, "External Clock", _val); + Py_DECREF(_val); + + _val = dmi_processor_frequency_py(data + 0x14); + PyDict_SetItemString(caseData, "Max Speed", _val); + Py_DECREF(_val); + + _val = dmi_processor_frequency_py(data + 0x16); + PyDict_SetItemString(caseData, "Current Speed", _val); + Py_DECREF(_val); + + if(data[0x18] & (1 << 6)) { + _val = + PyString_FromFormat("Populated:%s", + dmi_processor_status(data[0x18] & 0x07)); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); + } else { + _val = PyString_FromString("Populated:No"); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); + } + _val = dmi_processor_upgrade(data[0x19]); + PyDict_SetItemString(caseData, "Upgrade", _val); + Py_DECREF(_val); + + if(h->length < 0x20) + break; + _val = dmi_processor_cache(WORD(data + 0x1A), "L1", ver); + PyDict_SetItemString(caseData, "L1 Cache Handle", _val); + Py_DECREF(_val); + + _val = dmi_processor_cache(WORD(data + 0x1C), "L2", ver); + PyDict_SetItemString(caseData, "L2 Cache Handle", _val); + Py_DECREF(_val); + + _val = dmi_processor_cache(WORD(data + 0x1E), "L3", ver); + PyDict_SetItemString(caseData, "L3 Cache Handle", _val); + Py_DECREF(_val); + + if(h->length < 0x23) + break; + _val = dmi_string_py(h, data[0x20]); + PyDict_SetItemString(caseData, "Serial Number", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x21]); + PyDict_SetItemString(caseData, "Asset Tag", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x22]); + PyDict_SetItemString(caseData, "Part Number", _val); + Py_DECREF(_val); + + if(h->length < 0x28) + break; + if(data[0x23] != 0) { + _val = PyString_FromFormat("%i", data[0x23]); + PyDict_SetItemString(caseData, "Core Count", _val); + Py_DECREF(_val); + } + + if(data[0x24] != 0) { + _val = PyString_FromFormat("%i", data[0x24]); + PyDict_SetItemString(caseData, "Core Enabled", _val); + Py_DECREF(_val); + } + + if(data[0x25] != 0) { + _val = PyString_FromFormat("%i", data[0x25]); + PyDict_SetItemString(caseData, "Thread Count", _val); + Py_DECREF(_val); + } + + _val = dmi_processor_characteristics(WORD(data + 0x26)); + PyDict_SetItemString(caseData, "Characteristics", _val); + Py_DECREF(_val); + break; + + case 5: /* 3.3.6 Memory Controller Information */ + + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + + if(h->length < 0x0F) + break; + _val = dmi_memory_controller_ed_method(data[0x04]); + PyDict_SetItemString(caseData, "Error Detecting Method", _val); + Py_DECREF(_val); + + _val = dmi_memory_controller_ec_capabilities(data[0x05]); + PyDict_SetItemString(caseData, "Error Correcting Capabilities", _val); + Py_DECREF(_val); + + _val = dmi_memory_controller_interleave(data[0x06]); + PyDict_SetItemString(caseData, "Supported Interleave", _val); + Py_DECREF(_val); + + _val = dmi_memory_controller_interleave(data[0x07]); + PyDict_SetItemString(caseData, "Current Interleave", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i MB", 1 << data[0x08]); + PyDict_SetItemString(caseData, "Maximum Memory Module Size", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i MB", data[0x0E] * (1 << data[0x08])); + PyDict_SetItemString(caseData, "Maximum Total Memory Size", _val); + Py_DECREF(_val); + + _val = dmi_memory_controller_speeds(WORD(data + 0x09)); + PyDict_SetItemString(caseData, "Supported Speeds", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_types(WORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Supported Memory Types", _val); + Py_DECREF(_val); + + _val = dmi_processor_voltage(data[0x0D]); + PyDict_SetItemString(caseData, "Memory Module Voltage", _val); + Py_DECREF(_val); + + if(h->length < 0x0F + data[0x0E] * sizeof(u16)) + break; + _val = dmi_memory_controller_slots(data[0x0E], data + 0x0F); + PyDict_SetItemString(caseData, "Associated Memory Sluts", _val); + Py_DECREF(_val); + + if(h->length < 0x10 + data[0x0E] * sizeof(u16)) + break; + _val = dmi_memory_controller_ec_capabilities(data[0x0F + data[0x0E] * sizeof(u16)]); + PyDict_SetItemString(caseData, "Enabled Error Correcting Capabilities", _val); + Py_DECREF(_val); + break; + + case 6: /* 3.3.7 Memory Module Information */ + + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + + if(h->length < 0x0C) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Socket Designation", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_connections(data[0x05]); + PyDict_SetItemString(caseData, "Bank Connections", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_speed(data[0x06]); + PyDict_SetItemString(caseData, "Current Speed", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_types(WORD(data + 0x07)); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_size(data[0x09]); + PyDict_SetItemString(caseData, "Installed Size", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_size(data[0x0A]); + PyDict_SetItemString(caseData, "Enabled Size", _val); + Py_DECREF(_val); + + _val = dmi_memory_module_error(data[0x0B]); + PyDict_SetItemString(caseData, "Error Status", _val); + Py_DECREF(_val); + break; + + case 7: /* 3.3.8 Cache Information */ - case 25: /* 3.3.26 System Power Controls */ + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x09) break; - _val = dmi_power_controls_power_on(data+0x04); - PyDict_SetItemString(caseData, "Next Scheduled Power-on", _val); - Py_DECREF(_val); + if(h->length < 0x0F) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Socket Designation", _val); + Py_DECREF(_val); - break; + _val = PyDict_New(); + PyDict_SetItemString(_val, "Enabled", + WORD(data + 0x05) & 0x0080 ? Py_True : Py_False); + PyDict_SetItemString(_val, "Socketed", + WORD(data + 0x05) & 0x0008 ? Py_True : Py_False); + PyDict_SetItemString(_val, "Level", + PyInt_FromLong((WORD(data + 0x05) & 0x0007) + 1)); + PyDict_SetItemString(caseData, "Configuration", _val); + Py_DECREF(_val); + + _val = dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003); + PyDict_SetItemString(caseData, "Operational Mode", _val); + Py_DECREF(_val); + + _val = dmi_cache_location((WORD(data + 0x05) >> 5) & 0x0003); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); + + _val = dmi_cache_size(WORD(data + 0x09)); + PyDict_SetItemString(caseData, "Installed Size", _val); + Py_DECREF(_val); + + _val = dmi_cache_size(WORD(data + 0x07)); + PyDict_SetItemString(caseData, "Maximum Size", _val); + Py_DECREF(_val); - case 26: /* 3.3.27 Voltage Probe */ + _val = dmi_cache_types(WORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Supported SRAM Types", _val); + Py_DECREF(_val); - if(h->length<0x14) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); + _val = dmi_cache_types(WORD(data + 0x0D)); + PyDict_SetItemString(caseData, "Installed SRAM Type", _val); + Py_DECREF(_val); - _val = dmi_voltage_probe_location(data[0x05]&0x1f); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); + if(h->length < 0x13) + break; + _val = dmi_memory_module_speed(data[0x0F]); + PyDict_SetItemString(caseData, "Speed", _val); + Py_DECREF(_val); - _val = dmi_probe_status(data[0x05]>>5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + _val = dmi_cache_ec_type(data[0x10]); + PyDict_SetItemString(caseData, "Error Correction Type", _val); + Py_DECREF(_val); - _val = dmi_voltage_probe_value(WORD(data+0x06)); - PyDict_SetItemString(caseData, "Maximum Value", _val); - Py_DECREF(_val); + _val = dmi_cache_type(data[0x11]); + PyDict_SetItemString(caseData, "System Type", _val); + Py_DECREF(_val); - _val = dmi_voltage_probe_value(WORD(data+0x08)); - PyDict_SetItemString(caseData, "Minimum Value", _val); - Py_DECREF(_val); + _val = dmi_cache_associativity(data[0x12]); + PyDict_SetItemString(caseData, "Associativity", _val); + Py_DECREF(_val); - _val = dmi_voltage_probe_resolution(WORD(data+0x0A)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + break; - _val = dmi_voltage_probe_value(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Tolerance", _val); - Py_DECREF(_val); + case 8: /* 3.3.9 Port Connector Information */ - _val = dmi_probe_accuracy(WORD(data+0x0E)); - PyDict_SetItemString(caseData, "Accuracy", _val); - Py_DECREF(_val); + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - _val = PyString_FromFormat("0x%08x", DWORD(data+0x10)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + if(h->length < 0x09) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Internal Reference Designator", _val); + Py_DECREF(_val); - if(h->length<0x16) break; - _val = dmi_voltage_probe_value(WORD(data+0x14)); - PyDict_SetItemString(caseData, "Nominal Value", _val); - Py_DECREF(_val); + _val = dmi_port_connector_type(data[0x05]); + PyDict_SetItemString(caseData, "Internal Connector Type", _val); + Py_DECREF(_val); - break; + _val = dmi_string_py(h, data[0x06]); + PyDict_SetItemString(caseData, "External Reference Designator", _val); + Py_DECREF(_val); - case 27: /* 3.3.28 Cooling Device */ + _val = dmi_port_connector_type(data[0x07]); + PyDict_SetItemString(caseData, "External Connector Type", _val); + Py_DECREF(_val); - if(h->length<0x0C) break; - if(WORD(data+0x04)!=0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data+0x04)); - PyDict_SetItemString(caseData, "Temperature Probe Handle", _val); - Py_DECREF(_val); - } + _val = dmi_port_type(data[0x08]); + PyDict_SetItemString(caseData, "Port Type", _val); + Py_DECREF(_val); - _val = dmi_cooling_device_type(data[0x06]&0x1f); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + break; - _val = dmi_probe_status(data[0x06]>>5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + case 9: /* 3.3.10 System Slots */ - if(data[0x07]!=0x00) { - _val = PyString_FromFormat("%i", data[0x07]); - PyDict_SetItemString(caseData, "Cooling Unit Group", _val); - Py_DECREF(_val); - } + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - _val = PyString_FromFormat("0x%08x", DWORD(data+0x08)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + if(h->length < 0x0C) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Designation", _val); + Py_DECREF(_val); - if(h->length<0x0E) break; - _val = dmi_cooling_device_speed(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Nominal Speed", _val); - Py_DECREF(_val); + _val = dmi_slot_bus_width(data[0x06]); + PyDict_SetItemString(caseData, "Type:SlotBusWidth", _val); + Py_DECREF(_val); + _val = dmi_slot_type(data[0x05]); + PyDict_SetItemString(caseData, "Type:SlotType", _val); + Py_DECREF(_val); - break; + _val = dmi_slot_current_usage(data[0x07]); + PyDict_SetItemString(caseData, "Current Usage", _val); + Py_DECREF(_val); - case 28: /* 3.3.29 Temperature Probe */ + _val = dmi_slot_length(data[0x08]); + PyDict_SetItemString(caseData, "SlotLength", _val); + Py_DECREF(_val); + _val = dmi_slot_id(data[0x09], data[0x0A], data[0x05]); + PyDict_SetItemString(caseData, "SlotId", _val); + Py_DECREF(_val); - if(h->length<0x14) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); + _val = + (h->length < 0x0D) ? dmi_slot_characteristics(data[0x0B], + 0x00) : + dmi_slot_characteristics(data[0x0B], data[0x0C]); + PyDict_SetItemString(caseData, "Characteristics", _val); + Py_DECREF(_val); + break; - _val = dmi_temperature_probe_location(data[0x05]&0x1F); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); + case 10: /* 3.3.11 On Board Devices Information */ - _val = dmi_probe_status(data[0x05]>>5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - _val = dmi_temperature_probe_value(WORD(data+0x06)); - PyDict_SetItemString(caseData, "Maximum Value", _val); - Py_DECREF(_val); + break; - _val = dmi_temperature_probe_value(WORD(data+0x08)); - PyDict_SetItemString(caseData, "Minimum Value", _val); - Py_DECREF(_val); + case 11: /* 3.3.12 OEM Strings */ - _val = dmi_temperature_probe_resolution(WORD(data+0x0A)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - _val = dmi_temperature_probe_value(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Tolerance", _val); - Py_DECREF(_val); + if(h->length < 0x05) + break; + _val = dmi_oem_strings(h); + PyDict_SetItemString(caseData, "Strings", _val); + Py_DECREF(_val); - _val = dmi_probe_accuracy(WORD(data+0x0E)); - PyDict_SetItemString(caseData, "Accuracy", _val); - Py_DECREF(_val); + break; - _val = PyString_FromFormat("0x%08x", DWORD(data+0x10)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + case 12: /* 3.3.13 System Configuration Options */ - if(h->length<0x16) break; - _val = dmi_temperature_probe_value(WORD(data+0x14)); - PyDict_SetItemString(caseData, "Nominal Value", _val); - Py_DECREF(_val); + if(h->length < 0x05) + break; + _val = dmi_system_configuration_options(h); + PyDict_SetItemString(caseData, "Options", _val); + Py_DECREF(_val); - break; + break; - case 29: /* 3.3.30 Electrical Current Probe */ + case 13: /* 3.3.14 BIOS Language Information */ - if(h->length<0x14) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); + if(h->length < 0x16) + break; + _val = PyString_FromFormat("%i", data[0x04]); + PyDict_SetItemString(caseData, "Installable Languages", _val); + Py_DECREF(_val); - _val = dmi_voltage_probe_location(data[5]&0x1F); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); + _val = dmi_bios_languages(h); + PyList_SET_ITEM(_val, 0, dmi_string_py(h, data[0x15])); + PyDict_SetItemString(caseData, "Currently Installed Language", _val); + Py_DECREF(_val); + + break; - _val = dmi_probe_status(data[0x05]>>5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + case 14: /* 3.3.15 Group Associations */ - _val = dmi_current_probe_value(WORD(data+0x06)); - PyDict_SetItemString(caseData, "Maximum Value", _val); - Py_DECREF(_val); + if(h->length < 0x05) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Name", _val); + Py_DECREF(_val); - _val = dmi_current_probe_value(WORD(data+0x08)); - PyDict_SetItemString(caseData, "Minimum Value", _val); - Py_DECREF(_val); + _val = PyString_FromFormat("%i", (h->length - 0x05) / 3); + PyDict_SetItemString(caseData, "Items", _val); + Py_DECREF(_val); + + _val = dmi_group_associations_items((h->length - 0x05) / 3, data + 0x05); + PyDict_SetItemString(caseData, "Items2", _val); //. FIXME: Title + Py_DECREF(_val); + break; - _val = dmi_current_probe_resolution(WORD(data+0x0A)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + case 15: /* 3.3.16 System Event Log */ - _val = dmi_current_probe_value(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Tolerance", _val); - Py_DECREF(_val); + if(h->length < 0x14) + break; + _val = PyString_FromFormat("%i bytes", WORD(data + 0x04)); + PyDict_SetItemString(caseData, "Area Length", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Header Start Offset", _val); + Py_DECREF(_val); + + if(WORD(data + 0x08) - WORD(data + 0x06)) { + _val = + PyString_FromFormat("%i byte%s", WORD(data + 0x08) - WORD(data + 0x06), + WORD(data + 0x08) - WORD(data + 0x06) > + 1 ? "s" : ""); + PyDict_SetItemString(caseData, "Header Length", _val); + Py_DECREF(_val); + } - _val = dmi_probe_accuracy(WORD(data+0x0E)); - PyDict_SetItemString(caseData, "Accuracy", _val); - Py_DECREF(_val); + _val = PyString_FromFormat("0x%04x", WORD(data + 0x08)); + PyDict_SetItemString(caseData, "Data Start Offset", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("0x%08x", DWORD(data+0x10)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + _val = PyString_FromFormat("%s", dmi_event_log_method(data[0x0A])); + PyDict_SetItemString(caseData, "Access Method", _val); + Py_DECREF(_val); - if(h->length<0x16) break; - _val = dmi_current_probe_value(WORD(data+0x14)); - PyDict_SetItemString(caseData, "Nominal Value", _val); - Py_DECREF(_val); + _val = dmi_event_log_address_py(data[0x0A], data + 0x10); + PyDict_SetItemString(caseData, "Access Address", _val); + Py_DECREF(_val); - break; + _val = dmi_event_log_status_py(data[0x0B]); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); - case 30: /* 3.3.31 Out-of-band Remote Access */ + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Change Token", _val); + Py_DECREF(_val); - if(h->length<0x06) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer Name", _val); - Py_DECREF(_val); + if(h->length < 0x17) + break; + _val = PyString_FromFormat("%s", dmi_event_log_header_type(data[0x14])); + PyDict_SetItemString(caseData, "Header Format", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i", data[0x15]); + PyDict_SetItemString(caseData, "Supported Log Type Descriptors", _val); + Py_DECREF(_val); + + if(h->length < 0x17 + data[0x15] * data[0x16]) + break; + _val = dmi_event_log_descriptors(data[0x15], data[0x16], data + 0x17); + PyDict_SetItemString(caseData, "DMI Event Log Descriptors", _val); + Py_DECREF(_val); + + break; + + case 16: /* 3.3.17 Physical Memory Array */ + + if(h->length < 0x0F) + break; + _val = dmi_memory_array_location(data[0x04]); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); + + _val = dmi_memory_array_use(data[0x05]); + PyDict_SetItemString(caseData, "Use", _val); + Py_DECREF(_val); + + _val = dmi_memory_array_ec_type(data[0x06]); + PyDict_SetItemString(caseData, "Error Correction Type", _val); + Py_DECREF(_val); + + _val = dmi_memory_array_capacity(DWORD(data + 0x07)); + PyDict_SetItemString(caseData, "Maximum Capacity", _val); + Py_DECREF(_val); + + _val = dmi_memory_array_error_handle(WORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Error Information Handle", _val); + Py_DECREF(_val); + + _val = PyInt_FromLong(WORD(data + 0x0D)); + PyDict_SetItemString(caseData, "Number Of Devices", _val); + Py_DECREF(_val); + break; + + case 17: /* 3.3.18 Memory Device */ + + if(h->length < 0x15) + break; + _val = PyString_FromFormat("0x%04x", WORD(data + 0x04)); + PyDict_SetItemString(caseData, "Array Handle", _val); + Py_DECREF(_val); + + _val = dmi_memory_array_error_handle(WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Error Information Handle", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_width(WORD(data + 0x08)); + PyDict_SetItemString(caseData, "Total Width", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_width(WORD(data + 0x0A)); + PyDict_SetItemString(caseData, "Data Width", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_size(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Size", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_form_factor(data[0x0E]); + PyDict_SetItemString(caseData, "Form Factor", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_set(data[0x0F]); + PyDict_SetItemString(caseData, "Set", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x10]); + PyDict_SetItemString(caseData, "Locator", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x11]); + PyDict_SetItemString(caseData, "Bank Locator", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_type(data[0x12]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_memory_device_type_detail(WORD(data + 0x13)); + PyDict_SetItemString(caseData, "Type Detail", _val); + Py_DECREF(_val); + + if(h->length < 0x17) + break; + _val = dmi_memory_device_speed(WORD(data + 0x15)); + PyDict_SetItemString(caseData, "Speed", _val); + Py_DECREF(_val); + + if(h->length < 0x1B) + break; + _val = dmi_string_py(h, data[0x17]); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x18]); + PyDict_SetItemString(caseData, "Serial Number", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x19]); + PyDict_SetItemString(caseData, "Asset Tag", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x1A]); + PyDict_SetItemString(caseData, "Part Number", _val); + Py_DECREF(_val); + break; + + case 18: /* 3.3.19 32-bit Memory Error Information */ + + if(h->length < 0x17) + break; + _val = dmi_memory_error_type(data[0x04]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_memory_error_granularity(data[0x05]); + PyDict_SetItemString(caseData, "Granularity", _val); + Py_DECREF(_val); + + _val = dmi_memory_error_operation(data[0x06]); + PyDict_SetItemString(caseData, "Operation", _val); + Py_DECREF(_val); + + _val = dmi_memory_error_syndrome(DWORD(data + 0x07)); + PyDict_SetItemString(caseData, "Vendor Syndrome", _val); + Py_DECREF(_val); + + _val = dmi_32bit_memory_error_address(DWORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Memory Array Address", _val); + Py_DECREF(_val); + + _val = dmi_32bit_memory_error_address(DWORD(data + 0x0F)); + PyDict_SetItemString(caseData, "Device Address", _val); + Py_DECREF(_val); + + _val = dmi_32bit_memory_error_address(DWORD(data + 0x13)); + PyDict_SetItemString(caseData, "Resolution", _val); + Py_DECREF(_val); + break; + + case 19: /* 3.3.20 Memory Array Mapped Address */ + + if(h->length < 0x0F) + break; + _val = + PyString_FromFormat("0x%08x%03x", DWORD(data + 0x04) >> 2, + (DWORD(data + 0x04) & 0x3) << 10); + PyDict_SetItemString(caseData, "Starting Address", _val); + Py_DECREF(_val); + + _val = + PyString_FromFormat("0x%08x%03x", DWORD(data + 0x08) >> 2, + ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); + PyDict_SetItemString(caseData, "Ending Address", _val); + Py_DECREF(_val); + + _val = dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); + PyDict_SetItemString(caseData, "Range Size", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Physical Array Handle", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i", data[0x0F]); + PyDict_SetItemString(caseData, "Partition Width", _val); + Py_DECREF(_val); + break; + + case 20: /* 3.3.21 Memory Device Mapped Address */ + + if(h->length < 0x13) + break; + _val = + PyString_FromFormat("0x%08x%03x", DWORD(data + 0x04) >> 2, + (DWORD(data + 0x04) & 0x3) << 10); + PyDict_SetItemString(caseData, "Starting Address", _val); + Py_DECREF(_val); + + _val = + PyString_FromFormat("0x%08x%03x", DWORD(data + 0x08) >> 2, + ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); + PyDict_SetItemString(caseData, "Ending Address", _val); + Py_DECREF(_val); + + _val = dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); + PyDict_SetItemString(caseData, "Range Size", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Physical Device Handle", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x0E)); + PyDict_SetItemString(caseData, "Memory Array Mapped Address Handle", _val); + Py_DECREF(_val); + + _val = dmi_mapped_address_row_position(data[0x10]); + PyDict_SetItemString(caseData, "Partition Row Position", _val); + Py_DECREF(_val); + + _val = dmi_mapped_address_interleave_position(data[0x11]); + PyDict_SetItemString(caseData, ">>>", _val); + Py_DECREF(_val); + + _val = dmi_mapped_address_interleaved_data_depth(data[0x12]); + PyDict_SetItemString(caseData, ">>>", _val); + Py_DECREF(_val); + break; + + case 21: /* 3.3.22 Built-in Pointing Device */ + + if(h->length < 0x07) + break; + _val = dmi_pointing_device_type(data[0x04]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_pointing_device_interface(data[0x05]); + PyDict_SetItemString(caseData, "Interface", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i", data[0x06]); + PyDict_SetItemString(caseData, "Buttons", _val); + Py_DECREF(_val); + break; + + case 22: /* 3.3.23 Portable Battery */ + + if(h->length < 0x10) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x05]); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + if(data[0x06] || h->length < 0x1A) { + _val = dmi_string_py(h, data[0x06]); + PyDict_SetItemString(caseData, "Manufacture Date", _val); + Py_DECREF(_val); + } + + if(data[0x07] || h->length < 0x1A) { + _val = dmi_string_py(h, data[0x07]); + PyDict_SetItemString(caseData, "Serial Number", _val); + Py_DECREF(_val); + } + + _val = dmi_string_py(h, data[0x08]); + PyDict_SetItemString(caseData, "Name", _val); + Py_DECREF(_val); + + if(data[0x09] != 0x02 || h->length < 0x1A) { + _val = dmi_battery_chemistry(data[0x09]); + PyDict_SetItemString(caseData, "Chemistry", _val); + Py_DECREF(_val); + } + _val = + (h->length < 0x1A) ? dmi_battery_capacity(WORD(data + 0x0A), + 1) : dmi_battery_capacity(WORD(data + + 0x0A), + data[0x15]); + PyDict_SetItemString(caseData, "Design Capacity", _val); + Py_DECREF(_val); + + _val = dmi_battery_voltage(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Design Voltage", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x0E]); + PyDict_SetItemString(caseData, "SBDS Version", _val); + Py_DECREF(_val); + + _val = dmi_battery_maximum_error(data[0x0F]); + PyDict_SetItemString(caseData, "Maximum Error", _val); + Py_DECREF(_val); + + if(h->length < 0x1A) + break; + if(data[0x07] == 0) { + _val = PyString_FromFormat("%04x", WORD(data + 0x10)); + PyDict_SetItemString(caseData, "SBDS Serial Number", _val); + Py_DECREF(_val); + } + if(data[0x06] == 0) { + _val = + PyString_FromFormat("%i-%02u-%02u", 1980 + (WORD(data + 0x12) >> 9), + (WORD(data + 0x12) >> 5) & 0x0F, + WORD(data + 0x12) & 0x1F); + PyDict_SetItemString(caseData, "SBDS Manufacture Date", _val); + Py_DECREF(_val); + } + if(data[0x09] == 0x02) { + _val = dmi_string_py(h, data[0x14]); + PyDict_SetItemString(caseData, "SBDS Chemistry", _val); + Py_DECREF(_val); + } + + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x16)); + PyDict_SetItemString(caseData, "OEM-specific Information", _val); + Py_DECREF(_val); + break; + + case 23: /* 3.3.24 System Reset */ + + if(h->length < 0x0D) + break; + _val = PyString_FromFormat("%s", data[0x04] & (1 << 0) ? "Enabled" : "Disabled"); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%s", data[0x04] & (1 << 5) ? "Present" : "Not Present"); + PyDict_SetItemString(caseData, "Watchdog Timer", _val); + Py_DECREF(_val); + + if(!(data[0x04] & (1 << 5))) + break; + _val = dmi_system_reset_boot_option((data[0x04] >> 1) & 0x3); + PyDict_SetItemString(caseData, "Boot Option", _val); + Py_DECREF(_val); + + _val = dmi_system_reset_boot_option((data[0x04] >> 3) & 0x3); + PyDict_SetItemString(caseData, "Boot Option On Limit", _val); + Py_DECREF(_val); + + _val = dmi_system_reset_count(WORD(data + 0x05)); + PyDict_SetItemString(caseData, "Reset Count", _val); + Py_DECREF(_val); + + _val = dmi_system_reset_count(WORD(data + 0x07)); + PyDict_SetItemString(caseData, "Reset Limit", _val); + Py_DECREF(_val); + + _val = dmi_system_reset_timer(WORD(data + 0x09)); + PyDict_SetItemString(caseData, "Timer Interval", _val); + Py_DECREF(_val); + + _val = dmi_system_reset_timer(WORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Timeout", _val); + Py_DECREF(_val); + + break; + + case 24: /* 3.3.25 Hardware Security */ + + if(h->length < 0x05) + break; + _val = dmi_hardware_security_status(data[0x04] >> 6); + PyDict_SetItemString(caseData, "Power-On Password Status", _val); + Py_DECREF(_val); + + _val = dmi_hardware_security_status((data[0x04] >> 4) & 0x3); + PyDict_SetItemString(caseData, "Keyboard Password Status", _val); + Py_DECREF(_val); + + _val = dmi_hardware_security_status((data[0x04] >> 2) & 0x3); + PyDict_SetItemString(caseData, "Administrator Password Status", _val); + Py_DECREF(_val); + + _val = dmi_hardware_security_status(data[0x04] & 0x3); + PyDict_SetItemString(caseData, "Front Panel Reset Status", _val); + Py_DECREF(_val); + + break; + + case 25: /* 3.3.26 System Power Controls */ + + if(h->length < 0x09) + break; + _val = dmi_power_controls_power_on(data + 0x04); + PyDict_SetItemString(caseData, "Next Scheduled Power-on", _val); + Py_DECREF(_val); + + break; + + case 26: /* 3.3.27 Voltage Probe */ + + if(h->length < 0x14) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Description", _val); + Py_DECREF(_val); + + _val = dmi_voltage_probe_location(data[0x05] & 0x1f); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); + + _val = dmi_probe_status(data[0x05] >> 5); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); + + _val = dmi_voltage_probe_value(WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Maximum Value", _val); + Py_DECREF(_val); - _val = data[0x05]&(1<<0)?Py_True:Py_False; - PyDict_SetItemString(caseData, "Inbound Connection Enabled", _val); - Py_DECREF(_val); + _val = dmi_voltage_probe_value(WORD(data + 0x08)); + PyDict_SetItemString(caseData, "Minimum Value", _val); + Py_DECREF(_val); - _val = data[0x05]&(1<<1)?Py_True:Py_False; - PyDict_SetItemString(caseData, "Outbound Connection Enabled", _val); - Py_DECREF(_val); - break; + _val = dmi_voltage_probe_resolution(WORD(data + 0x0A)); + PyDict_SetItemString(caseData, "Resolution", _val); + Py_DECREF(_val); - case 31: /* 3.3.32 Boot Integrity Services Entry Point */ + _val = dmi_voltage_probe_value(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Tolerance", _val); + Py_DECREF(_val); - break; + _val = dmi_probe_accuracy(WORD(data + 0x0E)); + PyDict_SetItemString(caseData, "Accuracy", _val); + Py_DECREF(_val); - case 32: /* 3.3.33 System Boot Information */ + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x10)); + PyDict_SetItemString(caseData, "OEM-specific Information", _val); + Py_DECREF(_val); - if(h->length<0x0B) break; - _val = dmi_system_boot_status(data[0x0A]); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + if(h->length < 0x16) + break; + _val = dmi_voltage_probe_value(WORD(data + 0x14)); + PyDict_SetItemString(caseData, "Nominal Value", _val); + Py_DECREF(_val); - break; + break; - case 33: /* 3.3.34 64-bit Memory Error Information */ - if(h->length<0x1F) break; + case 27: /* 3.3.28 Cooling Device */ - _val = dmi_memory_error_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + if(h->length < 0x0C) + break; + if(WORD(data + 0x04) != 0xFFFF) { + _val = PyString_FromFormat("0x%04x", WORD(data + 0x04)); + PyDict_SetItemString(caseData, "Temperature Probe Handle", _val); + Py_DECREF(_val); + } - _val = dmi_memory_error_granularity(data[0x05]); - PyDict_SetItemString(caseData, "Granularity", _val); - Py_DECREF(_val); + _val = dmi_cooling_device_type(data[0x06] & 0x1f); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); - _val = dmi_memory_error_operation(data[0x06]); - PyDict_SetItemString(caseData, "Operation", _val); - Py_DECREF(_val); + _val = dmi_probe_status(data[0x06] >> 5); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); - _val = dmi_memory_error_syndrome(DWORD(data+0x07)); - PyDict_SetItemString(caseData, "Vendor Syndrome", _val); - Py_DECREF(_val); + if(data[0x07] != 0x00) { + _val = PyString_FromFormat("%i", data[0x07]); + PyDict_SetItemString(caseData, "Cooling Unit Group", _val); + Py_DECREF(_val); + } - _val = dmi_64bit_memory_error_address(QWORD(data+0x0B)); - PyDict_SetItemString(caseData, "Memory Array Address", _val); - Py_DECREF(_val); + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x08)); + PyDict_SetItemString(caseData, "OEM-specific Information", _val); + Py_DECREF(_val); - _val = dmi_64bit_memory_error_address(QWORD(data+0x13)); - PyDict_SetItemString(caseData, "Device Address", _val); - Py_DECREF(_val); + if(h->length < 0x0E) + break; + _val = dmi_cooling_device_speed(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Nominal Speed", _val); + Py_DECREF(_val); - _val = dmi_32bit_memory_error_address(DWORD(data+0x1B)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + break; - break; + case 28: /* 3.3.29 Temperature Probe */ - case 34: /* 3.3.35 Management Device */ + if(h->length < 0x14) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Description", _val); + Py_DECREF(_val); - if(h->length<0x0B) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); + _val = dmi_temperature_probe_location(data[0x05] & 0x1F); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); + + _val = dmi_probe_status(data[0x05] >> 5); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); - _val = dmi_management_device_type(data[0x05]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + _val = dmi_temperature_probe_value(WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Maximum Value", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("0x%08x", DWORD(data+0x06)); - PyDict_SetItemString(caseData, "Address", _val); - Py_DECREF(_val); + _val = dmi_temperature_probe_value(WORD(data + 0x08)); + PyDict_SetItemString(caseData, "Minimum Value", _val); + Py_DECREF(_val); - _val = dmi_management_device_address_type(data[0x0A]); - PyDict_SetItemString(caseData, "Address Type", _val); - Py_DECREF(_val); + _val = dmi_temperature_probe_resolution(WORD(data + 0x0A)); + PyDict_SetItemString(caseData, "Resolution", _val); + Py_DECREF(_val); - break; + _val = dmi_temperature_probe_value(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Tolerance", _val); + Py_DECREF(_val); - case 35: /* 3.3.36 Management Device Component */ + _val = dmi_probe_accuracy(WORD(data + 0x0E)); + PyDict_SetItemString(caseData, "Accuracy", _val); + Py_DECREF(_val); - if(h->length<0x0B) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x10)); + PyDict_SetItemString(caseData, "OEM-specific Information", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("0x%04x", WORD(data+0x05)); - PyDict_SetItemString(caseData, "Management Device Handle", _val); - Py_DECREF(_val); + if(h->length < 0x16) + break; + _val = dmi_temperature_probe_value(WORD(data + 0x14)); + PyDict_SetItemString(caseData, "Nominal Value", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("0x%04x", WORD(data+0x07)); - PyDict_SetItemString(caseData, "Component Handle", _val); - Py_DECREF(_val); + break; - if(WORD(data+0x09)!=0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data+0x09)); - PyDict_SetItemString(caseData, "Threshold Handle", _val); - Py_DECREF(_val); - } + case 29: /* 3.3.30 Electrical Current Probe */ - break; + if(h->length < 0x14) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Description", _val); + Py_DECREF(_val); - case 36: /* 3.3.37 Management Device Threshold Data */ + _val = dmi_voltage_probe_location(data[5] & 0x1F); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); - if(h->length<0x10) break; - if(WORD(data+0x04)!=0x8000) { - _val = PyString_FromFormat("%d", (i16)WORD(data+0x04)); - PyDict_SetItemString(caseData, "Lower Non-critical Threshold", _val); - Py_DECREF(_val); - } - if(WORD(data+0x06)!=0x8000) { - _val = PyString_FromFormat("%d", (i16)WORD(data+0x06)); - PyDict_SetItemString(caseData, "Upper Non-critical Threshold", _val); - Py_DECREF(_val); - } - if(WORD(data+0x08)!=0x8000) { - _val = PyString_FromFormat("%d", (i16)WORD(data+0x08)); - PyDict_SetItemString(caseData, "Lower Critical Threshold", _val); - Py_DECREF(_val); - } - if(WORD(data+0x0A)!=0x8000) { - _val = PyString_FromFormat("%d", (i16)WORD(data+0x0A)); - PyDict_SetItemString(caseData, "Upper Critical Threshold", _val); - Py_DECREF(_val); - } - if(WORD(data+0x0C)!=0x8000) { - _val = PyString_FromFormat("%d", (i16)WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Lower Non-recoverable Threshold", _val); - Py_DECREF(_val); - } - if(WORD(data+0x0E)!=0x8000) { - _val = PyString_FromFormat("%d", (i16)WORD(data+0x0E)); - PyDict_SetItemString(caseData, "Upper Non-recoverable Threshold", _val); - Py_DECREF(_val); - } + _val = dmi_probe_status(data[0x05] >> 5); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); - break; + _val = dmi_current_probe_value(WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Maximum Value", _val); + Py_DECREF(_val); - case 37: /* 3.3.38 Memory Channel */ + _val = dmi_current_probe_value(WORD(data + 0x08)); + PyDict_SetItemString(caseData, "Minimum Value", _val); + Py_DECREF(_val); - if(h->length<0x07) break; - _val = dmi_memory_channel_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + _val = dmi_current_probe_resolution(WORD(data + 0x0A)); + PyDict_SetItemString(caseData, "Resolution", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("%i", data[0x05]); - PyDict_SetItemString(caseData, "Maximal Load", _val); - Py_DECREF(_val); + _val = dmi_current_probe_value(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Tolerance", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("%i", data[0x06]); - PyDict_SetItemString(caseData, "Devices", _val); - Py_DECREF(_val); + _val = dmi_probe_accuracy(WORD(data + 0x0E)); + PyDict_SetItemString(caseData, "Accuracy", _val); + Py_DECREF(_val); - if(h->length<0x07+3*data[0x06]) break; - _val = dmi_memory_channel_devices(data[0x06], data+0x07); - PyDict_SetItemString(caseData, ">>>", _val); - Py_DECREF(_val); + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x10)); + PyDict_SetItemString(caseData, "OEM-specific Information", _val); + Py_DECREF(_val); - break; + if(h->length < 0x16) + break; + _val = dmi_current_probe_value(WORD(data + 0x14)); + PyDict_SetItemString(caseData, "Nominal Value", _val); + Py_DECREF(_val); - case 38: /* 3.3.39 IPMI Device Information */ - /* - * We use the word "Version" instead of "Revision", conforming to - * the IPMI specification. - */ + break; - if(h->length<0x10) break; - _val = dmi_ipmi_interface_type(data[0x04]); - PyDict_SetItemString(caseData, "Interface Type", _val); - Py_DECREF(_val); + case 30: /* 3.3.31 Out-of-band Remote Access */ - _val = PyString_FromFormat("%i.%i", data[0x05]>>4, data[0x05]&0x0F); - PyDict_SetItemString(caseData, "Specification Version", _val); - Py_DECREF(_val); + if(h->length < 0x06) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Manufacturer Name", _val); + Py_DECREF(_val); - _val = PyString_FromFormat("0x%02x", data[0x06]>>1); - PyDict_SetItemString(caseData, "I2C Slave Address", _val); - Py_DECREF(_val); + _val = data[0x05] & (1 << 0) ? Py_True : Py_False; + PyDict_SetItemString(caseData, "Inbound Connection Enabled", _val); + Py_DECREF(_val); - if(data[0x07]!=0xFF) { - _val = PyString_FromFormat("%i", data[0x07]); - PyDict_SetItemString(caseData, "NV Storage Device Address", _val); - Py_DECREF(_val); - } else { - _val = Py_None; - PyDict_SetItemString(caseData, "NV Storage Device: Not Present", _val); - Py_DECREF(_val); - } + _val = data[0x05] & (1 << 1) ? Py_True : Py_False; + PyDict_SetItemString(caseData, "Outbound Connection Enabled", _val); + Py_DECREF(_val); + break; - _val = dmi_ipmi_base_address(data[0x04], data+0x08, h->length<0x12?0:(data[0x10]>>5)&1); - PyDict_SetItemString(caseData, "Base Address", _val); - Py_DECREF(_val); + case 31: /* 3.3.32 Boot Integrity Services Entry Point */ - if(h->length<0x12) break; - if(data[0x04]!=0x04) { - _val = dmi_ipmi_register_spacing(data[0x10]>>6); - PyDict_SetItemString(caseData, "Register Spacing", _val); - Py_DECREF(_val); + break; - if(data[0x10]&(1<<3)) { - _val = PyString_FromFormat("%s", data[0x10]&(1<<1)?"Active High":"Active Low"); - PyDict_SetItemString(caseData, "Interrupt Polarity", _val); - Py_DECREF(_val); + case 32: /* 3.3.33 System Boot Information */ - _val = PyString_FromFormat("%s", data[0x10]&(1<<0)?"Level":"Edge"); - PyDict_SetItemString(caseData, "Interrupt Trigger Mode", _val); - Py_DECREF(_val); + if(h->length < 0x0B) + break; + _val = dmi_system_boot_status(data[0x0A]); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); + + break; + + case 33: /* 3.3.34 64-bit Memory Error Information */ + if(h->length < 0x1F) + break; + + _val = dmi_memory_error_type(data[0x04]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_memory_error_granularity(data[0x05]); + PyDict_SetItemString(caseData, "Granularity", _val); + Py_DECREF(_val); + + _val = dmi_memory_error_operation(data[0x06]); + PyDict_SetItemString(caseData, "Operation", _val); + Py_DECREF(_val); + + _val = dmi_memory_error_syndrome(DWORD(data + 0x07)); + PyDict_SetItemString(caseData, "Vendor Syndrome", _val); + Py_DECREF(_val); + + _val = dmi_64bit_memory_error_address(QWORD(data + 0x0B)); + PyDict_SetItemString(caseData, "Memory Array Address", _val); + Py_DECREF(_val); + + _val = dmi_64bit_memory_error_address(QWORD(data + 0x13)); + PyDict_SetItemString(caseData, "Device Address", _val); + Py_DECREF(_val); + + _val = dmi_32bit_memory_error_address(DWORD(data + 0x1B)); + PyDict_SetItemString(caseData, "Resolution", _val); + Py_DECREF(_val); + + break; + + case 34: /* 3.3.35 Management Device */ + + if(h->length < 0x0B) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Description", _val); + Py_DECREF(_val); + + _val = dmi_management_device_type(data[0x05]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%08x", DWORD(data + 0x06)); + PyDict_SetItemString(caseData, "Address", _val); + Py_DECREF(_val); + + _val = dmi_management_device_address_type(data[0x0A]); + PyDict_SetItemString(caseData, "Address Type", _val); + Py_DECREF(_val); + + break; + + case 35: /* 3.3.36 Management Device Component */ + + if(h->length < 0x0B) + break; + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(caseData, "Description", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x05)); + PyDict_SetItemString(caseData, "Management Device Handle", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%04x", WORD(data + 0x07)); + PyDict_SetItemString(caseData, "Component Handle", _val); + Py_DECREF(_val); + + if(WORD(data + 0x09) != 0xFFFF) { + _val = PyString_FromFormat("0x%04x", WORD(data + 0x09)); + PyDict_SetItemString(caseData, "Threshold Handle", _val); + Py_DECREF(_val); + } + + break; + + case 36: /* 3.3.37 Management Device Threshold Data */ + + if(h->length < 0x10) + break; + if(WORD(data + 0x04) != 0x8000) { + _val = PyString_FromFormat("%d", (i16) WORD(data + 0x04)); + PyDict_SetItemString(caseData, "Lower Non-critical Threshold", _val); + Py_DECREF(_val); + } + if(WORD(data + 0x06) != 0x8000) { + _val = PyString_FromFormat("%d", (i16) WORD(data + 0x06)); + PyDict_SetItemString(caseData, "Upper Non-critical Threshold", _val); + Py_DECREF(_val); + } + if(WORD(data + 0x08) != 0x8000) { + _val = PyString_FromFormat("%d", (i16) WORD(data + 0x08)); + PyDict_SetItemString(caseData, "Lower Critical Threshold", _val); + Py_DECREF(_val); + } + if(WORD(data + 0x0A) != 0x8000) { + _val = PyString_FromFormat("%d", (i16) WORD(data + 0x0A)); + PyDict_SetItemString(caseData, "Upper Critical Threshold", _val); + Py_DECREF(_val); + } + if(WORD(data + 0x0C) != 0x8000) { + _val = PyString_FromFormat("%d", (i16) WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Lower Non-recoverable Threshold", _val); + Py_DECREF(_val); + } + if(WORD(data + 0x0E) != 0x8000) { + _val = PyString_FromFormat("%d", (i16) WORD(data + 0x0E)); + PyDict_SetItemString(caseData, "Upper Non-recoverable Threshold", _val); + Py_DECREF(_val); + } + + break; + + case 37: /* 3.3.38 Memory Channel */ + + if(h->length < 0x07) + break; + _val = dmi_memory_channel_type(data[0x04]); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i", data[0x05]); + PyDict_SetItemString(caseData, "Maximal Load", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i", data[0x06]); + PyDict_SetItemString(caseData, "Devices", _val); + Py_DECREF(_val); + + if(h->length < 0x07 + 3 * data[0x06]) + break; + _val = dmi_memory_channel_devices(data[0x06], data + 0x07); + PyDict_SetItemString(caseData, ">>>", _val); + Py_DECREF(_val); + + break; + + case 38: /* 3.3.39 IPMI Device Information */ + /* + * We use the word "Version" instead of "Revision", conforming to + * the IPMI specification. + */ + + if(h->length < 0x10) + break; + _val = dmi_ipmi_interface_type(data[0x04]); + PyDict_SetItemString(caseData, "Interface Type", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%i.%i", data[0x05] >> 4, data[0x05] & 0x0F); + PyDict_SetItemString(caseData, "Specification Version", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("0x%02x", data[0x06] >> 1); + PyDict_SetItemString(caseData, "I2C Slave Address", _val); + Py_DECREF(_val); + + if(data[0x07] != 0xFF) { + _val = PyString_FromFormat("%i", data[0x07]); + PyDict_SetItemString(caseData, "NV Storage Device Address", _val); + Py_DECREF(_val); + } else { + _val = Py_None; + PyDict_SetItemString(caseData, "NV Storage Device: Not Present", _val); + Py_DECREF(_val); + } + + _val = + dmi_ipmi_base_address(data[0x04], data + 0x08, + h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1); + PyDict_SetItemString(caseData, "Base Address", _val); + Py_DECREF(_val); + + if(h->length < 0x12) + break; + if(data[0x04] != 0x04) { + _val = dmi_ipmi_register_spacing(data[0x10] >> 6); + PyDict_SetItemString(caseData, "Register Spacing", _val); + Py_DECREF(_val); + + if(data[0x10] & (1 << 3)) { + _val = + PyString_FromFormat("%s", + data[0x10] & (1 << 1) ? "Active High" : + "Active Low"); + PyDict_SetItemString(caseData, "Interrupt Polarity", _val); + Py_DECREF(_val); + + _val = + PyString_FromFormat("%s", + data[0x10] & (1 << 0) ? "Level" : "Edge"); + PyDict_SetItemString(caseData, "Interrupt Trigger Mode", _val); + Py_DECREF(_val); + } + } + if(data[0x11] != 0x00) { + _val = PyString_FromFormat("%x", data[0x11]); + PyDict_SetItemString(caseData, "Interrupt Number", _val); + Py_DECREF(_val); + } + break; + + case 39: /* 3.3.40 System Power Supply */ + + if(h->length < 0x10) + break; + if(data[0x04] != 0x00) { + _val = PyString_FromFormat("%i", data[0x04]); + PyDict_SetItemString(caseData, "Power Unit Group", _val); + Py_DECREF(_val); + } + + _val = dmi_string_py(h, data[0x05]); + PyDict_SetItemString(caseData, "Location", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x06]); + PyDict_SetItemString(caseData, "Name", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x07]); + PyDict_SetItemString(caseData, "Manufacturer", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x08]); + PyDict_SetItemString(caseData, "Serial Numberr", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x09]); + PyDict_SetItemString(caseData, "Asset Tag", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x0A]); + PyDict_SetItemString(caseData, "Model Part Number", _val); + Py_DECREF(_val); + + _val = dmi_string_py(h, data[0x0B]); + PyDict_SetItemString(caseData, "Revision", _val); + Py_DECREF(_val); + + _val = dmi_power_supply_power(WORD(data + 0x0C)); + PyDict_SetItemString(caseData, "Max Power Capacity", _val); + Py_DECREF(_val); + + if(WORD(data + 0x0E) & (1 << 1)) { + _val = dmi_power_supply_status((WORD(data + 0x0E) >> 7) & 0x07); + PyDict_SetItemString(caseData, "Status Present", _val); + Py_DECREF(_val); + } else { + _val = PyString_FromString("Not Present"); + PyDict_SetItemString(caseData, "Status", _val); + Py_DECREF(_val); + } + _val = dmi_power_supply_type((WORD(data + 0x0E) >> 10) & 0x0F); + PyDict_SetItemString(caseData, "Type", _val); + Py_DECREF(_val); + + _val = dmi_power_supply_range_switching((WORD(data + 0x0E) >> 3) & 0x0F); + PyDict_SetItemString(caseData, "Input Voltage Range Switching", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%s", WORD(data + 0x0E) & (1 << 2) ? "No" : "Yes"); + PyDict_SetItemString(caseData, "Plugged", _val); + Py_DECREF(_val); + + _val = PyString_FromFormat("%s", WORD(data + 0x0E) & (1 << 0) ? "Yes" : "No"); + PyDict_SetItemString(caseData, "Hot Replaceable", _val); + Py_DECREF(_val); + + if(h->length < 0x16) + break; + if(WORD(data + 0x10) != 0xFFFF) { + _val = PyString_FromFormat("0x%04x", WORD(data + 0x10)); + PyDict_SetItemString(caseData, "Input Voltage Probe Handle", _val); + Py_DECREF(_val); + } + + if(WORD(data + 0x12) != 0xFFFF) { + _val = PyString_FromFormat("0x%04x", WORD(data + 0x12)); + PyDict_SetItemString(caseData, "Cooling Device Handle", _val); + Py_DECREF(_val); + } + + if(WORD(data + 0x14) != 0xFFFF) { + _val = PyString_FromFormat("0x%04x", WORD(data + 0x14)); + PyDict_SetItemString(caseData, "Input Current Probe Handle", _val); + Py_DECREF(_val); + } + + break; + + case 40: /* 3.3.41 Additional Information */ + if(h->length < 0x0B) + break; + _key = PyString_FromFormat("Additional Information"); + _val = dmi_additional_info(h, ""); + PyDict_SetItem(caseData, _key, _val); + Py_DECREF(_key); + Py_DECREF(_val); + break; + + case 41: /* 3.3.42 Onboard Device Extended Information */ + if(h->length < 0x0B) + break; + PyObject *subdata = PyDict_New(); + + _val = dmi_string_py(h, data[0x04]); + PyDict_SetItemString(subdata, "Reference Designation", _val); + Py_DECREF(_val); + + _val = PyString_FromString(dmi_on_board_devices_type(data[0x05] & 0x7F)); + PyDict_SetItemString(subdata, "Type", _val); + Py_DECREF(_val); + + _val = PyString_FromString(data[0x05] & 0x80 ? "Enabled" : "Disabled"); + PyDict_SetItemString(subdata, "Status", _val); + Py_DECREF(_val); + + _val = PyInt_FromLong(data[0x06]); + PyDict_SetItemString(subdata, "Type Instance", _val); + Py_DECREF(_val); + + _val = dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A]); + PyDict_SetItemString(subdata, "Bus Address", _val); + Py_DECREF(_val); + + PyDict_SetItemString(caseData, "Onboard Device", subdata); + Py_DECREF(subdata); + break; + + case 126: /* 3.3.43 Inactive */ + _val = Py_None; + PyDict_SetItemString(caseData, "Inactive", _val); + Py_DECREF(_val); + break; + + case 127: /* 3.3.44 End Of Table */ + _val = Py_None; + PyDict_SetItemString(caseData, "End Of Table", _val); + Py_DECREF(_val); + break; + + default: + if(dmi_decode_oem(h)) + break; + _key = PyString_FromFormat("%s Type", h->type >= 128 ? "OEM-specific" : "Unknown"); + _val = dmi_dump(h); + PyDict_SetItem(caseData, _key, _val); + Py_DECREF(_key); + Py_DECREF(_val); } - } - if(data[0x11]!=0x00) { - _val = PyString_FromFormat("%x", data[0x11]); - PyDict_SetItemString(caseData, "Interrupt Number", _val); - Py_DECREF(_val); - } - break; - - case 39: /* 3.3.40 System Power Supply */ - - if(h->length<0x10) break; - if(data[0x04]!=0x00) { - _val = PyString_FromFormat("%i", data[0x04]); - PyDict_SetItemString(caseData, "Power Unit Group", _val); - Py_DECREF(_val); - } - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Name", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Serial Numberr", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x09]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x0A]); - PyDict_SetItemString(caseData, "Model Part Number", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x0B]); - PyDict_SetItemString(caseData, "Revision", _val); - Py_DECREF(_val); + Py_INCREF(caseData); + return caseData; +} - _val = dmi_power_supply_power(WORD(data+0x0C)); - PyDict_SetItemString(caseData, "Max Power Capacity", _val); - Py_DECREF(_val); +void to_dmi_header(struct dmi_header *h, u8 * data) +{ + h->type = data[0]; + h->length = data[1]; + h->handle = WORD(data + 2); + h->data = data; +} - if(WORD(data+0x0E)&(1<<1)) { - _val = dmi_power_supply_status((WORD(data+0x0E)>>7)&0x07); - PyDict_SetItemString(caseData, "Status Present", _val); - Py_DECREF(_val); - } else { - _val = PyString_FromString("Not Present"); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - } - _val = dmi_power_supply_type((WORD(data+0x0E)>>10)&0x0F); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_power_supply_range_switching((WORD(data+0x0E)>>3)&0x0F); - PyDict_SetItemString(caseData, "Input Voltage Range Switching", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%s", WORD(data+0x0E)&(1<<2)?"No":"Yes"); - PyDict_SetItemString(caseData, "Plugged", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%s", WORD(data+0x0E)&(1<<0)?"Yes":"No"); - PyDict_SetItemString(caseData, "Hot Replaceable", _val); - Py_DECREF(_val); - - if(h->length<0x16) break; - if(WORD(data+0x10)!=0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data+0x10)); - PyDict_SetItemString(caseData, "Input Voltage Probe Handle", _val); - Py_DECREF(_val); - } +static void dmi_table_string_py(const struct dmi_header *h, const u8 * data, PyObject * hDict, + u16 ver) +{ + int key; + u8 offset = opt.string->offset; - if(WORD(data+0x12)!=0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data+0x12)); - PyDict_SetItemString(caseData, "Cooling Device Handle", _val); - Py_DECREF(_val); - } + if(offset >= h->length) + return; - if(WORD(data+0x14)!=0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data+0x14)); - PyDict_SetItemString(caseData, "Input Current Probe Handle", _val); + //. TODO: These should have more meaningful dictionary names + key = (opt.string->type << 8) | offset; + PyObject *_val; + + switch (key) { + case 0x108: + _val = dmi_system_uuid_py(data + offset, ver); + PyDict_SetItemString(hDict, "0x108", _val); + break; + case 0x305: + _val = dmi_chassis_type_py(data[offset]); + PyDict_SetItemString(hDict, "0x305", _val); + case 0x406: + _val = PyString_FromString(dmi_processor_family(h)); + PyDict_SetItemString(hDict, "0x406", _val); + break; + case 0x416: + _val = dmi_processor_frequency_py((u8 *) data + offset); + PyDict_SetItemString(hDict, "0x416", _val); + break; + default: + _val = dmi_string_py(h, data[offset]); + PyDict_SetItemString(hDict, "0x???", _val); + } Py_DECREF(_val); - } - - break; - - case 40: /* 3.3.41 Additional Information */ - if(h->length < 0x0B) break; - _key = PyString_FromFormat("Additional Information"); - _val = dmi_additional_info(h, ""); - PyDict_SetItem(caseData, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - break; - - case 41: /* 3.3.42 Onboard Device Extended Information */ - if (h->length < 0x0B) break; - PyObject *subdata = PyDict_New(); - - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(subdata, "Reference Designation", _val); - Py_DECREF(_val); - - _val = PyString_FromString(dmi_on_board_devices_type(data[0x05] & 0x7F)); - PyDict_SetItemString(subdata, "Type", _val); - Py_DECREF(_val); - - _val = PyString_FromString(data[0x05]&0x80 ? "Enabled" : "Disabled"); - PyDict_SetItemString(subdata, "Status", _val); - Py_DECREF(_val); - - _val = PyInt_FromLong(data[0x06]); - PyDict_SetItemString(subdata, "Type Instance", _val); - Py_DECREF(_val); - - _val = dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A]); - PyDict_SetItemString(subdata, "Bus Address", _val); - Py_DECREF(_val); - - PyDict_SetItemString(caseData, "Onboard Device", subdata); - Py_DECREF(subdata); - break; - - case 126: /* 3.3.43 Inactive */ - _val = Py_None; - PyDict_SetItemString(caseData, "Inactive", _val); - Py_DECREF(_val); - break; - - case 127: /* 3.3.44 End Of Table */ - _val = Py_None; - PyDict_SetItemString(caseData, "End Of Table", _val); - Py_DECREF(_val); - break; - - default: - if(dmi_decode_oem(h)) break; - _key = PyString_FromFormat("%s Type", h->type>=128?"OEM-specific":"Unknown"); - _val = dmi_dump(h); - PyDict_SetItem(caseData, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - } - - Py_INCREF(caseData); - return caseData; -} - -void to_dmi_header(struct dmi_header *h, u8 *data) { - h->type=data[0]; - h->length=data[1]; - h->handle=WORD(data+2); - h->data=data; -} - -static void dmi_table_string_py(const struct dmi_header *h, const u8 *data, PyObject *hDict, u16 ver) { - int key; - u8 offset = opt.string->offset; - - if (offset >= h->length) return; - - //. TODO: These should have more meaningful dictionary names - key = (opt.string->type << 8) | offset; - PyObject *_val; - switch(key) { - case 0x108: - _val = dmi_system_uuid_py(data+offset, ver); - PyDict_SetItemString(hDict, "0x108", _val); - break; - case 0x305: - _val = dmi_chassis_type_py(data[offset]); - PyDict_SetItemString(hDict, "0x305", _val); - case 0x406: - _val = PyString_FromString(dmi_processor_family(h)); - PyDict_SetItemString(hDict, "0x406", _val); - break; - case 0x416: - _val = dmi_processor_frequency_py((u8 *)data + offset); - PyDict_SetItemString(hDict, "0x416", _val); - break; - default: - _val = dmi_string_py(h, data[offset]); - PyDict_SetItemString(hDict, "0x???", _val); - } - Py_DECREF(_val); } /* @@ -4459,327 +5012,369 @@ static void dmi_table_dump(u32 base, u16 len, const char *devmem) * as this is where we will put it in the output file. We adjust the * DMI checksum appropriately. The SMBIOS checksum needs no adjustment. */ -static void overwrite_dmi_address(u8 *buf) { - buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32; - buf[0x08] = 32; - buf[0x09] = 0; - buf[0x0A] = 0; - buf[0x0B] = 0; +static void overwrite_dmi_address(u8 * buf) +{ + buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32; + buf[0x08] = 32; + buf[0x09] = 0; + buf[0x0A] = 0; + buf[0x0B] = 0; } - #define NON_LEGACY 0 #define LEGACY 1 -int dumpling(u8 *buf, const char *dumpfile, u8 mode) { - u32 base; - u16 len; - if(mode == NON_LEGACY) { - if(!checksum(buf, buf[0x05]) || !memcmp(buf+0x10, "_DMI_", 5)==0 || !checksum(buf+0x10, 0x0F)) return 0; - base = DWORD(buf+0x18); - len = WORD(buf+0x16); - } else { - if(!checksum(buf, 0x0F)) return 0; - base = DWORD(buf+0x08); - len = WORD(buf+0x06); - } - - u8 *buff; - if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { - //. Part 1. - printf("# Writing %d bytes to %s.\n", len, dumpfile); - write_dump(32, len, buff, dumpfile, 0); - free(buff); - - //. Part 2. - if(mode != LEGACY) { - u8 crafted[32]; - memcpy(crafted, buf, 32); - overwrite_dmi_address(crafted+0x10); - printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); - write_dump(0, crafted[0x05], crafted, dumpfile, 1); - } else { - u8 crafted[16]; - memcpy(crafted, buf, 16); - overwrite_dmi_address(crafted); - printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); - write_dump(0, 0x0F, crafted, dumpfile, 1); - } - } else { - fprintf(stderr, "Failed to read table, sorry.\n"); - } - - //. TODO: Cleanup - return 1; -} - -int dump(const char *dumpfile) { - /* On success, return found, otherwise return -1 */ - int ret=0; - int found=0; - size_t fp; - int efi; - u8 *buf; - - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf=mem_chunk(0xF0000, 0x10000, DEFAULT_MEM_DEV))!=NULL) { - for(fp=0; fp<=0xFFF0; fp+=16) { - if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) { - if(dumpling(buf+fp, dumpfile, NON_LEGACY)) found++; - fp+=16; - } else if(memcmp(buf+fp, "_DMI_", 5)==0) { - if(dumpling(buf+fp, dumpfile, LEGACY)) found++; +int dumpling(u8 * buf, const char *dumpfile, u8 mode) +{ + u32 base; + u16 len; + + if(mode == NON_LEGACY) { + if(!checksum(buf, buf[0x05]) || !memcmp(buf + 0x10, "_DMI_", 5) == 0 || + !checksum(buf + 0x10, 0x0F)) + return 0; + base = DWORD(buf + 0x18); + len = WORD(buf + 0x16); + } else { + if(!checksum(buf, 0x0F)) + return 0; + base = DWORD(buf + 0x08); + len = WORD(buf + 0x06); } - } - } else ret = -1; - } else if(efi == EFI_NO_SMBIOS) { - ret = -1; - } else { - if((buf=mem_chunk(fp, 0x20, DEFAULT_MEM_DEV))==NULL) ret = -1; - else if(dumpling(buf, dumpfile, NON_LEGACY)) found++; - } - - if(ret==0) { - free(buf); - //. TODO: Exception - //dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G."); - if(!found) ret = -1; - } + u8 *buff; + + if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { + //. Part 1. + printf("# Writing %d bytes to %s.\n", len, dumpfile); + write_dump(32, len, buff, dumpfile, 0); + free(buff); + + //. Part 2. + if(mode != LEGACY) { + u8 crafted[32]; + + memcpy(crafted, buf, 32); + overwrite_dmi_address(crafted + 0x10); + printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); + write_dump(0, crafted[0x05], crafted, dumpfile, 1); + } else { + u8 crafted[16]; + + memcpy(crafted, buf, 16); + overwrite_dmi_address(crafted); + printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); + write_dump(0, 0x0F, crafted, dumpfile, 1); + } + } else { + fprintf(stderr, "Failed to read table, sorry.\n"); + } - return ret==0?found:ret; + //. TODO: Cleanup + return 1; } +int dump(const char *dumpfile) +{ + /* On success, return found, otherwise return -1 */ + int ret = 0; + int found = 0; + size_t fp; + int efi; + u8 *buf; + /* First try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + if(efi == EFI_NOT_FOUND) { + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(0xF0000, 0x10000, DEFAULT_MEM_DEV)) != NULL) { + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(dumpling(buf + fp, dumpfile, NON_LEGACY)) + found++; + fp += 16; + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(dumpling(buf + fp, dumpfile, LEGACY)) + found++; + } + } + } else + ret = -1; + } else if(efi == EFI_NO_SMBIOS) { + ret = -1; + } else { + if((buf = mem_chunk(fp, 0x20, DEFAULT_MEM_DEV)) == NULL) + ret = -1; + else if(dumpling(buf, dumpfile, NON_LEGACY)) + found++; + } + + if(ret == 0) { + free(buf); -static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, PyObject *pydata) { - u8 *buf; - u8 *data; - int i=0; + //. TODO: Exception + //dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G."); + if(!found) + ret = -1; + } + + return ret == 0 ? found : ret; +} - if(opt.type==NULL) { - dmiSetItem(pydata, "dmi_table_size", "%i structures occupying %i bytes", num, len); - /* TODO DUMP - if (!(opt.flags & FLAG_FROM_DUMP)) - dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base); - */ - dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base); - } +static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, PyObject * pydata) +{ + u8 *buf; + u8 *data; + int i = 0; + + if(opt.type == NULL) { + dmiSetItem(pydata, "dmi_table_size", "%i structures occupying %i bytes", num, len); + /* TODO DUMP + * if (!(opt.flags & FLAG_FROM_DUMP)) + * dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base); + */ + dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base); + } - if((buf=mem_chunk(base, len, devmem))==NULL) { - fprintf(stderr, "Table is unreachable, sorry." + if((buf = mem_chunk(base, len, devmem)) == NULL) { + fprintf(stderr, "Table is unreachable, sorry." #ifndef USE_MMAP - "Try compiling dmidecode with -DUSE_MMAP."; + "Try compiling dmidecode with -DUSE_MMAP."; #endif - "\n"); - return; - } + "\n"); + return; + } - data=buf; - while(i39 && h.type<=127) - && !opt.string); - - /* - ** If a short entry is found (less than 4 bytes), not only it - ** is invalid, but we cannot reliably locate the next entry. - ** Better stop at this point, and let the user know his/her - ** table is broken. - */ - if(h.length<4) { - fprintf(stderr, "Invalid entry length (%i). DMI table is broken! Stop.", (unsigned int)h.length); - break; - } - - /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together), stop decoding at end of table marker */ - - char hid[7]; - sprintf(hid, "0x%04x", h.handle); - PyObject *hDict = PyDict_New(); - dmiSetItem(hDict, "dmi_handle", hid); - dmiSetItem(hDict, "dmi_type", "%d", h.type); - dmiSetItem(hDict, "dmi_size", "%d", h.length); - - /* assign vendor for vendor-specific decodes later */ - if(h.type==0 && h.length>=5) - dmi_set_vendor(dmi_string(&h, data[0x04])); - - /* look for the next handle */ - next=data+h.length; - while(next-buf+1"); - } else if(opt.string!=NULL && opt.string->type==h.type) { - dmi_table_string_py(&h, data, hDict, ver); - } - - data=next; - i++; - } - - if(i!=num) - fprintf(stderr, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i); - if(data-buf!=len) - fprintf(stderr, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n", - len, (unsigned int)(data-buf)); - - free(buf); -} - - - - -int _smbios_decode_check(u8 *buf) { - int check = (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5)!=0 || !checksum(buf+0x10, 0x0F)) ? 0 : 1; - return check; -} -int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata) { - int check = _smbios_decode_check(buf); - char vbuf[64]; bzero(vbuf, 64); - if(check == 1) { - u16 ver = (buf[0x06] << 8) + buf[0x07]; - /* Some BIOS report weird SMBIOS version, fix that up */ - int _m, _M; - _m = 0; - _M = 0; - switch(ver) { - case 0x021F: - _m = 31; - _M = 3; - ver = 0x0203; - break; - case 0x0233: - _m = 51; - _M = 6; - ver = 0x0206; - break; - } - if(_m || _M) sprintf(vbuf, "SMBIOS %i.%i present (Version fixup 2.%d -> 2.%d)", ver>>8, ver&0xFF, _m, _M); - else sprintf(vbuf, "SMBIOS %i.%i present", ver>>8, ver&0xFF); - } else if(check == 0) { - sprintf(vbuf, "No SMBIOS nor DMI entry point found"); - } - if(check == 1) { - if(*pydata) { Py_DECREF(*pydata); } - *pydata = PyString_FromString(vbuf); - Py_INCREF(*pydata); - } - return check; -} -int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata) { - int check = _smbios_decode_check(buf); - if(check == 1) { - u16 ver = (buf[0x06] << 8) + buf[0x07]; - switch(ver) { - case 0x021F: - ver = 0x0203; - break; - case 0x0233: - ver = 0x0206; - break; - } - //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); - dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C), ver, devmem, pydata); - } - return check; -} - - - - -int _legacy_decode_check(u8 *buf) { - int check; - if(!checksum(buf, 0x0F)) check = 0; //. Bad - else check = 1; //. Good - return check; -} -int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata) { - int check = _legacy_decode_check(buf); - char vbuf[64]; bzero(vbuf, 64); - if(check == 1) { - sprintf(vbuf, "Legacy DMI %i.%i present", buf[0x0E]>>4, buf[0x0E]&0x0F); - } else if(check == 0) { - sprintf(vbuf, "No SMBIOS nor DMI entry point found"); - } - if(check == 1) { - if(*pydata) { Py_DECREF(*pydata); } - *pydata = PyString_FromString(vbuf); - Py_INCREF(*pydata); - } - return check; -} -int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata) { - int check = _legacy_decode_check(buf); - if(check == 1) - dmi_table(DWORD(buf+0x08), WORD(buf+0x06), WORD(buf+0x0C), ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, pydata); - return check; + && !opt.string); + + /* + ** If a short entry is found (less than 4 bytes), not only it + ** is invalid, but we cannot reliably locate the next entry. + ** Better stop at this point, and let the user know his/her + ** table is broken. + */ + if(h.length < 4) { + fprintf(stderr, "Invalid entry length (%i). DMI table is broken! Stop.", + (unsigned int)h.length); + break; + } + + /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together), stop decoding at end of table marker */ + + char hid[7]; + + sprintf(hid, "0x%04x", h.handle); + PyObject *hDict = PyDict_New(); + + dmiSetItem(hDict, "dmi_handle", hid); + dmiSetItem(hDict, "dmi_type", "%d", h.type); + dmiSetItem(hDict, "dmi_size", "%d", h.length); + + /* assign vendor for vendor-specific decodes later */ + if(h.type == 0 && h.length >= 5) + dmi_set_vendor(dmi_string(&h, data[0x04])); + + /* look for the next handle */ + next = data + h.length; + while(next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) + next++; + + next += 2; + + if(display) { + if(next - buf <= len) { + /* TODO: ... + * if(opt.flags & FLAG_DUMP) { + * PyDict_SetItem(hDict, PyString_FromString("lookup"), dmi_dump(&h)); + * } else { + * //. TODO: //. Is the value of `i' important?... + * //. TODO: PyDict_SetItem(hDict, PyInt_FromLong(i), dmi_decode(&h, ver)); + * //. TODO: ...removed and replaced with `data'... + * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); + * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); + * } */ + PyDict_SetItem(hDict, PyString_FromString("data"), + dmi_decode(&h, ver)); + PyDict_SetItem(pydata, PyString_FromString(hid), hDict); + } else + fprintf(stderr, ""); + } else if(opt.string != NULL && opt.string->type == h.type) { + dmi_table_string_py(&h, data, hDict, ver); + } + + data = next; + i++; + } + + if(i != num) + fprintf(stderr, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, + i); + if(data - buf != len) + fprintf(stderr, + "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n", + len, (unsigned int)(data - buf)); + + free(buf); +} + +int _smbios_decode_check(u8 * buf) +{ + int check = (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || + !checksum(buf + 0x10, 0x0F)) ? 0 : 1; + return check; +} +int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) +{ + int check = _smbios_decode_check(buf); + char vbuf[64]; + + bzero(vbuf, 64); + if(check == 1) { + u16 ver = (buf[0x06] << 8) + buf[0x07]; + + /* Some BIOS report weird SMBIOS version, fix that up */ + int _m, _M; + + _m = 0; + _M = 0; + switch (ver) { + case 0x021F: + _m = 31; + _M = 3; + ver = 0x0203; + break; + case 0x0233: + _m = 51; + _M = 6; + ver = 0x0206; + break; + } + if(_m || _M) + sprintf(vbuf, "SMBIOS %i.%i present (Version fixup 2.%d -> 2.%d)", ver >> 8, + ver & 0xFF, _m, _M); + else + sprintf(vbuf, "SMBIOS %i.%i present", ver >> 8, ver & 0xFF); + } else if(check == 0) { + sprintf(vbuf, "No SMBIOS nor DMI entry point found"); + } + if(check == 1) { + if(*pydata) { + Py_DECREF(*pydata); + } + *pydata = PyString_FromString(vbuf); + Py_INCREF(*pydata); + } + return check; +} +int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata) +{ + int check = _smbios_decode_check(buf); + + if(check == 1) { + u16 ver = (buf[0x06] << 8) + buf[0x07]; + + switch (ver) { + case 0x021F: + ver = 0x0203; + break; + case 0x0233: + ver = 0x0206; + break; + } + //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); + dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, + pydata); + } + return check; } +int _legacy_decode_check(u8 * buf) +{ + int check; + if(!checksum(buf, 0x0F)) + check = 0; //. Bad + else + check = 1; //. Good + return check; +} +int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) +{ + int check = _legacy_decode_check(buf); + char vbuf[64]; + + bzero(vbuf, 64); + if(check == 1) { + sprintf(vbuf, "Legacy DMI %i.%i present", buf[0x0E] >> 4, buf[0x0E] & 0x0F); + } else if(check == 0) { + sprintf(vbuf, "No SMBIOS nor DMI entry point found"); + } + if(check == 1) { + if(*pydata) { + Py_DECREF(*pydata); + } + *pydata = PyString_FromString(vbuf); + Py_INCREF(*pydata); + } + return check; +} +int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata) +{ + int check = _legacy_decode_check(buf); + if(check == 1) + dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), + ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, pydata); + return check; +} /******************************************************************************* ** Probe for EFI interface */ -int address_from_efi(size_t *address) { - FILE *efi_systab; - const char *filename; - char linebuf[64]; - int ret; - - *address = 0; /* Prevent compiler warning */ - - /* - ** Linux <= 2.6.6: /proc/efi/systab - ** Linux >= 2.6.7: /sys/firmware/efi/systab - */ - if((efi_systab=fopen(filename="/sys/firmware/efi/systab", "r"))==NULL - && (efi_systab=fopen(filename="/proc/efi/systab", "r"))==NULL) { - /* No EFI interface, fallback to memory scan */ - return EFI_NOT_FOUND; - } - ret=EFI_NO_SMBIOS; - while((fgets(linebuf, sizeof(linebuf)-1, efi_systab))!=NULL) { - char *addrp=strchr(linebuf, '='); - *(addrp++)='\0'; - if(strcmp(linebuf, "SMBIOS")==0) { - *address=strtoul(addrp, NULL, 0); - printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address); - ret=0; - break; - } - } - if(fclose(efi_systab)!=0) - perror(filename); - - if(ret==EFI_NO_SMBIOS) - fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); - - return ret; +int address_from_efi(size_t * address) +{ + FILE *efi_systab; + const char *filename; + char linebuf[64]; + int ret; + + *address = 0; /* Prevent compiler warning */ + + /* + ** Linux <= 2.6.6: /proc/efi/systab + ** Linux >= 2.6.7: /sys/firmware/efi/systab + */ + if((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL + && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) { + /* No EFI interface, fallback to memory scan */ + return EFI_NOT_FOUND; + } + ret = EFI_NO_SMBIOS; + while((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) { + char *addrp = strchr(linebuf, '='); + + *(addrp++) = '\0'; + if(strcmp(linebuf, "SMBIOS") == 0) { + *address = strtoul(addrp, NULL, 0); + printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address); + ret = 0; + break; + } + } + if(fclose(efi_systab) != 0) + perror(filename); + + if(ret == EFI_NO_SMBIOS) + fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); + + return ret; } diff --git a/src/dmidecode.h b/src/dmidecode.h index 7e99faa..066363f 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -1,3 +1,4 @@ + /* * This file is part of the dmidecode project. * @@ -20,26 +21,26 @@ #include struct dmi_header { - u8 type; - u8 length; - u16 handle; - u8 *data; + u8 type; + u8 length; + u16 handle; + u8 *data; }; PyObject *dmi_dump(struct dmi_header *h); -PyObject* dmi_decode(struct dmi_header *h, u16 ver); -int address_from_efi(size_t *address); -void to_dmi_header(struct dmi_header *h, u8 *data); -int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata); -int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata); -int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata); -int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata); +PyObject *dmi_decode(struct dmi_header *h, u16 ver); +int address_from_efi(size_t * address); +void to_dmi_header(struct dmi_header *h, u8 * data); +int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); +int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata); +int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); +int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata); const char *dmi_string(const struct dmi_header *dm, u8 s); -const char *dmi_system_uuid(u8 *p); -PyObject *dmi_system_uuid_py(const u8 *p, u16 ver); +const char *dmi_system_uuid(u8 * p); +PyObject *dmi_system_uuid_py(const u8 * p, u16 ver); const char *dmi_chassis_type(u8 code); -int dmi_processor_frequency(const u8 *p); +int dmi_processor_frequency(const u8 * p); int dump(const char *dumpfile); -int dumpling(u8 *buf, const char *devmem, u8 mode); +int dumpling(u8 * buf, const char *devmem, u8 mode); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 345b151..1870e86 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -2,261 +2,326 @@ #include options opt; -static void init(void) { - /* sanity check */ - if(sizeof(u8)!=1 || sizeof(u16)!=2 || sizeof(u32)!=4 || '\0'!=0) - fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule"); - - opt.devmem = DEFAULT_MEM_DEV; - opt.dumpfile = NULL; - opt.flags=0; - opt.type = NULL; +static void init(void) +{ + /* sanity check */ + if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) + fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule"); + + opt.devmem = DEFAULT_MEM_DEV; + opt.dumpfile = NULL; + opt.flags = 0; + opt.type = NULL; } +u8 *parse_opt_type(u8 * p, const char *arg) +{ -u8 *parse_opt_type(u8 *p, const char *arg) { - - /* Allocate memory on first call only */ - if(p == NULL) { - if(!(p = (u8 *)calloc(256, sizeof(u8)))) { - perror("calloc"); - return NULL; - } - } - - unsigned int i, j; - /* First try as a keyword */ - for(i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) { - if(!strcasecmp(arg, opt_type_keyword[i].keyword)) { - j = 0; - while(opt_type_keyword[i].type[j] != 255) - p[opt_type_keyword[i].type[j++]] = 1; - return p; - } - } - - /* Else try as a number */ - while(*arg != '\0') { - unsigned long val; - char *next; - - val = strtoul(arg, &next, 0); - if(next == arg) { - fprintf(stderr, "Invalid type keyword: %s\n", arg); - free(p); - return NULL; - } - if (val > 0xff) { - fprintf(stderr, "Invalid type number: %lu\n", val); - free(p); - return NULL; - } - - p[val] = 1; - arg = next; - while(*arg == ',' || *arg == ' ') - arg++; - } - - return p; -} + /* Allocate memory on first call only */ + if(p == NULL) { + if(!(p = (u8 *) calloc(256, sizeof(u8)))) { + perror("calloc"); + return NULL; + } + } + unsigned int i, j; -static int dmidecode_set_version(PyObject** pydata) { - int ret=0; - int found=0; - size_t fp; - int efi; - u8 *buf; + /* First try as a keyword */ + for(i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) { + if(!strcasecmp(arg, opt_type_keyword[i].keyword)) { + j = 0; + while(opt_type_keyword[i].type[j] != 255) + p[opt_type_keyword[i].type[j++]] = 1; + return p; + } + } + + /* Else try as a number */ + while(*arg != '\0') { + unsigned long val; + char *next; + + val = strtoul(arg, &next, 0); + if(next == arg) { + fprintf(stderr, "Invalid type keyword: %s\n", arg); + free(p); + return NULL; + } + if(val > 0xff) { + fprintf(stderr, "Invalid type number: %lu\n", val); + free(p); + return NULL; + } + + p[val] = 1; + arg = next; + while(*arg == ',' || *arg == ' ') + arg++; + } + + return p; +} - /* Set default option values */ - opt.devmem = DEFAULT_MEM_DEV; +static int dmidecode_set_version(PyObject ** pydata) +{ + int ret = 0; + int found = 0; + size_t fp; + int efi; + u8 *buf; + + /* Set default option values */ + opt.devmem = DEFAULT_MEM_DEV; /***********************************/ - /* Read from dump if so instructed */ - if(opt.dumpfile != NULL) { - const char *dumpfile = PyString_AS_STRING(opt.dumpfile); - //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); - if((buf = mem_chunk(0, 0x20, dumpfile))!=NULL) { - if(memcmp(buf, "_SM_", 4)==0) { - if(smbios_decode_set_version(buf, dumpfile, pydata)) found++; - } else if (memcmp(buf, "_DMI_", 5)==0) { - if(legacy_decode_set_version(buf, dumpfile, pydata)) found++; - } - } else ret = 1; - } else { /* Read from /dev/mem */ - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))!=NULL) { - for(fp=0; fp<=0xFFF0; fp+=16) { - if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) { - if(smbios_decode_set_version(buf+fp, opt.devmem, pydata)) found++; - fp+=16; - } else if(memcmp(buf+fp, "_DMI_", 5)==0) { - if(legacy_decode_set_version(buf+fp, opt.devmem, pydata)) found++; - } + /* Read from dump if so instructed */ + if(opt.dumpfile != NULL) { + const char *dumpfile = PyString_AS_STRING(opt.dumpfile); + + //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); + if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { + if(memcmp(buf, "_SM_", 4) == 0) { + if(smbios_decode_set_version(buf, dumpfile, pydata)) + found++; + } else if(memcmp(buf, "_DMI_", 5) == 0) { + if(legacy_decode_set_version(buf, dumpfile, pydata)) + found++; + } + } else + ret = 1; + } else { /* Read from /dev/mem */ + /* First try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + if(efi == EFI_NOT_FOUND) { + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(smbios_decode_set_version + (buf + fp, opt.devmem, pydata)) + found++; + fp += 16; + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(legacy_decode_set_version + (buf + fp, opt.devmem, pydata)) + found++; + } + } + } else + ret = 1; + } else if(efi == EFI_NO_SMBIOS) { + ret = 1; + } else { + if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) + ret = 1; + else if(smbios_decode_set_version(buf, opt.devmem, pydata)) + found++; + //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + } + } + + if(ret == 0) { + free(buf); + if(!found) { + fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G."); + } } - } else ret = 1; - } else if(efi == EFI_NO_SMBIOS) { - ret = 1; - } else { - if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1; - else if(smbios_decode_set_version(buf, opt.devmem, pydata)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); - } - } - - if(ret==0) { - free(buf); - if(!found) { - fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G."); - } - } - free(opt.type); - return ret; + free(opt.type); + return ret; } +static PyObject *dmidecode_get(PyObject * self, const char *section) +{ + //mtrace(); -static PyObject* dmidecode_get(PyObject *self, const char* section) { - //mtrace(); + int ret = 0; + int found = 0; + size_t fp; + int efi; + u8 *buf; - int ret=0; - int found=0; - size_t fp; - int efi; - u8 *buf; + /* Set default option values */ + opt.devmem = DEFAULT_MEM_DEV; + opt.flags = 0; + opt.type = NULL; + opt.type = parse_opt_type(opt.type, section); + if(opt.type == NULL) + return NULL; - /* Set default option values */ - opt.devmem = DEFAULT_MEM_DEV; - opt.flags = 0; - opt.type = NULL; - opt.type = parse_opt_type(opt.type, section); - if(opt.type==NULL) return NULL; + const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; - const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; - if(access(f, R_OK) < 0) - PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); + if(access(f, R_OK) < 0) + PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); - PyObject* pydata = PyDict_New(); + PyObject *pydata = PyDict_New(); /***********************************/ - /* Read from dump if so instructed */ - if(opt.dumpfile != NULL) { - const char *dumpfile = PyString_AS_STRING(opt.dumpfile); - //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); - if((buf = mem_chunk(0, 0x20, dumpfile))!=NULL) { - if(memcmp(buf, "_SM_", 4)==0) { - if(smbios_decode(buf, dumpfile, pydata)) found++; - } else if (memcmp(buf, "_DMI_", 5)==0) { - if(legacy_decode(buf, dumpfile, pydata)) found++; - } - } else ret = 1; - } else { /* Read from /dev/mem */ - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))!=NULL) { - for(fp=0; fp<=0xFFF0; fp+=16) { - if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) { - if(smbios_decode(buf+fp, opt.devmem, pydata)) { - found++; - fp+=16; - } - } else if(memcmp(buf+fp, "_DMI_", 5)==0) { - if(legacy_decode(buf+fp, opt.devmem, pydata)) found++; - } + /* Read from dump if so instructed */ + if(opt.dumpfile != NULL) { + const char *dumpfile = PyString_AS_STRING(opt.dumpfile); + + //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); + if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { + if(memcmp(buf, "_SM_", 4) == 0) { + if(smbios_decode(buf, dumpfile, pydata)) + found++; + } else if(memcmp(buf, "_DMI_", 5) == 0) { + if(legacy_decode(buf, dumpfile, pydata)) + found++; + } + } else + ret = 1; + } else { /* Read from /dev/mem */ + /* First try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + if(efi == EFI_NOT_FOUND) { + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(smbios_decode(buf + fp, opt.devmem, pydata)) { + found++; + fp += 16; + } + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(legacy_decode(buf + fp, opt.devmem, pydata)) + found++; + } + } + } else + ret = 1; + } else if(efi == EFI_NO_SMBIOS) { + ret = 1; + } else { + if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) + ret = 1; + else if(smbios_decode(buf, opt.devmem, pydata)) + found++; + //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + } + } + + free(opt.type); + if(ret == 0) { + free(buf); + } else { + Py_DECREF(pydata); + pydata = NULL; } - } else ret = 1; - } else if(efi == EFI_NO_SMBIOS) { - ret = 1; - } else { - if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1; - else if(smbios_decode(buf, opt.devmem, pydata)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); - } - } - - free(opt.type); - if(ret==0) { - free(buf); - } else { - Py_DECREF(pydata); - pydata = NULL; - } - - //muntrace(); - return pydata; + + //muntrace(); + return pydata; } -static PyObject* dmidecode_get_bios(PyObject *self, PyObject *args) { return dmidecode_get(self, "bios"); } -static PyObject* dmidecode_get_system(PyObject *self, PyObject *args) { return dmidecode_get(self, "system"); } -static PyObject* dmidecode_get_baseboard(PyObject *self, PyObject *args) { return dmidecode_get(self, "baseboard"); } -static PyObject* dmidecode_get_chassis(PyObject *self, PyObject *args) { return dmidecode_get(self, "chassis"); } -static PyObject* dmidecode_get_processor(PyObject *self, PyObject *args) { return dmidecode_get(self, "processor"); } -static PyObject* dmidecode_get_memory(PyObject *self, PyObject *args) { return dmidecode_get(self, "memory"); } -static PyObject* dmidecode_get_cache(PyObject *self, PyObject *args) { return dmidecode_get(self, "cache"); } -static PyObject* dmidecode_get_connector(PyObject *self, PyObject *args) { return dmidecode_get(self, "connector"); } -static PyObject* dmidecode_get_slot(PyObject *self, PyObject *args) { return dmidecode_get(self, "slot"); } -static PyObject* dmidecode_get_type(PyObject *self, PyObject *args) { - long unsigned int lu; - if(PyArg_ParseTuple(args, (char *)"i", &lu)) { - if(lu < 256) { - char s[8]; - sprintf(s, "%lu", lu); - return dmidecode_get(self, s); - } - return Py_False; - } - return Py_None; +static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "bios"); +} +static PyObject *dmidecode_get_system(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "system"); +} +static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "baseboard"); +} +static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "chassis"); +} +static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "processor"); +} +static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "memory"); +} +static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "cache"); +} +static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "connector"); +} +static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "slot"); +} +static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) +{ + long unsigned int lu; + + if(PyArg_ParseTuple(args, (char *)"i", &lu)) { + if(lu < 256) { + char s[8]; + + sprintf(s, "%lu", lu); + return dmidecode_get(self, s); + } + return Py_False; + } + return Py_None; } -static PyObject* dmidecode_dump(PyObject *self, PyObject *null) { - const char *f; - f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; - struct stat _buf; - stat(f, &_buf); +static PyObject *dmidecode_dump(PyObject * self, PyObject * null) +{ + const char *f; - if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode))) - if(dump(PyString_AS_STRING(opt.dumpfile))) - Py_RETURN_TRUE; - Py_RETURN_FALSE; -} + f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; + struct stat _buf; + + stat(f, &_buf); -static PyObject* dmidecode_get_dev(PyObject *self, PyObject *null) { - PyObject *dev; - if(opt.dumpfile != NULL) dev = opt.dumpfile; - else dev = PyString_FromString(opt.devmem); - Py_INCREF(dev); - return dev; + if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode))) + if(dump(PyString_AS_STRING(opt.dumpfile))) + Py_RETURN_TRUE; + Py_RETURN_FALSE; } -static PyObject* dmidecode_set_dev(PyObject *self, PyObject *arg) { - if(PyString_Check(arg)) { - if(opt.dumpfile == arg) Py_RETURN_TRUE; +static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) +{ + PyObject *dev; - struct stat buf; - char *f = PyString_AsString(arg); - stat(f, &buf); - if(opt.dumpfile) { Py_DECREF(opt.dumpfile); } + if(opt.dumpfile != NULL) + dev = opt.dumpfile; + else + dev = PyString_FromString(opt.devmem); + Py_INCREF(dev); + return dev; +} - if(S_ISCHR(buf.st_mode)) { - if(memcmp(PyString_AsString(arg), "/dev/mem", 8)==0) { - opt.dumpfile = NULL; - Py_RETURN_TRUE; - } else { +static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) +{ + if(PyString_Check(arg)) { + if(opt.dumpfile == arg) + Py_RETURN_TRUE; + + struct stat buf; + char *f = PyString_AsString(arg); + + stat(f, &buf); + if(opt.dumpfile) { + Py_DECREF(opt.dumpfile); + } + + if(S_ISCHR(buf.st_mode)) { + if(memcmp(PyString_AsString(arg), "/dev/mem", 8) == 0) { + opt.dumpfile = NULL; + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + } else if(!S_ISDIR(buf.st_mode)) { + opt.dumpfile = arg; + Py_INCREF(opt.dumpfile); + Py_RETURN_TRUE; + } + } Py_RETURN_FALSE; - } - } else if(!S_ISDIR(buf.st_mode)) { - opt.dumpfile = arg; - Py_INCREF(opt.dumpfile); - Py_RETURN_TRUE; - } - } - Py_RETURN_FALSE; - //PyErr_Occurred(); + //PyErr_Occurred(); } /* @@ -271,35 +336,42 @@ static PyMemberDef DMIDataMembers[] = { */ static PyMethodDef DMIDataMethods[] = { - { (char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file" }, - { (char *)"get_dev", dmidecode_get_dev, METH_NOARGS, (char *)"Get an alternative memory device file" }, - { (char *)"set_dev", dmidecode_set_dev, METH_O, (char *)"Set an alternative memory device file" }, - - { (char *)"bios", dmidecode_get_bios, METH_VARARGS, (char *)"BIOS Data" }, - { (char *)"system", dmidecode_get_system, METH_VARARGS, (char *)"System Data" }, - { (char *)"baseboard", dmidecode_get_baseboard, METH_VARARGS, (char *)"Baseboard Data" }, - { (char *)"chassis", dmidecode_get_chassis, METH_VARARGS, (char *)"Chassis Data" }, - { (char *)"processor", dmidecode_get_processor, METH_VARARGS, (char *)"Processor Data" }, - { (char *)"memory", dmidecode_get_memory, METH_VARARGS, (char *)"Memory Data" }, - { (char *)"cache", dmidecode_get_cache, METH_VARARGS, (char *)"Cache Data" }, - { (char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data" }, - { (char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data" }, - - { (char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type" }, - - { NULL, NULL, 0, NULL } + {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"}, + {(char *)"get_dev", dmidecode_get_dev, METH_NOARGS, + (char *)"Get an alternative memory device file"}, + {(char *)"set_dev", dmidecode_set_dev, METH_O, + (char *)"Set an alternative memory device file"}, + + {(char *)"bios", dmidecode_get_bios, METH_VARARGS, (char *)"BIOS Data"}, + {(char *)"system", dmidecode_get_system, METH_VARARGS, (char *)"System Data"}, + {(char *)"baseboard", dmidecode_get_baseboard, METH_VARARGS, (char *)"Baseboard Data"}, + {(char *)"chassis", dmidecode_get_chassis, METH_VARARGS, (char *)"Chassis Data"}, + {(char *)"processor", dmidecode_get_processor, METH_VARARGS, (char *)"Processor Data"}, + {(char *)"memory", dmidecode_get_memory, METH_VARARGS, (char *)"Memory Data"}, + {(char *)"cache", dmidecode_get_cache, METH_VARARGS, (char *)"Cache Data"}, + {(char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data"}, + {(char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data"}, + + {(char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type"}, + + {NULL, NULL, 0, NULL} }; -PyMODINIT_FUNC initdmidecode(void) { - init(); +PyMODINIT_FUNC initdmidecode(void) +{ + init(); + + PyObject *module = + Py_InitModule3((char *)"dmidecode", DMIDataMethods, + "Python extension module for dmidecode"); + + PyObject *version = PyString_FromString("2.10"); - PyObject *module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, "Python extension module for dmidecode"); + Py_INCREF(version); + PyModule_AddObject(module, "version", version); - PyObject *version = PyString_FromString("2.10"); - Py_INCREF(version); - PyModule_AddObject(module, "version", version); + PyObject *dmi_version = NULL; - PyObject *dmi_version = NULL; - dmidecode_set_version(&dmi_version); - PyModule_AddObject(module, "dmi", dmi_version?dmi_version:Py_None); + dmidecode_set_version(&dmi_version); + PyModule_AddObject(module, "dmi", dmi_version ? dmi_version : Py_None); } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index cf1e5f4..7c81b0a 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -23,17 +23,17 @@ //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern PyObject *dmi_dump(struct dmi_header *h); -extern PyObject* dmi_decode(struct dmi_header *h, u16 ver); -extern int address_from_efi(size_t *address); -extern void to_dmi_header(struct dmi_header *h, u8 *data); +extern PyObject *dmi_decode(struct dmi_header *h, u16 ver); +extern int address_from_efi(size_t * address); +extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); -extern int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata); -extern int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata); -extern int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata); -extern int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata); +extern int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata); +extern int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata); +extern int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); +extern int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); extern void *mem_chunk(size_t base, size_t len, const char *devmem); -extern u8 *parse_opt_type(u8 *p, const char *arg); +extern u8 *parse_opt_type(u8 * p, const char *arg); static const u8 opt_type_bios[] = { 0, 13, 255 }; static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 }; static const u8 opt_type_baseboard[] = { 2, 10, 255 }; @@ -44,20 +44,20 @@ static const u8 opt_type_cache[] = { 7, 255 }; static const u8 opt_type_connector[] = { 8, 255 }; static const u8 opt_type_slot[] = { 9, 255 }; struct type_keyword { - const char *keyword; - const u8 *type; + const char *keyword; + const u8 *type; }; static const struct type_keyword opt_type_keyword[] = { - { "bios", opt_type_bios }, - { "system", opt_type_system }, - { "baseboard", opt_type_baseboard }, - { "chassis", opt_type_chassis }, - { "processor", opt_type_processor }, - { "memory", opt_type_memory }, - { "cache", opt_type_cache }, - { "connector", opt_type_connector }, - { "slot", opt_type_slot }, + {"bios", opt_type_bios}, + {"system", opt_type_system}, + {"baseboard", opt_type_baseboard}, + {"chassis", opt_type_chassis}, + {"processor", opt_type_processor}, + {"memory", opt_type_memory}, + {"cache", opt_type_cache}, + {"connector", opt_type_connector}, + {"slot", opt_type_slot}, }; PyMODINIT_FUNC initdmidecode(void); diff --git a/src/dmihelper.c b/src/dmihelper.c index 6d52e04..4000a92 100644 --- a/src/dmihelper.c +++ b/src/dmihelper.c @@ -33,19 +33,21 @@ dmi_minor* dmiAppendObject(long code, char const *key, const char *format, ...) } */ -int dmiSetItem(PyObject* dict, const char *key, const char *format, ...) { - va_list arg; - va_start(arg, format); - char buffer[2048]; - vsprintf(buffer, format, arg); - va_end(arg); - //printf("DEBUG: Setting k:%s, f:%s s:%s...", key, format, buffer); - PyDict_SetItem(dict, PyString_FromString(key), PyString_FromString(buffer)); - //printf("Done.\n"); - return 0; +int dmiSetItem(PyObject * dict, const char *key, const char *format, ...) +{ + va_list arg; + + va_start(arg, format); + char buffer[2048]; + + vsprintf(buffer, format, arg); + va_end(arg); + //printf("DEBUG: Setting k:%s, f:%s s:%s...", key, format, buffer); + PyDict_SetItem(dict, PyString_FromString(key), PyString_FromString(buffer)); + //printf("Done.\n"); + return 0; } - /* NOTE: Decomissioned helper function... void dmiAppendData(PyObject *pydata, const int count) { dmi_minor* last = dmiAppendObject(count, "JUNK", "NODATA"); diff --git a/src/dmihelper.h b/src/dmihelper.h index a056eb2..ac82916 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -14,100 +14,101 @@ #define MAXVAL 1024 static const int map_maj[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, }; typedef struct _dmi_codes_major { - const unsigned short code; - const char *id; - const char *desc; + const unsigned short code; + const char *id; + const char *desc; } dmi_codes_major; static const dmi_codes_major dmiCodesMajor[] = { - { 0, "3.3.1", "BIOS Information" }, - { 1, "3.3.2", "System Information" }, - { 2, "3.3.3", "Base Board Information" }, - { 3, "3.3.4", "Chassis Information" }, - { 4, "3.3.5", "Processor Information" }, - { 5, "3.3.6", "Memory Controller Information" }, - { 6, "3.3.7", "Memory Module Information" }, - { 7, "3.3.8", "Cache Information" }, - { 8, "3.3.9", "Port Connector Information" }, - { 9, "3.3.10", "System Slots" }, - { 10, "3.3.11", "On Board Devices Information" }, - { 11, "3.3.12", "OEM Strings" }, - { 12, "3.3.13", "System Configuration Options" }, - { 13, "3.3.14", "BIOS Language Information" }, - { 14, "3.3.15", "Group Associations" }, - { 15, "3.3.16", "System Event Log" }, - { 16, "3.3.17", "Physical Memory Array" }, - { 17, "3.3.18", "Memory Device" }, - { 18, "3.3.19", "32-bit Memory Error Information" }, - { 19, "3.3.20", "Memory Array Mapped Address" }, - { 20, "3.3.21", "Memory Device Mapped Address" }, - { 21, "3.3.22", "Built-in Pointing Device" }, - { 22, "3.3.23", "Portable Battery" }, - { 23, "3.3.24", "System Reset" }, - { 24, "3.3.25", "Hardware Security" }, - { 25, "3.3.26", "System Power Controls" }, - { 26, "3.3.27", "Voltage Probe" }, - { 27, "3.3.28", "Cooling Device" }, - { 28, "3.3.29", "Temperature Probe" }, - { 29, "3.3.30", "Electrical Current Probe" }, - { 30, "3.3.31", "Out-of-band Remote Access" }, - { 31, "3.3.32", "Boot Integrity Services Entry Point" }, - { 32, "3.3.33", "System Boot Information" }, - { 33, "3.3.34", "64-bit Memory Error Information" }, - { 34, "3.3.35", "Management Device" }, - { 35, "3.3.36", "Management Device Component" }, - { 36, "3.3.37", "Management Device Threshold Data" }, - { 37, "3.3.38", "Memory Channel" }, - { 38, "3.3.39", "IPMI Device Information" }, - { 39, "3.3.40", "System Power Supply" }, - { 40, "3.3.41", "-------------------" }, - { 41, "3.3.42", "-------------------" }, - { 126, "3.3.41", "Inactive" }, - { 127, "3.3.42", "End Of Table" }, + {0, "3.3.1", "BIOS Information"}, + {1, "3.3.2", "System Information"}, + {2, "3.3.3", "Base Board Information"}, + {3, "3.3.4", "Chassis Information"}, + {4, "3.3.5", "Processor Information"}, + {5, "3.3.6", "Memory Controller Information"}, + {6, "3.3.7", "Memory Module Information"}, + {7, "3.3.8", "Cache Information"}, + {8, "3.3.9", "Port Connector Information"}, + {9, "3.3.10", "System Slots"}, + {10, "3.3.11", "On Board Devices Information"}, + {11, "3.3.12", "OEM Strings"}, + {12, "3.3.13", "System Configuration Options"}, + {13, "3.3.14", "BIOS Language Information"}, + {14, "3.3.15", "Group Associations"}, + {15, "3.3.16", "System Event Log"}, + {16, "3.3.17", "Physical Memory Array"}, + {17, "3.3.18", "Memory Device"}, + {18, "3.3.19", "32-bit Memory Error Information"}, + {19, "3.3.20", "Memory Array Mapped Address"}, + {20, "3.3.21", "Memory Device Mapped Address"}, + {21, "3.3.22", "Built-in Pointing Device"}, + {22, "3.3.23", "Portable Battery"}, + {23, "3.3.24", "System Reset"}, + {24, "3.3.25", "Hardware Security"}, + {25, "3.3.26", "System Power Controls"}, + {26, "3.3.27", "Voltage Probe"}, + {27, "3.3.28", "Cooling Device"}, + {28, "3.3.29", "Temperature Probe"}, + {29, "3.3.30", "Electrical Current Probe"}, + {30, "3.3.31", "Out-of-band Remote Access"}, + {31, "3.3.32", "Boot Integrity Services Entry Point"}, + {32, "3.3.33", "System Boot Information"}, + {33, "3.3.34", "64-bit Memory Error Information"}, + {34, "3.3.35", "Management Device"}, + {35, "3.3.36", "Management Device Component"}, + {36, "3.3.37", "Management Device Threshold Data"}, + {37, "3.3.38", "Memory Channel"}, + {38, "3.3.39", "IPMI Device Information"}, + {39, "3.3.40", "System Power Supply"}, + {40, "3.3.41", "-------------------"}, + {41, "3.3.42", "-------------------"}, + {126, "3.3.41", "Inactive"}, + {127, "3.3.42", "End Of Table"}, }; typedef struct _dmi_minor { - long id; - dmi_codes_major* major; - char *key; - char value[MAXVAL]; - struct _dmi_minor* next; + long id; + dmi_codes_major *major; + char *key; + char value[MAXVAL]; + struct _dmi_minor *next; } dmi_minor; -void dmiAppendData(PyObject *pydata, const int count); -int dmiSetItem(PyObject* dict, const char *key, const char *format, ...); +void dmiAppendData(PyObject * pydata, const int count); +int dmiSetItem(PyObject * dict, const char *key, const char *format, ...); + //dmi_minor* dmiAppendObject(long code, char const *key, const char *format, ...); /*** dmiopt.h ***/ struct string_keyword { - const char *keyword; - u8 type; - u8 offset; + const char *keyword; + u8 type; + u8 offset; }; /*** dmiopt.h ***/ typedef struct _options { - const char *devmem; - unsigned int flags; - u8 *type; - const struct string_keyword *string; - PyObject *dumpfile; + const char *devmem; + unsigned int flags; + u8 *type; + const struct string_keyword *string; + PyObject *dumpfile; } options; extern options opt; diff --git a/src/dmioem.c b/src/dmioem.c index a2fd2a2..361810a 100644 --- a/src/dmioem.c +++ b/src/dmioem.c @@ -1,3 +1,4 @@ + /* * Decoding of OEM-specific entries * This file is part of the dmidecode project. @@ -32,7 +33,7 @@ enum DMI_VENDORS { VENDOR_UNKNOWN, VENDOR_HP }; -static enum DMI_VENDORS dmi_vendor=VENDOR_UNKNOWN; +static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN; /* * Remember the system vendor for later use. We only actually store the @@ -41,8 +42,8 @@ static enum DMI_VENDORS dmi_vendor=VENDOR_UNKNOWN; */ void dmi_set_vendor(const char *s) { - if(strcmp(s, "HP")==0) - dmi_vendor=VENDOR_HP; + if(strcmp(s, "HP") == 0) + dmi_vendor = VENDOR_HP; } /* @@ -53,63 +54,60 @@ void dmi_set_vendor(const char *s) static int dmi_decode_hp(struct dmi_header *h) { - u8 *data=h->data; - int nic, ptr; + u8 *data = h->data; + int nic, ptr; - switch(h->type) - { - case 204: - /* - * Vendor Specific: HP ProLiant System/Rack Locator - */ - printf("HP ProLiant System/Rack Locator\n"); - if(h->length<0x0B) break; - printf("\tRack Name: %s\n", dmi_string(h, data[0x04])); - printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05])); - printf("\tEnclosure Model: %s\n", dmi_string(h, data[0x06])); - printf("\tEnclosure Serial: %s\n", dmi_string(h, data[0x0A])); - printf("\tEnclosure Bays: %d\n", data[0x08]); - printf("\tServer Bay: %s\n", dmi_string(h, data[0x07])); - printf("\tBays Filled: %d\n", data[0x09]); - break; + switch (h->type) { + case 204: + /* + * Vendor Specific: HP ProLiant System/Rack Locator + */ + printf("HP ProLiant System/Rack Locator\n"); + if(h->length < 0x0B) + break; + printf("\tRack Name: %s\n", dmi_string(h, data[0x04])); + printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05])); + printf("\tEnclosure Model: %s\n", dmi_string(h, data[0x06])); + printf("\tEnclosure Serial: %s\n", dmi_string(h, data[0x0A])); + printf("\tEnclosure Bays: %d\n", data[0x08]); + printf("\tServer Bay: %s\n", dmi_string(h, data[0x07])); + printf("\tBays Filled: %d\n", data[0x09]); + break; - case 209: - case 221: - /* - * Vendor Specific: HP ProLiant NIC MAC Information - * - * This prints the BIOS NIC number, - * PCI bus/device/function, and MAC address - */ - printf(h->type==221? - "HP BIOS iSCSI NIC PCI and MAC Information\n": - "HP BIOS NIC PCI and MAC Information\n"); - nic=1; - ptr=4; - while(h->length>=ptr+8) - { - if(data[ptr]==0x00 && data[ptr+1]==0x00) - printf("\tNIC %d: Disabled\n", nic); - else if(data[ptr]==0xFF && data[ptr+1]==0xFF) - printf("\tNIC %d: Not Installed\n", nic); - else - { - printf("\tNIC %d: PCI device %02x:%02x.%x, " - "MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", - nic, data[ptr+1], data[ptr]>>3, data[ptr]&7, - data[ptr+2], data[ptr+3], - data[ptr+4], data[ptr+5], - data[ptr+6], data[ptr+7]); - } - nic++; - ptr+=8; - } - break; + case 209: + case 221: + /* + * Vendor Specific: HP ProLiant NIC MAC Information + * + * This prints the BIOS NIC number, + * PCI bus/device/function, and MAC address + */ + printf(h->type == 221 ? + "HP BIOS iSCSI NIC PCI and MAC Information\n" : + "HP BIOS NIC PCI and MAC Information\n"); + nic = 1; + ptr = 4; + while(h->length >= ptr + 8) { + if(data[ptr] == 0x00 && data[ptr + 1] == 0x00) + printf("\tNIC %d: Disabled\n", nic); + else if(data[ptr] == 0xFF && data[ptr + 1] == 0xFF) + printf("\tNIC %d: Not Installed\n", nic); + else { + printf("\tNIC %d: PCI device %02x:%02x.%x, " + "MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", + nic, data[ptr + 1], data[ptr] >> 3, data[ptr] & 7, + data[ptr + 2], data[ptr + 3], + data[ptr + 4], data[ptr + 5], data[ptr + 6], data[ptr + 7]); + } + nic++; + ptr += 8; + } + break; - default: - return 0; - } - return 1; + default: + return 0; + } + return 1; } /* @@ -118,11 +116,10 @@ static int dmi_decode_hp(struct dmi_header *h) */ int dmi_decode_oem(struct dmi_header *h) { - switch(dmi_vendor) - { - case VENDOR_HP: - return dmi_decode_hp(h); - default: - return 0; - } + switch (dmi_vendor) { + case VENDOR_HP: + return dmi_decode_hp(h); + default: + return 0; + } } diff --git a/src/dmioem.h b/src/dmioem.h index 00483f2..b1b4af8 100644 --- a/src/dmioem.h +++ b/src/dmioem.h @@ -1,3 +1,4 @@ + /* * Decoding of OEM-specific entries * This file is part of the dmidecode project. diff --git a/src/types.h b/src/types.h index b124ecf..39d3d8f 100644 --- a/src/types.h +++ b/src/types.h @@ -21,25 +21,25 @@ typedef unsigned int u32; #ifdef BIGENDIAN typedef struct { - u32 h; - u32 l; + u32 h; + u32 l; } u64; #else typedef struct { - u32 l; - u32 h; + u32 l; + u32 h; } u64; #endif #ifdef ALIGNMENT_WORKAROUND static inline u64 U64(u32 low, u32 high) { - u64 self; - - self.l=low; - self.h=high; - - return self; + u64 self; + + self.l = low; + self.h = high; + + return self; } #endif diff --git a/src/util.c b/src/util.c index 15d24a7..d9ac510 100644 --- a/src/util.c +++ b/src/util.c @@ -1,3 +1,4 @@ + /* * Common "util" functions * This file is part of the dmidecode project. @@ -48,46 +49,41 @@ #include "util.h" #ifndef USE_MMAP -static int myread(int fd, u8 *buf, size_t count, const char *prefix) +static int myread(int fd, u8 * buf, size_t count, const char *prefix) { - ssize_t r = 1; - size_t r2 = 0; - - while (r2 != count && r != 0) - { - r = read(fd, buf + r2, count - r2); - if (r == -1) - { - if (errno != EINTR) - { - close(fd); - perror(prefix); - return -1; - } - } - else - r2 += r; - } - - if (r2 != count) - { - close(fd); - fprintf(stderr, "%s: Unexpected end of file\n", prefix); - return -1; - } - - return 0; + ssize_t r = 1; + size_t r2 = 0; + + while(r2 != count && r != 0) { + r = read(fd, buf + r2, count - r2); + if(r == -1) { + if(errno != EINTR) { + close(fd); + perror(prefix); + return -1; + } + } else + r2 += r; + } + + if(r2 != count) { + close(fd); + fprintf(stderr, "%s: Unexpected end of file\n", prefix); + return -1; + } + + return 0; } #endif -int checksum(const u8 *buf, size_t len) +int checksum(const u8 * buf, size_t len) { - u8 sum = 0; - size_t a; + u8 sum = 0; + size_t a; - for (a = 0; a < len; a++) - sum += buf[a]; - return (sum == 0); + for(a = 0; a < len; a++) + sum += buf[a]; + return (sum == 0); } /* @@ -96,110 +92,100 @@ int checksum(const u8 *buf, size_t len) */ void *mem_chunk(size_t base, size_t len, const char *devmem) { - void *p; - int fd; + void *p; + int fd; + #ifdef USE_MMAP - size_t mmoffset; - void *mmp; + size_t mmoffset; + void *mmp; #endif - if ((fd = open(devmem, O_RDONLY)) == -1) - { - perror(devmem); - return NULL; - } - - if ((p = malloc(len)) == NULL) - { - perror("malloc"); - return NULL; - } + if((fd = open(devmem, O_RDONLY)) == -1) { + perror(devmem); + return NULL; + } + if((p = malloc(len)) == NULL) { + perror("malloc"); + return NULL; + } #ifdef USE_MMAP #ifdef _SC_PAGESIZE - mmoffset = base % sysconf(_SC_PAGESIZE); + mmoffset = base % sysconf(_SC_PAGESIZE); #else - mmoffset = base % getpagesize(); + mmoffset = base % getpagesize(); #endif /* _SC_PAGESIZE */ - /* - * Please note that we don't use mmap() for performance reasons here, - * but to workaround problems many people encountered when trying - * to read from /dev/mem using regular read() calls. - */ - mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); - if (mmp == MAP_FAILED) - { - fprintf(stderr, "%s: ", devmem); - perror("mmap"); - free(p); - return NULL; - } - - memcpy(p, (u8 *)mmp + mmoffset, len); - - if (munmap(mmp, mmoffset + len) == -1) - { - fprintf(stderr, "%s: ", devmem); - perror("munmap"); - } + /* + * Please note that we don't use mmap() for performance reasons here, + * but to workaround problems many people encountered when trying + * to read from /dev/mem using regular read() calls. + */ + mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); + if(mmp == MAP_FAILED) { + fprintf(stderr, "%s: ", devmem); + perror("mmap"); + free(p); + return NULL; + } + + memcpy(p, (u8 *) mmp + mmoffset, len); + + if(munmap(mmp, mmoffset + len) == -1) { + fprintf(stderr, "%s: ", devmem); + perror("munmap"); + } #else /* USE_MMAP */ - if (lseek(fd, base, SEEK_SET) == -1) - { - fprintf(stderr, "%s: ", devmem); - perror("lseek"); - free(p); - return NULL; - } - - if (myread(fd, p, len, devmem) == -1) - { - free(p); - return NULL; - } + if(lseek(fd, base, SEEK_SET) == -1) { + fprintf(stderr, "%s: ", devmem); + perror("lseek"); + free(p); + return NULL; + } + + if(myread(fd, p, len, devmem) == -1) { + free(p); + return NULL; + } #endif /* USE_MMAP */ - if (close(fd) == -1) - perror(devmem); + if(close(fd) == -1) + perror(devmem); - return p; + return p; } int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add) { - FILE *f; - - f = fopen(dumpfile, add ? "r+b" : "wb"); - if (!f) - { - fprintf(stderr, "%s: ", dumpfile); - perror("fopen"); - return -1; - } - - if (fseek(f, base, SEEK_SET) != 0) - { - fprintf(stderr, "%s: ", dumpfile); - perror("fseek"); - goto err_close; - } - - if (fwrite(data, len, 1, f) != 1) - { - fprintf(stderr, "%s: ", dumpfile); - perror("fwrite"); - goto err_close; - } - - if (fclose(f)) - { - fprintf(stderr, "%s: ", dumpfile); - perror("fclose"); - return -1; - } - - return 0; - -err_close: - fclose(f); - return -1; + FILE *f; + + f = fopen(dumpfile, add ? "r+b" : "wb"); + if(!f) { + fprintf(stderr, "%s: ", dumpfile); + perror("fopen"); + return -1; + } + + if(fseek(f, base, SEEK_SET) != 0) { + fprintf(stderr, "%s: ", dumpfile); + perror("fseek"); + goto err_close; + } + + if(fwrite(data, len, 1, f) != 1) { + fprintf(stderr, "%s: ", dumpfile); + perror("fwrite"); + goto err_close; + } + + if(fclose(f)) { + fprintf(stderr, "%s: ", dumpfile); + perror("fclose"); + return -1; + } + + return 0; + + err_close: + fclose(f); + return -1; } diff --git a/src/util.h b/src/util.h index 894bd2f..3effd0c 100644 --- a/src/util.h +++ b/src/util.h @@ -1,3 +1,4 @@ + /* * This file is part of the dmidecode project. * @@ -24,6 +25,6 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) -int checksum(const u8 *buf, size_t len); +int checksum(const u8 * buf, size_t len); void *mem_chunk(size_t base, size_t len, const char *devmem); int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add); -- cgit From 1da04aa097db78c7474877049334c2c07b33bda1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Apr 2009 19:26:56 +0200 Subject: Added dmixml.[ch] - helper function for generating XML nodes --- src/dmixml.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dmixml.h | 32 ++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 src/dmixml.c create mode 100644 src/dmixml.h (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c new file mode 100644 index 0000000..434b2e7 --- /dev/null +++ b/src/dmixml.c @@ -0,0 +1,140 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#include +#include +#include + +#include +#include + +// Internal function for dmixml_* functions ... builds up a variable xmlChar* string +xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) { + xmlChar *ret = NULL, *xmlfmt = NULL; + + ret = (xmlChar *) malloc(len+2); + assert( ret != NULL ); + memset(ret, 0, len+2); + + xmlfmt = xmlCharStrdup(fmt); + assert( xmlfmt != NULL ); + + xmlStrVPrintf(ret, len, xmlfmt, ap); + free(xmlfmt); + + return ret; +} + + +// Adds an XML property/attribute to the given XML node +// +// xmldata_n = ""; +// dmixml_AddAttribute(xmldata_n, "value", "1234"); +// gives: xmldata_n = " + +xmlAttrNode *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); +xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); +xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); + +#endif -- cgit From 2ed8a0e7cb6cbdeec1c1c49e7aedf03188e72017 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Apr 2009 19:27:30 +0200 Subject: Modified setup.py to compile in dmixml.c and link against libxml2 --- src/setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/setup.py b/src/setup.py index b0999b5..6272e85 100644 --- a/src/setup.py +++ b/src/setup.py @@ -15,10 +15,12 @@ setup( "src/dmihelper.c", "src/util.c", "src/dmioem.c", - "src/dmidecode.c" + "src/dmidecode.c", + "src/dmixml.c" ], + include_dirs = [ "/usr/include/libxml2" ], library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], - libraries = [ "util" ], + libraries = [ "util", "xml2" ], #libraries = [ "util", "efence" ], ) ] -- cgit From a35afd0190f6a6925aa134ac43d2653aaf018ff8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 3 Apr 2009 14:50:02 +0200 Subject: Fixed wrong xmlAttrNode type to xmlAttr --- src/dmixml.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmixml.h b/src/dmixml.h index d7d2716..7d8c4ad 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -24,8 +24,9 @@ #define _XMLHELPER_H #include +#include -xmlAttrNode *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); +xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); -- cgit From 0cdb1cbffae8237635b991993ee4467e2753dafa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 7 Apr 2009 09:27:47 +0200 Subject: Checked in a work in progress - Python dict -> XML Does not compile yet --- src/dmidecode.c | 2364 +++++++++++++++++++++++++++++-------------------------- src/dmidecode.h | 8 +- 2 files changed, 1248 insertions(+), 1124 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index d687c81..907fe57 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -70,11 +70,13 @@ #include #include #include +#include #include "version.h" #include "config.h" #include "types.h" #include "util.h" +#include "dmixml.h" #include "dmidecode.h" #include "dmioem.h" @@ -151,54 +153,75 @@ const char *dmi_string(const struct dmi_header *dm, u8 s) return bp; } -static const char *dmi_smbios_structure_type(u8 code) +xmlNode *dmi_smbios_structure_type(xmlNode *node, u8 code) { - static const char *type[] = { - "BIOS", /* 0 */ - "System", - "Base Board", - "Chassis", - "Processor", - "Memory Controller", - "Memory Module", - "Cache", - "Port Connector", - "System Slots", - "On Board Devices", - "OEM Strings", - "System Configuration Options", - "BIOS Language", - "Group Associations", - "System Event Log", - "Physical Memory Array", - "Memory Device", - "32-bit Memory Error", - "Memory Array Mapped Address", - "Memory Device Mapped Address", - "Built-in Pointing Device", - "Portable Battery", - "System Reset", - "Hardware Security", - "System Power Controls", - "Voltage Probe", - "Cooling Device", - "Temperature Probe", - "Electrical Current Probe", - "Out-of-band Remote Access", - "Boot Integrity Services", - "System Boot", - "64-bit Memory Error", - "Management Device", - "Management Device Component", - "Management Device Threshold Data", - "Memory Channel", - "IPMI Device", - "Power Supply" /* 39 */ + static struct { + const char *descr; + const char *tagname; + const char *attrname; + const char *attrvalue; + } types[] = { + /* *INDENT-OFF* */ + {"BIOS", "BIOS", NULL, NULL}, /* 0 */ + {"System", "System", NULL, NULL}, + {"Base Board", "BaseBoard", NULL, NULL}, + {"Chassis", "Chassis", NULL, NULL}, + {"Processor", "Processor", NULL, NULL}, + {"Memory Controller", "Memory", "type", "controller"}, + {"Memory Module", "Memory", "type", "module"}, + {"Cache", "Cache", NULL, NULL}, + {"Port Connector", "PortConnectors", NULL, NULL}, + {"System Slots", "Slots", NULL, NULL}, + {"On Board Devices", "OnBoardDevices", NULL, NULL}, + {"OEM Strings", "OEMstrings", NULL, NULL}, + {"System Configuration Options", "SysConfigOpts", NULL, NULL}, + {"BIOS Language", "BIOS", "type", "language"}, + {"Group Associations", "GroupAssociations", NULL, NULL}, + {"System Event Log", "EventLog", NULL, NULL}, + {"Physical Memory Array", "PhysicalMemoryArray", NULL, NULL}, + {"Memory Device", "Memory", "type", "device"}, + {"32-bit Memory Error", "MemoryError", "bit", "32"}, + {"Memory Array Mapped Address", "MemoryAddressMap", "type", "MemoryArray"}, + {"Memory Device Mapped Address", "MemoryAddressMap", "type", "Device"}, + {"Built-in Pointing Device", "BuiltinPointingDevice",NULL, NULL}, + {"Portable Battery", "PortableBattery", NULL, NULL}, + {"System Reset", "SystemReset", NULL, NULL}, + {"Hardware Security", "HWsecurity", NULL, NULL}, + {"System Power Controls", "SysPowerCtrl", NULL, NULL}, + {"Voltage Probe", "Probe", "type", "Voltage"}, + {"Cooling Device", "CoolingDevice", NULL, NULL}, + {"Temperature Probe", "Probe", "type", "Temperature"}, + {"Electrical Current Probe", "Probe", "type", "ElectricalCurrent"}, + {"Out-of-band Remote Access", "RemoteAccess", NULL, NULL}, + {"Boot Integrity Services", "BootIntegritySrv", NULL, NULL}, + {"System Boot", "SystemBoot", NULL, NULL}, + {"64-bit Memory Error", "MemoryError", "bit", "64"}, + {"Management Device", "ManagementDevice", NULL, NULL}, + {"Management Device Component", "ManagementDevice", "type", "component"}, + {"Management Device Threshold Data","ManagementDevice", "type", "Threshold Data"}, + {"Memory Channel", "MemoryChannel", NULL, NULL}, + {"IPMI Device", "IPMIdevice", NULL, NULL}, + {"Power Supply", "PowerSupply", NULL, NULL} /* 39 */ + /* *INDENT-ON* */ }; + xmlNode *type_n = NULL; + + if(code <= 39) { + type_n = xmlNewChild(node, NULL, (xmlChar *)types[code].tagname, NULL); + assert( type_n != NULL ); + + dmixml_AddAttribute(type_n, "flags", "0x%04x", code); + dmixml_AddTextChild(type_n, "Description", "%s", types[code].descr); - if(code <= 39) - return (type[code]); - return out_of_spec; + if( (types[code].attrname != NULL) && (types[code].attrvalue != NULL) ) { + dmixml_AddAttribute(type_n, types[code].attrname, "%s", types[code].attrvalue); + } + } else { + type_n = xmlNewChild(node, NULL, (xmlChar *) "UnknownSMBiosType", NULL); + dmixml_AddAttribute(type_n, "flags", "0x%04x", code); + } + + return type_n; } static int dmi_bcd_range(u8 value, u8 low, u8 high) @@ -262,7 +285,7 @@ static PyObject *dmi_bios_runtime_size(u32 code) } /* 3.3.1.1 */ -static PyObject *dmi_bios_characteristics(u64 code) +void dmi_bios_characteristics(xmlNode *node, u64 code) { static const char *characteristics[] = { "BIOS characteristics not supported", /* 3 */ @@ -295,25 +318,28 @@ static PyObject *dmi_bios_characteristics(u64 code) "CGA/mono video services are supported (int 10h)", "NEC PC-98" /* 31 */ }; - - PyObject *data; + dmixml_AddAttribute(node, "dmispec", "3.3.1.1"); + dmixml_AddAttribute(node, "flags", "0x%04x", code); if(code.l & (1 << 3)) { - data = PyString_FromString(characteristics[0]); + dmixml_AddAttribute(node, "unavailable", "1"); + dmixml_AddTextContent(node, characteristics[0]); } else { - int i; + int i = 0; + xmlNode *flags_n = xmlNewChild(node, NULL, (xmlChar *) "flags", NULL); + assert( flags_n != NULL ); - data = PyDict_New(); for(i = 4; i <= 31; i++) - PyDict_SetItemString(data, characteristics[i - 3], - code.l & (1 << i) ? Py_True : Py_False); + if( code.l & (1 << i) ) { + dmixml_AddTextChild(flags_n, "flag", characteristics[i - 3]); + } } - return data; } /* 3.3.1.2.1 */ -static PyObject *dmi_bios_characteristics_x1(u8 code) +void dmi_bios_characteristics_x1(xmlNode *node, u8 code) { + int i = 0; static const char *characteristics[] = { "ACPI", /* 0 */ "USB legacy", @@ -325,42 +351,45 @@ static PyObject *dmi_bios_characteristics_x1(u8 code) "Smart battery" /* 7 */ }; - int i; - PyObject *data = PyDict_New(); - - for(i = 0; i <= 7; i++) - PyDict_SetItemString(data, characteristics[i], - code & (1 << i) ? Py_True : Py_False); - return data; + dmixml_AddAttribute(node, "dmispec", "3.3.1.2.1"); + dmixml_AddAttribute(node, "flags", "0x%04x", code); + for(i = 0; i <= 7; i++) { + if( code.l & (1 << i) ) { + dmixml_AddTextChild(node, "characteristic", characteristics[i]); + } + } } /* 3.3.1.2.2 */ -static PyObject *dmi_bios_characteristics_x2(u8 code) +void dmi_bios_characteristics_x2(xmlNode *node, u8 code) { + int i = 0; static const char *characteristics[] = { "BIOS boot specification", /* 0 */ "Function key-initiated network boot", "Targeted content distribution" /* 2 */ }; - int i; - PyObject *data = PyDict_New(); + dmixml_AddAttribute(node, "dmispec", "3.3.1.2.2"); + dmixml_AddAttribute(node, "flags", "0x%04x", code); - for(i = 0; i <= 2; i++) - PyDict_SetItemString(data, characteristics[i], - code & (1 << i) ? Py_True : Py_False); - return data; + for(i = 0; i <= 2; i++) { + if( code.l & (1 << i) ) { + dmixml_AddTextChild(node, "characteristic", characteristics[i]); + } + } } /******************************************************************************* ** 3.3.2 System Information (Type 1) */ -PyObject *dmi_system_uuid_py(const u8 * p, u16 ver) +void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver) { int only0xFF = 1, only0x00 = 1; int i; + xmlNode *uuid_n = NULL; for(i = 0; i < 16 && (only0x00 || only0xFF); i++) { if(p[i] != 0x00) @@ -369,11 +398,20 @@ PyObject *dmi_system_uuid_py(const u8 * p, u16 ver) only0xFF = 0; } - if(only0xFF) - return PyString_FromString("Not Present"); + uuid_n = xmlNewChild(node, NULL, (xmlChar *) "SystemUUID", NULL); + dmixml_AddAttribute(uuid_n, "dmispec", "3.3.2"); + + if(only0xFF ) { + dmixml_AddAttribute(uuid_n, "unavailable", "1"); + dmixml_AddTextContent(uuid_n, "Not Present"); + return; + } - if(only0x00) - return PyString_FromString("Not Settable"); + if(only0x00){ + dmixml_AddAttribute(uuid_n, "unavailable", "1"); + dmixml_AddTextContent(uuid_n,"Not Settable"); + return; + } /* * As off version 2.6 of the SMBIOS specification, the first 3 @@ -383,24 +421,21 @@ PyObject *dmi_system_uuid_py(const u8 * p, u16 ver) * network byte order, so I am reluctant to apply the byte-swapping * for older versions. */ - if(ver >= 0x0206) - return - PyString_FromFormat - ("%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", p[3], - p[2], p[1], p[0], p[5], p[4], p[7], p[6], p[8], p[9], p[10], p[11], p[12], - p[13], p[14], p[15] - ); - else - return - PyString_FromFormat - ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p[0], - p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], - p[13], p[14], p[15] - ); + if(ver >= 0x0206) { + dmixml_AddTextContent(uuid_n, + "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], p[8], p[9], p[10], + p[11], p[12], p[13], p[14], p[15]); + } else { + dmixml_AddTextContent(uuid_n, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], + p[11], p[12], p[13], p[14], p[15]); + } } /* 3.3.2.1 */ -static PyObject *dmi_system_wake_up_type(u8 code) +void dmi_system_wake_up_type(xmlNode *node, u8 code) { static const char *type[] = { "Reserved", /* 0x00 */ @@ -413,10 +448,16 @@ static PyObject *dmi_system_wake_up_type(u8 code) "PCI PME#", "AC Power Restored" /* 0x08 */ }; + xmlNode *swut_n = xmlNewChild(node, NULL, (xmlChar *) "SystemWakeUpType", NULL); + assert( swut_n != NULL ); + dmixml_AddAttribute(swut_n, "dmispec", "3.3.2.1"); + dmixml_AddAttribute(swut_n, "flags", "0x%04x", code); - if(code <= 0x08) - return PyString_FromString(type[code]); - return OUT_OF_SPEC; + if(code <= 0x08) { + dmixml_AddTextContent(swut_n, type[code]); + } else { + dmixml_AddAttribute(swut_n, "outofspec", "1"); + } } /******************************************************************************* @@ -424,7 +465,7 @@ static PyObject *dmi_system_wake_up_type(u8 code) */ /* 3.3.3.1 */ -static PyObject *dmi_base_board_features(u8 code) +void dmi_base_board_features(xmlNode *node, u8 code) { static const char *features[] = { "Board is a hosting board", /* 0 */ @@ -434,25 +475,25 @@ static PyObject *dmi_base_board_features(u8 code) "Board is hot swappable" /* 4 */ }; - PyObject *data; + xmlNode *feat_n = xmlNewChild(node, NULL, (xmlChar *) "Features", NULL); + assert( feat_n != NULL ); + dmixml_AddAttribute(feat_n, "dmispec", "3.3.3.1"); + dmixml_AddAttribute(feat_n, "flags", "0x%04x", code); - if((code & 0x1F) == 0) - data = Py_None; - else { + if((code & 0x1F) != 0) { int i; - data = PyList_New(5); for(i = 0; i <= 4; i++) { - if(code & (1 << i)) - PyList_SET_ITEM(data, i, PyString_FromString(features[i])); - else - PyList_SET_ITEM(data, i, Py_None); + if(code & (1 << i)) { + dmixml_AddTextChild(feat_n, "feature", features[i]); + } } + } else { + dmixml_AddAttribute(feat_n, "unavailable", "1"); } - return data; } -static PyObject *dmi_base_board_type(u8 code) +void dmi_base_board_type(xmlNode *node, const char *tagname, u8 code) { /* 3.3.3.2 */ static const char *type[] = { @@ -470,26 +511,33 @@ static PyObject *dmi_base_board_type(u8 code) "Processor+I/O Module", "Interconnect Board" /* 0x0D */ }; + xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( type_n != NULL ); + dmixml_AddAttribute(type_n, "dmispec", "3.3.3.2"); + dmixml_AddAttribute(type_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0D) - return PyString_FromString(type[code - 0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x0D) { + dmixml_AddTextContent(type_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(type_n, "unavailable", "1"); + } } -static PyObject *dmi_base_board_handles(u8 count, const u8 * p) +void dmi_base_board_handles(xmlNode *node, u8 count, const u8 * p) { int i; + xmlNode *dict_n = NULL; - PyObject *dict = PyDict_New(); - PyObject *list = PyList_New(count); - - for(i = 0; i < count; i++) - PyList_SET_ITEM(list, i, PyString_FromFormat("0x%04x", WORD(p + sizeof(u16) * i))); + dict_n = xmlNewChild(node, NULL, (xmlChar *) "ContainedObjectHandles", NULL); + assert( dict_n != NULL ); - PyDict_SetItemString(dict, "Contained Object Handles", list); - Py_DECREF(list); + dmixml_AddAttribute(dict_n, "count", "%i", count); - return dict; + for(i = 0; i < count; i++) { + xmlNode *elmt_n = xmlNewChild(dict_n, NULL, (xmlChar *) "Handle", NULL); + assert( elmt_n != NULL ); + dmixml_AddTextContent(elmt_n, "0x%04x", WORD(p + sizeof(u16) * i)); + } } /******************************************************************************* @@ -497,7 +545,7 @@ static PyObject *dmi_base_board_handles(u8 count, const u8 * p) */ /* 3.3.4.1 */ -const char *dmi_chassis_type(u8 code) +void dmi_chassis_type(xmlNode *node, u8 code) { static const char *type[] = { "Other", /* 0x01 */ @@ -530,29 +578,34 @@ const char *dmi_chassis_type(u8 code) "Blade", "Blade Enclosing" /* 0x1D */ }; - - if(code >= 0x01 && code <= 0x1B) - return type[code - 0x01]; - return out_of_spec; -} - -static PyObject *dmi_chassis_type_py(u8 code) -{ - return PyString_FromString(dmi_chassis_type(code)); + xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *)"ChassisType", NULL); + assert( type_n != NULL ); + dmixml_AddAttribute(type_n, "dmispec", "3.3.4.1"); + dmixml_AddAttribute(type_n, "flags", "0x%04x", code); + + if(code >= 0x01 && code <= 0x1B) { + dmixml_AddAttribute(type_n, "available", "1"); + dmixml_AddTextContent(type_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(type_n, "available", "0"); + } } -static PyObject *dmi_chassis_lock(u8 code) +void dmi_chassis_lock(xmlNode *node, u8 code) { static const char *lock[] = { "Not Present", /* 0x00 */ "Present" /* 0x01 */ }; - - return PyString_FromString(lock[code]); + xmlNode *lock_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisLock", NULL); + assert( lock_n != NULL ); + dmixml_AddAttribute(lock_n, "dmispec", "3.3.4"); + dmixml_AddAttribute(lock_n, "flags", "0x%04x", code); + dmixml_AddTextContent(lock_n, "%s", lock[code]); } /* 3.3.4.2 */ -static PyObject *dmi_chassis_state(u8 code) +void dmi_chassis_state(xmlNode *node, const char *tagname, u8 code) { static const char *state[] = { "Other", /* 0x01 */ @@ -562,14 +615,20 @@ static PyObject *dmi_chassis_state(u8 code) "Critical", "Non-recoverable" /* 0x06 */ }; + xmlNode *state_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( state_n != NULL ); + dmixml_AddAttribute(state_n, "dmispec", "3.3.4.2"); + dmixml_AddAttribute(state_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x06) - return PyString_FromString(state[code - 0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x06) { + dmixml_AddTextContent(state_n, "%s", state[code - 0x01]); + } else { + dmixml_AddAttribute(state_n, "unavailable", "1"); + } } /* 3.3.4.3 */ -static const char *dmi_chassis_security_status(u8 code) +void dmi_chassis_security_status(xmlNode *node, u8 code) { static const char *status[] = { "Other", /* 0x01 */ @@ -578,68 +637,77 @@ static const char *dmi_chassis_security_status(u8 code) "External Interface Locked Out", "External Interface Enabled" /* 0x05 */ }; + xmlNode *secstat_n = xmlNewChild(node, NULL, (xmlChar *) "SecurityStatus", NULL); + assert( secstat_n != NULL ); + dmixml_AddAttribute(secstat_n, "dmispec", "3.3.4.3"); + dmixml_AddAttribute(secstat_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x05) - return (status[code - 0x01]); - return out_of_spec; + if(code >= 0x01 && code <= 0x05) { + dmixml_AddTextContent(secstat_n, "%s", status[code - 0x01]); + } else { + dmixml_AddAttribute(secstat_n, "unavailable", "1"); + } } -static PyObject *dmi_chassis_height(u8 code) +void dmi_chassis_height(xmlNode *node, u8 code) { - if(code == 0x00) - return PyString_FromString("Unspecified"); - else - return PyString_FromFormat("%i U", code); + xmlNode *hght_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisHeight", NULL); + assert( hght_n != NULL ); + + if(code == 0x00) { + dmixml_AddAttribute(hght_n, "unspecified", "1"); + } else { + dmixml_AddAttribute(hght_n, "unit", "U"); + dmixml_AddTextContent(hght_n, "%i", code); + } } -static PyObject *dmi_chassis_power_cords(u8 code) +void dmi_chassis_power_cords(xmlNode *node, u8 code) { - if(code == 0x00) - return PyString_FromString("Unspecified"); - else - return PyString_FromFormat("%i", code); + xmlNode *pwrc_n = xmlNewChild(node, NULL, (xmlChar *) "PowerCords", NULL); + assert( pwrc_n != NULL ); + + if(code == 0x00) { + dmixml_AddAttribute(pwrc_n, "unspecified", "1"); + } else { + dmixml_AddTextContent(pwrc_n, "%i", code); + } } -static PyObject *dmi_chassis_elements(u8 count, u8 len, const u8 * p) +void dmi_chassis_elements(xmlNode *node, u8 count, u8 len, const u8 * p) { int i; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisElements", NULL); + assert( data_n != NULL ); - PyObject *data = PyDict_New(); - - PyDict_SetItemString(data, "Contained Elements", PyInt_FromLong(count)); - - PyObject *_key, *_val; + dmixml_AddAttribute(data_n, "count", "%i", count); for(i = 0; i < count; i++) { if(len >= 0x03) { + xmlNode *key_n = NULL; - _key = PyString_FromFormat("%s", - p[i * len] & 0x80 ? - dmi_smbios_structure_type(p[i * len] & 0x7F) : - PyString_AS_STRING(dmi_base_board_type - (p[i * len] & 0x7F)) - ); - - if(p[1 + i * len] == p[2 + i * len]) - _val = PyString_FromFormat("%i", p[1 + i * len]); - else - _val = PyString_FromFormat("%i-%i", p[1 + i * len], p[2 + i * len]); - - PyDict_SetItem(data, _key, _val); + if( p[i * len] & 0x80 ) { + key_n = dmi_smbios_structure_type(data_n, p[i * len] & 0x7F); + } else { + key_n = xmlNewChild(data_n, NULL, (xmlChar *) "BaseboardElement", NULL); + dmi_base_board_type(key_n, "Description", p[i * len] & 0x7F); + } + assert( key_n != NULL ); - Py_DECREF(_key); - Py_DECREF(_val); + if(p[1 + i * len] == p[2 + i * len]) { + dmixml_AddTextChild(key_n, "Value", "%i", p[1 + i * len]); + } else { + dmixml_AddTextChild(key_n, "Value", "%i-%i", p[1 + i * len], p[2 + i * len]); + } } } - - return data; } /******************************************************************************* ** 3.3.5 Processor Information (Type 4) */ -static PyObject *dmi_processor_type(u8 code) +void dmi_processor_type(xmlNode *node, u8 code) { /* 3.3.5.1 */ static const char *type[] = { @@ -650,13 +718,18 @@ static PyObject *dmi_processor_type(u8 code) "DSP Processor", "Video Processor" /* 0x06 */ }; - - if(code >= 0x01 && code <= 0x06) - return PyString_FromString(type[code - 0x01]); - return OUT_OF_SPEC; + xmlNode *proct_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( proct_n != NULL ); + dmixml_AddAttribute(proct_n, "dmispec", "3.3.5"); + dmixml_AddAttribute(proct_n, "flags", "0x%04x", code); + if(code >= 0x01 && code <= 0x06) { + dmixml_AddTextContent(proct_n, type[code - 0x01]); + } else { + dmixml_AddAttribute(proct_n, "outofspec", "1"); + } } -static const char *dmi_processor_family(const struct dmi_header *h) +void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { const u8 *data = h->data; unsigned int i, low, high; @@ -847,19 +920,32 @@ static const char *dmi_processor_family(const struct dmi_header *h) * return family2[i].name; */ + xmlNode *family_n = xmlNewChild(node, NULL, (xmlChar *) "Family", NULL); + assert( family_n != NULL ); + dmixml_AddAttribute(family_n, "dmispec", "3.3.3.5"); + code = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06]; + dmixml_AddAttribute(family_n, "flags", "0x%04x", code); + /* Special case for ambiguous value 0xBE */ if(code == 0xBE) { const char *manufacturer = dmi_string(h, data[0x07]); /* Best bet based on manufacturer string */ if(strstr(manufacturer, "Intel") != NULL || - strncasecmp(manufacturer, "Intel", 5) == 0) - return "Core 2"; - if(strstr(manufacturer, "AMD") != NULL || strncasecmp(manufacturer, "AMD", 3) == 0) - return "K7"; - return "Core 2 or K7"; + strncasecmp(manufacturer, "Intel", 5) == 0) { + dmixml_AddTextContent(family_n, "Core 2"); + return; + } + + if(strstr(manufacturer, "AMD") != NULL + || strncasecmp(manufacturer, "AMD", 3) == 0) { + dmixml_AddTextContent(family_n, "K7"); + return; + } + dmixml_AddTextContent(family_n, "Core 2 or K7"); + return; } /* Perform a binary search */ @@ -867,58 +953,73 @@ static const char *dmi_processor_family(const struct dmi_header *h) high = ARRAY_SIZE(family2) - 1; while(1) { i = (low + high) / 2; - if(family2[i].value == code) - return family2[i].name; - if(low == high) /* Not found */ - return out_of_spec; + if(family2[i].value == code) { + dmixml_AddTextContent(family_n, family2[i].name); + return; + } + + if(low == high) { /* Not found */ + dmixml_AddAttribute(family_n, "outofspec", "1"); + return; + } + if(code < family2[i].value) high = i; else low = i + 1; } - return out_of_spec; + dmixml_AddAttribute(family_n, "outofspec", "1"); } -static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) +xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *version) { - PyObject *data = PyDict_New(); - /* Intel AP-485 revision 31, table 3-4 */ - static const char *flags[32] = { - "FPU (Floating-point unit on-chip)", /* 0 */ - "VME (Virtual mode extension)", - "DE (Debugging extension)", - "PSE (Page size extension)", - "TSC (Time stamp counter)", - "MSR (Model specific registers)", - "PAE (Physical address extension)", - "MCE (Machine check exception)", - "CX8 (CMPXCHG8 instruction supported)", - "APIC (On-chip APIC hardware supported)", - NULL, /* 10 */ - "SEP (Fast system call)", - "MTRR (Memory type range registers)", - "PGE (Page global enable)", - "MCA (Machine check architecture)", - "CMOV (Conditional move instruction supported)", - "PAT (Page attribute table)", - "PSE-36 (36-bit page size extension)", - "PSN (Processor serial number present and enabled)", - "CLFSH (CLFLUSH instruction supported)", - NULL, /* 20 */ - "DS (Debug store)", - "ACPI (ACPI supported)", - "MMX (MMX technology supported)", - "FXSR (Fast floating-point save and restore)", - "SSE (Streaming SIMD extensions)", - "SSE2 (Streaming SIMD extensions 2)", - "SS (Self-snoop)", - "HTT (Hyper-threading technology)", - "TM (Thermal monitor supported)", - "IA64 (IA64 capabilities)", - "PBE (Pending break enabled)" /* 31 */ + static struct _cpuflags { + const char *flag; + const char *descr; + } flags[] = { + /* *INDENT-OFF* */ + {"FPU", "Floating-point unit on-chip"}, /* 0 */ + {"VME", "Virtual mode extension"}, + {"DE", "Debugging extension"}, + {"PSE", "Page size extension"}, + {"TSC", "Time stamp counter"}, + {"MSR", "Model specific registers"}, + {"PAE", "Physical address extension"}, + {"MCE", "Machine check exception"}, + {"CX8", "CMPXCHG8 instruction supported"}, + {"APIC", "On-chip APIC hardware supported"}, + {NULL, NULL}, /* 10 */ + {"SEP", "Fast system call"}, + {"MTRR", "Memory type range registers"}, + {"PGE", "Page global enable"}, + {"MCA", "Machine check architecture"}, + {"CMOV", "Conditional move instruction supported"}, + {"PAT", "Page attribute table"}, + {"PSE-36", "36-bit page size extension"}, + {"PSN", "Processor serial number present and enabled"}, + {"CLFSH", "CLFLUSH instruction supported"}, + {NULL, NULL }, /* 20 */ + {"DS", "Debug store"}, + {"ACPI", "ACPI supported"}, + {"MMX", "MMX technology supported"}, + {"FXSR", "Fast floating-point save and restore"}, + {"SSE", "Streaming SIMD extensions"}, + {"SSE2", "Streaming SIMD extensions 2"}, + {"SS", "Self-snoop"}, + {"HTT", "Hyper-threading technology"}, + {"TM", "Thermal monitor supported"}, + {"IA64", "IA64 capabilities"}, + {"PBE", "Pending break enabled"} /* 31 */ + /* *INDENT-ON* */ }; + + xmlNode *flags_n = NULL; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CPUCore", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.5"); + /* ** Extra flags are now returned in the ECX register when one calls ** the CPUID instruction. Their meaning is explained in table 3-5, but @@ -933,11 +1034,9 @@ static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) */ //. TODO: PyString_FromFormat does not support %x (yet?)... - PyDict_SetItemString(data, "ID", - PyString_FromFormat("%02x %02x %02x %02x %02x %02x %02x %02x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] - ) - ); + dmixml_AddTextChild(data_n, "ID", + "%02x %02x %02x %02x %02x %02x %02x %02x", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); if(type == 0x05) { /* 80386 */ u16 dx = WORD(p); @@ -945,12 +1044,10 @@ static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) /* ** 80386 have a different signature. */ - PyDict_SetItemString(data, "Signature", - PyString_FromFormat - ("Type %i, Family %i, Major Stepping %i, Minor Stepping %i", - dx >> 12, (dx >> 8) & 0xF, (dx >> 4) & 0xF, dx & 0xF) - ); - return data; + dmixml_AddTextChild(data_n, "Signature", + "Type %i, Family %i, Major Stepping %i, Minor Stepping %i", + dx >> 12, (dx >> 8) & 0xF, (dx >> 4) & 0xF, dx & 0xF); + return data_n; } if(type == 0x06) { /* 80486 */ @@ -961,17 +1058,16 @@ static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) ** wether the one we have here does or not. Note that this trick ** works only because we know that 80486 must be little-endian. */ - if((dx & 0x0F00) == 0x0400 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070) - && ((dx & 0x000F) >= 0x0003)) + if( (dx & 0x0F00) == 0x0400 + && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070) + && ((dx & 0x000F) >= 0x0003) ) { sig = 1; - else { - PyDict_SetItemString(data, "Signature", - PyString_FromFormat - ("Type %i, Family %i, Model %i, Stepping %i", - (dx >> 12) & 0x3, (dx >> 8) & 0xF, (dx >> 4) & 0xF, - dx & 0xF) - ); - return data; + } else { + dmixml_AddTextChild(data_n, "Signature", + "Type %i, Family %i, Model %i, Stepping %i", + (dx >> 12) & 0x3, (dx >> 8) & 0xF, (dx >> 4) & 0xF, + dx & 0xF); + return data_n; } } else if((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */ ||(type >= 0x28 && type <= 0x2B) /* Intel */ @@ -980,16 +1076,20 @@ static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) ||type == 0xB5 /* Intel */ || (type >= 0xB9 && type <= 0xC5) /* Intel */ ||(type >= 0xD2 && type <= 0xD5) /* VIA */ - ) + ) { + sig = 1; - else if((type >= 0x18 && type <= 0x1D) /* AMD */ + + } else if((type >= 0x18 && type <= 0x1D) /* AMD */ ||type == 0x1F /* AMD */ || (type >= 0x83 && type <= 0x8F) /* AMD */ ||(type >= 0xB6 && type <= 0xB7) /* AMD */ ||(type >= 0xE6 && type <= 0xEB) /* AMD */ - ) + ) { + sig = 2; - else if(type == 0x01 || type == 0x02) { + + } else if(type == 0x01 || type == 0x02) { /* ** Some X86-class CPU have family "Other" or "Unknown". In this case, ** we use the version string to determine if they are known to @@ -998,82 +1098,87 @@ static PyObject *dmi_processor_id(u8 type, const u8 * p, const char *version) if(strncmp(version, "Pentium III MMX", 15) == 0 || strncmp(version, "Intel(R) Core(TM)2", 18) == 0 || strncmp(version, "Intel(R) Pentium(R)", 19) == 0 - || strcmp(version, "Genuine Intel(R) CPU U1400") == 0) + || strcmp(version, "Genuine Intel(R) CPU U1400") == 0 + ) { + sig = 1; - else if(strncmp(version, "AMD Athlon(TM)", 14) == 0 - || strncmp(version, "AMD Opteron(tm)", 15) == 0 - || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0) + + } else if(strncmp(version, "AMD Athlon(TM)", 14) == 0 + || strncmp(version, "AMD Opteron(tm)", 15) == 0 + || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0) { + sig = 2; - else - return data; - } else /* not X86-class */ - return data; + + } else { + return data_n; + } + } else { /* not X86-class */ + return data_n; + } eax = DWORD(p); edx = DWORD(p + 4); switch (sig) { case 1: /* Intel */ - PyDict_SetItemString(data, "Signature", - PyString_FromFormat - ("Type %i, Family %i, Model %i, Stepping %i", - (eax >> 12) & 0x3, ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F), - ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), eax & 0xF) - ); + dmixml_AddTextChild(data_n, "Signature", + "Type %i, Family %i, Model %i, Stepping %i", + (eax >> 12) & 0x3, ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F), + ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), eax & 0xF); break; case 2: /* AMD, publication #25481 revision 2.28 */ - PyDict_SetItemString(data, "Signature", - PyString_FromFormat("Family %i, Model %i, Stepping %i", - ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == - 0xF ? (eax >> 20) & - 0xFF : 0), - ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == - 0xF ? (eax >> 12) & - 0xF0 : 0), eax & 0xF) - ); + dmixml_AddTextChild(data_n, "Signature", + "Family %i, Model %i, Stepping %i", + ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF + ? (eax >> 20) & 0xFF : 0), + ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF + ? (eax >> 12) & 0xF0 : 0), + eax & 0xF); break; } edx = DWORD(p + 4); - if((edx & 0xFFEFFBFF) == 0) - PyDict_SetItemString(data, "Flags", Py_None); - else { + flags_n = xmlNewChild(data_n, NULL, (xmlChar *) "cpu_flags", NULL); + if((edx & 0xFFEFFBFF) != 0) { int i; - PyObject *subdata = PyDict_New(); - for(i = 0; i <= 31; i++) - if(flags[i] != NULL) - PyDict_SetItemString(subdata, flags[i], - (edx & (1 << i)) ? Py_True : Py_False); - PyDict_SetItemString(data, "Flags", subdata); - Py_DECREF(subdata); + for(i = 0; i <= 31; i++) { + // Only add those flags which are present + if( (flags[i].flag != NULL) && (edx & (1 << i)) ) { + xmlNode *flg_n = dmixml_AddTextChild(flags_n, "flag", "%s", flags[i].descr); + dmixml_AddAttribute(flg_n, "flag", "%s", flags[i].flag); + } + } } - - return data; + return data_n; } /* 3.3.5.4 */ -static PyObject *dmi_processor_voltage(u8 code) +void dmi_processor_voltage(xmlNode *node, u8 code) { static const char *voltage[] = { - "5.0 V", /* 0 */ - "3.3 V", - "2.9 V" /* 2 */ + "5.0", /* 0 */ + "3.3", + "2.9" /* 2 */ }; int i; - - PyObject *data; - - if(code & 0x80) - data = PyString_FromFormat("%.1f V", (float)(code & 0x7f) / 10); - else { - data = PyDict_New(); - for(i = 0; i <= 2; i++) - PyDict_SetItemString(data, voltage[i], - (code & (1 << i) ? Py_True : Py_False)); - if(code == 0x00) - PyDict_SetItemString(data, "VOLTAGE", PyString_FromString("Unknown")); + xmlNode *vltg_n = xmlNewChild(node, NULL, (xmlChar *) "Voltages", NULL); + assert( vltg_n != NULL ); + dmixml_AddAttribute(vltg_n, "dmispec", "3.3.5.4"); + dmixml_AddAttribute(vltg_n, "flags", "0x%04x", code); + + if(code & 0x80) { + dmixml_AddTextChild(vltg_n, "Voltage", "%.1f", (float)(code & 0x7f) / 10); + dmixml_AddAttribute(vltg_n, "unit", "V"); + } else if( code == 0x00 ) { + dmixml_AddAttribute(vltg_n, "unknown_value", "1"); + } else { + for(i = 0; i <= 2; i++) { + if( code & (1 << i) ) { + xmlNode *v_n = dmixml_AddTextChild(vltg_n, "Voltage", "%s", voltage[i]); + dmixml_AddAttribute(v_n, "unit", "V"); + } + } } - return data; } int dmi_processor_frequency(const u8 * p) @@ -1085,12 +1190,8 @@ int dmi_processor_frequency(const u8 * p) else return -1; //. Unknown } -static PyObject *dmi_processor_frequency_py(const u8 * p) -{ - return PyInt_FromLong(dmi_processor_frequency(p)); -} -static const char *dmi_processor_status(u8 code) +void dmi_processor_status(xmlNode *node, u8 code) { static const char *status[] = { "Unknown", /* 0x00 */ @@ -1100,15 +1201,21 @@ static const char *dmi_processor_status(u8 code) "Idle", /* 0x04 */ "Other" /* 0x07 */ }; + xmlNode *prst_n = xmlNewChild(node, NULL, (xmlChar *) "Populated", NULL); + assert( prst_n != NULL ); - if(code <= 0x04) - return status[code]; - if(code == 0x07) - return status[0x05]; - return out_of_spec; + dmixml_AddAttribute(prst_n, "flags", "0x%04x", code); + + if(code <= 0x04) { + dmixml_AddTextContent(prst_n, "%s", status[code]); + } else if( code == 0x07 ) { + dmixml_AddTextContent(prst_n, "%s", status[5]); + } else { + dmixml_AddAttribute(prst_n, "outofspec", "1"); + } } -static PyObject *dmi_processor_upgrade(u8 code) +void dmi_processor_upgrade(xmlNode *node, u8 code) { /* 3.3.5.5 */ static const char *upgrade[] = { @@ -1137,54 +1244,69 @@ static PyObject *dmi_processor_upgrade(u8 code) "Socket AM2", "Socket F (1207)" /* 0x18 */ }; + xmlNode *upgr_n = xmlNewChild(node, NULL, (xmlChar *) "Upgrade", NULL); + assert( upgr_n != NULL ); + dmixml_AddAttribute(upgr_n, "dmispec", "3.3.5.5"); + dmixml_AddAttribute(upgr_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x15) - return PyString_FromString(upgrade[code - 0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x15) { + dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]); + } else { + dmixml_AddAttribute(upgr_n, "outofspec", "1"); + } } -static PyObject *dmi_processor_cache(u16 code, const char *level, u16 ver) +void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) { - PyObject *data; + assert( cache_n != NULL ); + + dmixml_AddAttribute(cache_n, "flags", "0x%04x", code); + dmixml_AddAttribute(cache_n, "ver", "0x%04x", ver); if(code == 0xFFFF) { - if(ver >= 0x0203) - data = PyString_FromString("Not Provided"); - else - data = PyString_FromFormat("No %s Cache", level); - } else - data = PyString_FromFormat("0x%04x", code); - return data; + if(ver >= 0x0203) { + dmixml_AddAttribute(cache_n, "provided", "0"); + dmixml_AddAttribute(cache_n, "available", "1"); + } else { + dmixml_AddAttribute(cache_n, "available", "0"); + } + } else { + dmixml_AddAttribute(cache_n, "provided", "1"); + dmixml_AddAttribute(cache_n, "available", "1"); + dmixml_AddTextChild(cache_n, "Handle", "0x%04x", code); + } } /* 3.3.5.9 */ -static PyObject *dmi_processor_characteristics(u16 code) +void dmi_processor_characteristics(xmlNode *node, u16 code) { static const char *characteristics[] = { + NULL, + "Unknown" /* 1 */ "64-bit capable" /* 2 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Characteristics", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.5.9"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if((code & 0x0004) == 0) { - data = Py_None; - } else { - data = PyList_New(1); + if((code & 0x0004) != 0) { int i; - for(i = 2; i <= 2; i++) - if(code & (1 << i)) - PyList_SET_ITEM(data, 0, - PyString_FromString(characteristics[i - 2])); + for(i = 1; i <= 2; i++) { + if(code & (1 << i)) { + dmixml_AddTextChild(data_n, "Flag", "%s", characteristics[i - 1]); + } + } } - return data; } /******************************************************************************* ** 3.3.6 Memory Controller Information (Type 5) */ -static PyObject *dmi_memory_controller_ed_method(u8 code) +void dmi_memory_controller_ed_method(xmlNode *node, u8 code) { /* 3.3.6.1 */ static const char *method[] = { @@ -1197,14 +1319,20 @@ static PyObject *dmi_memory_controller_ed_method(u8 code) "128-bit ECC", "CRC" /* 0x08 */ }; + xmlNode *ercm_n = xmlNewChild(node, NULL, (xmlChar *) "CorrectionMethod", NULL); + assert( ercm_n != NULL ); + dmixml_AddAttribute(ercm_n, "dmispec", "3.3.6.1"); + dmixml_AddAttribute(ercm_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x08) - return (PyString_FromString(method[code - 0x01])); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x08) { + dmixml_AddTextContent(ercm_n, method[code - 0x01]); + } else { + dmixml_AddAttribute(ercm_n, "outofspec", "1"); + } } /* 3.3.6.2 */ -static PyObject *dmi_memory_controller_ec_capabilities(u8 code) +void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u8 code) { static const char *capabilities[] = { "Other", /* 0 */ @@ -1215,24 +1343,24 @@ static PyObject *dmi_memory_controller_ec_capabilities(u8 code) "Error Scrubbing" /* 5 */ }; - PyObject *data = Py_None; + xmlNode *cap_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( cap_n != NULL ); + dmixml_AddAttribute(cap_n, "dmispec", "3.3.6.2"); + dmixml_AddAttribute(cap_n, "flags", "0x%04x", code); - if((code & 0x3F) == 0) - return Py_None; - else { + if((code & 0x3F) != 0) { int i; - - data = PyList_New(6); - for(i = 0; i <= 5; i++) - if(code & (1 << i)) - PyList_SET_ITEM(data, i, PyString_FromString(capabilities[i])); - else - PyList_SET_ITEM(data, i, Py_None); + for(i = 0; i <= 5; i++) { + if(code & (1 << i)) { + xmlNode *c_n = dmixml_AddTextChild(cap_n, "Capability", "%s", capabilities[i]); + assert( c_n != NULL ); + dmixml_AddAttribute(c_n, "index", "%i", i); + } + } } - return data; } -static PyObject *dmi_memory_controller_interleave(u8 code) +void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 code) { /* 3.3.6.3 */ static const char *interleave[] = { @@ -1244,49 +1372,62 @@ static PyObject *dmi_memory_controller_interleave(u8 code) "Eight-way Interleave", "Sixteen-way Interleave" /* 0x07 */ }; + xmlNode *mci_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( mci_n != NULL ); + dmixml_AddAttribute(mci_n, "dmispec", "3.3.6.3"); + dmixml_AddAttribute(mci_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x07) - return PyString_FromString(interleave[code - 0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x07) { + dmixml_AddTextContent(mci_n, interleave[code - 0x01]); + } else { + dmixml_AddAttribute(mci_n, "outofspec", "1"); + } } /* 3.3.6.4 */ -static PyObject *dmi_memory_controller_speeds(u16 code) +void dmi_memory_controller_speeds(xmlNode *node, u16 code) { - const char *speeds[] = { - "Other", /* 0 */ - "Unknown", - "70 ns", - "60 ns", - "50 ns" /* 4 */ + static struct { + const char *value; + const char *unit; + } const speeds[] = { + {"Other", NULL}, /* 0 */ + {"Unknown", NULL}, + {"70", "ns"}, + {"60", "ns"}, + {"50", "ns"} /* 4 */ }; + xmlNode *mcs_n = xmlNewChild(node, NULL, (xmlChar *) "SupportedSpeeds", NULL); + assert( mcs_n != NULL ); + dmixml_AddAttribute(mcs_n, "dmispec", "3.3.6.4"); + dmixml_AddAttribute(mcs_n, "flags", "0x%04x", code); - PyObject *data; - - if((code & 0x001F) != 0) - data = Py_None; - else { + if((code & 0x001F) == 0) { int i; - - data = PyList_New(5); - for(i = 0; i <= 4; i++) - if(code & (1 << i)) - PyList_SET_ITEM(data, i, PyString_FromString(speeds[i])); - else - PyList_SET_ITEM(data, i, Py_None); + for(i = 0; i <= 4; i++) { + if(code & (1 << i)) { + xmlNode *ms_n = dmixml_AddTextChild(mcs_n, "Speed", "%s", speeds[i].value); + assert( ms_n != NULL ); + dmixml_AddAttribute(ms_n, "index", "%i", i); + if( speeds[i].unit != NULL ) { + dmixml_AddAttribute(ms_n, "unit", speeds[i].unit); + } + ms_n = NULL; + } + } } - return data; } -static PyObject *dmi_memory_controller_slots(u8 count, const u8 * p) +void dmi_memory_controller_slots(xmlNode *node, u8 count, const u8 * p) { int i; + xmlNode *mslts_n = xmlNewChild(node, NULL, (xmlChar *) "AssociatedMemorySlots", NULL); + assert( mslts_n != NULL ); - PyObject *data = PyList_New(count); - - for(i = 0; i < count; i++) - PyList_SET_ITEM(data, i, PyString_FromFormat("0x%04x:", WORD(p + sizeof(u16) * i))); - return data; + for(i = 0; i < count; i++) { + xmlNode *sl_n = dmixml_AddTextChild(mslts_n, "Slot", "0x%04x:", WORD(p + sizeof(u16) * i)); + dmixml_AddAttribute(sl_n, "index", "%i", i); + } } /******************************************************************************* @@ -1294,7 +1435,7 @@ static PyObject *dmi_memory_controller_slots(u8 count, const u8 * p) */ /* 3.3.7.1 */ -static PyObject *dmi_memory_module_types(u16 code) +void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code) { static const char *types[] = { "Other", /* 0 */ @@ -1309,101 +1450,109 @@ static PyObject *dmi_memory_module_types(u16 code) "Burst EDO", "SDRAM" /* 10 */ }; + xmlNode *mmt_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( mmt_n != NULL ); + dmixml_AddAttribute(mmt_n, "dmispec", "3.3.7.1"); + dmixml_AddAttribute(mmt_n, "flags", "0x%04x", code); - PyObject *data; - - if((code & 0x07FF) == 0) - data = Py_None; - else { + if((code & 0x07FF) != 0) { int i; - data = PyList_New(11); - for(i = 0; i <= 10; i++) - if(code & (1 << i)) - PyList_SET_ITEM(data, i, PyString_FromString(types[i])); - else - PyList_SET_ITEM(data, i, Py_None); + for(i = 0; i <= 10; i++) { + if(code & (1 << i)) { + xmlNode *mt_n = dmixml_AddTextChild(mmt_n, "ModuleType", types[i]); + assert( mt_n != NULL ); + dmixml_AddAttribute(mt_n, "index", "%i", i); + } + } } - return data; } -static PyObject *dmi_memory_module_connections(u8 code) +void dmi_memory_module_connections(xmlNode *node, u8 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BankConnections", NULL); + assert( data_n != NULL ); - if(code == 0xFF) - data = Py_None; - else { - data = PyList_New(0); - if((code & 0xF0) != 0xF0) - PyList_Append(data, PyInt_FromLong(code >> 4)); - if((code & 0x0F) != 0x0F) - PyList_Append(data, PyInt_FromLong(code & 0x0F)); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code != 0xFF) { + if((code & 0xF0) != 0xF0) { + dmixml_AddTextContent(data_n, "%ld", (code >> 4)); + } + if((code & 0x0F) != 0x0F) { + dmixml_AddTextContent(data_n, "%ld", (code & 0x0F)); + } } - return data; } -static PyObject *dmi_memory_module_speed(u8 code) +void dmi_memory_module_speed(xmlNode *node, const char *tagname, u8 code) { - if(code == 0) - return PyString_FromString("Unknown"); - else - return PyString_FromFormat("%i ns", code); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + + dmixml_AddAttribute(data_n, "code", "0x%04x", code); + + if(code != 0) { + dmixml_AddAttribute(data_n, "unit", "ns"); + dmixml_AddTextContent(data_n, "%i", code); + } } /* 3.3.7.2 */ -static PyObject *dmi_memory_module_size(u8 code) +void dmi_memory_module_size(xmlNode *node, const char *tagname, u8 code) { - PyObject *data = PyDict_New(); int check_conn = 1; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + + dmixml_AddAttribute(data_n, "dmispec", "3.3.7.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); switch (code & 0x7F) { case 0x7D: - PyDict_SetItemString(data, "Size", PyString_FromString("Not Determinable")); + dmixml_AddAttribute(data_n, "Error", "Size not determinable"); break; case 0x7E: - PyDict_SetItemString(data, "Size", PyString_FromString("Disabled")); + dmixml_AddAttribute(data_n, "Error", "Disabled"); break; case 0x7F: - PyDict_SetItemString(data, "Size", PyString_FromString("Not Installed")); + dmixml_AddAttribute(data_n, "installed", "0"); check_conn = 0; default: - PyDict_SetItemString(data, "Size", - PyString_FromFormat("%i MB", 1 << (code & 0x7F))); + dmixml_AddAttribute(data_n, "installed", "1"); + dmixml_AddAttribute(data_n, "unit", "MB"); + dmixml_AddTextContent(data_n, "%i", 1 << (code & 0x7F)); } if(check_conn) { - if(code & 0x80) - PyDict_SetItemString(data, "Connection", - PyString_FromString("Double-bank")); - else - PyDict_SetItemString(data, "Connection", - PyString_FromString("Single-bank")); + dmixml_AddAttribute(data_n, "Connection", ((code & 0x80) ? "Double-bank" : "Single-bank")); } - return data; } -static PyObject *dmi_memory_module_error(u8 code) +void dmi_memory_module_error(xmlNode *node, u8 code) { - PyObject *data = NULL; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ModuleErrorStatus", NULL); + assert( data_n != NULL ); - if(code & (1 << 2)) - data = Py_None; //. TODO: sprintf(_, "See Event Log"); - else { - if((code & 0x03) == 0) - data = Py_True; - if(code & (1 << 0)) - data = PyString_FromString("Uncorrectable Errors"); - if(code & (1 << 1)) - data = PyString_FromString("Correctable Errors"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if( !(code & (1 << 2)) ) { + if((code & 0x03) == 0) { + dmixml_AddAttribute(data_n, "Error", "1"); + } + if(code & (1 << 0)) { + dmixml_AddTextContent(data_n, "Uncorrectable Errors"); + } + if(code & (1 << 1)) { + dmixml_AddTextContent(data_n, "Correctable Errors"); + } } - return data; } /******************************************************************************* ** 3.3.8 Cache Information (Type 7) */ -static PyObject *dmi_cache_mode(u8 code) +static const char *dmi_cache_mode(u8 code) { static const char *mode[] = { "Write Through", /* 0x00 */ @@ -1412,10 +1561,10 @@ static PyObject *dmi_cache_mode(u8 code) "Unknown" /* 0x03 */ }; - return PyString_FromString(mode[code]); + return mode[code]; } -static PyObject *dmi_cache_location(u8 code) +void dmi_cache_location(xmlNode *node, u8 code) { static const char *location[4] = { "Internal", /* 0x00 */ @@ -1424,28 +1573,36 @@ static PyObject *dmi_cache_location(u8 code) "Unknown" /* 0x03 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CacheLocation", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.8"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(location[code] != NULL) - data = PyString_FromString(location[code]); - else - data = OUT_OF_SPEC; - return data; + if(location[code] != NULL) { + dmixml_AddTextContent(data_n, location[code]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_cache_size(u16 code) +void dmi_cache_size(xmlNode *node, const char *tagname, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CacheLocation", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.8"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code & 0x8000) - data = PyString_FromFormat("%i KB", (code & 0x7FFF) << 6); - else - data = PyString_FromFormat("%i KB", code); - return data; + if(code & 0x8000) { + dmixml_AddAttribute(data_n, "unit", "KB"); + dmixml_AddTextContent(data_n, "%i", (code & 0x7FFF) << 6); + } else { + dmixml_AddAttribute(data_n, "unit", "KB"); + dmixml_AddTextContent(data_n, "%i", code); + } } /* 3.3.8.2 */ -static PyObject *dmi_cache_types(u16 code) +void dmi_cache_types(xmlNode *node, const char *tagname, u16 code) { static const char *types[] = { "Other", /* 0 */ @@ -1456,24 +1613,25 @@ static PyObject *dmi_cache_types(u16 code) "Synchronous", "Asynchronous" /* 6 */ }; - PyObject *data; - if((code & 0x007F) == 0) - data = Py_None; - else { - int i; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.8.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - data = PyList_New(7); - for(i = 0; i <= 6; i++) - if(code & (1 << i)) - PyList_SET_ITEM(data, i, PyString_FromString(types[i])); - else - PyList_SET_ITEM(data, i, Py_None); + + if((code & 0x007F) != 0) { + int i; + for(i = 0; i <= 6; i++) { + if(code & (1 << i)) { + xmlNode *n = dmixml_AddTextContent(data_n, "%s", types[i]); + dmixml_AddAttribute(n, "index", "%i", i); + } + } } - return data; } -static PyObject *dmi_cache_ec_type(u8 code) +void dmi_cache_ec_type(xmlNode *node, u8 code) { /* 3.3.8.3 */ static const char *type[] = { @@ -1484,16 +1642,19 @@ static PyObject *dmi_cache_ec_type(u8 code) "Single-bit ECC", "Multi-bit ECC" /* 0x06 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorCorrectionType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.8.3"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x06) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x06) { + dmixml_AddTextContent(data_n, type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_cache_type(u8 code) +void dmi_cache_type(xmlNode *node, u8 code) { /* 3.3.8.4 */ static const char *type[] = { @@ -1503,16 +1664,19 @@ static PyObject *dmi_cache_type(u8 code) "Data", "Unified" /* 0x05 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SystemType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.8.4"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x05) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x05) { + dmixml_AddTextContent(data_n, type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_cache_associativity(u8 code) +void dmi_cache_associativity(xmlNode *node, u8 code) { /* 3.3.8.5 */ static const char *type[] = { @@ -1525,20 +1689,23 @@ static PyObject *dmi_cache_associativity(u8 code) "8-way Set-associative", "16-way Set-associative" /* 0x08 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Associativity", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.8.5"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x08) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x08) { + dmixml_AddTextContent(data_n, type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /******************************************************************************* ** 3.3.9 Port Connector Information (Type 8) */ -static PyObject *dmi_port_connector_type(u8 code) +void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code) { /* 3.3.9.2 */ static const char *type[] = { @@ -1586,16 +1753,24 @@ static PyObject *dmi_port_connector_type(u8 code) "PC-98 Full" /* 0xA4 */ }; - if(code <= 0x22) - return PyString_FromString(type[code]); - if(code >= 0xA0 && code <= 0xA4) - return PyString_FromString(type_0xA0[code - 0xA0]); - if(code == 0xFF) - return PyString_FromString("Other"); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Connector", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.9.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + dmixml_AddAttribute(data_n, "type", "%s", tpref); + + if(code <= 0x22) { + dmixml_AddTextContent(data_n, type[code]); + } else if(code >= 0xA0 && code <= 0xA4) { + dmixml_AddTextContent(data_n, type_0xA0[code - 0xA0]); + } else if(code == 0xFF) { + dmixml_AddTextContent(data_n, "Other"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_port_type(u8 code) +void dmi_port_type(xmlNode *node, u8 code) { /* 3.3.9.3 */ static const char *type[] = { @@ -1639,20 +1814,27 @@ static PyObject *dmi_port_type(u8 code) "8251 FIFO Compatible" /* 0xA1 */ }; - if(code <= 0x21) - return PyString_FromString(type[code]); - if(code >= 0xA0 && code <= 0xA1) - return PyString_FromString(type_0xA0[code - 0xA0]); - if(code == 0xFF) - return PyString_FromString("Other"); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "PortType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.9.3"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code <= 0x21) { + dmixml_AddTextContent(data_n, type[code]); + } else if(code >= 0xA0 && code <= 0xA1) { + dmixml_AddTextContent(data_n, type_0xA0[code - 0xA0]); + } else if(code == 0xFF) { + dmixml_AddTextContent(data_n, "Other"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /******************************************************************************* ** 3.3.10 System Slots (Type 9) */ -static PyObject *dmi_slot_type(u8 code) +void dmi_slot_type(xmlNode *node, u8 code) { /* 3.3.10.1 */ static const char *type[] = { @@ -1689,15 +1871,21 @@ static PyObject *dmi_slot_type(u8 code) "PCI Express x8", "PCI Express x16" /* 0xAA */ }; - - if(code >= 0x01 && code <= 0x13) - return PyString_FromString(type[code - 0x01]); - if(code >= 0xA0 && code <= 0xAA) - return PyString_FromString(type_0xA0[code - 0xA0]); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.10.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code >= 0x01 && code <= 0x13) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else if(code >= 0xA0 && code <= 0xAA) { + dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xA0]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_slot_bus_width(u8 code) +void dmi_slot_bus_width(xmlNode *node, u8 code) { /* 3.3.10.2 */ static const char *width[] = { @@ -1716,13 +1904,19 @@ static PyObject *dmi_slot_bus_width(u8 code) "x16 ", "x32 " /* 0x0E */ }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotWidth", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.10.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0E) - return PyString_FromString(width[code - 0x01]); - return OUT_OF_SPEC; + if( (code >= 0x01) && (code <= 0x0E) ) { + dmixml_AddTextContent(data_n, "%s", width[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_slot_current_usage(u8 code) +void dmi_slot_current_usage(xmlNode *node, u8 code) { /* 3.3.10.3 */ static const char *usage[] = { @@ -1732,13 +1926,21 @@ static PyObject *dmi_slot_current_usage(u8 code) "In Use" /* 0x04 */ }; - if(code >= 0x01 && code <= 0x04) - return PyString_FromString(usage[code - 0x01]); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CurrentUsage", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.10.3"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + + if(code >= 0x01 && code <= 0x04) { + dmixml_AddTextContent(data_n, usage[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /* 3.3.1O.4 */ -static PyObject *dmi_slot_length(u8 code) +void dmi_slot_length(xmlNode *node, u8 code) { static const char *length[] = { "Other", /* 0x01 */ @@ -1747,22 +1949,28 @@ static PyObject *dmi_slot_length(u8 code) "Long" /* 0x04 */ }; - if(code >= 0x01 && code <= 0x04) - return PyString_FromString(length[code - 0x01]); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotLength", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.10.4"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code >= 0x01 && code <= 0x04) { + dmixml_AddTextContent(data_n, length[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /* 3.3.10.5 */ -static PyObject *dmi_slot_id(u8 code1, u8 code2, u8 type) +void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type) { - PyObject *data; - + dmixml_AddAttribute(node, "dmispec", "3.3.10.5"); switch (type) { case 0x04: /* MCA */ - data = PyString_FromFormat("%i", code1); + dmixml_AddAttribute(node, "id", "%i", code1); break; case 0x05: /* EISA */ - data = PyString_FromFormat("%i", code1); + dmixml_AddAttribute(node, "id", "%i", code1); break; case 0x06: /* PCI */ case 0x0E: /* PCI */ @@ -1772,18 +1980,18 @@ static PyObject *dmi_slot_id(u8 code1, u8 code2, u8 type) case 0x12: /* PCI-X */ case 0x13: /* AGP */ case 0xA5: /* PCI Express */ - data = PyString_FromFormat("%i", code1); + dmixml_AddAttribute(node, "id", "%i", code1); break; case 0x07: /* PCMCIA */ - data = PyString_FromFormat("Adapter %i, Socket %i", code1, code2); + dmixml_AddAttribute(node, "adapter", "%i", code1); + dmixml_AddAttribute(node, "id", "%i", code2); break; default: - data = Py_None; + break; } - return data; } -static PyObject *dmi_slot_characteristics(u8 code1, u8 code2) +void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) { /* 3.3.10.6 */ static const char *characteristics1[] = { @@ -1802,33 +2010,36 @@ static PyObject *dmi_slot_characteristics(u8 code1, u8 code2) "Hot-plug devices are supported", "SMBus signal is supported" /* 2 */ }; - - PyObject *data; - - if(code1 & (1 << 0)) - data = PyString_FromString("Unknown"); - else if((code1 & 0xFE) == 0 && (code2 & 0x07) == 0) - data = Py_None; - else { + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotCharacteristics", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.10.6"); + dmixml_AddAttribute(data_n, "flags1", "0x%04x", code1); + dmixml_AddAttribute(data_n, "flags2", "0x%04x", code2); + + if(code1 & (1 << 0)) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else if((code1 & 0xFE) == 0 && (code2 & 0x07) == 0) { + // Nothing - empty tag + } else { int i; - data = PyList_New(7 + 3); for(i = 1; i <= 7; i++) { - if(code1 & (1 << i)) - PyList_SET_ITEM(data, i - 1, - PyString_FromString(characteristics1[i - 1])); - else - PyList_SET_ITEM(data, i - 1, Py_None); + if(code1 & (1 << i)) { + xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s", + characteristics1[i - 1]); + dmixml_AddAttribute(c_n, "index", "%i", i); + c_n = NULL; + } } for(i = 0; i <= 2; i++) { - if(code2 & (1 << i)) - PyList_SET_ITEM(data, 7 + i, - PyString_FromString(characteristics2[i])); - else - PyList_SET_ITEM(data, 7 + i, Py_None); + if(code2 & (1 << i)) { + xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s", + characteristics2[i]); + dmixml_AddAttribute(c_n, "index", "%i", i); + c_n = NULL; + } } } - return data; } static PyObject *dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) @@ -1848,7 +2059,7 @@ static PyObject *dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) ** 3.3.11 On Board Devices Information (Type 10) */ -static const char *dmi_on_board_devices_type(u8 code) +static const char *dmi_on_board_devices_type(xmlNode *node, u8 code) { /* 3.3.11.1 */ static const char *type[] = { @@ -1864,133 +2075,126 @@ static const char *dmi_on_board_devices_type(u8 code) "SAS Controller" /* 0x0A */ }; - if(code >= 0x01 && code <= 0x0A) - return type[code - 0x01]; - return out_of_spec; + dmixml_AddAttribute(node, "dmispec", "3.3.11.1"); + dmixml_AddAttribute(node, "flags", "0x%04x", code); + + if(code >= 0x01 && code <= 0x0A) { + dmixml_AddTextChild(node, "Type", "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(node, "outofspec", "1"); + } } -static PyObject *dmi_on_board_devices(struct dmi_header *h) +void dmi_on_board_devices(xmlNode *node, const char *tagname, struct dmi_header *h) { - PyObject *data = NULL; u8 *p = h->data + 4; u8 count = (h->length - 0x04) / 2; int i; - if((data = PyList_New(count))) { - PyObject *_pydict; - PyObject *_val; - - for(i = 0; i < count; i++) { - _pydict = PyDict_New(); - - _val = PyString_FromString(dmi_on_board_devices_type(p[2 * i] & 0x7F)); - PyDict_SetItemString(_pydict, "Type", _val); - Py_DECREF(_val); - - _val = p[2 * i] & 0x80 ? Py_True : Py_False; - PyDict_SetItemString(_pydict, "Enabled", _val); - Py_DECREF(_val); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.11"); - _val = dmi_string_py(h, p[2 * i + 1]); - PyDict_SetItemString(_pydict, "Description", _val); - Py_DECREF(_val); + for(i = 0; i < count; i++) { + xmlNode *dev_n = xmlNewChild(data_n, NULL, (xmlChar *) "Device", NULL); + assert( dev_n != NULL ); - PyList_SET_ITEM(data, i, _pydict); - } + dmi_on_board_devices_type(dev_n, p[2 * i] & 0x7F); + dmixml_AddAttribute(dev_n, "Enabled", "%i", ((p[2 * i] & 0x80) ? 1 : 0)); + dmixml_AddTextChild(dev_n, "Description", "%s", dmi_string(h, p[2 * i + 1])); + dev_n = NULL; } - - assert(data != NULL); - Py_INCREF(data); - return data; } /******************************************************************************* * 3.3.12 OEM Strings (Type 11) */ -static PyObject *dmi_oem_strings(struct dmi_header *h) +void dmi_oem_strings(xmlNode *node, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int i; - PyObject *data = PyDict_New(); - PyObject *val; + dmixml_AddAttribute(node, "dmispec", "3.3.12"); + dmixml_AddAttribute(node, "count", "%i", count); for(i = 1; i <= count; i++) { - val = dmi_string_py(h, i); - PyDict_SetItem(data, PyInt_FromLong(i), val); - Py_DECREF(val); + xmlNode *str_n = dmixml_AddTextChild(node, "Record", "%s", dmi_string(h, i)); + assert( str_n != NULL ); + dmixml_AddAttribute(str_n, "index", "%i", i); } - - return data; } /******************************************************************************* ** 3.3.13 System Configuration Options (Type 12) */ -static PyObject *dmi_system_configuration_options(struct dmi_header *h) +void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int i; - PyObject *data = PyDict_New(); - PyObject *val; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Options", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.13"); + dmixml_AddAttribute(data_n, "count", "%i", count); for(i = 1; i <= count; i++) { - val = dmi_string_py(h, i); - PyDict_SetItem(data, PyInt_FromLong(i), val); - Py_DECREF(val); - } + xmlNode *o_n = dmixml_AddTextChild(data_n, "Option", "%s", dmi_string(h, i)); + assert( o_n != NULL ); - return data; + dmixml_AddAttribute(o_n, "index", "%ld", i); + } } /******************************************************************************* ** 3.3.14 BIOS Language Information (Type 13) */ -static PyObject *dmi_bios_languages(struct dmi_header *h) +void dmi_bios_languages(xmlNode *node, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int i; - PyObject *data = PyList_New(count + 1); - - for(i = 1; i <= count; i++) - PyList_SET_ITEM(data, i, dmi_string_py(h, i)); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Installed", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.14"); + dmixml_AddAttribute(data_n, "count", "%i", count); - return data; + for(i = 1; i <= count; i++) { + xmlNode *l_n = dmixml_AddTextChild(data_n, "Language", "%s", dmi_string_py(h, i)); + assert( l_n != NULL ); + dmixml_AddAttribute(l_n, "index", "%i", i); + } } /******************************************************************************* ** 3.3.15 Group Associations (Type 14) */ -static PyObject *dmi_group_associations_items(u8 count, const u8 * p) +void dmi_group_associations_items(xmlNode *node, u8 count, const u8 * p) { - int i; - - PyObject *data = PyList_New(count); - PyObject *val; + dmixml_AddAttribute(node, "dmispec", "3.3.15"); + dmixml_AddAttribute(node, "items", "%i", count); + int i; for(i = 0; i < count; i++) { - val = PyString_FromFormat("0x%04x (%s)", - WORD(p + 3 * i + 1), dmi_smbios_structure_type(p[3 * i]) - ); - PyList_SET_ITEM(data, i, val); + xmlNode *grp_n = xmlNewChild(node, NULL, (xmlChar *) "Group", NULL); + assert( grp_n != NULL ); + + dmixml_AddAttribute(grp_n, "handle", "0x%04x", WORD(p + 3 * i + 1)); + dmi_smbios_structure_type(grp_n, p[3 * i]); } - return data; } /******************************************************************************* ** 3.3.16 System Event Log (Type 15) */ -static const char *dmi_event_log_method(u8 code) +void dmi_event_log_method(xmlNode *node, u8 code) { static const char *method[] = { "Indexed I/O, one 8-bit index port, one 8-bit data port", /* 0x00 */ @@ -2000,14 +2204,22 @@ static const char *dmi_event_log_method(u8 code) "General-purpose non-volatile data functions" /* 0x04 */ }; - if(code <= 0x04) - return method[code]; - if(code >= 0x80) - return "OEM-specific"; - return out_of_spec; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "AccessMethod", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.16"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code <= 0x04) { + dmixml_AddTextContent(data_n, "%s", method[code]); + } else if(code >= 0x80){ + dmixml_AddTextContent(data_n, "OEM-specific"); + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_event_log_status_py(u8 code) +void dmi_event_log_status(xmlNode *node, u8 code) { static const char *valid[] = { "Invalid", /* 0 */ @@ -2018,44 +2230,64 @@ static PyObject *dmi_event_log_status_py(u8 code) "Full" /* 1 */ }; - return PyString_FromFormat("%s, %s", valid[(code >> 0) & 1], full[(code >> 1) & 1]); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.16"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + // FIXME: Should we use 0/1 instead of strings? + dmixml_AddAttribute(data_n, "Full", "%s", full[(code >> 1) & 1]); + dmixml_AddAttribute(data_n, "Valid", "%s", valid[(code >> 0) & 1]); } -static PyObject *dmi_event_log_address_py(u8 method, const u8 * p) +void dmi_event_log_address(xmlNode *node, u8 method, const u8 * p) { + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Address", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.16.3"); + dmixml_AddAttribute(data_n, "method", "0x%04x", method); + /* 3.3.16.3 */ switch (method) { case 0x00: case 0x01: case 0x02: - return PyString_FromFormat("Index 0x%04x, Data 0x%04x", WORD(p), WORD(p + 2)); + dmixml_AddAttribute(data_n, "Index", "0x%04x", WORD(p)); + dmixml_AddAttribute(data_n, "Data", "0x%04x", WORD(p + 2)); break; case 0x03: - return PyString_FromFormat("0x%08x", DWORD(p)); + dmixml_AddAttribute(data_n, "Data", "0x%08x", DWORD(p)); break; case 0x04: - return PyString_FromFormat("0x%04x", WORD(p)); + dmixml_AddAttribute(data_n, "Data", "0x%04x", WORD(p)); break; default: - return PyString_FromString("Unknown"); + dmixml_AddAttribute(data_n, "unknown", "1"); } } -static const char *dmi_event_log_header_type(u8 code) +void dmi_event_log_header_type(xmlNode *node, u8 code) { static const char *type[] = { "No Header", /* 0x00 */ "Type 1" /* 0x01 */ }; - if(code <= 0x01) - return type[code]; - if(code >= 0x80) - return "OEM-specific"; - return out_of_spec; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Format", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.16"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code <= 0x01) { + dmixml_AddTextContent(data_n, type[code]); + } else if(code >= 0x80) { + dmixml_AddTextContent(data_n, "OEM-specific"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_event_log_descriptor_type(u8 code) +void dmi_event_log_descriptor_type(xmlNode *node, u8 code) { /* 3.3.16.6.1 */ static const char *type[] = { @@ -2085,20 +2317,23 @@ static PyObject *dmi_event_log_descriptor_type(u8 code) "System boot" /* 0x17 */ }; - const char *data; - - if(code <= 0x17 && type[code] != NULL) - data = type[code]; - else if(code >= 0x80 && code <= 0xFE) - data = "OEM-specific"; - else if(code == 0xFF) - data = "End of log"; - else - data = out_of_spec; - return PyString_FromString(data); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Descriptor", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.16.6.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code <= 0x17 && type[code] != NULL) { + dmixml_AddTextContent(data_n, "%s", type[code]); + } else if(code >= 0x80 && code <= 0xFE) { + dmixml_AddTextContent(data_n, "OEM-specific"); + } else if(code == 0xFF) { + dmixml_AddTextContent(data_n, "End of log"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_event_log_descriptor_format(u8 code) +void dmi_event_log_descriptor_format(xmlNode *node, u8 code) { /* 3.3.16.6.2 */ static const char *format[] = { @@ -2111,37 +2346,36 @@ static PyObject *dmi_event_log_descriptor_format(u8 code) "Multiple-event system management" /* 0x06 */ }; - const char *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Format", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.16.6.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code <= 0x06) - data = format[code]; - else if(code >= 0x80) - data = "OEM-specific"; - else - data = out_of_spec; - return PyString_FromString(data); + if(code <= 0x06) { + dmixml_AddTextContent(data_n, format[code]); + } else if(code >= 0x80) { + dmixml_AddTextContent(data_n, "OEM-specific"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_event_log_descriptors(u8 count, const u8 len, const u8 * p) +void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * p) { /* 3.3.16.1 */ int i; - PyObject *data; + dmixml_AddAttribute(node, "dmispec", "3.3.16.1"); - data = PyList_New(count); for(i = 0; i < count; i++) { if(len >= 0x02) { - PyObject *subdata = PyDict_New(); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "LogType", NULL); + assert( data_n != NULL ); - PyDict_SetItemString(subdata, "Descriptor", - dmi_event_log_descriptor_type(p[i * len])); - PyDict_SetItemString(subdata, "Data Format", - dmi_event_log_descriptor_format(p[i * len + 1])); - PyList_SET_ITEM(data, i, subdata); + dmi_event_log_descriptor_type(data_n, p[i * len]); + dmi_event_log_descriptor_format(data_n, p[i * len + 1]); } } - return data; } /******************************************************************************* @@ -3303,256 +3537,191 @@ static PyObject *dmi_additional_info(const struct dmi_header *h, const char *pre ** Main */ -PyObject *dmi_decode(struct dmi_header * h, u16 ver) +void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) { - const u8 *data = h->data; - + xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; //. 0xF1 --> 0xF100 //int minor = h->type<<8; - char _[2048]; - bzero(_, 2048); //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; - dmi_codes_major *dmiMajor = (dmi_codes_major *) & dmiCodesMajor[h->type]; - PyObject *pylist = PyDict_New(); + dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; - PyDict_SetItemString(pylist, "id", PyString_FromString(dmiMajor->id)); - PyDict_SetItemString(pylist, "desc", PyString_FromString(dmiMajor->desc)); - PyObject *_val; //. A Temporary pointer (value) - PyObject *_key; //. Another temporary pointer (key) - PyObject *caseData = PyDict_New(); + dmixml_AddAttribute(handle_n, "id", "%s", dmiMajor->id); + dmixml_AddAttribute(handle_n, "type", "%s", h->type); + dmixml_AddTextChild(handle_n, "description", "%s", dmiMajor->desc); switch (h->type) { - case 0: /* 3.3.1 BIOS Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOS", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.1"); if(h->length < 0x12) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Vendor", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Release Date", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Vendor", "%s", data[0x04]); + dmixml_AddTextChild(sect_n, "Version", "%s", data[0x05]); + dmixml_AddTextChild(sect_n, "ReleaseDate", "%s", data[0x08]); /* * On IA-64, the BIOS base address will read 0 because * there is no BIOS. Skip the base address and the * runtime size in this case. */ - if(WORD(data + 0x06) != 0) { - _val = PyString_FromFormat("0x%04x0", WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Address", _val); - Py_DECREF(_val); - _val = dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4); - PyDict_SetItemString(caseData, "Runtime Size", _val); - Py_DECREF(_val); + if(WORD(data + 0x06) != 0) { + dmixml_AddTextChild(sect_n, "Address", "0x%04x0", WORD(data + 0x06)); + dmixml_AddTextChild(sect_n, "RuntimeSize", "%s", + dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4)); } - _val = PyString_FromFormat("%i kB", (data[0x09] + 1) << 6); - PyDict_SetItemString(caseData, "ROM Size", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "ROMsize", "%i kB", (data[0x09] + 1) << 6); - _val = dmi_bios_characteristics(QWORD(data + 0x0A)); - PyDict_SetItemString(caseData, "Characteristics", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); + assert( sub_n != NULL ); + + dmixml_AddAttribute(sub_n, "level", "0"); + dmi_bios_characteristics(sub_n, QWORD(data + 0x0A)); + sub_n = NULL; if(h->length < 0x13) break; - _val = dmi_bios_characteristics_x1(data[0x12]); - PyDict_SetItemString(caseData, "Characteristics x1", _val); - Py_DECREF(_val); + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); + assert( sub_n != NULL ); + + dmixml_AddAttribute(sub_n, "level", "x1"); + dmi_bios_characteristics_x1(sub_n, data[0x12]); if(h->length < 0x14) break; - _val = dmi_bios_characteristics_x2(data[0x13]); - PyDict_SetItemString(caseData, "Characteristics x2", _val); - Py_DECREF(_val); + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); + assert( sub_n != NULL ); + + dmixml_AddAttribute(sub_n, "level", "x2"); + dmi_bios_characteristics_x2(sub_n, data[0x13]); + sub_n = NULL; if(h->length < 0x18) break; if(data[0x14] != 0xFF && data[0x15] != 0xFF) { - _val = PyString_FromFormat("%i.%i", data[0x14], data[0x15]); - PyDict_SetItemString(caseData, "BIOS Revision", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "BIOSrevision", "%i.%i", data[0x14], data[0x15]); } if(data[0x16] != 0xFF && data[0x17] != 0xFF) { - _val = PyString_FromFormat("%i.%i", data[0x16], data[0x17]); - PyDict_SetItemString(caseData, "Firmware Revision", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "FirmwareRevision", "%i.%i", data[0x16], data[0x17]); } - + sect_n = NULL; break; case 1: /* 3.3.2 System Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemInformation", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.2"); if(h->length < 0x08) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Product Name", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); + dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05])); + dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06])); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); if(h->length < 0x19) break; - _val = dmi_system_uuid_py(data + 0x08, ver); - PyDict_SetItemString(caseData, "UUID", _val); - Py_DECREF(_val); - _val = dmi_system_wake_up_type(data[0x18]); - PyDict_SetItemString(caseData, "Wake-Up Type", _val); - Py_DECREF(_val); + dmi_system_uuid(sect_n, data + 0x08, ver); + + dmi_system_wake_up_type(sect_n, data[0x18]); if(h->length < 0x1B) break; - _val = dmi_string_py(h, data[0x19]); - PyDict_SetItemString(caseData, "SKU Number", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x1A]); - PyDict_SetItemString(caseData, "Family", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19])); + dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A])); + sect_n = NULL; break; case 2: /* 3.3.3 Base Board Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Baseboard", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.3"); if(h->length < 0x08) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Product Name", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); + dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05])); + dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06])); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); if(h->length < 0x0F) break; - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - _val = dmi_base_board_features(data[0x09]); - PyDict_SetItemString(caseData, "Features", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); - _val = dmi_string_py(h, data[0x0A]); - PyDict_SetItemString(caseData, "Location In Chassis", _val); - Py_DECREF(_val); + dmi_base_board_features(sect_n, data[0x09]); - _val = PyString_FromFormat("0x%04x", WORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Chassis Handle", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "ChassisLocation", "%s", dmi_string(h, data[0x0A])); + dmixml_AddTextChild(sect_n, "ChassisHandle", "0x%04x", WORD(data + 0x0B)); - _val = dmi_base_board_type(data[0x0D]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + dmi_base_board_type(sect_n, "Type", data[0x0D]); if(h->length < 0x0F + data[0x0E] * sizeof(u16)) break; - _val = dmi_base_board_handles(data[0x0E], data + 0x0F); - PyDict_SetItemString(caseData, "Type ???", _val); - Py_DECREF(_val); + + dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F); + sect_n = NULL; break; case 3: /* 3.3.4 Chassis Information */ + sect_n= xmlNewChild(handle_n, NULL, (xmlChar *) "Chassis", NULL); + assert( sect_n != NULL ); if(h->length < 0x09) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_chassis_type_py(data[0x05] & 0x7F); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_chassis_lock(data[0x05] >> 7); - PyDict_SetItemString(caseData, "Lock", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); + dmi_chassis_type(sect_n, data[0x05] & 0x7F); + dmi_chassis_lock(sect_n, data[0x05] >> 7); + dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06])); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); + dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); if(h->length < 0x0D) break; - _val = dmi_chassis_state(data[0x09]); - PyDict_SetItemString(caseData, "Boot-Up State", _val); - Py_DECREF(_val); - _val = dmi_chassis_state(data[0x0A]); - PyDict_SetItemString(caseData, "Power Supply State", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ChassisStates", NULL); + assert( sub_n != NULL ); - _val = dmi_chassis_state(data[0x0B]); - PyDict_SetItemString(caseData, "Thermal State", _val); - Py_DECREF(_val); + dmi_chassis_state(sub_n, "BootUp", data[0x09]); + dmi_chassis_state(sub_n, "PowerSupply", data[0x0A]); + dmi_chassis_state(sub_n, "Thermal", data[0x0B]); - _val = PyString_FromString(dmi_chassis_security_status(data[0x0C])); - PyDict_SetItemString(caseData, "Security Status", _val); - Py_DECREF(_val); + dmi_chassis_security_status(sect_n, data[0x0C]); if(h->length < 0x11) break; - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x0D)); - PyDict_SetItemString(caseData, "OEM Information", _val); - Py_DECREF(_val); + + dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x0D)); if(h->length < 0x13) break; - _val = dmi_chassis_height(data[0x11]); - PyDict_SetItemString(caseData, "Height", _val); - Py_DECREF(_val); - _val = dmi_chassis_power_cords(data[0x12]); - PyDict_SetItemString(caseData, "Number Of Power Cords", _val); - Py_DECREF(_val); + dmi_chassis_height(sect_n, data[0x11]); + dmi_chassis_power_cords(sect_n, data[0x12]); if(h->length < 0x15) break; + if(h->length < 0x15 + data[0x13] * data[0x14]) break; - _val = dmi_chassis_elements(data[0x13], data[0x14], data + 0x15); - PyDict_SetItemString(caseData, "Elements", _val); - Py_DECREF(_val); + dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15); + sect_n = NULL; break; case 4: /* 3.3.5 Processor Information */ @@ -3560,452 +3729,408 @@ PyObject *dmi_decode(struct dmi_header * h, u16 ver) if(h->length < 0x1A) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Socket Designation", _val); - Py_DECREF(_val); - - _val = dmi_processor_type(data[0x05]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Processor", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.5"); - _val = PyString_FromString(dmi_processor_family(h)); - PyDict_SetItemString(caseData, "Family", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04])); + dmi_processor_type(sect_n, data[0x05]); + dmi_processor_family(sect_n, h); - _val = dmi_processor_id(data[0x06], data + 8, dmi_string(h, data[0x10])); - PyDict_SetItemString(_val, "Vendor", dmi_string_py(h, data[0x07])); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); + dmi_processor_id(sect_n, data[0x06], data + 8, dmi_string(h, data[0x10])); - _val = dmi_string_py(h, data[0x10]); - PyDict_SetItemString(caseData, "Version", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Manufacturer", NULL); + assert( sub_n != NULL ); + dmixml_AddTextChild(sub_n, "Vendor", dmi_string(h, data[0x07])); - _val = dmi_processor_voltage(data[0x11]); - PyDict_SetItemString(caseData, "Voltage", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "Version", dmi_string(h, data[0x10])); + dmi_processor_voltage(sub_n, data[0x11]); + sub_n = NULL; - _val = dmi_processor_frequency_py(data + 0x12); - PyDict_SetItemString(caseData, "External Clock", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Frequencies", NULL); + assert( sub_n != NULL ); - _val = dmi_processor_frequency_py(data + 0x14); - PyDict_SetItemString(caseData, "Max Speed", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "ExternalClock", "%i", dmi_processor_frequency(data + 0x12)); + dmixml_AddTextChild(sub_n, "MaxSpeed", "%i", dmi_processor_frequency(data + 0x14)); + dmixml_AddTextChild(sub_n, "CurrentSpeed", "%i", dmi_processor_frequency(data + 0x16)); - _val = dmi_processor_frequency_py(data + 0x16); - PyDict_SetItemString(caseData, "Current Speed", _val); - Py_DECREF(_val); + /* TODO: Should CurrentSpeed be renamed to BootSpeed? Specification + * says this about Current Speed: + * + * This field identifies the processor's speed at + * system boot and the Processor ID field implies the + * processor's additional speed characteristics (i.e. single + * speed or multiple speed). + */ if(data[0x18] & (1 << 6)) { - _val = - PyString_FromFormat("Populated:%s", - dmi_processor_status(data[0x18] & 0x07)); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sect_n, "populated", "1"); + dmi_processor_status(sect_n, data[0x18] & 0x07); } else { - _val = PyString_FromString("Populated:No"); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sect_n, "populated", "0"); } - _val = dmi_processor_upgrade(data[0x19]); - PyDict_SetItemString(caseData, "Upgrade", _val); - Py_DECREF(_val); + + dmi_processor_upgrade(sect_n, data[0x19]); if(h->length < 0x20) break; - _val = dmi_processor_cache(WORD(data + 0x1A), "L1", ver); - PyDict_SetItemString(caseData, "L1 Cache Handle", _val); - Py_DECREF(_val); - _val = dmi_processor_cache(WORD(data + 0x1C), "L2", ver); - PyDict_SetItemString(caseData, "L2 Cache Handle", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cache", NULL); + assert( sub_n != NULL ); - _val = dmi_processor_cache(WORD(data + 0x1E), "L3", ver); - PyDict_SetItemString(caseData, "L3 Cache Handle", _val); - Py_DECREF(_val); + sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Level", NULL); + assert( sub2_n != NULL ); + + dmixml_AddAttribute(sub2_n, "level", "1"); + dmi_processor_cache(sub2_n, WORD(data + 0x1A), ver); + sub2_n = NULL; + + + sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Level", NULL); + assert( sub2_n != NULL ); + + dmixml_AddAttribute(sub2_n, "level", "2"); + dmi_processor_cache(sub2_n, WORD(data + 0x1C), ver); + sub2_n = NULL; + + sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Level", NULL); + assert( sub2_n != NULL ); + + dmixml_AddAttribute(sub2_n, "level", "3"); + dmi_processor_cache(sub2_n, WORD(data + 0x1E), ver); + sub2_n = NULL; + sub_n = NULL; if(h->length < 0x23) break; - _val = dmi_string_py(h, data[0x20]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x21]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - _val = dmi_string_py(h, data[0x22]); - PyDict_SetItemString(caseData, "Part Number", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x20])); + dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x21])); + dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x22])); if(h->length < 0x28) break; + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cores", NULL); + assert( cores_n != NULL ); + if(data[0x23] != 0) { - _val = PyString_FromFormat("%i", data[0x23]); - PyDict_SetItemString(caseData, "Core Count", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "CoreCount", "%i", data[0x23]); } if(data[0x24] != 0) { - _val = PyString_FromFormat("%i", data[0x24]); - PyDict_SetItemString(caseData, "Core Enabled", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "CoresEnabled", "%i", data[0x24]); } if(data[0x25] != 0) { - _val = PyString_FromFormat("%i", data[0x25]); - PyDict_SetItemString(caseData, "Thread Count", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "ThreadCount", "%i", data[0x25]); } - _val = dmi_processor_characteristics(WORD(data + 0x26)); - PyDict_SetItemString(caseData, "Characteristics", _val); - Py_DECREF(_val); + dmi_processor_characteristics(sub_n, WORD(data + 0x26)); + sub_n = NULL; + sect_n = NULL; break; case 5: /* 3.3.6 Memory Controller Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryController", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.6"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0F) break; - _val = dmi_memory_controller_ed_method(data[0x04]); - PyDict_SetItemString(caseData, "Error Detecting Method", _val); - Py_DECREF(_val); - - _val = dmi_memory_controller_ec_capabilities(data[0x05]); - PyDict_SetItemString(caseData, "Error Correcting Capabilities", _val); - Py_DECREF(_val); - - _val = dmi_memory_controller_interleave(data[0x06]); - PyDict_SetItemString(caseData, "Supported Interleave", _val); - Py_DECREF(_val); - _val = dmi_memory_controller_interleave(data[0x07]); - PyDict_SetItemString(caseData, "Current Interleave", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ErrorCorrection", NULL); + assert( errc_n != NULL ); - _val = PyString_FromFormat("%i MB", 1 << data[0x08]); - PyDict_SetItemString(caseData, "Maximum Memory Module Size", _val); - Py_DECREF(_val); + dmi_memory_controller_ed_method(sub_n, data[0x04]); + dmi_memory_controller_ec_capabilities(sub_n, "Capabilities", data[0x05]); + sub_n = NULL; - _val = PyString_FromFormat("%i MB", data[0x0E] * (1 << data[0x08])); - PyDict_SetItemString(caseData, "Maximum Total Memory Size", _val); - Py_DECREF(_val); + dmi_memory_controller_interleave(sect_n, "SupportedInterleave", data[0x06]); + dmi_memory_controller_interleave(sect_n, "CurrentInterleave", data[0x07]); - _val = dmi_memory_controller_speeds(WORD(data + 0x09)); - PyDict_SetItemString(caseData, "Supported Speeds", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "MaxMemoryModuleSize", + "%i", (1 << data[0x08])); + dmixml_AddAttribute(sub_n, "unit", "MB"); + sub_n = NULL; - _val = dmi_memory_module_types(WORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Supported Memory Types", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "MaxTotalMemorySize", + "%i", data[0x0E] * (1 << data[0x08])); + dmixml_AddAttribute(sub_n, "unit", "MB"); + sub_n = NULL; - _val = dmi_processor_voltage(data[0x0D]); - PyDict_SetItemString(caseData, "Memory Module Voltage", _val); - Py_DECREF(_val); + dmi_memory_controller_speeds(sect_n, WORD(data + 0x09)); + dmi_memory_module_types(sect_n, "SupportedTypes", WORD(data + 0x0B)); + dmi_processor_voltage(sect_n, data[0x0D]); if(h->length < 0x0F + data[0x0E] * sizeof(u16)) break; - _val = dmi_memory_controller_slots(data[0x0E], data + 0x0F); - PyDict_SetItemString(caseData, "Associated Memory Sluts", _val); - Py_DECREF(_val); + + dmi_memory_controller_slots(sect_n, data[0x0E], data + 0x0F); if(h->length < 0x10 + data[0x0E] * sizeof(u16)) break; - _val = dmi_memory_controller_ec_capabilities(data[0x0F + data[0x0E] * sizeof(u16)]); - PyDict_SetItemString(caseData, "Enabled Error Correcting Capabilities", _val); - Py_DECREF(_val); + + dmi_memory_controller_ec_capabilities(sect_n, "EnabledErrorCorrection", + data[0x0F + data[0x0E] * sizeof(u16)]); + sect_n = NULL; break; case 6: /* 3.3.7 Memory Module Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryModule", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.7"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0C) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Socket Designation", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_connections(data[0x05]); - PyDict_SetItemString(caseData, "Bank Connections", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_speed(data[0x06]); - PyDict_SetItemString(caseData, "Current Speed", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_types(WORD(data + 0x07)); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_module_size(data[0x09]); - PyDict_SetItemString(caseData, "Installed Size", _val); - Py_DECREF(_val); - _val = dmi_memory_module_size(data[0x0A]); - PyDict_SetItemString(caseData, "Enabled Size", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04])); + dmi_memory_module_connections(sect_n, data[0x05]); + dmi_memory_module_speed(sect_n, "ModuleSpeed", data[0x06]); + dmi_memory_module_types(sect_n, "Type", WORD(data + 0x07)); - _val = dmi_memory_module_error(data[0x0B]); - PyDict_SetItemString(caseData, "Error Status", _val); - Py_DECREF(_val); + dmi_memory_module_size(sect_n, "InstalledSize", data[0x09]); + dmi_memory_module_size(sect_n, "EnabledSize", data[0x0A]); + dmi_memory_module_error(sect_n, data[0x0B]); + sect_n = NULL; break; case 7: /* 3.3.8 Cache Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Cache", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.8"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0F) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Socket Designation", _val); - Py_DECREF(_val); - _val = PyDict_New(); - PyDict_SetItemString(_val, "Enabled", - WORD(data + 0x05) & 0x0080 ? Py_True : Py_False); - PyDict_SetItemString(_val, "Socketed", - WORD(data + 0x05) & 0x0008 ? Py_True : Py_False); - PyDict_SetItemString(_val, "Level", - PyInt_FromLong((WORD(data + 0x05) & 0x0007) + 1)); - PyDict_SetItemString(caseData, "Configuration", _val); - Py_DECREF(_val); - - _val = dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003); - PyDict_SetItemString(caseData, "Operational Mode", _val); - Py_DECREF(_val); - - _val = dmi_cache_location((WORD(data + 0x05) >> 5) & 0x0003); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_cache_size(WORD(data + 0x09)); - PyDict_SetItemString(caseData, "Installed Size", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SocketDesignation", dmi_string(h, data[0x04])); + dmixml_AddAttribute(sect_n, "Enabled", "%i", (WORD(data + 0x05) & 0x0080 ? 1 : 0)); + dmixml_AddAttribute(sect_n, "Socketed", "%i", (WORD(data + 0x05) & 0x0008 ? 1 : 0)); + dmixml_AddAttribute(sect_n, "Level", "%ld", ((WORD(data + 0x05) & 0x0007) + 1)); - _val = dmi_cache_size(WORD(data + 0x07)); - PyDict_SetItemString(caseData, "Maximum Size", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "OperationalMode", "%s", + dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003)); + dmixml_AddAttribute(sub_n, "flags", "0x%04x", (WORD(data + 0x05) >> 8) & 0x0003); - _val = dmi_cache_types(WORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Supported SRAM Types", _val); - Py_DECREF(_val); + dmi_cache_location(sect_n, (WORD(data + 0x05) >> 5) & 0x0003); + dmi_cache_size(sect_n, "InstalledSize", WORD(data + 0x09)); + dmi_cache_size(sect_n, "MaximumSize", WORD(data + 0x07)); - _val = dmi_cache_types(WORD(data + 0x0D)); - PyDict_SetItemString(caseData, "Installed SRAM Type", _val); - Py_DECREF(_val); + dmi_cache_types(sect_n, "SupportedSRAMtypes", WORD(data + 0x0B)); + dmi_cache_types(sect_n, "InstalledSRAMtypes", WORD(data + 0x0D)); if(h->length < 0x13) break; - _val = dmi_memory_module_speed(data[0x0F]); - PyDict_SetItemString(caseData, "Speed", _val); - Py_DECREF(_val); - - _val = dmi_cache_ec_type(data[0x10]); - PyDict_SetItemString(caseData, "Error Correction Type", _val); - Py_DECREF(_val); - _val = dmi_cache_type(data[0x11]); - PyDict_SetItemString(caseData, "System Type", _val); - Py_DECREF(_val); - - _val = dmi_cache_associativity(data[0x12]); - PyDict_SetItemString(caseData, "Associativity", _val); - Py_DECREF(_val); + dmi_memory_module_speed(sect_n, "Speed", data[0x0F]); + dmi_cache_ec_type(sect_n, data[0x10]); + dmi_cache_type(sect_n, data[0x11]); + dmi_cache_associativity(sect_n, data[0x12]); + sect_n = NULL; break; case 8: /* 3.3.9 Port Connector Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Connector", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.9"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x09) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Internal Reference Designator", _val); - Py_DECREF(_val); - _val = dmi_port_connector_type(data[0x05]); - PyDict_SetItemString(caseData, "Internal Connector Type", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x04])); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "type", "internal"); + sub_n = NULL; - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "External Reference Designator", _val); - Py_DECREF(_val); + dmi_port_connector_type(sect_n, "internal", data[0x05]); - _val = dmi_port_connector_type(data[0x07]); - PyDict_SetItemString(caseData, "External Connector Type", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x06])); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "type", "external"); + sub_n = NULL; - _val = dmi_port_type(data[0x08]); - PyDict_SetItemString(caseData, "Port Type", _val); - Py_DECREF(_val); + dmi_port_connector_type(sect_n, "external", data[0x07]); + dmi_port_type(sect_n, data[0x08]); + sect_n = NULL; break; case 9: /* 3.3.10 System Slots */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Connector", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.10"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0C) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Designation", _val); - Py_DECREF(_val); - _val = dmi_slot_bus_width(data[0x06]); - PyDict_SetItemString(caseData, "Type:SlotBusWidth", _val); - Py_DECREF(_val); - _val = dmi_slot_type(data[0x05]); - PyDict_SetItemString(caseData, "Type:SlotType", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Designation", "%s", dmi_string(h, data[0x04])); - _val = dmi_slot_current_usage(data[0x07]); - PyDict_SetItemString(caseData, "Current Usage", _val); - Py_DECREF(_val); + dmi_slot_bus_width(sect_n, data[0x06]); + dmi_slot_type(sect_n, data[0x05]); + dmi_slot_current_usage(sect_n, data[0x07]); + dmi_slot_length(sect_n, data[0x08]); + dmi_slot_id(sect_n, data[0x09], data[0x0A], data[0x05]); - _val = dmi_slot_length(data[0x08]); - PyDict_SetItemString(caseData, "SlotLength", _val); - Py_DECREF(_val); - _val = dmi_slot_id(data[0x09], data[0x0A], data[0x05]); - PyDict_SetItemString(caseData, "SlotId", _val); - Py_DECREF(_val); + if( h->length < 0x0D ) { + dmi_slot_characteristics(sect_n, data[0x0B], 0x00); + } else { + dmi_slot_characteristics(sect_n, data[0x0B], data[0x0C]); + } - _val = - (h->length < 0x0D) ? dmi_slot_characteristics(data[0x0B], - 0x00) : - dmi_slot_characteristics(data[0x0B], data[0x0C]); - PyDict_SetItemString(caseData, "Characteristics", _val); - Py_DECREF(_val); + sect_n = NULL; break; case 10: /* 3.3.11 On Board Devices Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OnBoardDevices", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.11"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); + sect_n = NULL; break; case 11: /* 3.3.12 OEM Strings */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OEMstrings", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.12"); - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); + dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x05) break; - _val = dmi_oem_strings(h); - PyDict_SetItemString(caseData, "Strings", _val); - Py_DECREF(_val); + dmi_oem_strings(sect_n, h); + + sect_n = NULL; break; case 12: /* 3.3.13 System Configuration Options */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemConfig", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.13"); if(h->length < 0x05) break; - _val = dmi_system_configuration_options(h); - PyDict_SetItemString(caseData, "Options", _val); - Py_DECREF(_val); + dmi_system_configuration_options(sect_n, h); + + sect_n = NULL; break; case 13: /* 3.3.14 BIOS Language Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOSlanguage", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.14"); if(h->length < 0x16) break; - _val = PyString_FromFormat("%i", data[0x04]); - PyDict_SetItemString(caseData, "Installable Languages", _val); - Py_DECREF(_val); - _val = dmi_bios_languages(h); - PyList_SET_ITEM(_val, 0, dmi_string_py(h, data[0x15])); - PyDict_SetItemString(caseData, "Currently Installed Language", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]); + + dmi_bios_languages(sect_n, h); + sect_n = NULL; break; case 14: /* 3.3.15 Group Associations */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "GroupAssociations", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.15"); if(h->length < 0x05) break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Name", _val); - Py_DECREF(_val); - _val = PyString_FromFormat("%i", (h->length - 0x05) / 3); - PyDict_SetItemString(caseData, "Items", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x04])); - _val = dmi_group_associations_items((h->length - 0x05) / 3, data + 0x05); - PyDict_SetItemString(caseData, "Items2", _val); //. FIXME: Title - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Groups", NULL); + assert( sub_n != NULL ); + dmi_group_associations_items(sub_n, (h->length - 0x05) / 3, data + 0x05); + + sect_n = NULL; break; case 15: /* 3.3.16 System Event Log */ + // SysEventLog - sect_n + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SysEventLog", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.16"); if(h->length < 0x14) break; - _val = PyString_FromFormat("%i bytes", WORD(data + 0x04)); - PyDict_SetItemString(caseData, "Area Length", _val); - Py_DECREF(_val); - _val = PyString_FromFormat("0x%04x", WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Header Start Offset", _val); - Py_DECREF(_val); + dmi_event_log_status(sect_n, data[0x0B]); - if(WORD(data + 0x08) - WORD(data + 0x06)) { - _val = - PyString_FromFormat("%i byte%s", WORD(data + 0x08) - WORD(data + 0x06), - WORD(data + 0x08) - WORD(data + 0x06) > - 1 ? "s" : ""); - PyDict_SetItemString(caseData, "Header Length", _val); - Py_DECREF(_val); - } + // SysEventLog/Access - sub + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Access", NULL); + assert( sub_n != NULL ); - _val = PyString_FromFormat("0x%04x", WORD(data + 0x08)); - PyDict_SetItemString(caseData, "Data Start Offset", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "AreaLength", "%i", WORD(data + 0x04)); + dmi_event_log_method(sub_n, data[0x0A]); + dmi_event_log_address(sub_n, data[0x0A], data + 0x10); - _val = PyString_FromFormat("%s", dmi_event_log_method(data[0x0A])); - PyDict_SetItemString(caseData, "Access Method", _val); - Py_DECREF(_val); + // SysEventLog/Access/Header - sub2 + sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Header", NULL); + assert( sub2_n != NULL ); - _val = dmi_event_log_address_py(data[0x0A], data + 0x10); - PyDict_SetItemString(caseData, "Access Address", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub2_n, "OffsetStart", "0x%04x", WORD(data + 0x06)); - _val = dmi_event_log_status_py(data[0x0B]); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + if((WORD(data + 0x08) - WORD(data + 0x06)) >= 0) { + dmixml_AddTextChild(sub2_n, "Length", "%i", WORD(data + 0x08) - WORD(data + 0x06)); + } - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Change Token", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub2_n, "DataOffset", "0x%04x", WORD(data + 0x08)); + dmixml_AddTextChild(sub2_n, "ChangeToken", "0x%08x", DWORD(data + 0x0C)); if(h->length < 0x17) break; - _val = PyString_FromFormat("%s", dmi_event_log_header_type(data[0x14])); - PyDict_SetItemString(caseData, "Header Format", _val); - Py_DECREF(_val); - _val = PyString_FromFormat("%i", data[0x15]); - PyDict_SetItemString(caseData, "Supported Log Type Descriptors", _val); - Py_DECREF(_val); + // SysEventLog/Access/Header/Format - sub2_n + dmi_event_log_header_type(sub2_n, data[0x14]); + + sub2_n = NULL; + sub_n = NULL; + + // SysEventLog/LogTypes - resuing sub_n + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "LogTypes", NULL); + assert( sub_n != NULL ); + + // SysEventLog/LogTypes/@count + dmixml_AddAttribute(sub_n, "count", "%i", data[0x15]); if(h->length < 0x17 + data[0x15] * data[0x16]) break; - _val = dmi_event_log_descriptors(data[0x15], data[0x16], data + 0x17); - PyDict_SetItemString(caseData, "DMI Event Log Descriptors", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "length", "%i", data[0x16]); + + // SysEventLog/LogTypes/LogType + dmi_event_log_descriptors(sub_n, data[0x15], data[0x16], data + 0x17); + + sub_n = NULL; + sect_n = NULL; break; case 16: /* 3.3.17 Physical Memory Array */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "PhysicalMemoryArray", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.17"); if(h->length < 0x0F) break; + + /* ** BOOKMARK ** */ + _val = dmi_memory_array_location(data[0x04]); PyDict_SetItemString(caseData, "Location", _val); Py_DECREF(_val); @@ -4941,9 +5066,6 @@ PyObject *dmi_decode(struct dmi_header * h, u16 ver) Py_DECREF(_key); Py_DECREF(_val); } - - Py_INCREF(caseData); - return caseData; } void to_dmi_header(struct dmi_header *h, u8 * data) @@ -5120,13 +5242,14 @@ int dump(const char *dumpfile) return ret == 0 ? found : ret; } -static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, PyObject * pydata) +static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; int i = 0; if(opt.type == NULL) { + /* FIXME: How to interpret this section in XML? */ dmiSetItem(pydata, "dmi_table_size", "%i structures occupying %i bytes", num, len); /* TODO DUMP * if (!(opt.flags & FLAG_FROM_DUMP)) @@ -5153,7 +5276,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P to_dmi_header(&h, data); display = ((opt.type == NULL || opt.type[h.type]) -// && !(h.type>39 && h.type<=127) + // && !(h.type>39 && h.type<=127) && !opt.string); /* @@ -5168,26 +5291,27 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P break; } - /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together), stop decoding at end of table marker */ - - char hid[7]; - - sprintf(hid, "0x%04x", h.handle); - PyObject *hDict = PyDict_New(); + /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together), + * stop decoding at end of table marker + */ - dmiSetItem(hDict, "dmi_handle", hid); - dmiSetItem(hDict, "dmi_type", "%d", h.type); - dmiSetItem(hDict, "dmi_size", "%d", h.length); + xmlNode *handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "dmi_handle", NULL); + assert( handle_n != NULL ); + dmixml_AddAttribute(handle_n, "id", "0x%04x%c", h.handle); + dmixml_AddAttribute(handle_n, "type", "%d", h.type); + dmixml_AddAttribute(handle_n, "size", "%d", h.length); /* assign vendor for vendor-specific decodes later */ - if(h.type == 0 && h.length >= 5) + if(h.type == 0 && h.length >= 5) { + /* FIXME: Need XML API */ dmi_set_vendor(dmi_string(&h, data[0x04])); + } /* look for the next handle */ next = data + h.length; - while(next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) + while(next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) { next++; - + } next += 2; if(display) { @@ -5202,12 +5326,11 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - PyDict_SetItem(hDict, PyString_FromString("data"), - dmi_decode(&h, ver)); - PyDict_SetItem(pydata, PyString_FromString(hid), hDict); + dmi_decode(handle_n, &h, ver); } else fprintf(stderr, ""); } else if(opt.string != NULL && opt.string->type == h.type) { + // <<<---- ** Need to handle this as well ** dmi_table_string_py(&h, data, hDict, ver); } @@ -5275,7 +5398,8 @@ int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) } return check; } -int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata) + +int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5292,7 +5416,7 @@ int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata) } //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, - pydata); + xmlnode); } return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index 066363f..b8c70fa 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -28,18 +28,18 @@ struct dmi_header { }; PyObject *dmi_dump(struct dmi_header *h); -PyObject *dmi_decode(struct dmi_header *h, u16 ver); +void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); -int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata); +int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata); const char *dmi_string(const struct dmi_header *dm, u8 s); -const char *dmi_system_uuid(u8 * p); +void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); PyObject *dmi_system_uuid_py(const u8 * p, u16 ver); -const char *dmi_chassis_type(u8 code); +void dmi_chassis_type(xmlNode *node, u8 code); int dmi_processor_frequency(const u8 * p); int dump(const char *dumpfile); -- cgit From 612445e94781f14af65490b52c898b9eaa5f5e85 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 8 Apr 2009 19:02:03 +0200 Subject: Ported most functions to XML interface Still do not compile --- src/dmidecode.c | 2592 +++++++++++++++++++++++++------------------------ src/dmidecode.h | 7 +- src/dmidecodemodule.h | 8 +- 3 files changed, 1323 insertions(+), 1284 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 907fe57..773a673 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5,6 +5,7 @@ * * Copyright 2000-2002 Alan Cox * Copyright 2002-2008 Jean Delvare + * Copyright 2009 David Sommerseth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,9 +64,9 @@ /* #undef NDEBUG -#include */ +#include #include #include #include @@ -95,37 +96,6 @@ static const char *bad_index = ""; ** Type-independant Stuff */ -static PyObject *dmi_string_py(const struct dmi_header *dm, u8 s) -{ - char *bp = (char *)dm->data; - size_t i, len; - - PyObject *data; - - if(s == 0) - data = PyString_FromString("Not Specified"); - else { - bp += dm->length; - while(s > 1 && *bp) { - bp += strlen(bp); - bp++; - s--; - } - - if(!*bp) - data = BAD_INDEX; - else { - /* ASCII filtering */ - len = strlen(bp); - for(i = 0; i < len; i++) - if(bp[i] < 32 || bp[i] == 127) - bp[i] = '.'; - data = PyString_FromString(bp); - } - } - return data; -} - const char *dmi_string(const struct dmi_header *dm, u8 s) { char *bp = (char *)dm->data; @@ -233,25 +203,36 @@ static int dmi_bcd_range(u8 value, u8 low, u8 high) return 1; } -PyObject *dmi_dump(struct dmi_header * h) +void dmi_dump(xmlNode *node, struct dmi_header * h) { int row, i; const char *s; + xmlNode *dump_n = NULL, *row_n = NULL; + char *tmp_s = NULL; - PyObject *data = PyDict_New(); - PyObject *data1 = PyList_New(0); + dump_n = xmlNewChild(node, NULL, (xmlChar *) "HeaderAndData", NULL); + assert( dump_n != NULL ); + tmp_s = (char *) malloc((h->length * 2) + 2); for(row = 0; row < ((h->length - 1) >> 4) + 1; row++) { - for(i = 0; i < 16 && i < h->length - (row << 4); i++) - PyList_Append(data1, - PyString_FromFormat("0x%02x", (h->data)[(row << 4) + i])); + memset(tmp_s, 0, (h->length * 2) + 2); + + for(i = 0; i < (16 && i < h->length - (row << 4)); i++) { + snprintf(tmp_s + strlen(tmp_s), (h->length * 2)-strlen(tmp_s), + "0x%02x", (h->data)[(row << 4) + i]); + } + row_n = dmixml_AddTextChild(dump_n, "Row", "%s", tmp_s); + dmixml_AddAttribute(row_n, "index", "%i", row); + row_n = NULL; } - PyDict_SetItemString(data, "Header and Data", data1); + free(tmp_s); tmp_s = NULL; + dump_n = NULL; + + dump_n = xmlNewChild(node, NULL, (xmlChar *) "Strings", NULL); + assert( dump_n != NULL ); if((h->data)[h->length] || (h->data)[h->length + 1]) { i = 1; - PyObject *data2 = PyList_New(0); - while((s = dmi_string(h, i++)) != bad_index) { //. FIXME: DUMP /* @@ -265,23 +246,31 @@ PyObject *dmi_dump(struct dmi_header * h) * } * else fprintf(stderr, "%s|", s); */ - PyList_Append(data1, PyString_FromFormat("%s", s)); + row_n = dmixml_AddTextChild(dump_n, "String", "%s", s); + dmixml_AddAttribute(row_n, "index", "%i", i); + row_n = NULL; } - PyDict_SetItemString(data, "Strings", data2); } - return data; + dump_n = NULL; } /******************************************************************************* ** 3.3.1 BIOS Information (Type 0) */ -static PyObject *dmi_bios_runtime_size(u32 code) +void dmi_bios_runtime_size(xmlNode *node, u32 code) { - if(code & 0x000003FF) - return PyString_FromFormat("%i bytes", code); - else - return PyString_FromFormat("%i kB", code >> 10); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RuntimeSize", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code & 0x000003FF) { + dmixml_AddAttribute(data_n, "unit", "bytes"); + dmixml_AddTextContent(data_n, "%i", code); + } else { + dmixml_AddAttribute(data_n, "unit", "KB"); + dmixml_AddTextContent(data_n, "%i", code >> 10); + } } /* 3.3.1.1 */ @@ -321,7 +310,7 @@ void dmi_bios_characteristics(xmlNode *node, u64 code) dmixml_AddAttribute(node, "dmispec", "3.3.1.1"); dmixml_AddAttribute(node, "flags", "0x%04x", code); - if(code.l & (1 << 3)) { + if(code.l&(1<<3)) { dmixml_AddAttribute(node, "unavailable", "1"); dmixml_AddTextContent(node, characteristics[0]); } else { @@ -2042,24 +2031,23 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) } } -static PyObject *dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) +void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3) { /* 3.3.10.8 */ - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BusAddress", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.10.8"); - if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) - data = - PyString_FromFormat("%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7); - else - data = Py_None; - return data; + if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) { + dmixml_AddTextContent(data_n, "%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7); + } } /******************************************************************************* ** 3.3.11 On Board Devices Information (Type 10) */ -static const char *dmi_on_board_devices_type(xmlNode *node, u8 code) +void dmi_on_board_devices_type(xmlNode *node, u8 code) { /* 3.3.11.1 */ static const char *type[] = { @@ -2165,7 +2153,7 @@ void dmi_bios_languages(xmlNode *node, struct dmi_header *h) dmixml_AddAttribute(data_n, "count", "%i", count); for(i = 1; i <= count; i++) { - xmlNode *l_n = dmixml_AddTextChild(data_n, "Language", "%s", dmi_string_py(h, i)); + xmlNode *l_n = dmixml_AddTextChild(data_n, "Language", "%s", dmi_string(h, i)); assert( l_n != NULL ); dmixml_AddAttribute(l_n, "index", "%i", i); } @@ -2382,7 +2370,7 @@ void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * ** 3.3.17 Physical Memory Array (Type 16) */ -static PyObject *dmi_memory_array_location(u8 code) +void dmi_memory_array_location(xmlNode *node, u8 code) { /* 3.3.17.1 */ static const char *location[] = { @@ -2405,14 +2393,21 @@ static PyObject *dmi_memory_array_location(u8 code) "PC-98/Card Slot Add-on Card" /* 0xA4, from master.mif */ }; - if(code >= 0x01 && code <= 0x0A) - return PyString_FromString(location[code - 0x01]); - if(code >= 0xA0 && code <= 0xA4) - return PyString_FromString(location_0xA0[code - 0xA0]); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.17.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code >= 0x01 && code <= 0x0A) { + dmixml_AddTextContent(data_n, location[code - 0x01]); + } else if(code >= 0xA0 && code <= 0xA4) { + dmixml_AddTextContent(data_n, location_0xA0[code - 0xA0]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_array_use(u8 code) +void dmi_memory_array_use(xmlNode *node, u8 code) { /* 3.3.17.2 */ static const char *use[] = { @@ -2424,13 +2419,19 @@ static PyObject *dmi_memory_array_use(u8 code) "Non-volatile RAM", "Cache Memory" /* 0x07 */ }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Use", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.17.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x07) - return PyString_FromString(use[code - 0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x07) { + dmixml_AddTextContent(data_n, use[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_array_ec_type(u8 code) +void dmi_memory_array_ec_type(xmlNode *node, u8 code) { /* 3.3.17.3 */ static const char *type[] = { @@ -2443,78 +2444,92 @@ static PyObject *dmi_memory_array_ec_type(u8 code) "CRC" /* 0x07 */ }; - if(code >= 0x01 && code <= 0x07) - return PyString_FromString(type[code - 0x01]); - return OUT_OF_SPEC; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorCorrectionType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.17.3"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code >= 0x01 && code <= 0x07) { + dmixml_AddTextContent(data_n, type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_array_capacity(u32 code) +void dmi_memory_array_capacity(xmlNode *node, u32 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxCapacity", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000000) - data = PyString_FromString("Unknown"); - else { - if((code & 0x000FFFFF) == 0) - data = PyString_FromFormat("%i GB", code >> 20); - else if((code & 0x000003FF) == 0) - data = PyString_FromFormat("%i MB", code >> 10); - else - data = PyString_FromFormat("%i kB", code); + if(code == 0x8000000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + if((code & 0x000FFFFF) == 0) { + dmixml_AddAttribute(data_n, "unit", "GB"); + dmixml_AddTextContent(data_n, "%i", code >> 20); + } else if((code & 0x000003FF) == 0) { + dmixml_AddAttribute(data_n, "unit", "MB"); + dmixml_AddTextContent(data_n, "%i", code >> 10); + } else { + dmixml_AddAttribute(data_n, "unit", "KB"); + dmixml_AddTextContent(data_n, "%i", code); + } } - return data; } -static PyObject *dmi_memory_array_error_handle(u16 code) +void dmi_memory_array_error_handle(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorInfoHandle", NULL); + assert( data_n != NULL ); - if(code == 0xFFFE) - data = PyString_FromString("Not Provided"); - else if(code == 0xFFFF) - data = PyString_FromString("No Error"); - else - data = PyString_FromFormat("0x%04x", code); - return data; + if(code == 0xFFFE) { + dmixml_AddAttribute(data_n, "not_provided", "1"); + } else if(code == 0xFFFF) { + dmixml_AddAttribute(data_n, "no_error", "1"); + } else { + dmixml_AddTextContent(data_n, "0x%04x", code); + } } /******************************************************************************* ** 3.3.18 Memory Device (Type 17) */ -static PyObject *dmi_memory_device_width(u16 code) +void dmi_memory_device_width(xmlNode *node, const char *tagname, u16 code) { /* ** If no memory module is present, width may be 0 */ - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); - if(code == 0xFFFF || code == 0) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%i bits", code); - return data; + if(code == 0xFFFF || code == 0) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "bit"); + dmixml_AddTextContent(data_n, "%i", code); + } } -static PyObject *dmi_memory_device_size(u16 code) +void dmi_memory_device_size(xmlNode *node, u16 code) { - PyObject *data = NULL; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Size", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0) - data = Py_None; //. No Module Installed - else if(code == 0xFFFF) - data = PyString_FromString("Unknown"); //. Unknown - else { + if(code == 0) { + dmixml_AddAttribute(data_n, "empty", "1"); + } else if(code == 0xFFFF) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { //. Keeping this as String rather than Int as it has KB and MB representations... - if(code & 0x8000) - data = PyString_FromFormat("%d KB", code & 0x7FFF); - else - data = PyString_FromFormat("%d MB", code); + dmixml_AddAttribute(data_n, "unit", "%s", (code & 0x8000 ? "KB" : "MB")); + dmixml_AddTextContent(data_n, "%d", (code & 0x8000 ? code & 0x7FFF : code)); } - return data; } -static PyObject *dmi_memory_device_form_factor(u8 code) +void dmi_memory_device_form_factor(xmlNode *node, u8 code) { /* 3.3.18.1 */ static const char *form_factor[] = { @@ -2534,27 +2549,32 @@ static PyObject *dmi_memory_device_form_factor(u8 code) "SRIMM", "FB-DIMM" /* 0x0F */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "FormFactor", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.18.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0F) - return data = PyString_FromString(form_factor[code - 0x01]); - return data = OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x0F) { + dmixml_AddTextContent(data_n, "%s", form_factor[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_device_set(u8 code) +void dmi_memory_device_set(xmlNode *node, u8 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Set", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0) - data = Py_None; - else if(code == 0xFF) - data = PyString_FromString("Unknown"); - else - data = PyInt_FromLong(code); - return data; + if(code == 0xFF) { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } else if( code > 0 ) { + dmixml_AddTextContent(data_n, "%ld", code); + } } -static PyObject *dmi_memory_device_type(u8 code) +void dmi_memory_device_type(xmlNode *node, u8 code) { /* 3.3.18.2 */ static const char *type[] = { @@ -2579,13 +2599,19 @@ static PyObject *dmi_memory_device_type(u8 code) "DDR2", "DDR2 FB-DIMM" /* 0x14 */ }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.18.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x14) - return PyString_FromString(type[code - 0x01]); - return OUT_OF_SPEC; + if(code >= 0x01 && code <= 0x14) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_device_type_detail(u16 code) +void dmi_memory_device_type_detail(xmlNode *node, u16 code) { /* 3.3.18.3 */ static const char *detail[] = { @@ -2602,40 +2628,43 @@ static PyObject *dmi_memory_device_type_detail(u16 code) "Cache DRAM", "Non-Volatile" /* 12 */ }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "TypeDetails", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.18.3"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - PyObject *data; - - if((code & 0x1FFE) == 0) - data = Py_None; - else { + if((code & 0x1FFE) != 0) { int i; - - data = PyList_New(12); - for(i = 1; i <= 12; i++) - if(code & (1 << i)) - PyList_SET_ITEM(data, i - 1, PyString_FromString(detail[i - 1])); - else - PyList_SET_ITEM(data, i - 1, Py_None); + for(i = 1; i <= 12; i++) { + if(code & (1 << i)) { + xmlNode *td_n = dmixml_AddTextChild(data_n, "flag", "%s", detail[i - 1]); + assert( td_n != NULL ); + dmixml_AddAttribute(td_n, "index", "%i", i); + } + } } - return data; } -static PyObject *dmi_memory_device_speed(u16 code) +void dmi_memory_device_speed(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Speed", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%i MHz (%.1f ns)", code, (float)1000 / code); - return data; + if(code == 0) { + dmixml_AddAttribute(data_n, "unkown", "1"); + } else { + dmixml_AddAttribute(data_n, "speed_ns", "%.1f ns", (float) 1000 / code); + dmixml_AddAttribute(data_n, "unit", "MHz"); + dmixml_AddTextContent(data_n, "%i", code); + } } /******************************************************************************* * 3.3.19 32-bit Memory Error Information (Type 18) */ -static PyObject *dmi_memory_error_type(u8 code) +void dmi_memory_error_type(xmlNode *node, u8 code) { /* 3.3.19.1 */ static const char *type[] = { @@ -2654,15 +2683,19 @@ static PyObject *dmi_memory_error_type(u8 code) "Corrected Error", "Uncorrectable Error" /* 0x0E */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.19.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0E) - data = PyString_FromString(type[code - 0x01]); - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x0E) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_error_granularity(u8 code) +void dmi_memory_error_granularity(xmlNode *node, u8 code) { /* 3.3.19.2 */ static const char *granularity[] = { @@ -2671,16 +2704,19 @@ static PyObject *dmi_memory_error_granularity(u8 code) "Device Level", "Memory Partition Level" /* 0x04 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Granularity", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.19.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x04) - data = PyString_FromString(granularity[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x04) { + dmixml_AddTextContent(data_n, "%s", granularity[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_error_operation(u8 code) +void dmi_memory_error_operation(xmlNode *node, u8 code) { /* 3.3.19.3 */ static const char *operation[] = { @@ -2690,108 +2726,114 @@ static PyObject *dmi_memory_error_operation(u8 code) "Write", "Partial Write" /* 0x05 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Operation", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.19.3"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x05) - data = PyString_FromString(operation[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x05) { + dmixml_AddTextContent(data_n, "%s", operation[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_error_syndrome(u32 code) +void dmi_memory_error_syndrome(xmlNode *node, u32 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "VendorSyndrome", NULL); + assert( data_n != NULL ); - if(code == 0x00000000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("0x%08x", code); - return data; + if(code == 0x00000000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddTextContent(data_n, "0x%08x", code); + } } -static PyObject *dmi_32bit_memory_error_address(u32 code) +void dmi_32bit_memory_error_address(xmlNode *node, char *tagname, u32 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); - if(code == 0x80000000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("0x%08x", code); - return data; + if(code == 0x80000000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddTextContent(data_n, "0x%08x", code); + } } /******************************************************************************* ** 3.3.20 Memory Array Mapped Address (Type 19) */ -static PyObject *dmi_mapped_address_size(u32 code) +void dmi_mapped_address_size(xmlNode *node, u32 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RangeSize", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.19.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0) - data = PyString_FromString("Invalid"); - else if((code & 0x000FFFFF) == 0) - data = PyString_FromFormat("%i GB", code >> 20); - else if((code & 0x000003FF) == 0) - data = PyString_FromFormat("%i MB", code >> 10); - else - data = PyString_FromFormat("%i kB", code); - return data; + if(code == 0) { + dmixml_AddAttribute(data_n, "invalid", "1"); + } else if((code & 0x000FFFFF) == 0) { + dmixml_AddAttribute(data_n, "unit", "GB"); + dmixml_AddTextContent(data_n, "%i", code >> 20); + } else if((code & 0x000003FF) == 0) { + dmixml_AddAttribute(data_n, "unit", "MB"); + dmixml_AddTextContent(data_n, "%i", code >> 10); + } else { + dmixml_AddAttribute(data_n, "unit", "KB"); + dmixml_AddTextContent(data_n, "%i", code); + } } /******************************************************************************* ** 3.3.21 Memory Device Mapped Address (Type 20) */ -static PyObject *dmi_mapped_address_row_position(u8 code) +void dmi_mapped_address_row_position(xmlNode *node, u8 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "PartitionRowPosition", NULL); + assert( data_n != NULL ); - if(code == 0) - data = OUT_OF_SPEC; - else if(code == 0xFF) - data = PyString_FromString("Unknown"); - else - data = PyInt_FromLong(code); - return data; + if(code == 0) { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } else if(code == 0xFF) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddTextContent(data_n, "%ld", code); + } } -static PyObject *dmi_mapped_address_interleave_position(u8 code) +void dmi_mapped_address_interleave_position(xmlNode *node, u8 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterleavePosition", NULL); + assert( data_n != NULL ); - if(code != 0) { - data = PyDict_New(); - PyDict_SetItemString(data, "Interleave Position", - (code == - 0xFF) ? PyString_FromString("Unknown") : - PyInt_FromLong(code)); - } else - data = Py_None; - return data; + if( code <= 0xFE ) { + dmixml_AddTextContent(data_n, "%i", code); + } else { + dmixml_AddAttribute(data_n, "unknown", "1"); + } } -static PyObject *dmi_mapped_address_interleaved_data_depth(u8 code) +void dmi_mapped_address_interleaved_data_depth(xmlNode *node, u8 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterleaveDataDepth", NULL); + assert( data_n != NULL ); - if(code != 0) { - data = PyDict_New(); - PyDict_SetItemString(data, "Interleave Data Depth", - (code == - 0xFF) ? PyString_FromString("Unknown") : - PyInt_FromLong(code)); - } else - data = Py_None; - return data; + if( code < 0xFF ) { + dmixml_AddTextContent(data_n, "%i", code); + } else { + dmixml_AddAttribute(data_n, "unknown", "1"); + } } /******************************************************************************* ** 3.3.22 Built-in Pointing Device (Type 21) */ -static PyObject *dmi_pointing_device_type(u8 code) +void dmi_pointing_device_type(xmlNode *node, u8 code) { /* 3.3.22.1 */ static const char *type[] = { @@ -2805,16 +2847,19 @@ static PyObject *dmi_pointing_device_type(u8 code) "Touch Screen", "Optical Sensor" /* 0x09 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DeviceType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.22.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x09) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x09) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_pointing_device_interface(u8 code) +void dmi_pointing_device_interface(xmlNode *node, u8 code) { /* 3.3.22.2 */ static const char *interface[] = { @@ -2832,22 +2877,25 @@ static PyObject *dmi_pointing_device_interface(u8 code) "Bus Mouse Micro DIN", "USB" /* 0xA2 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DeviceInterface", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.22.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x08) - data = PyString_FromString(interface[code - 0x01]); - else if(code >= 0xA0 && code <= 0xA2) - data = PyString_FromString(interface_0xA0[code - 0xA0]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x08) { + dmixml_AddTextContent(data_n, interface[code - 0x01]); + } else if(code >= 0xA0 && code <= 0xA2) { + dmixml_AddTextContent(data_n, interface_0xA0[code - 0xA0]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /******************************************************************************* ** 3.3.23 Portable Battery (Type 22) */ -static PyObject *dmi_battery_chemistry(u8 code) +void dmi_battery_chemistry(xmlNode *node, u8 code) { /* 3.3.23.1 */ static const char *chemistry[] = { @@ -2860,94 +2908,110 @@ static PyObject *dmi_battery_chemistry(u8 code) "Zinc Air", "Lithium Polymer" /* 0x08 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BatteryChemistry", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.22.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x08) - data = PyString_FromString(chemistry[code - 0x01]); - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x08) { + dmixml_AddTextContent(data_n, "%s", chemistry[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_battery_capacity(u16 code, u8 multiplier) +void dmi_battery_capacity(xmlNode *node, u16 code, u8 multiplier) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DesignCapacity", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "value", "0x%04x", code); + dmixml_AddAttribute(data_n, "multiplier", "0x%04x", multiplier); - if(code == 0) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%i mWh", code * multiplier); - return data; + if(code != 0) { + dmixml_AddAttribute(data_n, "unit", "mWh"); + dmixml_AddTextContent(data_n, "%i", code * multiplier); + } } -static PyObject *dmi_battery_voltage(u16 code) +void dmi_battery_voltage(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DesignVoltage", NULL); + assert( data_n != NULL ); - if(code == 0) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%i mV", code); - return data; + if(code == 0) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "mV"); + dmixml_AddTextContent(data_n, "%i", code); + } } -static PyObject *dmi_battery_maximum_error(u8 code) +void dmi_battery_maximum_error(xmlNode *node, u8 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaximumError", NULL); + assert( data_n != NULL ); - if(code == 0xFF) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%i%%", code); - return data; + if(code == 0xFF) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddTextContent(data_n, "%i%%", code); + } } /******************************************************************************* ** 3.3.24 System Reset (Type 23) */ -static PyObject *dmi_system_reset_boot_option(u8 code) +void dmi_system_reset_boot_option(xmlNode *node, const char *tagname, u8 code) { static const char *option[] = { "Operating System", /* 0x1 */ "System Utilities", "Do Not Reboot" /* 0x3 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x1) - data = PyString_FromString(option[code - 0x1]); - else - data = OUT_OF_SPEC; - return data; + if( (code > 0) && (code < 4) ) { + dmixml_AddTextContent(data_n, option[code - 0x1]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_system_reset_count(u16 code) +void dmi_system_reset_count(xmlNode *node, const char *tagname, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0xFFFF) - data = PyString_FromString("Unknown"); - else - data = PyInt_FromLong(code); - return data; + if(code == 0xFFFF) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddTextContent(data_n, "%ld", code); + } } -static PyObject *dmi_system_reset_timer(u16 code) +void dmi_system_reset_timer(xmlNode *node, const char *tagname, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0xFFFF) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%i min", code); - return data; + if(code == 0xFFFF) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "min"); + dmixml_AddTextContent(data_n, "%i", code); + } } /******************************************************************************* * 3.3.25 Hardware Security (Type 24) */ -static PyObject *dmi_hardware_security_status(u8 code) +void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code) { static const char *status[] = { "Disabled", /* 0x00 */ @@ -2955,48 +3019,45 @@ static PyObject *dmi_hardware_security_status(u8 code) "Not Implemented", "Unknown" /* 0x03 */ }; - - return PyString_FromString(status[code]); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + dmixml_AddTextContent(data_n, "%s", status[code]); } /******************************************************************************* ** 3.3.26 System Power Controls (Type 25) */ -static PyObject *dmi_power_controls_power_on(const u8 * p) +#define DMI_POWER_CTRL_TIME_STR(dest, variant, data) \ + if( variant ) { snprintf(dest, 3, "%02x", data); } \ + else { snprintf(dest, 3, "*"); } \ + +void dmi_power_controls_power_on(xmlNode *node, const char *tagname, const u8 * p) { /* 3.3.26.1 */ - PyObject *data = PyList_New(5); - - PyList_SET_ITEM(data, 0, - dmi_bcd_range(p[0], 0x01, 0x12) ? PyString_FromFormat(" %02x", - p[0]) : - PyString_FromString(" *")); - PyList_SET_ITEM(data, 1, - dmi_bcd_range(p[1], 0x01, 0x31) ? PyString_FromFormat("-%02x", - p[1]) : - PyString_FromString("-*")); - PyList_SET_ITEM(data, 2, - dmi_bcd_range(p[2], 0x00, 0x23) ? PyString_FromFormat(" %02x", - p[2]) : - PyString_FromString(" *")); - PyList_SET_ITEM(data, 3, - dmi_bcd_range(p[3], 0x00, 0x59) ? PyString_FromFormat(":%02x", - p[3]) : - PyString_FromString(":*")); - PyList_SET_ITEM(data, 4, - dmi_bcd_range(p[4], 0x00, 0x59) ? PyString_FromFormat(":%02x", - p[4]) : - PyString_FromString(":*")); - - return data; + char timestr[5][5]; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.26.1"); + dmixml_AddAttribute(data_n, "flags", "0x%08x", p); + + DMI_POWER_CTRL_TIME_STR(timestr[0], dmi_bcd_range(p[0], 0x01, 0x12), p[0]) + DMI_POWER_CTRL_TIME_STR(timestr[1], dmi_bcd_range(p[1], 0x01, 0x31), p[1]) + DMI_POWER_CTRL_TIME_STR(timestr[2], dmi_bcd_range(p[2], 0x01, 0x23), p[2]) + DMI_POWER_CTRL_TIME_STR(timestr[3], dmi_bcd_range(p[3], 0x01, 0x59), p[3]) + DMI_POWER_CTRL_TIME_STR(timestr[4], dmi_bcd_range(p[4], 0x01, 0x59), p[4]) + + dmixml_AddTextContent(data_n, "%s-%s %s:%s:%s", + timestr[0], timestr[1], + timestr[2], timestr[3], timestr[4]); } /******************************************************************************* * 3.3.27 Voltage Probe (Type 26) */ -static PyObject *dmi_voltage_probe_location(u8 code) +void dmi_voltage_probe_location(xmlNode *node, u8 code) { /* 3.3.27.1 */ static const char *location[] = { @@ -3012,16 +3073,19 @@ static PyObject *dmi_voltage_probe_location(u8 code) "Power Unit", "Add-in Card" /* 0x0B */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.27.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0B) - data = PyString_FromString(location[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x0B) { + dmixml_AddTextContent(data_n, "%s", location[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_probe_status(u8 code) +void dmi_probe_status(xmlNode *node, u8 code) { /* 3.3.27.1 */ static const char *status[] = { @@ -3032,53 +3096,65 @@ static PyObject *dmi_probe_status(u8 code) "Critical", "Non-recoverable" /* 0x06 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.27.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x06) - data = PyString_FromString(status[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x06) { + dmixml_AddTextContent(data_n, "%s", status[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_voltage_probe_value(u16 code) +void dmi_voltage_probe_value(xmlNode *node, const char *tagname, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.3f V", (float)(i16) code / 1000); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "V"); + dmixml_AddTextContent(data_n, "%.3f", (float)(i16) code / 1000); + } } -static PyObject *dmi_voltage_probe_resolution(u16 code) +void dmi_voltage_probe_resolution(xmlNode *node, u16 code) { - PyObject *data; - - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.1f mV", (float)code / 10); - return data; -} + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); -static PyObject *dmi_probe_accuracy(u16 code) + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "mV"); + dmixml_AddTextContent(data_n, "%.1f", (float) code / 10); + } +} + +void dmi_probe_accuracy(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Accuracy", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.2f%%", (float)code / 100); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "%%"); + dmixml_AddTextContent(data_n, "%.2f", (float)code / 100); + } } /******************************************************************************* ** 3.3.28 Cooling Device (Type 27) */ -static PyObject *dmi_cooling_device_type(u8 code) +void dmi_cooling_device_type(xmlNode *node, u8 code) { /* 3.3.28.1 */ static const char *type[] = { @@ -3096,33 +3172,39 @@ static PyObject *dmi_cooling_device_type(u8 code) "Active Cooling", /* 0x10, master.mif says 32 */ "Passive Cooling" /* 0x11, master.mif says 33 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.28.1", code); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x09) - data = PyString_FromString(type[code - 0x01]); - else if(code >= 0x10 && code <= 0x11) - data = PyString_FromString(type_0x10[code - 0x10]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x09) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else if(code >= 0x10 && code <= 0x11) { + dmixml_AddTextContent(data_n, "%s", type_0x10[code - 0x10]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_cooling_device_speed(u16 code) +void dmi_cooling_device_speed(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "NominalSpeed", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown Or Non-rotating"); - else - data = PyString_FromFormat("%i rpm", code); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } + + dmixml_AddAttribute(data_n, "unit", "rpm"); + dmixml_AddTextContent(data_n, "%i", code); } /******************************************************************************* ** 3.3.29 Temperature Probe (Type 28) */ -static PyObject *dmi_temperature_probe_location(u8 code) +void dmi_temperature_probe_location(xmlNode *node, u8 code) { /* 3.3.29.1 */ static const char *location[] = { @@ -3142,68 +3224,83 @@ static PyObject *dmi_temperature_probe_location(u8 code) "Power System Board", "Drive Back Plane" /* 0x0F */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.29.1", code); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0F) - data = PyString_FromString(location[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x0F) { + dmixml_AddTextChild(node, "%s", location[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_temperature_probe_value(u16 code) +void dmi_temperature_probe_value(xmlNode *node, const char *tagname, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.1f deg C", (float)(i16) code / 10); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "C"); + dmixml_AddTextContent(data_n, "%.1f", (float)(i16) code / 10); + } } -static PyObject *dmi_temperature_probe_resolution(u16 code) +void dmi_temperature_probe_resolution(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.3f deg C", (float)code / 1000); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "C"); + dmixml_AddTextContent(data_n, "%.3f deg C", (float)code / 1000); + } } /******************************************************************************* ** 3.3.30 Electrical Current Probe (Type 29) */ -static PyObject *dmi_current_probe_value(u16 code) +void dmi_current_probe_value(xmlNode *node, const char *tagname, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.3f A", (float)(i16) code / 1000); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "A"); + dmixml_AddTextContent(data_n, "%.3f", (float)(i16) code / 1000); + } } -static PyObject *dmi_current_probe_resolution(u16 code) +void dmi_current_probe_resolution(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.1f mA", (float)code / 10); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "mA"); + dmixml_AddTextContent(data_n, "%.1f A", (float)code / 10); + } } /******************************************************************************* ** 3.3.33 System Boot Information (Type 32) */ -static PyObject *dmi_system_boot_status(u8 code) +void dmi_system_boot_status(xmlNode *node, u8 code) { static const char *status[] = { "No errors detected", /* 0 */ @@ -3216,39 +3313,42 @@ static PyObject *dmi_system_boot_status(u8 code) "Previously-requested image", "System watchdog timer expired" /* 8 */ }; - PyObject *data; - - if(code <= 8) - data = PyString_FromString(status[code]); - else if(code >= 128 && code <= 191) - data = PyString_FromString("OEM-specific"); - else if(code >= 192) - data = PyString_FromString("Product-specific"); - else - data = OUT_OF_SPEC; - return data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if(code <= 8) { + dmixml_AddTextContent(data_n, "%s", status[code]); + } else if(code >= 128 && code <= 191) { + dmixml_AddTextContent(data_n, "OEM-specific"); + } else if(code >= 192) { + dmixml_AddTextContent(data_n, "Product-specific"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /******************************************************************************* ** 3.3.34 64-bit Memory Error Information (Type 33) */ -static PyObject *dmi_64bit_memory_error_address(u64 code) +void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); + assert( data_n != NULL ); - if(code.h == 0x80000000 && code.l == 0x00000000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("0x%08x%08x", code.h, code.l); - return data; + if(code.h == 0x80000000 && code.l == 0x00000000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddTextContent(data_n, "0x%08x%08x", code.h, code.l); + } } /******************************************************************************* ** 3.3.35 Management Device (Type 34) */ -static PyObject *dmi_management_device_type(u8 code) +void dmi_management_device_type(xmlNode *node, u8 code) { /* 3.3.35.1 */ static const char *type[] = { @@ -3266,16 +3366,19 @@ static PyObject *dmi_management_device_type(u8 code) "W83781D", "HT82H791" /* 0x0D */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.35.1", code); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0D) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x0D) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_management_device_address_type(u8 code) +void dmi_management_device_address_type(xmlNode *node, u8 code) { /* 3.3.35.2 */ static const char *type[] = { @@ -3285,20 +3388,23 @@ static PyObject *dmi_management_device_address_type(u8 code) "Memory", "SMBus" /* 0x05 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "AddressType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.35.2", code); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x05) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x05) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /******************************************************************************* ** 3.3.38 Memory Channel (Type 37) */ -static PyObject *dmi_memory_channel_type(u8 code) +void dmi_memory_channel_type(xmlNode *node, u8 code) { /* 3.3.38.1 */ static const char *type[] = { @@ -3307,43 +3413,36 @@ static PyObject *dmi_memory_channel_type(u8 code) "RamBus", "SyncLink" /* 0x04 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.38.1", code); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x04) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x04) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_memory_channel_devices(u8 count, const u8 * p) +void dmi_memory_channel_devices(xmlNode *node, u8 count, const u8 * p) { - PyObject *data = PyDict_New(); - PyObject *subdata, *val; int i; for(i = 1; i <= count; i++) { - subdata = PyList_New(2); - - val = PyString_FromFormat("Load: %i", p[3 * i]); - PyList_SET_ITEM(subdata, 0, val); - Py_DECREF(val); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Device", NULL); + assert( data_n != NULL ); - val = PyString_FromFormat("Handle: 0x%04x", WORD(p + 3 * i + 1)); - PyList_SET_ITEM(subdata, 1, val); - Py_DECREF(val); - - PyDict_SetItem(data, PyInt_FromLong(i), subdata); - Py_DECREF(subdata); + dmixml_AddAttribute(data_n, "Load", "%i", p[3 * i]); + dmixml_AddAttribute(data_n, "Handle", "0x%04x", WORD(p + 3 * i + 1)); } - return data; } /******************************************************************************* ** 3.3.39 IPMI Device Information (Type 38) */ -static PyObject *dmi_ipmi_interface_type(u8 code) +void dmi_ipmi_interface_type(xmlNode *node, u8 code) { /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */ static const char *type[] = { @@ -3353,32 +3452,36 @@ static PyObject *dmi_ipmi_interface_type(u8 code) "BT (Block Transfer)", "SSIF (SMBus System Interface)" /* 0x04 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterfaceType", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.39.1", code); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code <= 0x04) - data = PyString_FromString(type[code]); - else - data = OUT_OF_SPEC; - return data; + if(code <= 0x04) { + dmixml_AddTextContent(data_n, "%s", type[code]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_ipmi_base_address(u8 type, const u8 * p, u8 lsb) +void dmi_ipmi_base_address(xmlNode *node, u8 type, const u8 * p, u8 lsb) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BaseAddress", NULL); + assert( data_n != NULL ); if(type == 0x04) { /* SSIF */ - data = PyString_FromFormat("0x%02x (SMBus)", (*p) >> 1); + dmixml_AddAttribute(data_n, "interface", "SMBus-SSIF"); + dmixml_AddTextContent(data_n, "0x%02x", (*p) >> 1); } else { u64 address = QWORD(p); - - data = - PyString_FromFormat("0x%08x%08x (%s)", address.h, (address.l & ~1) | lsb, - address.l & 1 ? "I/O" : "Memory-mapped"); + dmixml_AddAttribute(data_n, "interface", "%s", + address.l & 1 ? "I/O" : "Memory-mapped"); + dmixml_AddTextContent(data_n, "0x%08x%08x", + address.h, (address.l & ~1) | lsb); } - return data; } -static PyObject *dmi_ipmi_register_spacing(u8 code) +void dmi_ipmi_register_spacing(xmlNode *node, u8 code) { /* IPMI 2.0, appendix C1, table C1-1 */ static const char *spacing[] = { @@ -3386,29 +3489,36 @@ static PyObject *dmi_ipmi_register_spacing(u8 code) "32-bit Boundaries", "16-byte Boundaries" /* 0x02 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RegisterSpacing", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code <= 0x02) - return data = PyString_FromString(spacing[code]); - return data = OUT_OF_SPEC; + if(code <= 0x02) { + dmixml_AddTextContent(data_n, "%s", spacing[code]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /******************************************************************************* ** 3.3.40 System Power Supply (Type 39) */ -static PyObject *dmi_power_supply_power(u16 code) +void dmi_power_supply_power(xmlNode *node, u16 code) { - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxPowerCapacity", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code == 0x8000) - data = PyString_FromString("Unknown"); - else - data = PyString_FromFormat("%.3f W", (float)code / 1000); - return data; + if(code == 0x8000) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "W"); + dmixml_AddTextContent(data_n, "%.3f", (float)code / 1000); + } } -static PyObject *dmi_power_supply_type(u8 code) +void dmi_power_supply_type(xmlNode *node, u8 code) { /* 3.3.40.1 */ static const char *type[] = { @@ -3421,16 +3531,19 @@ static PyObject *dmi_power_supply_type(u8 code) "Converter", "Regulator" /* 0x08 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x08) - data = PyString_FromString(type[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x08) { + dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_power_supply_status(u8 code) +void dmi_power_supply_status(xmlNode *node, u8 code) { /* 3.3.40.1 */ static const char *status[] = { @@ -3440,16 +3553,20 @@ static PyObject *dmi_power_supply_status(u8 code) "Non-critical", "Critical" /* 0x05 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + dmixml_AddAttribute(data_n, "present", "1"); - if(code >= 0x01 && code <= 0x05) - data = PyString_FromString(status[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x05) { + dmixml_AddTextContent(data_n, "%s", status[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } -static PyObject *dmi_power_supply_range_switching(u8 code) +void dmi_power_supply_range_switching(xmlNode *node, u8 code) { /* 3.3.40.1 */ static const char *switching[] = { @@ -3460,13 +3577,16 @@ static PyObject *dmi_power_supply_range_switching(u8 code) "Wide Range", "N/A" /* 0x06 */ }; - PyObject *data; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "VoltageRangeSwitching", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x06) - data = PyString_FromString(switching[code - 0x01]); - else - data = OUT_OF_SPEC; - return data; + if(code >= 0x01 && code <= 0x06) { + dmixml_AddTextContent(data_n, "%s", switching[code - 0x01]); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } } /* @@ -3477,60 +3597,55 @@ static PyObject *dmi_power_supply_range_switching(u8 code) ** whether it's worth the effort. */ -static PyObject *dmi_additional_info(const struct dmi_header *h, const char *prefix) +void dmi_additional_info(xmlNode *node, const struct dmi_header *h) { u8 *p = h->data + 4; u8 count = *p++; u8 length; int i, offset = 5; - PyObject *data = PyList_New(count); + + assert( node != NULL ); for(i = 0; i < count; i++) { - PyObject *subdata = PyDict_New(); + xmlNode *data_n = NULL, *str_n = NULL, *val_n = NULL; /* Check for short entries */ - if(h->length < offset + 1) + if(h->length < offset + 1) { break; + } + length = p[0x00]; if(length < 0x05 || h->length < offset + length) break; - PyDict_SetItemString(subdata, - "Referenced Handle", - PyString_FromFormat("0x%04x", WORD(p + 0x01)) - ); + data_n = xmlNewChild(node, NULL, (xmlChar *) "Record", NULL); + assert( data_n != NULL ); - PyDict_SetItemString(subdata, - "Referenced Offset", PyString_FromFormat("0x%02x", p[0x03]) - ); + dmixml_AddAttribute(data_n, "index", "%i", i); + dmixml_AddAttribute(data_n, "ReferenceHandle", "0x%04x", WORD(p + 0x01)); + dmixml_AddAttribute(data_n, "ReferenceOffset", "0x%02x", p[0x03]); - PyDict_SetItemString(subdata, "String", dmi_string_py(h, p[0x04]) - ); - - PyObject *_val; + str_n = dmixml_AddTextChild(data_n, "String", "%s", dmi_string(h, p[0x04])); switch (length - 0x05) { case 1: - _val = PyString_FromFormat("0x%02x", p[0x05]); + dmixml_AddTextChild(data_n, "Value", "0x%02x", p[0x05]); break; case 2: - _val = PyString_FromFormat("0x%04x", WORD(p + 0x05)); + dmixml_AddTextChild(data_n, "Value", "0x%04x", WORD(p + 0x05)); break; case 4: - _val = PyString_FromFormat("0x%08x", DWORD(p + 0x05)); + dmixml_AddTextChild(data_n, "Value", "0x%08x", DWORD(p + 0x05)); break; default: - _val = PyString_FromString("Unexpected size"); + val_n = xmlNewChild(data_n, NULL, (xmlChar *) "Value", NULL); + dmixml_AddAttribute(val_n, "unexpected_size", "1"); break; } - PyDict_SetItemString(subdata, "Value", _val); - Py_DECREF(_val); p += length; offset += length; - PyList_SET_ITEM(data, i, subdata); } - return data; } /******************************************************************************* @@ -3553,12 +3668,14 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) switch (h->type) { case 0: /* 3.3.1 BIOS Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOS", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOSinformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.1"); - if(h->length < 0x12) + if(h->length < 0x12) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "Vendor", "%s", data[0x04]); dmixml_AddTextChild(sect_n, "Version", "%s", data[0x05]); @@ -3572,11 +3689,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) if(WORD(data + 0x06) != 0) { dmixml_AddTextChild(sect_n, "Address", "0x%04x0", WORD(data + 0x06)); - dmixml_AddTextChild(sect_n, "RuntimeSize", "%s", - dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4)); + dmi_bios_runtime_size(sect_n, (0x10000 - WORD(data + 0x06)) << 4); } - dmixml_AddTextChild(sect_n, "ROMsize", "%i kB", (data[0x09] + 1) << 6); + dmixml_AddTextChild(sect_n, "ROMsize", "%i KB", (data[0x09] + 1) << 6); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); assert( sub_n != NULL ); @@ -3585,17 +3701,22 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_bios_characteristics(sub_n, QWORD(data + 0x0A)); sub_n = NULL; - if(h->length < 0x13) + if(h->length < 0x13) { + sect_n = NULL; break; + } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); assert( sub_n != NULL ); dmixml_AddAttribute(sub_n, "level", "x1"); dmi_bios_characteristics_x1(sub_n, data[0x12]); + sub_n = NULL; - if(h->length < 0x14) + if(h->length < 0x14) { + sect_n = NULL; break; + } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); assert( sub_n != NULL ); @@ -3604,8 +3725,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_bios_characteristics_x2(sub_n, data[0x13]); sub_n = NULL; - if(h->length < 0x18) + if(h->length < 0x18) { + sect_n = NULL; break; + } if(data[0x14] != 0xFF && data[0x15] != 0xFF) { dmixml_AddTextChild(sect_n, "BIOSrevision", "%i.%i", data[0x14], data[0x15]); @@ -3622,44 +3745,55 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.2"); - if(h->length < 0x08) + if(h->length < 0x08) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05])); dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06])); dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); - if(h->length < 0x19) + if(h->length < 0x19) { + sect_n = NULL; break; + } dmi_system_uuid(sect_n, data + 0x08, ver); dmi_system_wake_up_type(sect_n, data[0x18]); - if(h->length < 0x1B) + if(h->length < 0x1B) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19])); dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A])); + sect_n = NULL; break; case 2: /* 3.3.3 Base Board Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Baseboard", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BaseboardInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.3"); - if(h->length < 0x08) + if(h->length < 0x08) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05])); dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06])); dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); - if(h->length < 0x0F) + if(h->length < 0x0F) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); @@ -3670,19 +3804,23 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_base_board_type(sect_n, "Type", data[0x0D]); - if(h->length < 0x0F + data[0x0E] * sizeof(u16)) + if(h->length < 0x0F + data[0x0E] * sizeof(u16)) { + sect_n = NULL; break; + } dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F); sect_n = NULL; break; case 3: /* 3.3.4 Chassis Information */ - sect_n= xmlNewChild(handle_n, NULL, (xmlChar *) "Chassis", NULL); + sect_n= xmlNewChild(handle_n, NULL, (xmlChar *) "ChassisInformation", NULL); assert( sect_n != NULL ); - if(h->length < 0x09) + if(h->length < 0x09) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); dmi_chassis_type(sect_n, data[0x05] & 0x7F); @@ -3691,8 +3829,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); - if(h->length < 0x0D) + if(h->length < 0x0D) { + sect_n = NULL; break; + } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ChassisStates", NULL); assert( sub_n != NULL ); @@ -3700,39 +3840,44 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_chassis_state(sub_n, "BootUp", data[0x09]); dmi_chassis_state(sub_n, "PowerSupply", data[0x0A]); dmi_chassis_state(sub_n, "Thermal", data[0x0B]); + sub_n = NULL; dmi_chassis_security_status(sect_n, data[0x0C]); - if(h->length < 0x11) + if(h->length < 0x11) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x0D)); - if(h->length < 0x13) + if(h->length < 0x13) { + sect_n = NULL; break; + } dmi_chassis_height(sect_n, data[0x11]); dmi_chassis_power_cords(sect_n, data[0x12]); - if(h->length < 0x15) - break; - - if(h->length < 0x15 + data[0x13] * data[0x14]) + if((h->length < 0x15) || (h->length < 0x15 + data[0x13] * data[0x14])){ + sect_n = NULL; break; + } dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15); sect_n = NULL; break; case 4: /* 3.3.5 Processor Information */ - - if(h->length < 0x1A) - break; - - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Processor", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ProcessorInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.5"); + if(h->length < 0x1A) { + sect_n = NULL; + break; + } + dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04])); dmi_processor_type(sect_n, data[0x05]); dmi_processor_family(sect_n, h); @@ -3753,6 +3898,7 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sub_n, "ExternalClock", "%i", dmi_processor_frequency(data + 0x12)); dmixml_AddTextChild(sub_n, "MaxSpeed", "%i", dmi_processor_frequency(data + 0x14)); dmixml_AddTextChild(sub_n, "CurrentSpeed", "%i", dmi_processor_frequency(data + 0x16)); + sub_n = NULL; /* TODO: Should CurrentSpeed be renamed to BootSpeed? Specification * says this about Current Speed: @@ -3772,8 +3918,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_processor_upgrade(sect_n, data[0x19]); - if(h->length < 0x20) + if(h->length < 0x20) { + sect_n = NULL; break; + } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cache", NULL); assert( sub_n != NULL ); @@ -3801,15 +3949,19 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub2_n = NULL; sub_n = NULL; - if(h->length < 0x23) + if(h->length < 0x23) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x20])); dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x21])); dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x22])); - if(h->length < 0x28) + if(h->length < 0x28) { + sect_n = NULL; break; + } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cores", NULL); assert( cores_n != NULL ); @@ -3828,18 +3980,21 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_processor_characteristics(sub_n, WORD(data + 0x26)); sub_n = NULL; + sect_n = NULL; break; case 5: /* 3.3.6 Memory Controller Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryController", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryControllerInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.6"); dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0F) + if(h->length < 0x0F) { + sect_n = NULL; break; + } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ErrorCorrection", NULL); assert( errc_n != NULL ); @@ -3865,13 +4020,17 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_memory_module_types(sect_n, "SupportedTypes", WORD(data + 0x0B)); dmi_processor_voltage(sect_n, data[0x0D]); - if(h->length < 0x0F + data[0x0E] * sizeof(u16)) + if(h->length < 0x0F + data[0x0E] * sizeof(u16)) { + sect_n = NULL; break; + } dmi_memory_controller_slots(sect_n, data[0x0E], data + 0x0F); - if(h->length < 0x10 + data[0x0E] * sizeof(u16)) + if(h->length < 0x10 + data[0x0E] * sizeof(u16)) { + sect_n = NULL; break; + } dmi_memory_controller_ec_capabilities(sect_n, "EnabledErrorCorrection", data[0x0F + data[0x0E] * sizeof(u16)]); @@ -3879,14 +4038,16 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 6: /* 3.3.7 Memory Module Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryModule", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryModuleInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.7"); dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0C) + if(h->length < 0x0C) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04])); dmi_memory_module_connections(sect_n, data[0x05]); @@ -3900,14 +4061,16 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 7: /* 3.3.8 Cache Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Cache", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "CacheInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.8"); dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0F) + if(h->length < 0x0F) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "SocketDesignation", dmi_string(h, data[0x04])); dmixml_AddAttribute(sect_n, "Enabled", "%i", (WORD(data + 0x05) & 0x0080 ? 1 : 0)); @@ -3917,6 +4080,7 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub_n = dmixml_AddTextChild(sect_n, "OperationalMode", "%s", dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003)); dmixml_AddAttribute(sub_n, "flags", "0x%04x", (WORD(data + 0x05) >> 8) & 0x0003); + sub_n = NULL; dmi_cache_location(sect_n, (WORD(data + 0x05) >> 5) & 0x0003); dmi_cache_size(sect_n, "InstalledSize", WORD(data + 0x09)); @@ -3925,8 +4089,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_cache_types(sect_n, "SupportedSRAMtypes", WORD(data + 0x0B)); dmi_cache_types(sect_n, "InstalledSRAMtypes", WORD(data + 0x0D)); - if(h->length < 0x13) + if(h->length < 0x13) { + sect_n = NULL; break; + } dmi_memory_module_speed(sect_n, "Speed", data[0x0F]); dmi_cache_ec_type(sect_n, data[0x10]); @@ -3937,14 +4103,16 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 8: /* 3.3.9 Port Connector Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Connector", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "PortConnectorInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.9"); dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x09) + if(h->length < 0x09) { + sect_n = NULL; break; + } sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x04])); assert( sub_n != NULL ); @@ -3965,14 +4133,16 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 9: /* 3.3.10 System Slots */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Connector", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemSlots", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.10"); dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0C) + if(h->length < 0x0C) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "Designation", "%s", dmi_string(h, data[0x04])); @@ -3992,7 +4162,7 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 10: /* 3.3.11 On Board Devices Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OnBoardDevices", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OnBoardDevicesInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.11"); @@ -4008,8 +4178,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x05) + if(h->length < 0x05) { + sect_n = NULL; break; + } dmi_oem_strings(sect_n, h); @@ -4017,12 +4189,14 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 12: /* 3.3.13 System Configuration Options */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemConfig", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemConfigurationOptions", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.13"); - if(h->length < 0x05) + if(h->length < 0x05) { + sect_n = NULL; break; + } dmi_system_configuration_options(sect_n, h); @@ -4030,12 +4204,14 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; case 13: /* 3.3.14 BIOS Language Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOSlanguage", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOSlanguageInformation", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.14"); - if(h->length < 0x16) + if(h->length < 0x16) { + sect_n = NULL; break; + } dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]); @@ -4049,26 +4225,31 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.15"); - if(h->length < 0x05) + if(h->length < 0x05) { + sect_n = NULL; break; + } dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x04])); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Groups", NULL); assert( sub_n != NULL ); dmi_group_associations_items(sub_n, (h->length - 0x05) / 3, data + 0x05); + sub_n = NULL; sect_n = NULL; break; case 15: /* 3.3.16 System Event Log */ // SysEventLog - sect_n - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SysEventLog", NULL); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemEventLog", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.16"); - if(h->length < 0x14) + if(h->length < 0x14) { + sect_n = NULL; break; + } dmi_event_log_status(sect_n, data[0x0B]); @@ -4093,8 +4274,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sub2_n, "DataOffset", "0x%04x", WORD(data + 0x08)); dmixml_AddTextChild(sub2_n, "ChangeToken", "0x%08x", DWORD(data + 0x0C)); - if(h->length < 0x17) + if(h->length < 0x17) { + sect_n = NULL; break; + } // SysEventLog/Access/Header/Format - sub2_n dmi_event_log_header_type(sub2_n, data[0x14]); @@ -4109,15 +4292,17 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) // SysEventLog/LogTypes/@count dmixml_AddAttribute(sub_n, "count", "%i", data[0x15]); - if(h->length < 0x17 + data[0x15] * data[0x16]) + if(h->length < 0x17 + data[0x15] * data[0x16]) { + sect_n = NULL; break; + } dmixml_AddAttribute(sub_n, "length", "%i", data[0x16]); // SysEventLog/LogTypes/LogType dmi_event_log_descriptors(sub_n, data[0x15], data[0x16], data + 0x17); - sub_n = NULL; + sect_n = NULL; break; @@ -4126,730 +4311,589 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "3.3.17"); - if(h->length < 0x0F) + if(h->length < 0x0F) { + sect_n = NULL; break; + } - /* ** BOOKMARK ** */ - - _val = dmi_memory_array_location(data[0x04]); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_use(data[0x05]); - PyDict_SetItemString(caseData, "Use", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_ec_type(data[0x06]); - PyDict_SetItemString(caseData, "Error Correction Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_capacity(DWORD(data + 0x07)); - PyDict_SetItemString(caseData, "Maximum Capacity", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_error_handle(WORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Error Information Handle", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sect_n, "NumDevices", "%ld", WORD(data + 0x0D)); + dmi_memory_array_location(sect_n, data[0x04]); + dmi_memory_array_use(sect_n, data[0x05]); + dmi_memory_array_ec_type(sect_n, data[0x06]); + dmi_memory_array_capacity(sect_n, DWORD(data + 0x07)); + dmi_memory_array_error_handle(sect_n, WORD(data + 0x0B)); - _val = PyInt_FromLong(WORD(data + 0x0D)); - PyDict_SetItemString(caseData, "Number Of Devices", _val); - Py_DECREF(_val); + sect_n = NULL; break; case 17: /* 3.3.18 Memory Device */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryDevice", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.18"); - if(h->length < 0x15) + if(h->length < 0x15) { + sect_n = NULL; break; - _val = PyString_FromFormat("0x%04x", WORD(data + 0x04)); - PyDict_SetItemString(caseData, "Array Handle", _val); - Py_DECREF(_val); - - _val = dmi_memory_array_error_handle(WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Error Information Handle", _val); - Py_DECREF(_val); - - _val = dmi_memory_device_width(WORD(data + 0x08)); - PyDict_SetItemString(caseData, "Total Width", _val); - Py_DECREF(_val); + } - _val = dmi_memory_device_width(WORD(data + 0x0A)); - PyDict_SetItemString(caseData, "Data Width", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sect_n, "ArrayHandle", "0x%04x", WORD(data + 0x04)); + dmi_memory_array_error_handle(sect_n, WORD(data + 0x06)); - _val = dmi_memory_device_size(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Size", _val); - Py_DECREF(_val); + dmi_memory_device_width(sect_n, "TotalWidth", WORD(data + 0x08)); + dmi_memory_device_width(sect_n, "DataWidth", WORD(data + 0x0A)); + dmi_memory_device_size(sect_n, WORD(data + 0x0C)); + dmi_memory_device_form_factor(sect_n, data[0x0E]); + dmi_memory_device_set(sect_n, data[0x0F]); + dmixml_AddTextChild(sect_n, "Locator", dmi_string(h, data[0x10])); + dmixml_AddTextChild(sect_n, "BankLocator", dmi_string(h, data[0x11])); - _val = dmi_memory_device_form_factor(data[0x0E]); - PyDict_SetItemString(caseData, "Form Factor", _val); - Py_DECREF(_val); + dmi_memory_device_type(sect_n, data[0x12]); + dmi_memory_device_type_detail(sect_n, WORD(data + 0x13)); - _val = dmi_memory_device_set(data[0x0F]); - PyDict_SetItemString(caseData, "Set", _val); - Py_DECREF(_val); + if(h->length < 0x17) { + sect_n = NULL; + break; + } - _val = dmi_string_py(h, data[0x10]); - PyDict_SetItemString(caseData, "Locator", _val); - Py_DECREF(_val); + dmi_memory_device_speed(sect_n, WORD(data + 0x15)); - _val = dmi_string_py(h, data[0x11]); - PyDict_SetItemString(caseData, "Bank Locator", _val); - Py_DECREF(_val); + if(h->length < 0x1B) { + sect_n = NULL; + break; + } - _val = dmi_memory_device_type(data[0x12]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x17])); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x18])); + dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x19])); + dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x1A])); - _val = dmi_memory_device_type_detail(WORD(data + 0x13)); - PyDict_SetItemString(caseData, "Type Detail", _val); - Py_DECREF(_val); + sect_n = NULL; + break; - if(h->length < 0x17) - break; - _val = dmi_memory_device_speed(WORD(data + 0x15)); - PyDict_SetItemString(caseData, "Speed", _val); - Py_DECREF(_val); + case 18: /* 3.3.19 32-bit Memory Error Information */ + case 33: /* 3.3.34 64-bit Memory Error Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryErrorInfo", NULL); + assert( sect_n != NULL ); - if(h->length < 0x1B) - break; - _val = dmi_string_py(h, data[0x17]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); + if( h->type == 18 ) { + dmixml_AddAttribute(sect_n, "dmispec", "3.3.19"); + dmixml_AddAttribute(sect_n, "bits", "32"); + } else { + dmixml_AddAttribute(sect_n, "dmispec", "3.3.34"); + dmixml_AddAttribute(sect_n, "bits", "64"); + } - _val = dmi_string_py(h, data[0x18]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); + if( ((h->type == 18) && (h->length < 0x17)) /* 32-bit */ + || ((h->type == 33) && (h->length < 0x1F)) ) /* 64-bit */ + { + sect_n = NULL; + break; + } - _val = dmi_string_py(h, data[0x19]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); + dmi_memory_error_type(sect_n, data[0x04]); + dmi_memory_error_granularity(sect_n, data[0x05]); + dmi_memory_error_operation(sect_n, data[0x06]); + dmi_memory_error_syndrome(sect_n, DWORD(data + 0x07)); + + if( h->type == 18 ) { + /* 32-bit */ + dmi_32bit_memory_error_address(sect_n, "MemArrayAddr", DWORD(data + 0x0B)); + dmi_32bit_memory_error_address(sect_n, "DeviceAddr", DWORD(data + 0x0F)); + dmi_32bit_memory_error_address(sect_n, "Resolution", DWORD(data + 0x13)); + } else if( h->type == 33 ) { + /* 64-bit */ + dmi_64bit_memory_error_address(sect_n, "MemArrayAddr", QWORD(data + 0x0B)); + dmi_64bit_memory_error_address(sect_n, "DeviceAddr", QWORD(data + 0x13)); + dmi_32bit_memory_error_address(sect_n, "Resolution", DWORD(data + 0x1B)); + } - _val = dmi_string_py(h, data[0x1A]); - PyDict_SetItemString(caseData, "Part Number", _val); - Py_DECREF(_val); + sect_n = NULL; break; - case 18: /* 3.3.19 32-bit Memory Error Information */ + case 19: /* 3.3.20 Memory Array Mapped Address */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryArrayMappedAddress", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.20"); - if(h->length < 0x17) + if(h->length < 0x0F) { + sect_n = NULL; break; - _val = dmi_memory_error_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + } - _val = dmi_memory_error_granularity(data[0x05]); - PyDict_SetItemString(caseData, "Granularity", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x", + (DWORD(data + 0x04) >> 2), + (DWORD(data + 0x04) & 0x3) << 10); + dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x", + (DWORD(data + 0x08) >> 2), + ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); + dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1); + dmixml_AddTextChild(sect_n, "PhysicalArrayHandle", "0x%04x", WORD(data + 0x0C)); + dmixml_AddTextChild(sect_n, "PartitionWidth", "%i", data[0x0F]); - _val = dmi_memory_error_operation(data[0x06]); - PyDict_SetItemString(caseData, "Operation", _val); - Py_DECREF(_val); + sect_n = NULL; + break; - _val = dmi_memory_error_syndrome(DWORD(data + 0x07)); - PyDict_SetItemString(caseData, "Vendor Syndrome", _val); - Py_DECREF(_val); + case 20: /* 3.3.21 Memory Device Mapped Address */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryDeviceMappedAddress", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.21"); - _val = dmi_32bit_memory_error_address(DWORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Memory Array Address", _val); - Py_DECREF(_val); + if(h->length < 0x13) { + sect_n = NULL; + break; + } - _val = dmi_32bit_memory_error_address(DWORD(data + 0x0F)); - PyDict_SetItemString(caseData, "Device Address", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x", + (DWORD(data + 0x04) >> 2), + (DWORD(data + 0x04) & 0x3) << 10); - _val = dmi_32bit_memory_error_address(DWORD(data + 0x13)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); - break; + dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x", + (DWORD(data + 0x08) >> 2), + ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); - case 19: /* 3.3.20 Memory Array Mapped Address */ + dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1); - if(h->length < 0x0F) - break; - _val = - PyString_FromFormat("0x%08x%03x", DWORD(data + 0x04) >> 2, - (DWORD(data + 0x04) & 0x3) << 10); - PyDict_SetItemString(caseData, "Starting Address", _val); - Py_DECREF(_val); - - _val = - PyString_FromFormat("0x%08x%03x", DWORD(data + 0x08) >> 2, - ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); - PyDict_SetItemString(caseData, "Ending Address", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); - PyDict_SetItemString(caseData, "Range Size", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Physical Array Handle", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%i", data[0x0F]); - PyDict_SetItemString(caseData, "Partition Width", _val); - Py_DECREF(_val); - break; + dmixml_AddTextChild(sect_n, "PhysicalDeviceHandle", "0x%04x", WORD(data + 0x0C)); + dmixml_AddTextChild(sect_n, "MemArrayMappedAddrHandle", "0x%04x", WORD(data + 0x0E)); - case 20: /* 3.3.21 Memory Device Mapped Address */ + dmi_mapped_address_row_position(sect_n, data[0x10]); - if(h->length < 0x13) - break; - _val = - PyString_FromFormat("0x%08x%03x", DWORD(data + 0x04) >> 2, - (DWORD(data + 0x04) & 0x3) << 10); - PyDict_SetItemString(caseData, "Starting Address", _val); - Py_DECREF(_val); - - _val = - PyString_FromFormat("0x%08x%03x", DWORD(data + 0x08) >> 2, - ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); - PyDict_SetItemString(caseData, "Ending Address", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); - PyDict_SetItemString(caseData, "Range Size", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Physical Device Handle", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data + 0x0E)); - PyDict_SetItemString(caseData, "Memory Array Mapped Address Handle", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_row_position(data[0x10]); - PyDict_SetItemString(caseData, "Partition Row Position", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_interleave_position(data[0x11]); - PyDict_SetItemString(caseData, ">>>", _val); - Py_DECREF(_val); - - _val = dmi_mapped_address_interleaved_data_depth(data[0x12]); - PyDict_SetItemString(caseData, ">>>", _val); - Py_DECREF(_val); + dmi_mapped_address_interleave_position(sect_n, data[0x11]); + dmi_mapped_address_interleaved_data_depth(sect_n, data[0x12]); + + sect_n = NULL; break; case 21: /* 3.3.22 Built-in Pointing Device */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BuiltInPointingDevice", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.22"); - if(h->length < 0x07) + if(h->length < 0x07) { + sect_n = NULL; break; - _val = dmi_pointing_device_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + } - _val = dmi_pointing_device_interface(data[0x05]); - PyDict_SetItemString(caseData, "Interface", _val); - Py_DECREF(_val); + dmi_pointing_device_type(sect_n, data[0x04]); + dmi_pointing_device_interface(sect_n, data[0x05]); + dmixml_AddTextContent(sect_n, "Buttons", "%i", data[0x06]); - _val = PyString_FromFormat("%i", data[0x06]); - PyDict_SetItemString(caseData, "Buttons", _val); - Py_DECREF(_val); + sect_n = NULL; break; case 22: /* 3.3.23 Portable Battery */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "PortableBattery", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.23"); - if(h->length < 0x10) + if(h->length < 0x10) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); + } - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Location", "%s", dmi_string(h, data[0x04])); + dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x05])); if(data[0x06] || h->length < 0x1A) { - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Manufacture Date", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "ManufactureDate", "%s", dmi_string(h, data[0x06])); } if(data[0x07] || h->length < 0x1A) { - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Serial Number", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); } - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Name", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x08])); if(data[0x09] != 0x02 || h->length < 0x1A) { - _val = dmi_battery_chemistry(data[0x09]); - PyDict_SetItemString(caseData, "Chemistry", _val); - Py_DECREF(_val); - } - _val = - (h->length < 0x1A) ? dmi_battery_capacity(WORD(data + 0x0A), - 1) : dmi_battery_capacity(WORD(data + - 0x0A), - data[0x15]); - PyDict_SetItemString(caseData, "Design Capacity", _val); - Py_DECREF(_val); - - _val = dmi_battery_voltage(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Design Voltage", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x0E]); - PyDict_SetItemString(caseData, "SBDS Version", _val); - Py_DECREF(_val); - - _val = dmi_battery_maximum_error(data[0x0F]); - PyDict_SetItemString(caseData, "Maximum Error", _val); - Py_DECREF(_val); - - if(h->length < 0x1A) + dmi_battery_chemistry(sect_n, data[0x09]); + } + + dmi_battery_capacity(sect_n, WORD(data + 0x0A), (h->length < 0x1A ? 1 : data[0x15])); + dmi_battery_voltage(sect_n, WORD(data + 0x0C)); + dmixml_AddTextChild(sect_n, "SBDSversion", "%s", dmi_string(h, data[0x0E])); + + dmi_battery_maximum_error(sect_n, data[0x0F]); + + if(h->length < 0x1A) { + sect_n = NULL; break; + } + if(data[0x07] == 0) { - _val = PyString_FromFormat("%04x", WORD(data + 0x10)); - PyDict_SetItemString(caseData, "SBDS Serial Number", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SBDSserialNumber", "%04x", WORD(data + 0x10)); } if(data[0x06] == 0) { - _val = - PyString_FromFormat("%i-%02u-%02u", 1980 + (WORD(data + 0x12) >> 9), - (WORD(data + 0x12) >> 5) & 0x0F, - WORD(data + 0x12) & 0x1F); - PyDict_SetItemString(caseData, "SBDS Manufacture Date", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SBDSmanufactureDate", "%i-%02u-%02u", + 1980 + (WORD(data + 0x12) >> 9), + (WORD(data + 0x12) >> 5) & 0x0F, + (WORD(data + 0x12) & 0x1F)); } if(data[0x09] == 0x02) { - _val = dmi_string_py(h, data[0x14]); - PyDict_SetItemString(caseData, "SBDS Chemistry", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "SBDSchemistry", "%s", dmi_string(h, data[0x14])); } - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x16)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "OEMinformation", "%s", "0x%08x", DWORD(data + 0x16)); + + sect_n = NULL; break; case 23: /* 3.3.24 System Reset */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemReset", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.24"); - if(h->length < 0x0D) + if(h->length < 0x0D) { + sect_n = NULL; break; - _val = PyString_FromFormat("%s", data[0x04] & (1 << 0) ? "Enabled" : "Disabled"); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("%s", data[0x04] & (1 << 5) ? "Present" : "Not Present"); - PyDict_SetItemString(caseData, "Watchdog Timer", _val); - Py_DECREF(_val); + } - if(!(data[0x04] & (1 << 5))) - break; - _val = dmi_system_reset_boot_option((data[0x04] >> 1) & 0x3); - PyDict_SetItemString(caseData, "Boot Option", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "Status", "%s", + data[0x04] & (1 << 0) ? "Enabled" : "Disabled"); + dmixml_AddAttribute(sub_n, "enabled", "%i", data[0x04] & (1 << 0) ? 1 : 0); + sub_n = NULL; - _val = dmi_system_reset_boot_option((data[0x04] >> 3) & 0x3); - PyDict_SetItemString(caseData, "Boot Option On Limit", _val); - Py_DECREF(_val); + sub_n = dmixml_AddTextChild(sect_n, "WatchdogTimer", "%s", + data[0x04] & (1 << 5) ? "Present" : "Not Present"); + dmixml_AddAttribute(sub_n, "present", "%i", data[0x04] & (1 << 5) ? 1 : 0); + sub_n = NULL; - _val = dmi_system_reset_count(WORD(data + 0x05)); - PyDict_SetItemString(caseData, "Reset Count", _val); - Py_DECREF(_val); + if(!(data[0x04] & (1 << 5))) { + sect_n = NULL; + break; + } - _val = dmi_system_reset_count(WORD(data + 0x07)); - PyDict_SetItemString(caseData, "Reset Limit", _val); - Py_DECREF(_val); + dmi_system_reset_boot_option(sect_n, "BootOption", (data[0x04] >> 1) & 0x3); + dmi_system_reset_boot_option(sect_n, "BootOptionOnLimit", (data[0x04] >> 3) & 0x3); - _val = dmi_system_reset_timer(WORD(data + 0x09)); - PyDict_SetItemString(caseData, "Timer Interval", _val); - Py_DECREF(_val); + dmi_system_reset_count(sect_n, "ResetCount", WORD(data + 0x05)); + dmi_system_reset_count(sect_n, "ResetLimit", WORD(data + 0x07)); - _val = dmi_system_reset_timer(WORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Timeout", _val); - Py_DECREF(_val); + dmi_system_reset_timer(sect_n, "TimerInterval", WORD(data + 0x09)); + dmi_system_reset_timer(sect_n, "Timeout", WORD(data + 0x0B)); + sect_n = NULL; break; case 24: /* 3.3.25 Hardware Security */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "HardwareSecurity", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.25"); - if(h->length < 0x05) + if(h->length < 0x05) { + sect_n = NULL; break; - _val = dmi_hardware_security_status(data[0x04] >> 6); - PyDict_SetItemString(caseData, "Power-On Password Status", _val); - Py_DECREF(_val); - - _val = dmi_hardware_security_status((data[0x04] >> 4) & 0x3); - PyDict_SetItemString(caseData, "Keyboard Password Status", _val); - Py_DECREF(_val); - - _val = dmi_hardware_security_status((data[0x04] >> 2) & 0x3); - PyDict_SetItemString(caseData, "Administrator Password Status", _val); - Py_DECREF(_val); + } - _val = dmi_hardware_security_status(data[0x04] & 0x3); - PyDict_SetItemString(caseData, "Front Panel Reset Status", _val); - Py_DECREF(_val); + dmi_hardware_security_status(sect_n, "PowerOnPassword", data[0x04] >> 6); + dmi_hardware_security_status(sect_n, "KeyboardPassword", (data[0x04] >> 4) & 0x3); + dmi_hardware_security_status(sect_n, "AdministratorPassword", (data[0x04] >> 2) & 0x3); + dmi_hardware_security_status(sect_n, "FronPanelReset", data[0x04] & 0x3); + sect_n = NULL; break; case 25: /* 3.3.26 System Power Controls */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemPowerControls", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.26"); - if(h->length < 0x09) + if(h->length < 0x09) { + sect_n = NULL; break; - _val = dmi_power_controls_power_on(data + 0x04); - PyDict_SetItemString(caseData, "Next Scheduled Power-on", _val); - Py_DECREF(_val); + } + dmi_power_controls_power_on(sect_n, "NextSchedPowerOn", data + 0x04); + + sect_n = NULL; break; case 26: /* 3.3.27 Voltage Probe */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "VoltageProbe", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.27"); - if(h->length < 0x14) + if(h->length < 0x14) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); - - _val = dmi_voltage_probe_location(data[0x05] & 0x1f); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_probe_status(data[0x05] >> 5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - _val = dmi_voltage_probe_value(WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Maximum Value", _val); - Py_DECREF(_val); + } - _val = dmi_voltage_probe_value(WORD(data + 0x08)); - PyDict_SetItemString(caseData, "Minimum Value", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); - _val = dmi_voltage_probe_resolution(WORD(data + 0x0A)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + dmi_voltage_probe_location(sect_n, data[0x05] & 0x1f); + dmi_probe_status(sect_n, data[0x05] >> 5); - _val = dmi_voltage_probe_value(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Tolerance", _val); - Py_DECREF(_val); + dmi_voltage_probe_value(sect_n, "MaxValue", WORD(data + 0x06)); + dmi_voltage_probe_value(sect_n, "MinValue", WORD(data + 0x08)); + dmi_voltage_probe_resolution(sect_n, WORD(data + 0x0A)); + dmi_voltage_probe_value(sect_n, "Tolerance", WORD(data + 0x0C)); - _val = dmi_probe_accuracy(WORD(data + 0x0E)); - PyDict_SetItemString(caseData, "Accuracy", _val); - Py_DECREF(_val); + dmi_probe_accuracy(sect_n, WORD(data + 0x0E)); - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x10)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); - if(h->length < 0x16) + if(h->length < 0x16) { + sect_n = NULL; break; - _val = dmi_voltage_probe_value(WORD(data + 0x14)); - PyDict_SetItemString(caseData, "Nominal Value", _val); - Py_DECREF(_val); + } + dmi_voltage_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); + + sect_n = NULL; break; case 27: /* 3.3.28 Cooling Device */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "CoolingDevice", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.28"); - if(h->length < 0x0C) + if(h->length < 0x0C) { + sect_n = NULL; break; - if(WORD(data + 0x04) != 0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data + 0x04)); - PyDict_SetItemString(caseData, "Temperature Probe Handle", _val); - Py_DECREF(_val); } - _val = dmi_cooling_device_type(data[0x06] & 0x1f); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + if(WORD(data + 0x04) != 0xFFFF) { + dmixml_AddTextContent(sect_n, "TemperatureProbeHandle", "0x%04x", WORD(data + 0x04)); + } - _val = dmi_probe_status(data[0x06] >> 5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + dmi_cooling_device_type(sect_n, data[0x06] & 0x1f); + dmi_probe_status(sect_n, data[0x06] >> 5); if(data[0x07] != 0x00) { - _val = PyString_FromFormat("%i", data[0x07]); - PyDict_SetItemString(caseData, "Cooling Unit Group", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "UnitGroup", "%i", data[0x07]); } - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x08)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x08)); - if(h->length < 0x0E) + if(h->length < 0x0E) { + sect_n = NULL; break; - _val = dmi_cooling_device_speed(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Nominal Speed", _val); - Py_DECREF(_val); + } + + dmi_cooling_device_speed(sect_n, WORD(data + 0x0C)); + sect_n = NULL; break; case 28: /* 3.3.29 Temperature Probe */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "TemperatureProbe", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.29"); - if(h->length < 0x14) + if(h->length < 0x14) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); - - _val = dmi_temperature_probe_location(data[0x05] & 0x1F); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_probe_status(data[0x05] >> 5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - _val = dmi_temperature_probe_value(WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Maximum Value", _val); - Py_DECREF(_val); - - _val = dmi_temperature_probe_value(WORD(data + 0x08)); - PyDict_SetItemString(caseData, "Minimum Value", _val); - Py_DECREF(_val); - - _val = dmi_temperature_probe_resolution(WORD(data + 0x0A)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + } - _val = dmi_temperature_probe_value(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Tolerance", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); + dmi_temperature_probe_location(sect_n,data[0x05] & 0x1F); + dmi_probe_status(sect_n, data[0x05] >> 5); - _val = dmi_probe_accuracy(WORD(data + 0x0E)); - PyDict_SetItemString(caseData, "Accuracy", _val); - Py_DECREF(_val); + dmi_temperature_probe_value(sect_n, "MaxValue", WORD(data + 0x06)); + dmi_temperature_probe_value(sect_n, "MinValue", WORD(data + 0x08)); + dmi_temperature_probe_resolution(sect_n, WORD(data + 0x0A)); + dmi_temperature_probe_value(sect_n, "Tolerance", WORD(data + 0x0C)); + dmi_probe_accuracy(sect_n, WORD(data + 0x0E)); - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x10)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); - if(h->length < 0x16) + if(h->length < 0x16) { + sect_n = NULL; break; - _val = dmi_temperature_probe_value(WORD(data + 0x14)); - PyDict_SetItemString(caseData, "Nominal Value", _val); - Py_DECREF(_val); + } + + dmi_temperature_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); + sect_n = NULL; break; case 29: /* 3.3.30 Electrical Current Probe */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ElectricalCurrentProbe", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.30"); - if(h->length < 0x14) + if(h->length < 0x14) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); - - _val = dmi_voltage_probe_location(data[5] & 0x1F); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_probe_status(data[0x05] >> 5); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - _val = dmi_current_probe_value(WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Maximum Value", _val); - Py_DECREF(_val); - - _val = dmi_current_probe_value(WORD(data + 0x08)); - PyDict_SetItemString(caseData, "Minimum Value", _val); - Py_DECREF(_val); + } - _val = dmi_current_probe_resolution(WORD(data + 0x0A)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04])); + dmi_voltage_probe_location(sect_n, data[5] & 0x1F); + dmi_probe_status(sect_n, data[0x05] >> 5); - _val = dmi_current_probe_value(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Tolerance", _val); - Py_DECREF(_val); + dmi_current_probe_value(sect_n, "MaxValue", WORD(data + 0x06)); + dmi_current_probe_value(sect_n, "MinValue", WORD(data + 0x08)); + dmi_current_probe_resolution(sect_n, WORD(data + 0x0A)); + dmi_current_probe_value(sect_n, "Tolerance", WORD(data + 0x0C)); - _val = dmi_probe_accuracy(WORD(data + 0x0E)); - PyDict_SetItemString(caseData, "Accuracy", _val); - Py_DECREF(_val); + dmi_probe_accuracy(sect_n, WORD(data + 0x0E)); - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x10)); - PyDict_SetItemString(caseData, "OEM-specific Information", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); - if(h->length < 0x16) + if(h->length < 0x16) { + sect_n = NULL; break; - _val = dmi_current_probe_value(WORD(data + 0x14)); - PyDict_SetItemString(caseData, "Nominal Value", _val); - Py_DECREF(_val); + } + dmi_current_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); + + sect_n = NULL; break; case 30: /* 3.3.31 Out-of-band Remote Access */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OutOfBandRemoteAccess", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.31"); - if(h->length < 0x06) + if(h->length < 0x06) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Manufacturer Name", _val); - Py_DECREF(_val); + } - _val = data[0x05] & (1 << 0) ? Py_True : Py_False; - PyDict_SetItemString(caseData, "Inbound Connection Enabled", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "ManufacturerName", "%s", dmi_string(h, data[0x04])); + dmixml_AddAttribute(sect_n, "InboundConnectionEnabled", "%i", data[0x05] & (1 << 0) ? 1 : 0); + dmixml_AddAttribute(sect_n, "OutboundConnectionEnabled", "%i", data[0x05] & (1 << 1) ? 1 : 0); - _val = data[0x05] & (1 << 1) ? Py_True : Py_False; - PyDict_SetItemString(caseData, "Outbound Connection Enabled", _val); - Py_DECREF(_val); + sect_n = NULL; break; case 31: /* 3.3.32 Boot Integrity Services Entry Point */ - + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BootIntegrityServiceEntryPoint", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.32"); + dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1"); break; case 32: /* 3.3.33 System Boot Information */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemBootInformation", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.33"); - if(h->length < 0x0B) - break; - _val = dmi_system_boot_status(data[0x0A]); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); - - break; - - case 33: /* 3.3.34 64-bit Memory Error Information */ - if(h->length < 0x1F) + if(h->length < 0x0B) { + sect_n = NULL; break; + } - _val = dmi_memory_error_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = dmi_memory_error_granularity(data[0x05]); - PyDict_SetItemString(caseData, "Granularity", _val); - Py_DECREF(_val); - - _val = dmi_memory_error_operation(data[0x06]); - PyDict_SetItemString(caseData, "Operation", _val); - Py_DECREF(_val); - - _val = dmi_memory_error_syndrome(DWORD(data + 0x07)); - PyDict_SetItemString(caseData, "Vendor Syndrome", _val); - Py_DECREF(_val); - - _val = dmi_64bit_memory_error_address(QWORD(data + 0x0B)); - PyDict_SetItemString(caseData, "Memory Array Address", _val); - Py_DECREF(_val); - - _val = dmi_64bit_memory_error_address(QWORD(data + 0x13)); - PyDict_SetItemString(caseData, "Device Address", _val); - Py_DECREF(_val); - - _val = dmi_32bit_memory_error_address(DWORD(data + 0x1B)); - PyDict_SetItemString(caseData, "Resolution", _val); - Py_DECREF(_val); + dmi_system_boot_status(sect_n, data[0x0A]); + sect_n = NULL; break; case 34: /* 3.3.35 Management Device */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ManagementDevice", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.35"); - if(h->length < 0x0B) + if(h->length < 0x0B) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); - - _val = dmi_management_device_type(data[0x05]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%08x", DWORD(data + 0x06)); - PyDict_SetItemString(caseData, "Address", _val); - Py_DECREF(_val); + } - _val = dmi_management_device_address_type(data[0x0A]); - PyDict_SetItemString(caseData, "Address Type", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); + dmi_management_device_type(sect_n, data[0x05]); + dmixml_AddTextChild(sect_n, "Address", "0x%08x", DWORD(data + 0x06)); + dmi_management_device_address_type(sect_n, data[0x0A]); + sect_n = NULL; break; case 35: /* 3.3.36 Management Device Component */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ManagementDeviceComponent", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.36"); - if(h->length < 0x0B) + if(h->length < 0x0B) { + sect_n = NULL; break; - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(caseData, "Description", _val); - Py_DECREF(_val); - - _val = PyString_FromFormat("0x%04x", WORD(data + 0x05)); - PyDict_SetItemString(caseData, "Management Device Handle", _val); - Py_DECREF(_val); + } - _val = PyString_FromFormat("0x%04x", WORD(data + 0x07)); - PyDict_SetItemString(caseData, "Component Handle", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04])); + dmixml_AddTextChild(sect_n, "ManagementDeviceHandle", "0x%04x", WORD(data + 0x05)); + dmixml_AddTextChild(sect_n, "ComponentHandle", "0x%04x", WORD(data + 0x07)); if(WORD(data + 0x09) != 0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data + 0x09)); - PyDict_SetItemString(caseData, "Threshold Handle", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "ThresholdHandle", "0x%04x", WORD(data + 0x09)); } + sect_n = NULL; break; case 36: /* 3.3.37 Management Device Threshold Data */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ManagementDeviceThresholdData", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.37"); - if(h->length < 0x10) + if(h->length < 0x10) { + sect_n = NULL; break; + } + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Thresholds", NULL); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "mode", "non-critical"); + if(WORD(data + 0x04) != 0x8000) { - _val = PyString_FromFormat("%d", (i16) WORD(data + 0x04)); - PyDict_SetItemString(caseData, "Lower Non-critical Threshold", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x04)); } if(WORD(data + 0x06) != 0x8000) { - _val = PyString_FromFormat("%d", (i16) WORD(data + 0x06)); - PyDict_SetItemString(caseData, "Upper Non-critical Threshold", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x06)); } + sub_n = NULL; + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Thresholds", NULL); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "mode", "critical"); + if(WORD(data + 0x08) != 0x8000) { - _val = PyString_FromFormat("%d", (i16) WORD(data + 0x08)); - PyDict_SetItemString(caseData, "Lower Critical Threshold", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x08)); } if(WORD(data + 0x0A) != 0x8000) { - _val = PyString_FromFormat("%d", (i16) WORD(data + 0x0A)); - PyDict_SetItemString(caseData, "Upper Critical Threshold", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x0A)); + } + sub_n = NULL; + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Thresholds", NULL); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "mode", "non-recoverable"); + if(WORD(data + 0x0C) != 0x8000) { - _val = PyString_FromFormat("%d", (i16) WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Lower Non-recoverable Threshold", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x0C)); } if(WORD(data + 0x0E) != 0x8000) { - _val = PyString_FromFormat("%d", (i16) WORD(data + 0x0E)); - PyDict_SetItemString(caseData, "Upper Non-recoverable Threshold", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x0E)); } + sub_n = NULL; + sect_n = NULL; break; case 37: /* 3.3.38 Memory Channel */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryChannel", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.38"); - if(h->length < 0x07) + if(h->length < 0x07) { + sect_n = NULL; break; - _val = dmi_memory_channel_type(data[0x04]); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); + } - _val = PyString_FromFormat("%i", data[0x05]); - PyDict_SetItemString(caseData, "Maximal Load", _val); - Py_DECREF(_val); + dmi_memory_channel_type(sect_n, data[0x04]); + dmixml_AddTextChild(sect_n, "MaxLoad", "%i", data[0x05]); - _val = PyString_FromFormat("%i", data[0x06]); - PyDict_SetItemString(caseData, "Devices", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Devices", NULL); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "devices", "%i", data[0x06]); - if(h->length < 0x07 + 3 * data[0x06]) + if(h->length < 0x07 + 3 * data[0x06]) { + sub_n = NULL; + sect_n = NULL; break; - _val = dmi_memory_channel_devices(data[0x06], data + 0x07); - PyDict_SetItemString(caseData, ">>>", _val); - Py_DECREF(_val); + } + dmi_memory_channel_devices(sub_n, data[0x06], data + 0x07); + sub_n = NULL; + + sect_n = NULL; break; case 38: /* 3.3.39 IPMI Device Information */ @@ -4857,214 +4901,197 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) * We use the word "Version" instead of "Revision", conforming to * the IPMI specification. */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "IPMIdeviceInformation", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.39"); - if(h->length < 0x10) + if(h->length < 0x10) { + sect_n = NULL; break; - _val = dmi_ipmi_interface_type(data[0x04]); - PyDict_SetItemString(caseData, "Interface Type", _val); - Py_DECREF(_val); + } + + dmi_ipmi_interface_type(sect_n, data[0x04]); - _val = PyString_FromFormat("%i.%i", data[0x05] >> 4, data[0x05] & 0x0F); - PyDict_SetItemString(caseData, "Specification Version", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sect_n, "spec_version", "%i.%i", data[0x05] >> 4, data[0x05] & 0x0F); + dmixml_AddAttribute(sect_n, "I2CslaveAddr", "0x%02x", data[0x06] >> 1); - _val = PyString_FromFormat("0x%02x", data[0x06] >> 1); - PyDict_SetItemString(caseData, "I2C Slave Address", _val); - Py_DECREF(_val); + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "NVstorageDevice", NULL); + assert( sub_n != NULL ); if(data[0x07] != 0xFF) { - _val = PyString_FromFormat("%i", data[0x07]); - PyDict_SetItemString(caseData, "NV Storage Device Address", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Address", "%i", data[0x07]); } else { - _val = Py_None; - PyDict_SetItemString(caseData, "NV Storage Device: Not Present", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "NotPresent", "1"); } + sub_n = NULL; - _val = - dmi_ipmi_base_address(data[0x04], data + 0x08, - h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1); - PyDict_SetItemString(caseData, "Base Address", _val); - Py_DECREF(_val); + dmi_ipmi_base_address(sect_n, data[0x04], data + 0x08, + h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1); - if(h->length < 0x12) + if(h->length < 0x12) { + sect_n = NULL; break; + } + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Interrupt", NULL); + assert( sub_n != NULL ); + if(data[0x04] != 0x04) { - _val = dmi_ipmi_register_spacing(data[0x10] >> 6); - PyDict_SetItemString(caseData, "Register Spacing", _val); - Py_DECREF(_val); + dmi_ipmi_register_spacing(sect_n, data[0x10] >> 6); if(data[0x10] & (1 << 3)) { - _val = - PyString_FromFormat("%s", - data[0x10] & (1 << 1) ? "Active High" : - "Active Low"); - PyDict_SetItemString(caseData, "Interrupt Polarity", _val); - Py_DECREF(_val); - - _val = - PyString_FromFormat("%s", - data[0x10] & (1 << 0) ? "Level" : "Edge"); - PyDict_SetItemString(caseData, "Interrupt Trigger Mode", _val); - Py_DECREF(_val); + sub2_n = dmixml_AddTextChild(sub_n, "Polarity", "%s", + data[0x10] & (1 << 1) ? "Active High" : "Active Low"); + assert( sub2_n != NULL ); + dmixml_AddAttribute(sub2_n, "active_high", "%i", data[0x10] & (1 << 1) ? 1: 0); + sub2_n = NULL; + + dmixml_AddTextChild(sub_n, "TriggerMode", "%s", + data[0x10] & (1 << 0) ? "Level" : "Edge"); } } if(data[0x11] != 0x00) { - _val = PyString_FromFormat("%x", data[0x11]); - PyDict_SetItemString(caseData, "Interrupt Number", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "InterruptNumber", "%x", data[0x11]); } + sub_n = NULL; + + sect_n = NULL; break; case 39: /* 3.3.40 System Power Supply */ + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemPowerSupply", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.40"); - if(h->length < 0x10) + if(h->length < 0x10) { + sect_n = NULL; break; - if(data[0x04] != 0x00) { - _val = PyString_FromFormat("%i", data[0x04]); - PyDict_SetItemString(caseData, "Power Unit Group", _val); - Py_DECREF(_val); } - _val = dmi_string_py(h, data[0x05]); - PyDict_SetItemString(caseData, "Location", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x06]); - PyDict_SetItemString(caseData, "Name", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x07]); - PyDict_SetItemString(caseData, "Manufacturer", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x08]); - PyDict_SetItemString(caseData, "Serial Numberr", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x09]); - PyDict_SetItemString(caseData, "Asset Tag", _val); - Py_DECREF(_val); - - _val = dmi_string_py(h, data[0x0A]); - PyDict_SetItemString(caseData, "Model Part Number", _val); - Py_DECREF(_val); + if(data[0x04] != 0x00) { + dmixml_AddAttribute(sect_n, "UnitGroup", "%i", data[0x04]); + } - _val = dmi_string_py(h, data[0x0B]); - PyDict_SetItemString(caseData, "Revision", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "Location", "%s", dmi_string(h, data[0x05])); + dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x06])); + dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x07])); + dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x08])); + dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x09])); + dmixml_AddTextChild(sect_n, "ModelPartNumber", "%s", dmi_string(h, data[0x0A])); + dmixml_AddTextChild(sect_n, "Revision", "%s", dmi_string(h, data[0x0B])); - _val = dmi_power_supply_power(WORD(data + 0x0C)); - PyDict_SetItemString(caseData, "Max Power Capacity", _val); - Py_DECREF(_val); + dmi_power_supply_power(sect_n, WORD(data + 0x0C)); if(WORD(data + 0x0E) & (1 << 1)) { - _val = dmi_power_supply_status((WORD(data + 0x0E) >> 7) & 0x07); - PyDict_SetItemString(caseData, "Status Present", _val); - Py_DECREF(_val); + dmi_power_supply_status(sect_n, (WORD(data + 0x0E) >> 7) & 0x07); } else { - _val = PyString_FromString("Not Present"); - PyDict_SetItemString(caseData, "Status", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Status", NULL); + assert( sub_n != NULL ); + dmixml_AddAttribute(sub_n, "present", "0"); + sub_n = NULL; } - _val = dmi_power_supply_type((WORD(data + 0x0E) >> 10) & 0x0F); - PyDict_SetItemString(caseData, "Type", _val); - Py_DECREF(_val); - _val = dmi_power_supply_range_switching((WORD(data + 0x0E) >> 3) & 0x0F); - PyDict_SetItemString(caseData, "Input Voltage Range Switching", _val); - Py_DECREF(_val); + dmi_power_supply_type(sect_n, (WORD(data + 0x0E) >> 10) & 0x0F); + + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Input", NULL); + assert( sub_n != NULL ); - _val = PyString_FromFormat("%s", WORD(data + 0x0E) & (1 << 2) ? "No" : "Yes"); - PyDict_SetItemString(caseData, "Plugged", _val); - Py_DECREF(_val); + dmi_power_supply_range_switching(sub_n, (WORD(data + 0x0E) >> 3) & 0x0F); - _val = PyString_FromFormat("%s", WORD(data + 0x0E) & (1 << 0) ? "Yes" : "No"); - PyDict_SetItemString(caseData, "Hot Replaceable", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Plugged", "%i", WORD(data + 0x0E) & (1 << 2) ? 0 : 1); + dmixml_AddAttribute(sub_n, "HotReplacable", "%i", WORD(data + 0x0E) & (1 << 0) ? 1 : 0); - if(h->length < 0x16) + if(h->length < 0x16) { + sub_n = NULL; + sect_n = NULL; break; + } + if(WORD(data + 0x10) != 0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data + 0x10)); - PyDict_SetItemString(caseData, "Input Voltage Probe Handle", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "ProbeHandle", "0x%04x", WORD(data + 0x10)); } if(WORD(data + 0x12) != 0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data + 0x12)); - PyDict_SetItemString(caseData, "Cooling Device Handle", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "CoolingDeviceHandle", "0x%04x", WORD(data + 0x12)); } if(WORD(data + 0x14) != 0xFFFF) { - _val = PyString_FromFormat("0x%04x", WORD(data + 0x14)); - PyDict_SetItemString(caseData, "Input Current Probe Handle", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sub_n, "CurrentProbeHandle", "0x%04x", WORD(data + 0x14)); } + sub_n = NULL; + sect_n = NULL; break; case 40: /* 3.3.41 Additional Information */ - if(h->length < 0x0B) + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "AdditionalInformation", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.41"); + + if(h->length < 0x0B) { + sect_n = NULL; break; - _key = PyString_FromFormat("Additional Information"); - _val = dmi_additional_info(h, ""); - PyDict_SetItem(caseData, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); + } + + dmi_additional_info(sect_n, h); + + sect_n = NULL; break; case 41: /* 3.3.42 Onboard Device Extended Information */ - if(h->length < 0x0B) - break; - PyObject *subdata = PyDict_New(); - - _val = dmi_string_py(h, data[0x04]); - PyDict_SetItemString(subdata, "Reference Designation", _val); - Py_DECREF(_val); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OnboardDeviceExtendedInformation", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.42"); - _val = PyString_FromString(dmi_on_board_devices_type(data[0x05] & 0x7F)); - PyDict_SetItemString(subdata, "Type", _val); - Py_DECREF(_val); + if(h->length < 0x0B) { + sect_n = NULL; + break; + } - _val = PyString_FromString(data[0x05] & 0x80 ? "Enabled" : "Disabled"); - PyDict_SetItemString(subdata, "Status", _val); - Py_DECREF(_val); + dmixml_AddTextChild(sect_n, "ReferenceDesignation", "%s", dmi_string(h, data[0x04])); - _val = PyInt_FromLong(data[0x06]); - PyDict_SetItemString(subdata, "Type Instance", _val); - Py_DECREF(_val); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "OnboardDevice", NULL); + dmi_on_board_devices_type(sub_n, data[0x05] & 0x7F); - _val = dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A]); - PyDict_SetItemString(subdata, "Bus Address", _val); - Py_DECREF(_val); + dmixml_AddAttribute(sub_n, "Enabled", "%i", data[0x05] & 0x80 ? 1 : 0); + dmixml_AddAttribute(sub_n, "TypeInstance", "%ld", data[0x06]); + dmi_slot_segment_bus_func(sub_n, WORD(data + 0x07), data[0x09], data[0x0A]); + sub_n = NULL; - PyDict_SetItemString(caseData, "Onboard Device", subdata); - Py_DECREF(subdata); + sect_n = NULL; break; case 126: /* 3.3.43 Inactive */ - _val = Py_None; - PyDict_SetItemString(caseData, "Inactive", _val); - Py_DECREF(_val); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Inactive", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.43"); + + sect_n = NULL; break; case 127: /* 3.3.44 End Of Table */ - _val = Py_None; - PyDict_SetItemString(caseData, "End Of Table", _val); - Py_DECREF(_val); + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "EndOfTable", NULL); + assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "dmispec", "3.3.44"); + sect_n = NULL; + break; default: if(dmi_decode_oem(h)) break; - _key = PyString_FromFormat("%s Type", h->type >= 128 ? "OEM-specific" : "Unknown"); - _val = dmi_dump(h); - PyDict_SetItem(caseData, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); + + sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "DMIdump", NULL); + assert( sect_n != NULL ); + + dmixml_AddAttribute(sect_n, "Type", "%i", h->type); + dmixml_AddAttribute(sect_n, "InfoType", "%s", h->type >= 128 ? "OEM-specific" : "Unknown"); + + dmi_dump(sect_n, h); + + sect_n = NULL; + break; } } @@ -5076,40 +5103,45 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -static void dmi_table_string_py(const struct dmi_header *h, const u8 * data, PyObject * hDict, - u16 ver) +void dmi_table_string(const struct dmi_header *h, const u8 *data, xmlNode *node, u16 ver) { int key; u8 offset = opt.string->offset; + xmlNode *dmi_n = NULL; if(offset >= h->length) return; //. TODO: These should have more meaningful dictionary names key = (opt.string->type << 8) | offset; - PyObject *_val; switch (key) { case 0x108: - _val = dmi_system_uuid_py(data + offset, ver); - PyDict_SetItemString(hDict, "0x108", _val); + dmi_system_uuid(node, data + offset, ver); + dmixml_AddAttribute(node, "DMItype", "0x108"); break; + case 0x305: - _val = dmi_chassis_type_py(data[offset]); - PyDict_SetItemString(hDict, "0x305", _val); + dmi_chassis_type(node, data[offset]); + dmixml_AddAttribute(node, "DMItype", "0x305"); + // FIXME: Missing break? + case 0x406: - _val = PyString_FromString(dmi_processor_family(h)); - PyDict_SetItemString(hDict, "0x406", _val); + dmi_processor_family(node, h); + dmixml_AddAttribute(node, "DMItype", "0x406"); break; + case 0x416: - _val = dmi_processor_frequency_py((u8 *) data + offset); - PyDict_SetItemString(hDict, "0x416", _val); + dmi_n = dmixml_AddTextChild(node, "ProcessorFrequency", "%s", + dmi_processor_frequency((u8 *) data + offset)); + dmixml_AddAttribute(dmi_n, "DMItype", "0x416"); + dmi_n = NULL; break; + default: - _val = dmi_string_py(h, data[offset]); - PyDict_SetItemString(hDict, "0x???", _val); + dmi_n = dmixml_AddTextChild(node, "Unknown", "%s", dmi_string(h, data[offset])); + dmixml_AddAttribute(dmi_n, "DMItype", "0x%03x", key); } - Py_DECREF(_val); } /* @@ -5249,13 +5281,19 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x int i = 0; if(opt.type == NULL) { - /* FIXME: How to interpret this section in XML? */ - dmiSetItem(pydata, "dmi_table_size", "%i structures occupying %i bytes", num, len); + xmlNode *info_n = NULL; + + info_n = dmixml_AddTextChild(xmlnode, "DMIinfo", "%i structures occupying %i bytes", num, len); + dmixml_AddAttribute(info_n, "dmi_structures", "%i", num); + dmixml_AddAttribute(info_n, "dmi_size", "%i", len); + /* TODO DUMP * if (!(opt.flags & FLAG_FROM_DUMP)) - * dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base); + * dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base); */ - dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base); + + dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base); + info_n = NULL; } if((buf = mem_chunk(base, len, devmem)) == NULL) { @@ -5295,15 +5333,15 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x * stop decoding at end of table marker */ - xmlNode *handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "dmi_handle", NULL); + xmlNode *handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMIentry", NULL); assert( handle_n != NULL ); - dmixml_AddAttribute(handle_n, "id", "0x%04x%c", h.handle); + + dmixml_AddAttribute(handle_n, "handle", "0x%04x%c", h.handle); dmixml_AddAttribute(handle_n, "type", "%d", h.type); dmixml_AddAttribute(handle_n, "size", "%d", h.length); /* assign vendor for vendor-specific decodes later */ if(h.type == 0 && h.length >= 5) { - /* FIXME: Need XML API */ dmi_set_vendor(dmi_string(&h, data[0x04])); } @@ -5331,7 +5369,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x fprintf(stderr, ""); } else if(opt.string != NULL && opt.string->type == h.type) { // <<<---- ** Need to handle this as well ** - dmi_table_string_py(&h, data, hDict, ver); + dmi_table_string(&h, data, handle_n, ver); } data = next; @@ -5451,13 +5489,13 @@ int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) } return check; } -int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata) +int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), - ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, pydata); + ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index b8c70fa..9f6738d 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -18,7 +18,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include +#include struct dmi_header { u8 type; @@ -27,18 +29,17 @@ struct dmi_header { u8 *data; }; -PyObject *dmi_dump(struct dmi_header *h); +void dmi_dump(xmlNode *node, struct dmi_header * h); void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); -int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata); +int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); -PyObject *dmi_system_uuid_py(const u8 * p, u16 ver); void dmi_chassis_type(xmlNode *node, u8 code); int dmi_processor_frequency(const u8 * p); diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 7c81b0a..11a7f15 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -22,13 +22,13 @@ #include "dmihelper.h" //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); -extern PyObject *dmi_dump(struct dmi_header *h); -extern PyObject *dmi_decode(struct dmi_header *h, u16 ver); +extern void dmi_dump(xmlNode *node, struct dmi_header *h); +extern void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); -extern int smbios_decode(u8 * buf, const char *devmem, PyObject * pydata); -extern int legacy_decode(u8 * buf, const char *devmem, PyObject * pydata); +extern int smbios_decode(u8 * buf, const char *devmem, xmlNode *node); +extern int legacy_decode(u8 * buf, const char *devmem, xmlNode *node); extern int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); extern int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); extern void *mem_chunk(size_t base, size_t len, const char *devmem); -- cgit From 581b015c91a3b364b1c1324bed775bfd2ce99dbd Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 9 Apr 2009 11:49:50 +0200 Subject: Made it compile --- src/dmidecode.c | 13 ++++--------- src/dmidecodemodule.c | 23 ++++++++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 773a673..c146969 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -86,11 +86,6 @@ #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) -static const char *out_of_spec = ""; -static const char *bad_index = ""; - -#define BAD_INDEX PyString_FromString("") -#define OUT_OF_SPEC PyString_FromString("") /******************************************************************************* ** Type-independant Stuff @@ -112,7 +107,7 @@ const char *dmi_string(const struct dmi_header *dm, u8 s) } if(!*bp) - return bad_index; + return NULL; /* ASCII filtering */ len = strlen(bp); @@ -233,7 +228,7 @@ void dmi_dump(xmlNode *node, struct dmi_header * h) if((h->data)[h->length] || (h->data)[h->length + 1]) { i = 1; - while((s = dmi_string(h, i++)) != bad_index) { + while((s = dmi_string(h, i++)) != NULL) { //. FIXME: DUMP /* * if(opt.flags & FLAG_DUMP) { @@ -344,7 +339,7 @@ void dmi_bios_characteristics_x1(xmlNode *node, u8 code) dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 7; i++) { - if( code.l & (1 << i) ) { + if( code & (1 << i) ) { dmixml_AddTextChild(node, "characteristic", characteristics[i]); } } @@ -364,7 +359,7 @@ void dmi_bios_characteristics_x2(xmlNode *node, u8 code) dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 2; i++) { - if( code.l & (1 << i) ) { + if( code & (1 << i) ) { dmixml_AddTextChild(node, "characteristic", characteristics[i]); } } diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 1870e86..9528647 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -117,7 +117,7 @@ static int dmidecode_set_version(PyObject ** pydata) ret = 1; else if(smbios_decode_set_version(buf, opt.devmem, pydata)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress); } } @@ -154,7 +154,9 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) if(access(f, R_OK) < 0) PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); - PyObject *pydata = PyDict_New(); + PyObject *pydata = NULL; + xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); + assert( dmixml != NULL ); /***********************************/ /* Read from dump if so instructed */ @@ -164,10 +166,10 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(buf, dumpfile, pydata)) + if(smbios_decode(buf, dumpfile, dmixml_n)) found++; } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode(buf, dumpfile, pydata)) + if(legacy_decode(buf, dumpfile, dmixml_n)) found++; } } else @@ -180,12 +182,12 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(smbios_decode(buf + fp, opt.devmem, pydata)) { + if(smbios_decode(buf + fp, opt.devmem, dmixml_n)) { found++; fp += 16; } } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode(buf + fp, opt.devmem, pydata)) + if(legacy_decode(buf + fp, opt.devmem, dmixml_n)) found++; } } @@ -196,7 +198,7 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) } else { if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) ret = 1; - else if(smbios_decode(buf, opt.devmem, pydata)) + else if(smbios_decode(buf, opt.devmem, dmixml_n)) found++; //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); } @@ -206,8 +208,11 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) if(ret == 0) { free(buf); } else { - Py_DECREF(pydata); - pydata = NULL; + xmlFreeNode(dmixml_n); + if( pydata != NULL ) { + PyDECREF(pydata); + pydata = NULL; + } } //muntrace(); -- cgit From 95b156e3d8a6b82bddb5516735e82355f5dee50a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 9 Apr 2009 12:12:56 +0200 Subject: Removed all Python dependencies in dmidecode.[ch] --- src/dmidecode.c | 59 +++++++++++++++++++++++++-------------------------- src/dmidecode.h | 5 ++--- src/dmidecodemodule.c | 1 + src/dmidecodemodule.h | 4 ++-- 4 files changed, 34 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index c146969..f6f4283 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -60,8 +60,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include - /* #undef NDEBUG */ @@ -5388,12 +5386,14 @@ int _smbios_decode_check(u8 * buf) !checksum(buf + 0x10, 0x0F)) ? 0 : 1; return check; } -int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) + +int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) { int check = _smbios_decode_check(buf); - char vbuf[64]; - bzero(vbuf, 64); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SMBIOSversion", NULL); + assert( data_n != NULL ); + if(check == 1) { u16 ver = (buf[0x06] << 8) + buf[0x07]; @@ -5414,20 +5414,18 @@ int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) ver = 0x0206; break; } - if(_m || _M) - sprintf(vbuf, "SMBIOS %i.%i present (Version fixup 2.%d -> 2.%d)", ver >> 8, - ver & 0xFF, _m, _M); - else - sprintf(vbuf, "SMBIOS %i.%i present", ver >> 8, ver & 0xFF); - } else if(check == 0) { - sprintf(vbuf, "No SMBIOS nor DMI entry point found"); - } - if(check == 1) { - if(*pydata) { - Py_DECREF(*pydata); + if(_m || _M) { + dmixml_AddTextContent(data_n, "SMBIOS %i.%i present (Version fixup 2.%d -> 2.%d)", + ver >> 8, ver & 0xFF, _m, _M); + dmixml_AddAttribute(data_n, "version", "%i.%i", ver >> 8, ver & 0xFF); + dmixml_AddAttribute(data_n, "fixup_version", "2.%d_2.%d", _m, _M); + } else { + dmixml_AddTextContent(data_n, "SMBIOS %i.%i present", ver >> 8, ver & 0xFF); + dmixml_AddAttribute(data_n, "version", "%i.%i", ver >> 8, ver & 0xFF); } - *pydata = PyString_FromString(vbuf); - Py_INCREF(*pydata); + } else if(check == 0) { + dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); + dmixml_AddAttribute(data_n, "unknown", "1"); } return check; } @@ -5464,26 +5462,27 @@ int _legacy_decode_check(u8 * buf) check = 1; //. Good return check; } -int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata) + +int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) { int check = _legacy_decode_check(buf); - char vbuf[64]; - bzero(vbuf, 64); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "LegacyDMI", NULL); + assert( data_n != NULL ); + if(check == 1) { - sprintf(vbuf, "Legacy DMI %i.%i present", buf[0x0E] >> 4, buf[0x0E] & 0x0F); + dmixml_AddTextContent(data_n, "Legacy DMI %i.%i present", + buf[0x0E] >> 4, buf[0x0E] & 0x0F); + dmixml_AddAttribute(data_n, "version", "%i.%i", + buf[0x0E] >> 4, buf[0x0E] & 0x0F); } else if(check == 0) { - sprintf(vbuf, "No SMBIOS nor DMI entry point found"); - } - if(check == 1) { - if(*pydata) { - Py_DECREF(*pydata); - } - *pydata = PyString_FromString(vbuf); - Py_INCREF(*pydata); + dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); + dmixml_AddAttribute(data_n, "unknown", "1"); } + return check; } + int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); diff --git a/src/dmidecode.h b/src/dmidecode.h index 9f6738d..bbc8eca 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -19,7 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include struct dmi_header { @@ -33,9 +32,9 @@ void dmi_dump(xmlNode *node, struct dmi_header * h); void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); -int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); +int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); -int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); +int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 9528647..e9e688c 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -1,3 +1,4 @@ +#include #include "dmidecodemodule.h" #include diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 11a7f15..4de9a2d 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -29,8 +29,8 @@ extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); extern int smbios_decode(u8 * buf, const char *devmem, xmlNode *node); extern int legacy_decode(u8 * buf, const char *devmem, xmlNode *node); -extern int smbios_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); -extern int legacy_decode_set_version(u8 * buf, const char *devmem, PyObject ** pydata); +extern int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +extern int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); extern void *mem_chunk(size_t base, size_t len, const char *devmem); extern u8 *parse_opt_type(u8 * p, const char *arg); -- cgit From 8b2fe610dc309579f07787696f0814c359aa4de1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 9 Apr 2009 14:51:31 +0200 Subject: Added missing copyright details --- src/dmixml.c | 5 ++++- src/dmixml.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 434b2e7..8be62ff 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -1,4 +1,7 @@ -/* +/* Simplified XML API for dmidecode + * + * Copyright 2009 David Sommerseth + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff --git a/src/dmixml.h b/src/dmixml.h index 7d8c4ad..e3b99a9 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -1,4 +1,7 @@ -/* +/* Simplified XML API for dmidecode + * + * Copyright 2009 David Sommerseth + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or -- cgit From 46988f9abcec9eb072be5f5d52fc594de89478e8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 9 Apr 2009 15:13:23 +0200 Subject: Added more XML functions --- src/dmixml.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dmixml.h | 5 +++++ 2 files changed, 58 insertions(+) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 8be62ff..0feb90c 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -141,3 +141,56 @@ xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...) return res; } + +char *dmixml_GetAttrValue(xmlNode *node, const char *key) { + xmlAttr *aptr = NULL; + xmlChar *key_s = NULL; + + if( node == NULL ) { + return NULL; + } + + key_s = xmlCharStrdup(key); + assert( key_s != NULL ); + + for( aptr = node->properties; aptr != NULL; aptr = aptr->next ) { + if( xmlStrcmp(aptr->name, key_s) == 0 ) { + free(key_s); key_s = NULL; + // FIXME: Should find better way how to return UTF-8 data + return (char *)(aptr->children != NULL ? aptr->children->content : NULL); + } + } + free(key_s); key_s = NULL; + return NULL; +} + +xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { + xmlNode *ptr_n = NULL; + xmlChar *key_s = NULL; + + if( node->children == NULL ) { + return NULL; + } + + key_s = xmlCharStrdup(key); + assert( key_s != NULL ); + + for( ptr_n = node->children; ptr_n != NULL; ptr_n = ptr_n->next ) { + if( xmlStrcmp(ptr_n->name, key_s) == 0 ) { + free(key_s); key_s = NULL; + return ptr_n; + } + } + free(key_s); key_s = NULL; + return NULL; +} + +inline char *dmixml_GetContent(xmlNode *node) { + // FIXME: Should find better way how to return UTF-8 data + return (char *) (((node != NULL) && (node->children != NULL)) ? node->children->content : NULL); +} + +inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { + return dmixml_GetContent(dmixml_FindNode(node, key)); +} + diff --git a/src/dmixml.h b/src/dmixml.h index e3b99a9..4683bc9 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -33,4 +33,9 @@ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); +char *dmixml_GetAttrValue(xmlNode *node, const char *key); +xmlNode *dmixml_FindNode(xmlNode *, const char *key); +inline char *dmixml_GetContent(xmlNode *node); +inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); + #endif -- cgit From 92ea3b07784853558d93391dbc364c69463cd61d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 10 Apr 2009 11:28:41 +0200 Subject: Fixed wrong string handling of DMI data, which caused SEGV --- src/dmidecode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index f6f4283..9c00e63 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3656,7 +3656,7 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; dmixml_AddAttribute(handle_n, "id", "%s", dmiMajor->id); - dmixml_AddAttribute(handle_n, "type", "%s", h->type); + dmixml_AddAttribute(handle_n, "type", "%i", h->type); dmixml_AddTextChild(handle_n, "description", "%s", dmiMajor->desc); switch (h->type) { @@ -3670,9 +3670,9 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) break; } - dmixml_AddTextChild(sect_n, "Vendor", "%s", data[0x04]); - dmixml_AddTextChild(sect_n, "Version", "%s", data[0x05]); - dmixml_AddTextChild(sect_n, "ReleaseDate", "%s", data[0x08]); + dmixml_AddTextChild(sect_n, "Vendor", "%s", dmi_string(h, data[0x04])); + dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x05])); + dmixml_AddTextChild(sect_n, "ReleaseDate", "%s", dmi_string(h, data[0x08])); /* * On IA-64, the BIOS base address will read 0 because -- cgit From b8bcbc709a3bdb5ee1e59e22d5e54c59f391165f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 10 Apr 2009 13:38:52 +0200 Subject: Added right trim of xml data --- src/dmixml.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 0feb90c..08c5259 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -33,6 +33,7 @@ // Internal function for dmixml_* functions ... builds up a variable xmlChar* string xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) { xmlChar *ret = NULL, *xmlfmt = NULL; + xmlChar *ptr = NULL; ret = (xmlChar *) malloc(len+2); assert( ret != NULL ); @@ -44,6 +45,12 @@ xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) { xmlStrVPrintf(ret, len, xmlfmt, ap); free(xmlfmt); + // Right trim the string + ptr = ret + xmlStrlen(ret)-1; + while( (ptr >= ret) && (*ptr == ' ') ) { + *ptr = 0; + ptr--; + } return ret; } -- cgit From 62f276eea2d8477854d7fe9b230a957a8df4102c Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 10 Apr 2009 13:51:01 +0200 Subject: Do not add XML values if input is "(null)" --- src/dmixml.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 08c5259..1fe862d 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -79,7 +79,8 @@ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); - res = xmlNewProp(node, atrname_s, val_s); + res = xmlNewProp(node, atrname_s, + (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s)); free(atrname_s); free(val_s); @@ -112,7 +113,9 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); - res = xmlNewTextChild(node, NULL, tagname_s, val_s); + // Do not add any contents if the string contents is "(null)" + res = xmlNewTextChild(node, NULL, tagname_s, + (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s)); free(tagname_s); free(val_s); @@ -141,7 +144,11 @@ xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...) val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); - res = xmlAddChild(node, xmlNewText(val_s)); + if( xmlStrcmp(val_s, (xmlChar *) "(null)") != 0 ) { + res = xmlAddChild(node, xmlNewText(val_s)); + } else { + res = node; + } free(val_s); assert( res != NULL ); -- cgit From 38c943db697b13e5f9be020a0729f58b7366e932 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 10 Apr 2009 13:52:47 +0200 Subject: Cleaned up the XML data --- src/dmidecode.c | 361 +++++--------------------------------------------------- src/dmidecode.h | 2 +- src/dmihelper.h | 90 +++++++------- 3 files changed, 79 insertions(+), 374 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 9c00e63..c348380 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -702,8 +702,8 @@ void dmi_processor_type(xmlNode *node, u8 code) }; xmlNode *proct_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); assert( proct_n != NULL ); - dmixml_AddAttribute(proct_n, "dmispec", "3.3.5"); dmixml_AddAttribute(proct_n, "flags", "0x%04x", code); + if(code >= 0x01 && code <= 0x06) { dmixml_AddTextContent(proct_n, type[code - 0x01]); } else { @@ -1000,7 +1000,6 @@ xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *vers xmlNode *flags_n = NULL; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CPUCore", NULL); assert( data_n != NULL ); - dmixml_AddAttribute(data_n, "dmispec", "3.3.5"); /* ** Extra flags are now returned in the ECX register when one calls @@ -1149,8 +1148,8 @@ void dmi_processor_voltage(xmlNode *node, u8 code) dmixml_AddAttribute(vltg_n, "flags", "0x%04x", code); if(code & 0x80) { - dmixml_AddTextChild(vltg_n, "Voltage", "%.1f", (float)(code & 0x7f) / 10); - dmixml_AddAttribute(vltg_n, "unit", "V"); + xmlNode *v_n = dmixml_AddTextChild(vltg_n, "Voltage", "%.1f", (float)(code & 0x7f) / 10); + dmixml_AddAttribute(v_n, "unit", "V"); } else if( code == 0x00 ) { dmixml_AddAttribute(vltg_n, "unknown_value", "1"); } else { @@ -1242,10 +1241,10 @@ void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) { assert( cache_n != NULL ); - dmixml_AddAttribute(cache_n, "flags", "0x%04x", code); dmixml_AddAttribute(cache_n, "ver", "0x%04x", ver); if(code == 0xFFFF) { + dmixml_AddAttribute(cache_n, "flags", "0x%04x", code); if(ver >= 0x0203) { dmixml_AddAttribute(cache_n, "provided", "0"); dmixml_AddAttribute(cache_n, "available", "1"); @@ -1255,7 +1254,7 @@ void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) } else { dmixml_AddAttribute(cache_n, "provided", "1"); dmixml_AddAttribute(cache_n, "available", "1"); - dmixml_AddTextChild(cache_n, "Handle", "0x%04x", code); + dmixml_AddAttribute(cache_n, "Handle", "0x%04x", code); } } @@ -3645,7 +3644,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) ** Main */ -void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) +xmlNode *dmi_decode(struct dmi_header * h, u16 ver) { const u8 *data = h->data; xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; @@ -3655,18 +3654,17 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; - dmixml_AddAttribute(handle_n, "id", "%s", dmiMajor->id); - dmixml_AddAttribute(handle_n, "type", "%i", h->type); - dmixml_AddTextChild(handle_n, "description", "%s", dmiMajor->desc); + + sect_n = xmlNewNode(NULL, (xmlChar *) dmiMajor->tagname); + assert( sect_n != NULL ); + + dmixml_AddAttribute(sect_n, "id", "%s", dmiMajor->id); + dmixml_AddAttribute(sect_n, "type", "%i", h->type); + dmixml_AddTextChild(sect_n, "description", "%s", dmiMajor->desc); switch (h->type) { case 0: /* 3.3.1 BIOS Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOSinformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.1"); - if(h->length < 0x12) { - sect_n = NULL; break; } @@ -3695,7 +3693,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub_n = NULL; if(h->length < 0x13) { - sect_n = NULL; break; } @@ -3707,7 +3704,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub_n = NULL; if(h->length < 0x14) { - sect_n = NULL; break; } @@ -3719,7 +3715,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub_n = NULL; if(h->length < 0x18) { - sect_n = NULL; break; } @@ -3730,16 +3725,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) if(data[0x16] != 0xFF && data[0x17] != 0xFF) { dmixml_AddTextChild(sect_n, "FirmwareRevision", "%i.%i", data[0x16], data[0x17]); } - sect_n = NULL; break; case 1: /* 3.3.2 System Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.2"); - if(h->length < 0x08) { - sect_n = NULL; break; } @@ -3749,7 +3738,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); if(h->length < 0x19) { - sect_n = NULL; break; } @@ -3758,23 +3746,15 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_system_wake_up_type(sect_n, data[0x18]); if(h->length < 0x1B) { - sect_n = NULL; break; } dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19])); dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A])); - - sect_n = NULL; break; case 2: /* 3.3.3 Base Board Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BaseboardInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.3"); - if(h->length < 0x08) { - sect_n = NULL; break; } @@ -3784,7 +3764,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); if(h->length < 0x0F) { - sect_n = NULL; break; } @@ -3798,20 +3777,14 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_base_board_type(sect_n, "Type", data[0x0D]); if(h->length < 0x0F + data[0x0E] * sizeof(u16)) { - sect_n = NULL; break; } dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F); - sect_n = NULL; break; case 3: /* 3.3.4 Chassis Information */ - sect_n= xmlNewChild(handle_n, NULL, (xmlChar *) "ChassisInformation", NULL); - assert( sect_n != NULL ); - if(h->length < 0x09) { - sect_n = NULL; break; } @@ -3823,7 +3796,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); if(h->length < 0x0D) { - sect_n = NULL; break; } @@ -3838,14 +3810,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_chassis_security_status(sect_n, data[0x0C]); if(h->length < 0x11) { - sect_n = NULL; break; } dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x0D)); if(h->length < 0x13) { - sect_n = NULL; break; } @@ -3853,21 +3823,14 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_chassis_power_cords(sect_n, data[0x12]); if((h->length < 0x15) || (h->length < 0x15 + data[0x13] * data[0x14])){ - sect_n = NULL; break; } dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15); - sect_n = NULL; break; case 4: /* 3.3.5 Processor Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ProcessorInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.5"); - if(h->length < 0x1A) { - sect_n = NULL; break; } @@ -3912,7 +3875,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_processor_upgrade(sect_n, data[0x19]); if(h->length < 0x20) { - sect_n = NULL; break; } @@ -3943,7 +3905,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub_n = NULL; if(h->length < 0x23) { - sect_n = NULL; break; } @@ -3952,7 +3913,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x22])); if(h->length < 0x28) { - sect_n = NULL; break; } @@ -3973,19 +3933,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_processor_characteristics(sub_n, WORD(data + 0x26)); sub_n = NULL; - - sect_n = NULL; break; case 5: /* 3.3.6 Memory Controller Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryControllerInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.6"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0F) { - sect_n = NULL; break; } @@ -4014,31 +3967,23 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_processor_voltage(sect_n, data[0x0D]); if(h->length < 0x0F + data[0x0E] * sizeof(u16)) { - sect_n = NULL; break; } dmi_memory_controller_slots(sect_n, data[0x0E], data + 0x0F); if(h->length < 0x10 + data[0x0E] * sizeof(u16)) { - sect_n = NULL; break; } dmi_memory_controller_ec_capabilities(sect_n, "EnabledErrorCorrection", data[0x0F + data[0x0E] * sizeof(u16)]); - sect_n = NULL; break; case 6: /* 3.3.7 Memory Module Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryModuleInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.7"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0C) { - sect_n = NULL; break; } @@ -4050,18 +3995,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_memory_module_size(sect_n, "InstalledSize", data[0x09]); dmi_memory_module_size(sect_n, "EnabledSize", data[0x0A]); dmi_memory_module_error(sect_n, data[0x0B]); - sect_n = NULL; break; case 7: /* 3.3.8 Cache Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "CacheInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.8"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0F) { - sect_n = NULL; break; } @@ -4083,7 +4022,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_cache_types(sect_n, "InstalledSRAMtypes", WORD(data + 0x0D)); if(h->length < 0x13) { - sect_n = NULL; break; } @@ -4091,19 +4029,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_cache_ec_type(sect_n, data[0x10]); dmi_cache_type(sect_n, data[0x11]); dmi_cache_associativity(sect_n, data[0x12]); - - sect_n = NULL; break; case 8: /* 3.3.9 Port Connector Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "PortConnectorInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.9"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x09) { - sect_n = NULL; break; } @@ -4121,19 +4052,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_port_connector_type(sect_n, "external", data[0x07]); dmi_port_type(sect_n, data[0x08]); - - sect_n = NULL; break; case 9: /* 3.3.10 System Slots */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemSlots", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.10"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x0C) { - sect_n = NULL; break; } @@ -4150,76 +4074,42 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) } else { dmi_slot_characteristics(sect_n, data[0x0B], data[0x0C]); } - - sect_n = NULL; break; case 10: /* 3.3.11 On Board Devices Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OnBoardDevicesInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.11"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - - sect_n = NULL; break; case 11: /* 3.3.12 OEM Strings */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OEMstrings", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.12"); - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); if(h->length < 0x05) { - sect_n = NULL; break; } dmi_oem_strings(sect_n, h); - - sect_n = NULL; break; case 12: /* 3.3.13 System Configuration Options */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemConfigurationOptions", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.13"); - if(h->length < 0x05) { - sect_n = NULL; break; } dmi_system_configuration_options(sect_n, h); - - sect_n = NULL; break; case 13: /* 3.3.14 BIOS Language Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BIOSlanguageInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.14"); - if(h->length < 0x16) { - sect_n = NULL; break; } dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]); dmi_bios_languages(sect_n, h); - - sect_n = NULL; break; case 14: /* 3.3.15 Group Associations */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "GroupAssociations", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.15"); - if(h->length < 0x05) { - sect_n = NULL; break; } @@ -4229,18 +4119,11 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) assert( sub_n != NULL ); dmi_group_associations_items(sub_n, (h->length - 0x05) / 3, data + 0x05); sub_n = NULL; - - sect_n = NULL; break; case 15: /* 3.3.16 System Event Log */ // SysEventLog - sect_n - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemEventLog", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.16"); - if(h->length < 0x14) { - sect_n = NULL; break; } @@ -4268,7 +4151,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sub2_n, "ChangeToken", "0x%08x", DWORD(data + 0x0C)); if(h->length < 0x17) { - sect_n = NULL; break; } @@ -4286,7 +4168,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddAttribute(sub_n, "count", "%i", data[0x15]); if(h->length < 0x17 + data[0x15] * data[0x16]) { - sect_n = NULL; break; } @@ -4295,17 +4176,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) // SysEventLog/LogTypes/LogType dmi_event_log_descriptors(sub_n, data[0x15], data[0x16], data + 0x17); sub_n = NULL; - - sect_n = NULL; break; case 16: /* 3.3.17 Physical Memory Array */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "PhysicalMemoryArray", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.17"); - if(h->length < 0x0F) { - sect_n = NULL; break; } @@ -4315,17 +4189,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_memory_array_ec_type(sect_n, data[0x06]); dmi_memory_array_capacity(sect_n, DWORD(data + 0x07)); dmi_memory_array_error_handle(sect_n, WORD(data + 0x0B)); - - sect_n = NULL; break; case 17: /* 3.3.18 Memory Device */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryDevice", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.18"); - if(h->length < 0x15) { - sect_n = NULL; break; } @@ -4344,14 +4211,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_memory_device_type_detail(sect_n, WORD(data + 0x13)); if(h->length < 0x17) { - sect_n = NULL; break; } dmi_memory_device_speed(sect_n, WORD(data + 0x15)); if(h->length < 0x1B) { - sect_n = NULL; break; } @@ -4359,27 +4224,19 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x18])); dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x19])); dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x1A])); - - sect_n = NULL; break; case 18: /* 3.3.19 32-bit Memory Error Information */ case 33: /* 3.3.34 64-bit Memory Error Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryErrorInfo", NULL); - assert( sect_n != NULL ); - if( h->type == 18 ) { - dmixml_AddAttribute(sect_n, "dmispec", "3.3.19"); dmixml_AddAttribute(sect_n, "bits", "32"); } else { - dmixml_AddAttribute(sect_n, "dmispec", "3.3.34"); dmixml_AddAttribute(sect_n, "bits", "64"); } if( ((h->type == 18) && (h->length < 0x17)) /* 32-bit */ || ((h->type == 33) && (h->length < 0x1F)) ) /* 64-bit */ { - sect_n = NULL; break; } @@ -4399,17 +4256,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_64bit_memory_error_address(sect_n, "DeviceAddr", QWORD(data + 0x13)); dmi_32bit_memory_error_address(sect_n, "Resolution", DWORD(data + 0x1B)); } - - sect_n = NULL; break; case 19: /* 3.3.20 Memory Array Mapped Address */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryArrayMappedAddress", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.20"); - if(h->length < 0x0F) { - sect_n = NULL; break; } @@ -4422,17 +4272,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1); dmixml_AddTextChild(sect_n, "PhysicalArrayHandle", "0x%04x", WORD(data + 0x0C)); dmixml_AddTextChild(sect_n, "PartitionWidth", "%i", data[0x0F]); - - sect_n = NULL; break; case 20: /* 3.3.21 Memory Device Mapped Address */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryDeviceMappedAddress", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.21"); - if(h->length < 0x13) { - sect_n = NULL; break; } @@ -4453,34 +4296,20 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_mapped_address_interleave_position(sect_n, data[0x11]); dmi_mapped_address_interleaved_data_depth(sect_n, data[0x12]); - - sect_n = NULL; break; case 21: /* 3.3.22 Built-in Pointing Device */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BuiltInPointingDevice", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.22"); - if(h->length < 0x07) { - sect_n = NULL; break; } dmi_pointing_device_type(sect_n, data[0x04]); dmi_pointing_device_interface(sect_n, data[0x05]); dmixml_AddTextContent(sect_n, "Buttons", "%i", data[0x06]); - - sect_n = NULL; break; case 22: /* 3.3.23 Portable Battery */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "PortableBattery", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.23"); - if(h->length < 0x10) { - sect_n = NULL; break; } @@ -4508,7 +4337,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_battery_maximum_error(sect_n, data[0x0F]); if(h->length < 0x1A) { - sect_n = NULL; break; } @@ -4526,17 +4354,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) } dmixml_AddTextChild(sect_n, "OEMinformation", "%s", "0x%08x", DWORD(data + 0x16)); - - sect_n = NULL; break; case 23: /* 3.3.24 System Reset */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemReset", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.24"); - if(h->length < 0x0D) { - sect_n = NULL; break; } @@ -4551,7 +4372,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) sub_n = NULL; if(!(data[0x04] & (1 << 5))) { - sect_n = NULL; break; } @@ -4563,17 +4383,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_system_reset_timer(sect_n, "TimerInterval", WORD(data + 0x09)); dmi_system_reset_timer(sect_n, "Timeout", WORD(data + 0x0B)); - - sect_n = NULL; break; case 24: /* 3.3.25 Hardware Security */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "HardwareSecurity", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.25"); - if(h->length < 0x05) { - sect_n = NULL; break; } @@ -4582,31 +4395,20 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_hardware_security_status(sect_n, "AdministratorPassword", (data[0x04] >> 2) & 0x3); dmi_hardware_security_status(sect_n, "FronPanelReset", data[0x04] & 0x3); - sect_n = NULL; break; case 25: /* 3.3.26 System Power Controls */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemPowerControls", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.26"); - if(h->length < 0x09) { - sect_n = NULL; break; } dmi_power_controls_power_on(sect_n, "NextSchedPowerOn", data + 0x04); - - sect_n = NULL; break; case 26: /* 3.3.27 Voltage Probe */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "VoltageProbe", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.27"); + dmixml_AddAttribute(sect_n, "probetype", "Voltage"); if(h->length < 0x14) { - sect_n = NULL; break; } @@ -4625,22 +4427,14 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); if(h->length < 0x16) { - sect_n = NULL; break; } dmi_voltage_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); - - sect_n = NULL; break; case 27: /* 3.3.28 Cooling Device */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "CoolingDevice", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.28"); - if(h->length < 0x0C) { - sect_n = NULL; break; } @@ -4658,22 +4452,16 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x08)); if(h->length < 0x0E) { - sect_n = NULL; break; } dmi_cooling_device_speed(sect_n, WORD(data + 0x0C)); - - sect_n = NULL; break; case 28: /* 3.3.29 Temperature Probe */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "TemperatureProbe", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.29"); + dmixml_AddAttribute(sect_n, "probetype", "Temperature"); if(h->length < 0x14) { - sect_n = NULL; break; } @@ -4690,22 +4478,16 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); if(h->length < 0x16) { - sect_n = NULL; break; } dmi_temperature_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); - - sect_n = NULL; break; case 29: /* 3.3.30 Electrical Current Probe */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ElectricalCurrentProbe", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.30"); + dmixml_AddAttribute(sect_n, "probetype", "Electrical Current"); if(h->length < 0x14) { - sect_n = NULL; break; } @@ -4723,61 +4505,38 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); if(h->length < 0x16) { - sect_n = NULL; break; } dmi_current_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); - - sect_n = NULL; break; case 30: /* 3.3.31 Out-of-band Remote Access */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OutOfBandRemoteAccess", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.31"); - if(h->length < 0x06) { - sect_n = NULL; break; } dmixml_AddTextChild(sect_n, "ManufacturerName", "%s", dmi_string(h, data[0x04])); dmixml_AddAttribute(sect_n, "InboundConnectionEnabled", "%i", data[0x05] & (1 << 0) ? 1 : 0); dmixml_AddAttribute(sect_n, "OutboundConnectionEnabled", "%i", data[0x05] & (1 << 1) ? 1 : 0); - - sect_n = NULL; break; case 31: /* 3.3.32 Boot Integrity Services Entry Point */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "BootIntegrityServiceEntryPoint", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.32"); dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1"); break; case 32: /* 3.3.33 System Boot Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemBootInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.33"); - if(h->length < 0x0B) { - sect_n = NULL; break; } dmi_system_boot_status(sect_n, data[0x0A]); - - sect_n = NULL; break; case 34: /* 3.3.35 Management Device */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ManagementDevice", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.35"); + dmixml_AddAttribute(sect_n, "mgmtype", ""); if(h->length < 0x0B) { - sect_n = NULL; break; } @@ -4785,17 +4544,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmi_management_device_type(sect_n, data[0x05]); dmixml_AddTextChild(sect_n, "Address", "0x%08x", DWORD(data + 0x06)); dmi_management_device_address_type(sect_n, data[0x0A]); - - sect_n = NULL; break; case 35: /* 3.3.36 Management Device Component */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ManagementDeviceComponent", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.36"); + dmixml_AddAttribute(sect_n, "mgmtype", "Component"); if(h->length < 0x0B) { - sect_n = NULL; break; } @@ -4806,17 +4560,12 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) if(WORD(data + 0x09) != 0xFFFF) { dmixml_AddTextChild(sect_n, "ThresholdHandle", "0x%04x", WORD(data + 0x09)); } - - sect_n = NULL; break; case 36: /* 3.3.37 Management Device Threshold Data */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "ManagementDeviceThresholdData", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.37"); + dmixml_AddAttribute(sect_n, "mgmtype", "Threshold Data"); if(h->length < 0x10) { - sect_n = NULL; break; } @@ -4856,17 +4605,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x0E)); } sub_n = NULL; - - sect_n = NULL; break; case 37: /* 3.3.38 Memory Channel */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "MemoryChannel", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.38"); - if(h->length < 0x07) { - sect_n = NULL; break; } @@ -4879,14 +4621,11 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) if(h->length < 0x07 + 3 * data[0x06]) { sub_n = NULL; - sect_n = NULL; break; } dmi_memory_channel_devices(sub_n, data[0x06], data + 0x07); sub_n = NULL; - - sect_n = NULL; break; case 38: /* 3.3.39 IPMI Device Information */ @@ -4894,12 +4633,7 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) * We use the word "Version" instead of "Revision", conforming to * the IPMI specification. */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "IPMIdeviceInformation", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.39"); - if(h->length < 0x10) { - sect_n = NULL; break; } @@ -4923,7 +4657,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1); if(h->length < 0x12) { - sect_n = NULL; break; } @@ -4948,17 +4681,10 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sub_n, "InterruptNumber", "%x", data[0x11]); } sub_n = NULL; - - sect_n = NULL; break; case 39: /* 3.3.40 System Power Supply */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "SystemPowerSupply", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.40"); - if(h->length < 0x10) { - sect_n = NULL; break; } @@ -4997,7 +4723,6 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) if(h->length < 0x16) { sub_n = NULL; - sect_n = NULL; break; } @@ -5014,31 +4739,24 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) } sub_n = NULL; - sect_n = NULL; break; case 40: /* 3.3.41 Additional Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "AdditionalInformation", NULL); - assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "subtype", "AdditionalInformation"); dmixml_AddAttribute(sect_n, "dmispec", "3.3.41"); if(h->length < 0x0B) { - sect_n = NULL; break; } dmi_additional_info(sect_n, h); - - sect_n = NULL; break; case 41: /* 3.3.42 Onboard Device Extended Information */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "OnboardDeviceExtendedInformation", NULL); - assert( sect_n != NULL ); + dmixml_AddAttribute(sect_n, "subtype", "OnboardDeviceExtendedInformation"); dmixml_AddAttribute(sect_n, "dmispec", "3.3.42"); if(h->length < 0x0B) { - sect_n = NULL; break; } @@ -5051,41 +4769,26 @@ void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver) dmixml_AddAttribute(sub_n, "TypeInstance", "%ld", data[0x06]); dmi_slot_segment_bus_func(sub_n, WORD(data + 0x07), data[0x09], data[0x0A]); sub_n = NULL; - - sect_n = NULL; break; case 126: /* 3.3.43 Inactive */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "Inactive", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.43"); - - sect_n = NULL; - break; - case 127: /* 3.3.44 End Of Table */ - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "EndOfTable", NULL); - assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "dmispec", "3.3.44"); - sect_n = NULL; - break; default: if(dmi_decode_oem(h)) break; - sect_n = xmlNewChild(handle_n, NULL, (xmlChar *) "DMIdump", NULL); + sect_n = xmlNewChild(sect_n, NULL, (xmlChar *) "DMIdump", NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "Type", "%i", h->type); dmixml_AddAttribute(sect_n, "InfoType", "%s", h->type >= 128 ? "OEM-specific" : "Unknown"); dmi_dump(sect_n, h); - - sect_n = NULL; break; } + return sect_n; } void to_dmi_header(struct dmi_header *h, u8 * data) @@ -5326,13 +5029,6 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x * stop decoding at end of table marker */ - xmlNode *handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMIentry", NULL); - assert( handle_n != NULL ); - - dmixml_AddAttribute(handle_n, "handle", "0x%04x%c", h.handle); - dmixml_AddAttribute(handle_n, "type", "%d", h.type); - dmixml_AddAttribute(handle_n, "size", "%d", h.length); - /* assign vendor for vendor-specific decodes later */ if(h.type == 0 && h.length >= 5) { dmi_set_vendor(dmi_string(&h, data[0x04])); @@ -5345,6 +5041,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x } next += 2; + xmlNode *handle_n = NULL; if(display) { if(next - buf <= len) { /* TODO: ... @@ -5357,13 +5054,19 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - dmi_decode(handle_n, &h, ver); + handle_n = dmi_decode(&h, ver); } else fprintf(stderr, ""); } else if(opt.string != NULL && opt.string->type == h.type) { - // <<<---- ** Need to handle this as well ** + handle_n = xmlNewNode(NULL, (xmlChar *) "DMItable"); + assert( handle_n != NULL ); dmi_table_string(&h, data, handle_n, ver); } + if( handle_n != NULL ) { + dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); + dmixml_AddAttribute(handle_n, "size", "%d", h.length); + xmlAddChild(xmlnode, handle_n); + } data = next; i++; diff --git a/src/dmidecode.h b/src/dmidecode.h index bbc8eca..ef13ce3 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -29,7 +29,7 @@ struct dmi_header { }; void dmi_dump(xmlNode *node, struct dmi_header * h); -void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver); +xmlNode *dmi_decode(struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); diff --git a/src/dmihelper.h b/src/dmihelper.h index ac82916..6c0b854 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -33,53 +33,55 @@ typedef struct _dmi_codes_major { const unsigned short code; const char *id; const char *desc; + const char *tagname; } dmi_codes_major; static const dmi_codes_major dmiCodesMajor[] = { - {0, "3.3.1", "BIOS Information"}, - {1, "3.3.2", "System Information"}, - {2, "3.3.3", "Base Board Information"}, - {3, "3.3.4", "Chassis Information"}, - {4, "3.3.5", "Processor Information"}, - {5, "3.3.6", "Memory Controller Information"}, - {6, "3.3.7", "Memory Module Information"}, - {7, "3.3.8", "Cache Information"}, - {8, "3.3.9", "Port Connector Information"}, - {9, "3.3.10", "System Slots"}, - {10, "3.3.11", "On Board Devices Information"}, - {11, "3.3.12", "OEM Strings"}, - {12, "3.3.13", "System Configuration Options"}, - {13, "3.3.14", "BIOS Language Information"}, - {14, "3.3.15", "Group Associations"}, - {15, "3.3.16", "System Event Log"}, - {16, "3.3.17", "Physical Memory Array"}, - {17, "3.3.18", "Memory Device"}, - {18, "3.3.19", "32-bit Memory Error Information"}, - {19, "3.3.20", "Memory Array Mapped Address"}, - {20, "3.3.21", "Memory Device Mapped Address"}, - {21, "3.3.22", "Built-in Pointing Device"}, - {22, "3.3.23", "Portable Battery"}, - {23, "3.3.24", "System Reset"}, - {24, "3.3.25", "Hardware Security"}, - {25, "3.3.26", "System Power Controls"}, - {26, "3.3.27", "Voltage Probe"}, - {27, "3.3.28", "Cooling Device"}, - {28, "3.3.29", "Temperature Probe"}, - {29, "3.3.30", "Electrical Current Probe"}, - {30, "3.3.31", "Out-of-band Remote Access"}, - {31, "3.3.32", "Boot Integrity Services Entry Point"}, - {32, "3.3.33", "System Boot Information"}, - {33, "3.3.34", "64-bit Memory Error Information"}, - {34, "3.3.35", "Management Device"}, - {35, "3.3.36", "Management Device Component"}, - {36, "3.3.37", "Management Device Threshold Data"}, - {37, "3.3.38", "Memory Channel"}, - {38, "3.3.39", "IPMI Device Information"}, - {39, "3.3.40", "System Power Supply"}, - {40, "3.3.41", "-------------------"}, - {41, "3.3.42", "-------------------"}, - {126, "3.3.41", "Inactive"}, - {127, "3.3.42", "End Of Table"}, + {0, "3.3.1", "BIOS Information", "BIOSinfo"}, + {1, "3.3.2", "System Information", "SystemInfo"}, + {2, "3.3.3", "Base Board Information", "BaseBoardInfo"}, + {3, "3.3.4", "Chassis Information", "ChassisInfo"}, + {4, "3.3.5", "Processor Information", "ProcessorInfo"}, + {5, "3.3.6", "Memory Controller Information", "MemoryCtrlInfo"}, + {6, "3.3.7", "Memory Module Information", "MemoryModuleInfo"}, + {7, "3.3.8", "Cache Information", "CacheInfo"}, + {8, "3.3.9", "Port Connector Information", "PortConnectorInfo"}, + {9, "3.3.10", "System Slots", "SystemSlots"}, + {10, "3.3.11", "On Board Devices Information", "OnBoardDevicesInfo"}, + {11, "3.3.12", "OEM Strings", "OEMstrings"}, + {12, "3.3.13", "System Configuration Options", "SysConfigOptions"}, + {13, "3.3.14", "BIOS Language Information", "BIOSlanguage"}, + {14, "3.3.15", "Group Associations", "GroupAssoc"}, + {15, "3.3.16", "System Event Log", "SysEventLog"}, + {16, "3.3.17", "Physical Memory Array", "PhysicalMemoryArray"}, + {17, "3.3.18", "Memory Device", "MemoryDevice"}, + {18, "3.3.19", "32-bit Memory Error Information", "MemoryErrorInfo"}, + {19, "3.3.20", "Memory Array Mapped Address", "MemoryArrayMappedAddress"}, + {20, "3.3.21", "Memory Device Mapped Address", "MemoryDeviceMappedAddress"}, + {21, "3.3.22", "Built-in Pointing Device", "BuiltIntPointingDevice"}, + {22, "3.3.23", "Portable Battery", "PortableBattery"}, + {23, "3.3.24", "System Reset", "SystemReset"}, + {24, "3.3.25", "Hardware Security", "HardwareSecurity"}, + {25, "3.3.26", "System Power Controls", "SystemPowerCtrls"}, + {26, "3.3.27", "Voltage Probe", "Probe"}, + {27, "3.3.28", "Cooling Device", "CoolingDevice"}, + {28, "3.3.29", "Temperature Probe", "Probe"}, + {29, "3.3.30", "Electrical Current Probe", "Probe"}, + {30, "3.3.31", "Out-of-band Remote Access", "RemoteAccess"}, + {31, "3.3.32", "Boot Integrity Services Entry Point", "BootIntegrity"}, + {32, "3.3.33", "System Boot Information", "SystemBootInfo"}, + {33, "3.3.34", "64-bit Memory Error Information", "MemoryErrorInfo"}, + {34, "3.3.35", "Management Device", "ManagementDevice"}, + {35, "3.3.36", "Management Device Component", "ManagementDevice"}, + {36, "3.3.37", "Management Device Threshold Data", "ManagementDevice"}, + {37, "3.3.38", "Memory Channel", "MemoryChannel"}, + {38, "3.3.39", "IPMI Device Information", "IPMIdeviceInfo"}, + {39, "3.3.40", "System Power Supply", "SystemPowerSupply"}, + {40, "3.3.41", "-------------------", "Unknown"}, + {41, "3.3.42", "-------------------", "Unknown"}, + {126, "3.3.41", "Inactive", "Inactive"}, + {127, "3.3.42", "End Of Table", "EndOfTable"}, + {-1, NULL, NULL, NULL} }; typedef struct _dmi_minor { -- cgit From 8c5015cfd169bbec89974e57b04da3985425e6cd Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 14 Apr 2009 14:21:48 +0200 Subject: More XML cleanup --- src/dmidecode.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index c348380..1087df2 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -311,10 +311,10 @@ void dmi_bios_characteristics(xmlNode *node, u64 code) xmlNode *flags_n = xmlNewChild(node, NULL, (xmlChar *) "flags", NULL); assert( flags_n != NULL ); - for(i = 4; i <= 31; i++) - if( code.l & (1 << i) ) { - dmixml_AddTextChild(flags_n, "flag", characteristics[i - 3]); - } + for(i = 4; i <= 31; i++) { + xmlNode *flg_n = dmixml_AddTextChild(flags_n, "flag", characteristics[i - 3]); + dmixml_AddAttribute(flg_n, "enabled", "%i", (code.l & (1 << i) ? 1 : 0 )); + } } } @@ -337,9 +337,8 @@ void dmi_bios_characteristics_x1(xmlNode *node, u8 code) dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 7; i++) { - if( code & (1 << i) ) { - dmixml_AddTextChild(node, "characteristic", characteristics[i]); - } + xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]); + dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0)); } } @@ -357,9 +356,8 @@ void dmi_bios_characteristics_x2(xmlNode *node, u8 code) dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 2; i++) { - if( code & (1 << i) ) { - dmixml_AddTextChild(node, "characteristic", characteristics[i]); - } + xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]); + dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0)); } } @@ -3658,7 +3656,7 @@ xmlNode *dmi_decode(struct dmi_header * h, u16 ver) sect_n = xmlNewNode(NULL, (xmlChar *) dmiMajor->tagname); assert( sect_n != NULL ); - dmixml_AddAttribute(sect_n, "id", "%s", dmiMajor->id); + dmixml_AddAttribute(sect_n, "dmispec", "%s", dmiMajor->id); dmixml_AddAttribute(sect_n, "type", "%i", h->type); dmixml_AddTextChild(sect_n, "description", "%s", dmiMajor->desc); -- cgit From 0af6d685a83d7c060de52717859e00104bc7c4b8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 14 Apr 2009 14:22:09 +0200 Subject: Fixed compiler error due to API changes This fixes a regression from commit 7f0fa9b2e1afd6aecea0b34b62cf9ebdf075164d --- src/dmidecodemodule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 4de9a2d..7583eb7 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -23,7 +23,7 @@ //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern void dmi_dump(xmlNode *node, struct dmi_header *h); -extern void dmi_decode(xmlNode *handle_n, struct dmi_header * h, u16 ver); +extern xmlNode *dmi_decode(struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); -- cgit From 75aaf67d43cf4a28fe8d3e07111dab75a0c4396d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 24 Apr 2009 17:09:41 +0200 Subject: Don't return NULL in dmixml_GetContent(...) --- src/dmixml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 1fe862d..6fcf24f 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -201,7 +201,7 @@ xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { inline char *dmixml_GetContent(xmlNode *node) { // FIXME: Should find better way how to return UTF-8 data - return (char *) (((node != NULL) && (node->children != NULL)) ? node->children->content : NULL); + return (((node != NULL) && (node->children != NULL)) ? (char *) node->children->content : "(not set)"); } inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { -- cgit From 70e35765fbb9be6ddd6aab6555916777a593e0aa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 11:07:51 +0200 Subject: Only consider XML nodes which is of XML_ELEMENT_NODE when finding a specific node --- src/dmixml.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 6fcf24f..a9ecd67 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -190,7 +190,8 @@ xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { assert( key_s != NULL ); for( ptr_n = node->children; ptr_n != NULL; ptr_n = ptr_n->next ) { - if( xmlStrcmp(ptr_n->name, key_s) == 0 ) { + if( (ptr_n->type == XML_ELEMENT_NODE) + && (xmlStrcmp(ptr_n->name, key_s) == 0) ) { free(key_s); key_s = NULL; return ptr_n; } -- cgit From c7be629d44d4e2be6c8116796714e0042a977885 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 11:12:58 +0200 Subject: Added generic XML -> Python parser The xmlpythonizer module will convert any XML data (xmlNode or xmlDoc) and format it as a Python object. The formatting is defined in it's own XML file. Basic format: The keytype and key attributes defines the key in the Python Dict. The root element will always be a Python Dict structure. The valid key types are: * constant Uses the value in {key} as the key value * string, integer, float Uses a string value from the data XML to be converted to Python. The value set in the key attribute defines an XPath value which points to the data to be used as a Python dict key. Since Python only supports C strings in the C interface for Python dict keys, integer and float will be treated as strings. The valuetype and value attributes are similar to the keys, but with some more features. Valid valuetypes are: * constant The value given in the value attribute will be used in the value in the Python result. * string, integer, float The value given in the value attribute defines the XPath to the data XML, of where to retrieve the value for the given key. The valuetype defines if the data should be understood as a string, integer or float in the Python result. * list:string, list:integer, list:float This does the same as the string, integer or float type, with a tweak. The data will be put into a list. If the XPath given returns multiple nodes, all of them will be added to this list. * dict The dict valuetype is more special. It should not contain any value attribute. On the other hand, it should contain a sub-level of tags. In this way, you can build up a multi dimensional Python dict. Example: ** pythonmap.xml ** ** exampledata.xml ** String value #1 More test data Value1 in list Value2 in list Value3 in list ** C code snippet ** void xmlpythonizer() { xmlDoc *xmlmap = NULL; xmlDoc *xmldata = NULL; ptzMAP *mapping = NULL; PyObject *pythondata = NULL; // Read XML files xmlmap = xmlReadFile("pythonmap.xml", NULL, 0); xmldata = xmlReadFile("exampledata.xml", NULL, 0); // Parse the mapping XML mapping = dmiMAP_ParseMappingXML(xmlmap, "example_map"); // Parse the xmldata into a Python object pythondata = pythonizeXMLdoc(mapping, xmldata); // ..... the program continues to do something useful } The result stored inside the pythondata object should now be something similar to: {'DemoCase': 'XML Pythonizing', 'String1': 'String value #1', 'AttribString1: 1234, 'TestData': {'Value1': 'More test data', 'ValueList': ['Value1 in list','Value2 in list','Value3 in list']} } --- src/pythonmap.xml | 16 ++ src/setup.py | 3 +- src/xmlpythonizer.c | 522 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/xmlpythonizer.h | 50 +++++ 4 files changed, 590 insertions(+), 1 deletion(-) create mode 100644 src/pythonmap.xml create mode 100644 src/xmlpythonizer.c create mode 100644 src/xmlpythonizer.h (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml new file mode 100644 index 0000000..a49a8ab --- /dev/null +++ b/src/pythonmap.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/setup.py b/src/setup.py index 6272e85..ec66c3f 100644 --- a/src/setup.py +++ b/src/setup.py @@ -16,7 +16,8 @@ setup( "src/util.c", "src/dmioem.c", "src/dmidecode.c", - "src/dmixml.c" + "src/dmixml.c", + "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c new file mode 100644 index 0000000..92e0d7f --- /dev/null +++ b/src/xmlpythonizer.c @@ -0,0 +1,522 @@ +/* Converts XML docs and nodes to Python dicts and lists by + * using an XML file which describes the Python dict layout + * + * Copyright 2009 David Sommerseth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "dmixml.h" +#include "xmlpythonizer.h" + +ptzMAP *ptzmap_Add(const ptzMAP *chain, + ptzTYPES ktyp, const char *key, + ptzTYPES vtyp, const char *value, + ptzMAP *child) +{ + ptzMAP *ret = NULL; + + assert( (ktyp == ptzCONST) || (ktyp == ptzSTR) || (ktyp == ptzINT) || (ktyp == ptzFLOAT) ); + assert( key != NULL ); + // Make sure that value and child are not used together + assert( ((value == NULL) && child != NULL) || ((value != NULL) && (child == NULL)) ); + + ret = (ptzMAP *) malloc(sizeof(ptzMAP)+2); + assert( ret != NULL ); + memset(ret, 0, sizeof(ptzMAP)+2); + + ret->type_key = ktyp; + ret->key = strdup(key); + + ret->type_value = vtyp; + if( value != NULL ) { + ret->value = strdup(value); + ret->child = NULL; + } else if( child != NULL ) { + ret->value = NULL; + ret->child = child; + } + + if( chain != NULL ) { + ret->next = (ptzMAP *) chain; + } + return ret; +}; + +#define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } +void ptzmap_Free_func(ptzMAP *ptr) +{ + if( ptr == NULL ) { + return; + } + + free(ptr->key); + ptr->key = NULL; + + if( ptr->value != NULL ) { + free(ptr->value); + ptr->value = NULL; + } + + if( ptr->child != NULL ) { + ptzmap_Free(ptr->child); + } + if( ptr->next != NULL ) { + ptzmap_Free(ptr->next); + } + free(ptr); +} + + +#if 1 +// DEBUG FUNCTIONS +static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", + "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", + "ptzDICT", NULL }; + +void indent(int lvl) +{ + int i = 0; + if( lvl == 0 ) { + return; + } + + for( i = 0; i < (lvl * 3); i++ ) { + printf(" "); + } +} + +#define ptzmap_Dump(ptr) { ptzmap_Dump_func(ptr, 0); } +void ptzmap_Dump_func(const ptzMAP *ptr, int level) +{ + if( ptr == NULL ) { + return; + } + + indent(level); printf("key type: (%i) %-13.13s - key: %s\n", + ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); + indent(level); printf("value type: (%i) %-13.13s - value: %s\n", + ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value); + if( ptr->child != NULL ) { + indent(level); printf(" ** CHILD\n"); + ptzmap_Dump_func(ptr->child, level + 1); + indent(level); printf(" ** ---------\n"); + } + if( ptr->next != NULL ) { + printf("\n"); + ptzmap_Dump_func(ptr->next, level); + } +} +#endif // END OF DEBUG FUNCTIONS + +// +// Parser for the XML -> Python mapping XML file +// +// This mappipng XML file describes how the Python result +// should look like and where it should pick the data from +// when later on parsing the dmidecode XML data. +// + +// Valid key and value types for the mapping file +inline ptzTYPES _convert_maptype(const char *str) { + if( strcmp(str, "string") == 0 ) { + return ptzSTR; + } else if( strcmp(str, "constant") == 0 ) { + return ptzCONST; + } else if( strcmp(str, "integer") == 0 ) { + return ptzINT; + } else if( strcmp(str, "float") == 0 ) { + return ptzFLOAT; + } else if( strcmp(str, "list:string") == 0 ) { + return ptzLIST_STR; + } else if( strcmp(str, "list:integer") == 0 ) { + return ptzLIST_INT; + } else if( strcmp(str, "list:float") == 0 ) { + return ptzLIST_FLOAT; + } else if( strcmp(str, "dict") == 0 ) { + return ptzDICT; + } else { + fprintf(stderr, "Unknown field type: %s - defaulting to 'string'\n", str); + return ptzSTR; + } +} + +// Internal parser +ptzMAP *_do_dmimap_parsing(xmlNode *node) { + ptzMAP *retmap = NULL; + xmlNode *ptr_n = NULL, *map_n = NULL;; + + // Go to the next XML_ELEMENT_NODE + for( map_n = node; map_n != NULL; map_n = map_n->next ) { + if( map_n->type == XML_ELEMENT_NODE ) { + break; + } + } + if( map_n == NULL ) { + return NULL; + } + + // Go to the first node + if( xmlStrcmp(node->name, (xmlChar *) "Map") != 0 ) { + map_n = dmixml_FindNode(node, "Map"); + if( map_n == NULL ) { + return NULL; + } + } + + // Loop through it's children + for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { + ptzTYPES type_key, type_value; + char *key = NULL, *value = NULL; + + if( ptr_n->type != XML_ELEMENT_NODE ) { + continue; + } + + // Get the attributes defining key, keytype, value and valuetype + key = dmixml_GetAttrValue(ptr_n, "key"); + type_key = _convert_maptype(dmixml_GetAttrValue(ptr_n, "keytype")); + + value = dmixml_GetAttrValue(ptr_n, "value"); + type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); + + if( type_value == ptzDICT ) { + // When value type is ptzDICT, traverse the children nodes + // - should contain another Map set instead of a value attribute + if( ptr_n->children == NULL ) { + continue; + } + // Recursion + retmap = ptzmap_Add(retmap, type_key, key, type_value, NULL, + _do_dmimap_parsing(ptr_n->children->next)); + } else { + // Append the value as a normal value when the + // value type is not a Python Dict + retmap = ptzmap_Add(retmap, type_key, key, type_value, value, NULL); + } + value = NULL; + key = NULL; + } + return retmap; +} + +// Main parser function for the mapping XML +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { + ptzMAP *map = NULL; + xmlNode *node = NULL; + + // Find the root tag and locate our mapping + node = xmlDocGetRootElement(xmlmap); + assert( node != NULL ); + + // Verify that the root node got the right name + if( (node == NULL) + || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { + fprintf(stderr, "Invalid XML-Python mapping file\n"); + return NULL; + } + + // Verify that it's of a version we support + if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { + fprintf(stderr, "Unsupported XML-Python mapping file format\n"); + return NULL; + } + + // Find the section matching our request (mapname) + for( node = node->children->next; node != NULL; node = node->next ) { + if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { + char *name = dmixml_GetAttrValue(node, "name"); + if( (name != NULL) && (strcmp(name, mapname) == 0) ) { + break; + } + } + } + + if( node == NULL ) { + fprintf(stderr, "No mapping for '%s' was found " + "in the XML-Python mapping file\n", mapname); + return NULL; + } + + // Start creating an internal map structure based on the mapping XML. + map = _do_dmimap_parsing(node); + + return map; +} + + +// +// Parser routines for converting XML data into Python structures +// + +inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { + PyObject *value; + + switch( type ) { + case ptzINT: + case ptzLIST_INT: + value = PyInt_FromLong((str != NULL ? atoi(str) : 0)); + break; + + case ptzFLOAT: + case ptzLIST_FLOAT: + value = PyFloat_FromDouble((str != NULL ? atof(str) : 0)); + break; + + case ptzSTR: + case ptzLIST_STR: + value = PyString_FromString(str); + break; + + default: + fprintf(stderr, "Invalid type '%i' for value '%s'\n", type, str); + value = Py_None; + } + return value; +} + + +// Retrieve a value from the XML doc (XPath Context) based on a XPath query +xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { + xmlChar *xp_xpr = NULL; + xmlXPathObject *xp_obj = NULL; + + if( xpath == NULL ) { + return NULL; + } + + xp_xpr = xmlCharStrdup(xpath); + xp_obj = xmlXPathEvalExpression(xp_xpr, xpctx); + assert( xp_obj != NULL ); + free(xp_xpr); + + if( (xp_obj->nodesetval == NULL) || (xp_obj->nodesetval->nodeNr == 0) ) { + xmlXPathFreeObject(xp_obj); + return NULL; + } + + return xp_obj; +} + +// Internal XML parser routine, which traverses the given mapping table, +// returning a Python structure accordingly to the map. +PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { + ptzMAP *map_p = NULL; + PyObject *retdata = NULL; + int i = 0; + + retdata = PyDict_New(); + for( map_p = in_map; map_p != NULL; map_p = map_p->next ) { + xmlXPathObject *xpobj = NULL; + char *key = NULL; + PyObject *value = NULL; + + // Get key value + switch( map_p->type_key ) { + case ptzCONST: + key = map_p->key; + break; + + case ptzSTR: + case ptzINT: + case ptzFLOAT: + xpobj = _get_xpath_values(xpctx, map_p->key); + if( xpobj != NULL ) { + key = dmixml_GetContent(xpobj->nodesetval->nodeTab[0]); + xmlXPathFreeObject(xpobj); + } + break; + default: + fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); + return Py_None; + break; + } + + // Get 'value' value + switch( map_p->type_value ) { + case ptzCONST: + value = PyString_FromString(map_p->value); + break; + + case ptzSTR: + case ptzINT: + case ptzFLOAT: + xpobj = _get_xpath_values(xpctx, map_p->value); + if( xpobj != NULL ) { + value = StringToPyObj(map_p->type_value, + dmixml_GetContent(xpobj->nodesetval->nodeTab[0])); + xmlXPathFreeObject(xpobj); + } + break; + + case ptzLIST_STR: + case ptzLIST_INT: + case ptzLIST_FLOAT: + xpobj = _get_xpath_values(xpctx, map_p->value); + value = PyList_New(0); + if( xpobj != NULL ) { + for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { + char *valstr = dmixml_GetContent(xpobj->nodesetval->nodeTab[i]); + PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); + } + xmlXPathFreeObject(xpobj); + } + break; + + case ptzDICT: + // Traverse the children to get the value of this element + value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); + Py_DECREF(value); + break; + + default: + fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); + free(key); key = NULL; + return Py_None; + break; + } + + PyDict_SetItemString(retdata, key, value); + Py_DECREF(value); + } + Py_INCREF(retdata); + return retdata; +} + +// Convert a xmlDoc to a Python object, based on the given map +PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc) +{ + xmlXPathContext *xp_ctx = NULL; + PyObject *retdata = NULL; + + // Prepare a XPath context for XPath queries + xp_ctx = xmlXPathNewContext(xmldoc); + assert( xp_ctx != NULL ); + + // Parse the XML and create Python data + retdata = _do_pythonizeXML(map, xp_ctx, 0); + + // Clean up and return data + xmlXPathFreeContext(xp_ctx); + + return retdata; +} + +// Convert a xmlNode to a Python object, based on the given map +PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes) +{ + xmlDoc *xmldoc = NULL; + PyObject *retdata = NULL; + + // Create our own internal XML doc and + // copy over the input nodes to our internal doc. + // This is needed as the XPath parser in libxml2 + // only works with xmlDoc. + xmldoc = xmlNewDoc((xmlChar *) "1.0"); + assert( xmldoc != NULL ); + xmlDocSetRootElement(xmldoc, xmlCopyNode(nodes, 1)); + + // Parse the internal xmlDoc + retdata = pythonizeXMLdoc(map, xmldoc); + + // Clean up and return data + xmlFreeDoc(xmldoc); + return retdata; +} + + + +#if 0 +// Simple independent main function - only for debugging +int main() { + xmlDoc *doc = NULL; + ptzMAP *map = NULL; + + doc = xmlReadFile("pythonmap.xml", NULL, 0); + assert( doc != NULL ); + + map = dmiMAP_ParseMappingXML(doc, "BIOSLanguage"); + ptzmap_Dump(map); + + ptzmap_Free(map); + xmlFreeDoc(doc); + + return 0; +} +#endif + +#if 0 +// Simple test module for Python - only for debugging +PyObject* demo_xmlpy() +{ + xmlDoc *doc = NULL, *mapping_xml = NULL; + ptzMAP *mapping = NULL; + PyObject *ret = NULL; + + // Read the XML-Python mapping setup + mapping_xml = xmlReadFile("pythonmap.xml", NULL, 0); + assert( mapping_xml != NULL ); + + mapping = dmiMAP_ParseMappingXML(mapping_xml, "BIOSLanguage"); + assert( mapping != NULL ); + + // Read XML data from file + doc = xmlReadFile("test.xml", NULL, 0); + assert( doc != NULL ); + + // Create a PyObject out of the XML indata + ret = pythonizeXMLdoc(mapping, doc); + + // Clean up and return the data + ptzmap_Free(mapping); + xmlFreeDoc(doc); + xmlFreeDoc(mapping_xml); + + return ret; +} + + +static PyMethodDef DemoMethods[] = { + {"xmlpy", demo_xmlpy, METH_NOARGS, ""}, + {NULL, NULL, 0, NULL} +}; + +PyMODINIT_FUNC initxmlpythonizer(void) { + PyObject *module = + Py_InitModule3((char *)"xmlpythonizer", DemoMethods, + "XML to Python Proof-of-Concept Python Module"); + + PyObject *version = PyString_FromString("2.10"); + Py_INCREF(version); + PyModule_AddObject(module, "version", version); +} +#endif // Python test module + diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h new file mode 100644 index 0000000..4882d81 --- /dev/null +++ b/src/xmlpythonizer.h @@ -0,0 +1,50 @@ +/* Converts XML docs and nodes to Python dicts and lists by + * using an XML file which describes the Python dict layout + * + * Copyright 2009 David Sommerseth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#ifndef _XMLPYTHONIZER_H +#define _XMLPYTHONIZER_H + +typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, + ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, + ptzDICT } ptzTYPES; + +typedef struct ptzMAP_s { + ptzTYPES type_key; // Valid types: ptzCONST, ptzSTR, ptzINT, ptzFLOAT + char *key; // for ptzCONST key contains a static string, other types an XPath to XML data + ptzTYPES type_value; + char *value; // for ptzCONST key contains a static string, + // the rest of types, an XPath to XML data + struct ptzMAP_s *child; // Only used for type_value == pyDICT + struct ptzMAP_s *next; // Pointer chain + +} ptzMAP; + + +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc); +PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes); + +#endif // _XMLPYTHONIZER_H -- cgit From 11691f4b5e5786878cca1d30b183103477d5311f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 16:58:33 +0200 Subject: Updated xmlpythonizer to support boolean type and dynamic XPath keys * Added support boolean and list:boolean value types * Traversing child nodes and having dynamic keys Now it is possible to do the following: ** test.xml ** Option 1 Option 2 Option 3 ** mapping.xml ** Which should result in: {'Option 1': True, 'Option 2': False, 'Option 3': True'} --- src/xmlpythonizer.c | 121 +++++++++++++++++++++++++++++++++++++--------------- src/xmlpythonizer.h | 4 +- 2 files changed, 88 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 92e0d7f..594717c 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -96,10 +96,10 @@ void ptzmap_Free_func(ptzMAP *ptr) } -#if 1 +#if 0 // DEBUG FUNCTIONS -static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", - "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", +static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL", + "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL", "ptzDICT", NULL }; void indent(int lvl) @@ -155,12 +155,16 @@ inline ptzTYPES _convert_maptype(const char *str) { return ptzINT; } else if( strcmp(str, "float") == 0 ) { return ptzFLOAT; + } else if( strcmp(str, "boolean") == 0 ) { + return ptzBOOL; } else if( strcmp(str, "list:string") == 0 ) { return ptzLIST_STR; } else if( strcmp(str, "list:integer") == 0 ) { return ptzLIST_INT; } else if( strcmp(str, "list:float") == 0 ) { return ptzLIST_FLOAT; + } else if( strcmp(str, "list:boolean") == 0 ) { + return ptzLIST_BOOL; } else if( strcmp(str, "dict") == 0 ) { return ptzDICT; } else { @@ -280,15 +284,24 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { PyObject *value; + if( str == NULL ) { + return Py_None; + } + switch( type ) { case ptzINT: case ptzLIST_INT: - value = PyInt_FromLong((str != NULL ? atoi(str) : 0)); + value = PyInt_FromLong(atoi(str)); break; case ptzFLOAT: case ptzLIST_FLOAT: - value = PyFloat_FromDouble((str != NULL ? atof(str) : 0)); + value = PyFloat_FromDouble(atof(str)); + break; + + case ptzBOOL: + case ptzLIST_BOOL: + value = PyBool_FromLong((atoi(str) == 1 ? 1:0)); break; case ptzSTR: @@ -326,6 +339,43 @@ xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { return xp_obj; } +inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { + char *key = NULL; + xmlXPathObject *xpobj = NULL; + + switch( map_p->type_key ) { + case ptzCONST: + key = map_p->key; + break; + + case ptzSTR: + case ptzINT: + case ptzFLOAT: + xpobj = _get_xpath_values(xpctx, map_p->key); + if( xpobj != NULL ) { + key = dmixml_GetContent(xpobj->nodesetval->nodeTab[idx]); + xmlXPathFreeObject(xpobj); + } + break; + + default: + fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); + break; + } + if( key == NULL ) { + fprintf(stderr, "Could not find the key value: %s\n", map_p->key); + } + return key; +} + + +#define PyADD_DICT_VALUE(p, k, v) { \ + if( k != NULL ) { \ + PyDict_SetItemString(p, k, v); \ + Py_DECREF(v); \ + } \ + } + // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { @@ -339,40 +389,27 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { char *key = NULL; PyObject *value = NULL; - // Get key value - switch( map_p->type_key ) { - case ptzCONST: - key = map_p->key; - break; - - case ptzSTR: - case ptzINT: - case ptzFLOAT: - xpobj = _get_xpath_values(xpctx, map_p->key); - if( xpobj != NULL ) { - key = dmixml_GetContent(xpobj->nodesetval->nodeTab[0]); - xmlXPathFreeObject(xpobj); - } - break; - default: - fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); - return Py_None; - break; - } - // Get 'value' value switch( map_p->type_value ) { case ptzCONST: value = PyString_FromString(map_p->value); + key = _get_key_value(map_p, xpctx, 0); + PyADD_DICT_VALUE(retdata, key, value); + break; case ptzSTR: case ptzINT: case ptzFLOAT: + case ptzBOOL: xpobj = _get_xpath_values(xpctx, map_p->value); if( xpobj != NULL ) { - value = StringToPyObj(map_p->type_value, - dmixml_GetContent(xpobj->nodesetval->nodeTab[0])); + for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { + value = StringToPyObj(map_p->type_value, + dmixml_GetContent(xpobj->nodesetval->nodeTab[i])); + key = _get_key_value(map_p, xpctx, i); + PyADD_DICT_VALUE(retdata, key, value); + } xmlXPathFreeObject(xpobj); } break; @@ -380,6 +417,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzLIST_STR: case ptzLIST_INT: case ptzLIST_FLOAT: + case ptzLIST_BOOL: xpobj = _get_xpath_values(xpctx, map_p->value); value = PyList_New(0); if( xpobj != NULL ) { @@ -388,6 +426,8 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); } xmlXPathFreeObject(xpobj); + key = _get_key_value(map_p, xpctx, 0); + PyADD_DICT_VALUE(retdata, key, value); } break; @@ -395,17 +435,16 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { // Traverse the children to get the value of this element value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); Py_DECREF(value); + + key = _get_key_value(map_p, xpctx, 0); + PyADD_DICT_VALUE(retdata, key, value); break; default: fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); - free(key); key = NULL; return Py_None; break; } - - PyDict_SetItemString(retdata, key, value); - Py_DECREF(value); } Py_INCREF(retdata); return retdata; @@ -457,16 +496,28 @@ PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes) #if 0 // Simple independent main function - only for debugging int main() { - xmlDoc *doc = NULL; + xmlDoc *doc = NULL, *data = NULL; ptzMAP *map = NULL; + PyObject *pydat = NULL; doc = xmlReadFile("pythonmap.xml", NULL, 0); assert( doc != NULL ); - map = dmiMAP_ParseMappingXML(doc, "BIOSLanguage"); + map = dmiMAP_ParseMappingXML(doc, "bios"); ptzmap_Dump(map); + printf("----------------------\n"); + + + data = xmlReadFile("test.xml", NULL, 0); + assert( data != NULL ); + + pydat = pythonizeXMLdoc(map, data); + Py_INCREF(pydat); + PyObject_Print(pydat, stdout, 0); + Py_DECREF(pydat); ptzmap_Free(map); + xmlFreeDoc(data); xmlFreeDoc(doc); return 0; @@ -485,7 +536,7 @@ PyObject* demo_xmlpy() mapping_xml = xmlReadFile("pythonmap.xml", NULL, 0); assert( mapping_xml != NULL ); - mapping = dmiMAP_ParseMappingXML(mapping_xml, "BIOSLanguage"); + mapping = dmiMAP_ParseMappingXML(mapping_xml, "bios"); assert( mapping != NULL ); // Read XML data from file diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 4882d81..59cc0cd 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -27,8 +27,8 @@ #ifndef _XMLPYTHONIZER_H #define _XMLPYTHONIZER_H -typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, - ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, +typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL, + ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, ptzLIST_BOOL, ptzDICT } ptzTYPES; typedef struct ptzMAP_s { -- cgit From 4b925a1433b65c217e787804df3cf349d6b387aa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 19:10:45 +0200 Subject: Added filter and filtervalue attributes to xmlpythonizer's tags Using these attributes, only XML data (from the given XPath in 'filter') which matches the value in 'filtervalue' will be added to the Python data. --- src/xmlpythonizer.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-------- src/xmlpythonizer.h | 4 +++ 2 files changed, 78 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 594717c..32f0181 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -40,6 +40,7 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, ptzTYPES ktyp, const char *key, ptzTYPES vtyp, const char *value, + const char *filter, const char *filterval, ptzMAP *child) { ptzMAP *ret = NULL; @@ -65,6 +66,11 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, ret->child = child; } + if( filter != NULL && filterval != NULL ) { + ret->filter = strdup(filter); + ret->filtervalue = strdup(filterval); + } + if( chain != NULL ) { ret->next = (ptzMAP *) chain; } @@ -86,6 +92,16 @@ void ptzmap_Free_func(ptzMAP *ptr) ptr->value = NULL; } + if( ptr->filter != NULL ) { + free(ptr->filter); + ptr->filter = NULL; + } + + if( ptr->filtervalue != NULL ) { + free(ptr->filtervalue); + ptr->filtervalue = NULL; + } + if( ptr->child != NULL ) { ptzmap_Free(ptr->child); } @@ -125,6 +141,10 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); indent(level); printf("value type: (%i) %-13.13s - value: %s\n", ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value); + if( ptr->filter != NULL ) { + indent(level); printf("filter: %s == %s\n", ptr->filter, ptr->filtervalue); + } + if( ptr->child != NULL ) { indent(level); printf(" ** CHILD\n"); ptzmap_Dump_func(ptr->child, level + 1); @@ -200,6 +220,7 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { ptzTYPES type_key, type_value; char *key = NULL, *value = NULL; + char *filter = NULL, *filterval = NULL; if( ptr_n->type != XML_ELEMENT_NODE ) { continue; @@ -212,6 +233,12 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); + // Get filters + filter = dmixml_GetAttrValue(ptr_n, "filter"); + if( filter != NULL ) { + filterval = dmixml_GetAttrValue(ptr_n, "filtervalue"); + } + if( type_value == ptzDICT ) { // When value type is ptzDICT, traverse the children nodes // - should contain another Map set instead of a value attribute @@ -219,12 +246,18 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { continue; } // Recursion - retmap = ptzmap_Add(retmap, type_key, key, type_value, NULL, + retmap = ptzmap_Add(retmap, type_key, key, + type_value, NULL, + filter, filterval, _do_dmimap_parsing(ptr_n->children->next)); + } else { // Append the value as a normal value when the // value type is not a Python Dict - retmap = ptzmap_Add(retmap, type_key, key, type_value, value, NULL); + retmap = ptzmap_Add(retmap, type_key, key, + type_value, value, + filter, filterval, + NULL); } value = NULL; key = NULL; @@ -272,7 +305,6 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // Start creating an internal map structure based on the mapping XML. map = _do_dmimap_parsing(node); - return map; } @@ -369,12 +401,42 @@ inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { } -#define PyADD_DICT_VALUE(p, k, v) { \ - if( k != NULL ) { \ - PyDict_SetItemString(p, k, v); \ - Py_DECREF(v); \ - } \ +void _register_value(PyObject *pyobj, xmlXPathContext *xpctx, + ptzMAP *map_p, const char *key, PyObject *value) +{ + if( key != NULL ) { + if( (map_p->filter != NULL) && (map_p->filtervalue != NULL) ) { + xmlXPathObject *xpobj = NULL; + int i = 0, found = 0; + + xpobj = _get_xpath_values(xpctx, map_p->filter); + if( (xpobj == NULL) || (xpobj->nodesetval->nodeNr < 1) ) { + // If node not found, or our value index is higher + // than what we found, filter it out. + if( xpobj != NULL ) { + xmlXPathFreeObject(xpobj); + } + return; + } + + for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { + if( strcmp(map_p->filtervalue, + dmixml_GetContent(xpobj->nodesetval->nodeTab[i])) == 0 ) { + found = 1; + break; + } + } + + if( found != 1 ) { + // If value did not match - no hit => do not add value + xmlXPathFreeObject(xpobj); + return; + } + } + PyDict_SetItemString(pyobj, key, value); + Py_DECREF(value); } +} // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. @@ -394,7 +456,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzCONST: value = PyString_FromString(map_p->value); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); break; @@ -408,7 +470,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { value = StringToPyObj(map_p->type_value, dmixml_GetContent(xpobj->nodesetval->nodeTab[i])); key = _get_key_value(map_p, xpctx, i); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); } xmlXPathFreeObject(xpobj); } @@ -427,7 +489,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { } xmlXPathFreeObject(xpobj); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); } break; @@ -437,7 +499,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { Py_DECREF(value); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); break; default: diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 59cc0cd..2c89390 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -37,6 +37,10 @@ typedef struct ptzMAP_s { ptzTYPES type_value; char *value; // for ptzCONST key contains a static string, // the rest of types, an XPath to XML data + + char *filter; // Used for simple filtering. If NULL, no filtering is performed + char *filtervalue; // Only XML contents which matches the given value will be parsed further + struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From e013d57e504c4e989c0503e62b63369bb16ebdaf Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 19:12:25 +0200 Subject: Added pythonmap.xml - default XML -> Python mapping setup Only added mapping for the 'bios' section. --- src/pythonmap.xml | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index a49a8ab..14f4f9b 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -1,16 +1,37 @@ - - + + + valuetype="list:string" value="/dmidecode/BIOSlanguage/Installed/Language"/> + valuetype="integer" value="/dmidecode/BIOSlanguage/@installable_languages"/> - - - + + + + + + + + + + + + + + + + + + -- cgit From c6baf0a8f50cc19f319ad13ceeb2c40ace0b4d7e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 11:18:57 +0200 Subject: Exported ptzmap_Free() --- src/xmlpythonizer.c | 1 - src/xmlpythonizer.h | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 32f0181..91507e8 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -77,7 +77,6 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, return ret; }; -#define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr) { if( ptr == NULL ) { diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 2c89390..8572403 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -46,8 +46,10 @@ typedef struct ptzMAP_s { } ptzMAP; - ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +#define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } +void ptzmap_Free_func(ptzMAP *ptr); + PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc); PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes); -- cgit From 7cf8017a95f04d6207ae3bbf923c8be5d873f6a1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 13:07:16 +0200 Subject: Revert "Added filter and filtervalue attributes to xmlpythonizer's tags" This reverts commit 4b925a1433b65c217e787804df3cf349d6b387aa. Discovered that XPath got the needed power for filtering, no need for this extra feature --- src/xmlpythonizer.c | 86 ++++++++--------------------------------------------- src/xmlpythonizer.h | 4 --- 2 files changed, 12 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 91507e8..fb8c8bb 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -40,7 +40,6 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, ptzTYPES ktyp, const char *key, ptzTYPES vtyp, const char *value, - const char *filter, const char *filterval, ptzMAP *child) { ptzMAP *ret = NULL; @@ -66,11 +65,6 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, ret->child = child; } - if( filter != NULL && filterval != NULL ) { - ret->filter = strdup(filter); - ret->filtervalue = strdup(filterval); - } - if( chain != NULL ) { ret->next = (ptzMAP *) chain; } @@ -91,16 +85,6 @@ void ptzmap_Free_func(ptzMAP *ptr) ptr->value = NULL; } - if( ptr->filter != NULL ) { - free(ptr->filter); - ptr->filter = NULL; - } - - if( ptr->filtervalue != NULL ) { - free(ptr->filtervalue); - ptr->filtervalue = NULL; - } - if( ptr->child != NULL ) { ptzmap_Free(ptr->child); } @@ -140,10 +124,6 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); indent(level); printf("value type: (%i) %-13.13s - value: %s\n", ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value); - if( ptr->filter != NULL ) { - indent(level); printf("filter: %s == %s\n", ptr->filter, ptr->filtervalue); - } - if( ptr->child != NULL ) { indent(level); printf(" ** CHILD\n"); ptzmap_Dump_func(ptr->child, level + 1); @@ -219,7 +199,6 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { ptzTYPES type_key, type_value; char *key = NULL, *value = NULL; - char *filter = NULL, *filterval = NULL; if( ptr_n->type != XML_ELEMENT_NODE ) { continue; @@ -232,12 +211,6 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); - // Get filters - filter = dmixml_GetAttrValue(ptr_n, "filter"); - if( filter != NULL ) { - filterval = dmixml_GetAttrValue(ptr_n, "filtervalue"); - } - if( type_value == ptzDICT ) { // When value type is ptzDICT, traverse the children nodes // - should contain another Map set instead of a value attribute @@ -245,18 +218,12 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { continue; } // Recursion - retmap = ptzmap_Add(retmap, type_key, key, - type_value, NULL, - filter, filterval, + retmap = ptzmap_Add(retmap, type_key, key, type_value, NULL, _do_dmimap_parsing(ptr_n->children->next)); - } else { // Append the value as a normal value when the // value type is not a Python Dict - retmap = ptzmap_Add(retmap, type_key, key, - type_value, value, - filter, filterval, - NULL); + retmap = ptzmap_Add(retmap, type_key, key, type_value, value, NULL); } value = NULL; key = NULL; @@ -304,6 +271,7 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // Start creating an internal map structure based on the mapping XML. map = _do_dmimap_parsing(node); + return map; } @@ -400,42 +368,12 @@ inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { } -void _register_value(PyObject *pyobj, xmlXPathContext *xpctx, - ptzMAP *map_p, const char *key, PyObject *value) -{ - if( key != NULL ) { - if( (map_p->filter != NULL) && (map_p->filtervalue != NULL) ) { - xmlXPathObject *xpobj = NULL; - int i = 0, found = 0; - - xpobj = _get_xpath_values(xpctx, map_p->filter); - if( (xpobj == NULL) || (xpobj->nodesetval->nodeNr < 1) ) { - // If node not found, or our value index is higher - // than what we found, filter it out. - if( xpobj != NULL ) { - xmlXPathFreeObject(xpobj); - } - return; - } - - for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { - if( strcmp(map_p->filtervalue, - dmixml_GetContent(xpobj->nodesetval->nodeTab[i])) == 0 ) { - found = 1; - break; - } - } - - if( found != 1 ) { - // If value did not match - no hit => do not add value - xmlXPathFreeObject(xpobj); - return; - } - } - PyDict_SetItemString(pyobj, key, value); - Py_DECREF(value); +#define PyADD_DICT_VALUE(p, k, v) { \ + if( k != NULL ) { \ + PyDict_SetItemString(p, k, v); \ + Py_DECREF(v); \ + } \ } -} // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. @@ -455,7 +393,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzCONST: value = PyString_FromString(map_p->value); key = _get_key_value(map_p, xpctx, 0); - _register_value(retdata, xpctx, map_p, key, value); + PyADD_DICT_VALUE(retdata, key, value); break; @@ -469,7 +407,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { value = StringToPyObj(map_p->type_value, dmixml_GetContent(xpobj->nodesetval->nodeTab[i])); key = _get_key_value(map_p, xpctx, i); - _register_value(retdata, xpctx, map_p, key, value); + PyADD_DICT_VALUE(retdata, key, value); } xmlXPathFreeObject(xpobj); } @@ -488,7 +426,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { } xmlXPathFreeObject(xpobj); key = _get_key_value(map_p, xpctx, 0); - _register_value(retdata, xpctx, map_p, key, value); + PyADD_DICT_VALUE(retdata, key, value); } break; @@ -498,7 +436,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { Py_DECREF(value); key = _get_key_value(map_p, xpctx, 0); - _register_value(retdata, xpctx, map_p, key, value); + PyADD_DICT_VALUE(retdata, key, value); break; default: diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 8572403..770fa66 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -37,10 +37,6 @@ typedef struct ptzMAP_s { ptzTYPES type_value; char *value; // for ptzCONST key contains a static string, // the rest of types, an XPath to XML data - - char *filter; // Used for simple filtering. If NULL, no filtering is performed - char *filtervalue; // Only XML contents which matches the given value will be parsed further - struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From 6a89cde8f253cb9826da4287007a869de99709a6 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 13:09:07 +0200 Subject: Filter out BIOS characteristics with XPath expressions --- src/pythonmap.xml | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 14f4f9b..d1bd9dc 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -11,27 +11,24 @@ - - - - - - - - - - - - + + + + + + + + + + + + - + -- cgit From a3047723df9b66b6a56bcc72a469a129bbaf4d54 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 18:28:02 +0200 Subject: dmidecode: Moved ROMsize size unit into tag attribute --- src/dmidecode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 1087df2..491183d 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3681,7 +3681,9 @@ xmlNode *dmi_decode(struct dmi_header * h, u16 ver) dmi_bios_runtime_size(sect_n, (0x10000 - WORD(data + 0x06)) << 4); } - dmixml_AddTextChild(sect_n, "ROMsize", "%i KB", (data[0x09] + 1) << 6); + sub_n = dmixml_AddTextChild(sect_n, "ROMsize", "%i", (data[0x09] + 1) << 6); + dmixml_AddAttribute(sub_n, "unit", "KB"); + sub_n = NULL; sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); assert( sub_n != NULL ); -- cgit From d64ab66e4fbf8d6dfceed628aef21f01063c3d66 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 18:29:50 +0200 Subject: Added function for retrieving values from XPath objects Reverted commit 75aaf67d43cf4a28fe8d3e07111dab75a0c4396d in addition --- src/dmixml.c | 35 ++++++++++++++++++++++++++++++++++- src/dmixml.h | 2 ++ 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index a9ecd67..f8a6219 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -28,6 +28,7 @@ #include #include +#include #include // Internal function for dmixml_* functions ... builds up a variable xmlChar* string @@ -202,10 +203,42 @@ xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { inline char *dmixml_GetContent(xmlNode *node) { // FIXME: Should find better way how to return UTF-8 data - return (((node != NULL) && (node->children != NULL)) ? (char *) node->children->content : "(not set)"); + return (((node != NULL) && (node->children != NULL)) ? (char *) node->children->content : NULL); } inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { return dmixml_GetContent(dmixml_FindNode(node, key)); } +char *dmixml_GetXPathContent(xmlXPathObject *xpo, int idx) { + char *ret = NULL; + + if( xpo == NULL ) { + return NULL; + } + + switch( xpo->type ) { + case XPATH_STRING: + ret = (char *)xpo->stringval; + break; + + case XPATH_NUMBER: + ret = (char *) malloc(34); + memset(ret, 0, 34); + snprintf(ret, 32, "%f", xpo->floatval); + break; + + case XPATH_NODESET: + ret = ( (xpo->nodesetval->nodeNr >= (idx+1)) + ? dmixml_GetContent(xpo->nodesetval->nodeTab[idx]) + : NULL); + break; + + default: + fprintf(stderr, "dmixml_GetXPathContent(...):: " + "Do not know how to handle XPath type %i\n", + xpo->type); + } + return ret; +} + diff --git a/src/dmixml.h b/src/dmixml.h index 4683bc9..7176483 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -28,6 +28,7 @@ #include #include +#include xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); @@ -37,5 +38,6 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key); xmlNode *dmixml_FindNode(xmlNode *, const char *key); inline char *dmixml_GetContent(xmlNode *node); inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); +char *dmixml_GetXPathContent(xmlXPathObject *xpo, int idx); #endif -- cgit From 2aaa3c0822bff7204167f73b62035bc10f620881 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 18:32:57 +0200 Subject: Reimplemented the XPath integration Now the XPath expressions can include XPath functions as well. The previous implementation only supported XPATH_NODESET results from XPath queries. Now XPATH_STRING and XPATH_NUMBER results are supported as well. XPATH_BOOLEAN might be needed later on. --- src/xmlpythonizer.c | 70 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index fb8c8bb..0b6c54e 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -330,11 +330,6 @@ xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { assert( xp_obj != NULL ); free(xp_xpr); - if( (xp_obj->nodesetval == NULL) || (xp_obj->nodesetval->nodeNr == 0) ) { - xmlXPathFreeObject(xp_obj); - return NULL; - } - return xp_obj; } @@ -351,8 +346,8 @@ inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { case ptzINT: case ptzFLOAT: xpobj = _get_xpath_values(xpctx, map_p->key); + key = dmixml_GetXPathContent(xpobj, idx); if( xpobj != NULL ) { - key = dmixml_GetContent(xpobj->nodesetval->nodeTab[idx]); xmlXPathFreeObject(xpobj); } break; @@ -361,20 +356,43 @@ inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); break; } - if( key == NULL ) { - fprintf(stderr, "Could not find the key value: %s\n", map_p->key); - } return key; } #define PyADD_DICT_VALUE(p, k, v) { \ - if( k != NULL ) { \ - PyDict_SetItemString(p, k, v); \ - Py_DECREF(v); \ - } \ + PyDict_SetItemString(p, k, v); \ + Py_DECREF(v); \ } +inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) { + int i = 0; + char *key = NULL; + + assert( pydat != NULL && value != NULL ); + + switch( value->type ) { + case XPATH_NODESET: + for( i = 0; i < value->nodesetval->nodeNr; i++ ) { + key = _get_key_value(map_p, xpctx, i); + if( key != NULL ) { + char *val = NULL; + val = dmixml_GetXPathContent(value, i); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); + } + } + break; + default: + key = _get_key_value(map_p, xpctx, 0); + if( key != NULL ) { + char *val = NULL; + val = dmixml_GetXPathContent(value, 0); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); + } + break; + } +} + // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { @@ -391,10 +409,11 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { // Get 'value' value switch( map_p->type_value ) { case ptzCONST: - value = PyString_FromString(map_p->value); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); - + if( key != NULL ) { + value = PyString_FromString(map_p->value); + PyADD_DICT_VALUE(retdata, key, value); + } break; case ptzSTR: @@ -403,12 +422,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzBOOL: xpobj = _get_xpath_values(xpctx, map_p->value); if( xpobj != NULL ) { - for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { - value = StringToPyObj(map_p->type_value, - dmixml_GetContent(xpobj->nodesetval->nodeTab[i])); - key = _get_key_value(map_p, xpctx, i); - PyADD_DICT_VALUE(retdata, key, value); - } + _add_xpath_result(retdata, xpctx, map_p, xpobj); xmlXPathFreeObject(xpobj); } break; @@ -421,8 +435,9 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { value = PyList_New(0); if( xpobj != NULL ) { for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { - char *valstr = dmixml_GetContent(xpobj->nodesetval->nodeTab[i]); + char *valstr = dmixml_GetXPathContent(xpobj, i); PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); + free(valstr); } xmlXPathFreeObject(xpobj); key = _get_key_value(map_p, xpctx, 0); @@ -432,11 +447,12 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzDICT: // Traverse the children to get the value of this element - value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); - Py_DECREF(value); - key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + if( key != NULL ) { + value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); + Py_DECREF(value); + PyADD_DICT_VALUE(retdata, key, value); + } break; default: -- cgit From 6453a1131547b71c4a21a978fd9588d67d056233 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 18:42:12 +0200 Subject: Completed mapping the bios section --- src/pythonmap.xml | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index d1bd9dc..6fbc602 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -13,18 +13,29 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + -- cgit From cea1270777d0a5bd42284011307fe183a67f8ada Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 30 Apr 2009 16:07:43 +0200 Subject: Rewritten dmixml_GetXPathContent(...) and _get_key_value(...) This rewrite was to handle XPATH_NUMBER more correctly. Now these functions needs an preallocated memory buffer for the result. --- src/dmixml.c | 19 +++++++-------- src/dmixml.h | 2 +- src/xmlpythonizer.c | 69 +++++++++++++++++++++++++++++++++-------------------- 3 files changed, 53 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index f8a6219..8228bf3 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -210,8 +210,8 @@ inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { return dmixml_GetContent(dmixml_FindNode(node, key)); } -char *dmixml_GetXPathContent(xmlXPathObject *xpo, int idx) { - char *ret = NULL; +char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx) { + memset(buf, 0, buflen); if( xpo == NULL ) { return NULL; @@ -219,26 +219,25 @@ char *dmixml_GetXPathContent(xmlXPathObject *xpo, int idx) { switch( xpo->type ) { case XPATH_STRING: - ret = (char *)xpo->stringval; + strncpy(buf, (char *)xpo->stringval, buflen-1); break; case XPATH_NUMBER: - ret = (char *) malloc(34); - memset(ret, 0, 34); - snprintf(ret, 32, "%f", xpo->floatval); + snprintf(buf, buflen-1, "%f", xpo->floatval); break; case XPATH_NODESET: - ret = ( (xpo->nodesetval->nodeNr >= (idx+1)) - ? dmixml_GetContent(xpo->nodesetval->nodeTab[idx]) - : NULL); + if( xpo->nodesetval->nodeNr >= (idx+1) ) { + strncpy(buf, dmixml_GetContent(xpo->nodesetval->nodeTab[idx]), buflen-1); + } break; default: fprintf(stderr, "dmixml_GetXPathContent(...):: " "Do not know how to handle XPath type %i\n", xpo->type); + return NULL; } - return ret; + return buf; } diff --git a/src/dmixml.h b/src/dmixml.h index 7176483..b1d86c6 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -38,6 +38,6 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key); xmlNode *dmixml_FindNode(xmlNode *, const char *key); inline char *dmixml_GetContent(xmlNode *node); inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); -char *dmixml_GetXPathContent(xmlXPathObject *xpo, int idx); +char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx); #endif diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 0b6c54e..6287ea2 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -333,29 +333,36 @@ xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { return xp_obj; } -inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { - char *key = NULL; +char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { xmlXPathObject *xpobj = NULL; + memset(key, 0, buflen); + switch( map_p->type_key ) { case ptzCONST: - key = map_p->key; + strncpy(key, map_p->key, buflen-1); break; case ptzSTR: case ptzINT: case ptzFLOAT: xpobj = _get_xpath_values(xpctx, map_p->key); - key = dmixml_GetXPathContent(xpobj, idx); - if( xpobj != NULL ) { + if( xpobj == NULL ) { + return NULL; + } + if( dmixml_GetXPathContent(key, buflen, xpobj, idx) == NULL ) { xmlXPathFreeObject(xpobj); + return NULL; } + xmlXPathFreeObject(xpobj); break; default: fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); - break; + return NULL; } + // We consider to have a key, if the first byte is a readable + // character (usually starting at 0x20/32d) return key; } @@ -368,29 +375,34 @@ inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) { int i = 0; char *key = NULL; + char *val = NULL; assert( pydat != NULL && value != NULL ); + key = (char *) malloc(258); + assert( key != NULL ); + + val = (char *) malloc(4098); + assert( val != NULL ); + switch( value->type ) { case XPATH_NODESET: for( i = 0; i < value->nodesetval->nodeNr; i++ ) { - key = _get_key_value(map_p, xpctx, i); - if( key != NULL ) { - char *val = NULL; - val = dmixml_GetXPathContent(value, i); + if( _get_key_value(key, 256, map_p, xpctx, i) != NULL ) { + dmixml_GetXPathContent(val, 4097, value, i); PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); } } break; default: - key = _get_key_value(map_p, xpctx, 0); - if( key != NULL ) { - char *val = NULL; - val = dmixml_GetXPathContent(value, 0); + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + dmixml_GetXPathContent(val, 4097, value, 0); PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); } break; } + free(key); + free(val); } // Internal XML parser routine, which traverses the given mapping table, @@ -399,18 +411,20 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { ptzMAP *map_p = NULL; PyObject *retdata = NULL; int i = 0; + char *key = NULL; + + key = (char *) malloc(258); + assert( key != NULL ); retdata = PyDict_New(); for( map_p = in_map; map_p != NULL; map_p = map_p->next ) { xmlXPathObject *xpobj = NULL; - char *key = NULL; PyObject *value = NULL; // Get 'value' value switch( map_p->type_value ) { case ptzCONST: - key = _get_key_value(map_p, xpctx, 0); - if( key != NULL ) { + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { value = PyString_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); } @@ -434,21 +448,23 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { xpobj = _get_xpath_values(xpctx, map_p->value); value = PyList_New(0); if( xpobj != NULL ) { - for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { - char *valstr = dmixml_GetXPathContent(xpobj, i); - PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); - free(valstr); + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { + char *valstr = NULL; + valstr = (char *) malloc(4098); + dmixml_GetXPathContent(valstr, 4097, xpobj, i); + PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); + free(valstr); + } + xmlXPathFreeObject(xpobj); + PyADD_DICT_VALUE(retdata, key, value); } - xmlXPathFreeObject(xpobj); - key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); } break; case ptzDICT: // Traverse the children to get the value of this element - key = _get_key_value(map_p, xpctx, 0); - if( key != NULL ) { + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); Py_DECREF(value); PyADD_DICT_VALUE(retdata, key, value); @@ -461,6 +477,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { break; } } + free(key); Py_INCREF(retdata); return retdata; } -- cgit From 27b3d2281f4b7677e908ef2505bd649305b5ac78 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 30 Apr 2009 18:24:49 +0200 Subject: Began completing the rewrite of needed dmidecodemodule changes --- src/dmidecode.c | 55 ++++++++------- src/dmidecode.h | 6 +- src/dmidecodemodule.c | 181 +++++++++++++++++++++++++++++++------------------- src/dmidecodemodule.h | 6 +- src/dmihelper.h | 4 ++ 5 files changed, 154 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 491183d..bdb0758 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3642,7 +3642,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) ** Main */ -xmlNode *dmi_decode(struct dmi_header * h, u16 ver) +xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) { const u8 *data = h->data; xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; @@ -3652,8 +3652,7 @@ xmlNode *dmi_decode(struct dmi_header * h, u16 ver) //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; - - sect_n = xmlNewNode(NULL, (xmlChar *) dmiMajor->tagname); + sect_n = xmlNewChild(prnt_n, NULL, (xmlChar *) dmiMajor->tagname, NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "%s", dmiMajor->id); @@ -4799,45 +4798,50 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -void dmi_table_string(const struct dmi_header *h, const u8 *data, xmlNode *node, u16 ver) +xmlNode *dmi_table_string(xmlNode *prnt_n, const struct dmi_header *h, const u8 *data, u16 ver) { int key; u8 offset = opt.string->offset; - xmlNode *dmi_n = NULL; + xmlNode *handle_n = NULL, *dmi_n = NULL; if(offset >= h->length) - return; + return NULL; + + handle_n = xmlNewChild(prnt_n, NULL, (xmlChar *) "DMItable", NULL); + assert( handle_n != NULL ); //. TODO: These should have more meaningful dictionary names key = (opt.string->type << 8) | offset; switch (key) { case 0x108: - dmi_system_uuid(node, data + offset, ver); - dmixml_AddAttribute(node, "DMItype", "0x108"); + dmi_system_uuid(handle_n, data + offset, ver); + dmixml_AddAttribute(handle_n, "DMItype", "0x108"); break; case 0x305: - dmi_chassis_type(node, data[offset]); - dmixml_AddAttribute(node, "DMItype", "0x305"); + dmi_chassis_type(handle_n, data[offset]); + dmixml_AddAttribute(handle_n, "DMItype", "0x305"); // FIXME: Missing break? case 0x406: - dmi_processor_family(node, h); - dmixml_AddAttribute(node, "DMItype", "0x406"); + dmi_processor_family(handle_n, h); + dmixml_AddAttribute(handle_n, "DMItype", "0x406"); break; case 0x416: - dmi_n = dmixml_AddTextChild(node, "ProcessorFrequency", "%s", + dmi_n = dmixml_AddTextChild(handle_n, "ProcessorFrequency", "%s", dmi_processor_frequency((u8 *) data + offset)); dmixml_AddAttribute(dmi_n, "DMItype", "0x416"); dmi_n = NULL; break; default: - dmi_n = dmixml_AddTextChild(node, "Unknown", "%s", dmi_string(h, data[offset])); + dmi_n = dmixml_AddTextChild(handle_n, "Unknown", "%s", dmi_string(h, data[offset])); dmixml_AddAttribute(dmi_n, "DMItype", "0x%03x", key); } + + return handle_n; } /* @@ -5054,18 +5058,15 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - handle_n = dmi_decode(&h, ver); + handle_n = dmi_decode(xmlnode, &h, ver); } else fprintf(stderr, ""); } else if(opt.string != NULL && opt.string->type == h.type) { - handle_n = xmlNewNode(NULL, (xmlChar *) "DMItable"); - assert( handle_n != NULL ); - dmi_table_string(&h, data, handle_n, ver); + handle_n = dmi_table_string(xmlnode, &h, data, ver); } if( handle_n != NULL ) { dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); dmixml_AddAttribute(handle_n, "size", "%d", h.length); - xmlAddChild(xmlnode, handle_n); } data = next; @@ -5090,13 +5091,15 @@ int _smbios_decode_check(u8 * buf) return check; } -int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) +xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem) { int check = _smbios_decode_check(buf); - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SMBIOSversion", NULL); + xmlNode *data_n = xmlNewNode(NULL, (xmlChar *) "DMIversion"); assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "type", "SMBIOS"); + if(check == 1) { u16 ver = (buf[0x06] << 8) + buf[0x07]; @@ -5130,7 +5133,7 @@ int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); dmixml_AddAttribute(data_n, "unknown", "1"); } - return check; + return data_n; } int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) @@ -5166,13 +5169,15 @@ int _legacy_decode_check(u8 * buf) return check; } -int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) +xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem) { int check = _legacy_decode_check(buf); - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "LegacyDMI", NULL); + xmlNode *data_n = xmlNewNode(NULL, (xmlChar *) "DMIversion"); assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "type", "legacy"); + if(check == 1) { dmixml_AddTextContent(data_n, "Legacy DMI %i.%i present", buf[0x0E] >> 4, buf[0x0E] & 0x0F); @@ -5183,7 +5188,7 @@ int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) dmixml_AddAttribute(data_n, "unknown", "1"); } - return check; + return data_n; } int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) diff --git a/src/dmidecode.h b/src/dmidecode.h index ef13ce3..04d8f04 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -29,12 +29,12 @@ struct dmi_header { }; void dmi_dump(xmlNode *node, struct dmi_header * h); -xmlNode *dmi_decode(struct dmi_header * h, u16 ver); +xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); -int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem); int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); -int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem); int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index e9e688c..8c3a2b9 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -1,8 +1,14 @@ #include + +#include + +#include "xmlpythonizer.h" #include "dmidecodemodule.h" +#include "dmixml.h" #include options opt; + static void init(void) { /* sanity check */ @@ -13,6 +19,8 @@ static void init(void) opt.dumpfile = NULL; opt.flags = 0; opt.type = NULL; + opt.mappingxml = NULL; + opt.dmiversion_n = NULL; } u8 *parse_opt_type(u8 * p, const char *arg) @@ -64,18 +72,18 @@ u8 *parse_opt_type(u8 * p, const char *arg) return p; } -static int dmidecode_set_version(PyObject ** pydata) + +xmlNode *dmidecode_set_version() { - int ret = 0; int found = 0; size_t fp; int efi; - u8 *buf; + u8 *buf = NULL; + xmlNode *ver_n = NULL; /* Set default option values */ opt.devmem = DEFAULT_MEM_DEV; - /***********************************/ /* Read from dump if so instructed */ if(opt.dumpfile != NULL) { const char *dumpfile = PyString_AS_STRING(opt.dumpfile); @@ -83,15 +91,18 @@ static int dmidecode_set_version(PyObject ** pydata) //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode_set_version(buf, dumpfile, pydata)) + ver_n = smbios_decode_set_version(buf, dumpfile); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode_set_version(buf, dumpfile, pydata)) + ver_n = legacy_decode_set_version(buf, dumpfile); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } } - } else - ret = 1; - } else { /* Read from /dev/mem */ + } + } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(&fp); if(efi == EFI_NOT_FOUND) { @@ -99,40 +110,44 @@ static int dmidecode_set_version(PyObject ** pydata) if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(smbios_decode_set_version - (buf + fp, opt.devmem, pydata)) + ver_n = smbios_decode_set_version(buf + fp, opt.devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } fp += 16; } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode_set_version - (buf + fp, opt.devmem, pydata)) + ver_n = legacy_decode_set_version (buf + fp, opt.devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } } } - } else - ret = 1; + } } else if(efi == EFI_NO_SMBIOS) { - ret = 1; + ver_n = NULL; } else { - if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) - ret = 1; - else if(smbios_decode_set_version(buf, opt.devmem, pydata)) - found++; - //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress); + // Process as EFI + if((buf = mem_chunk(fp, 0x20, opt.devmem)) != NULL) { + ver_n = smbios_decode_set_version(buf, opt.devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { + found++; + } + //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress); + } } } - - if(ret == 0) { + if( buf != NULL ) { free(buf); - if(!found) { - fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G."); - } + } + + if( !found ) { + fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry."); } free(opt.type); - return ret; + return ver_n; } -static PyObject *dmidecode_get(PyObject * self, const char *section) +xmlNode *dmidecode_get_xml(PyObject *self, const char *section) { //mtrace(); @@ -142,29 +157,24 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) int efi; u8 *buf; - /* Set default option values */ - opt.devmem = DEFAULT_MEM_DEV; - opt.flags = 0; - opt.type = NULL; - opt.type = parse_opt_type(opt.type, section); - if(opt.type == NULL) - return NULL; + xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); + assert( dmixml != NULL ); + + // Append DMI version info + if( opt.dmiversion_n != NULL ) { + xmlAddChild(dmixml_n, opt.dmiversion_n); + } const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; if(access(f, R_OK) < 0) PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); - PyObject *pydata = NULL; - xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); - assert( dmixml != NULL ); - - /***********************************/ /* Read from dump if so instructed */ if(opt.dumpfile != NULL) { const char *dumpfile = PyString_AS_STRING(opt.dumpfile); - //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); + // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { if(smbios_decode(buf, dumpfile, dmixml_n)) @@ -173,8 +183,9 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) if(legacy_decode(buf, dumpfile, dmixml_n)) found++; } - } else + } else { ret = 1; + } } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(&fp); @@ -201,7 +212,7 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) ret = 1; else if(smbios_decode(buf, opt.devmem, dmixml_n)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } } @@ -210,16 +221,62 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) free(buf); } else { xmlFreeNode(dmixml_n); - if( pydata != NULL ) { - PyDECREF(pydata); - pydata = NULL; - } + dmixml_n = NULL; } //muntrace(); + return dmixml_n; +} + +static PyObject *dmidecode_get(PyObject *self, const char *section) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + + /* Set default option values */ + opt.devmem = DEFAULT_MEM_DEV; + opt.flags = 0; + opt.type = NULL; + opt.type = parse_opt_type(opt.type, section); + + if(opt.type == NULL) { + return NULL; + } + + dmixml_n = dmidecode_get_xml(self, section); + if( dmixml_n != NULL ) { + ptzMAP *mapping = NULL; + + // Convert the retrieved XML nodes to Python dicts + if( opt.mappingxml == NULL ) { + // Load mapping into memory + opt.mappingxml = xmlReadFile("pythonmap.xml", NULL, 0); + assert( opt.mappingxml != NULL ); + } + + mapping = dmiMAP_ParseMappingXML(opt.mappingxml, section); + assert( mapping != NULL ); + + // Generate Python dict out of XML node + pydata = pythonizeXMLnode(mapping, dmixml_n); + +#if 0 // DEBUG - will dump generated XML to stdout + xmlDoc *doc = xmlNewDoc((xmlChar *) "1.0"); + xmlDocSetRootElement(doc, xmlCopyNode(dmixml_n, 1)); + xmlSaveFormatFileEnc("-", doc, "UTF-8", 1); + xmlFreeDoc(doc); +#endif + ptzmap_Free(mapping); + xmlFreeNode(dmixml_n); + } else { + return NULL; + } + return pydata; } + + static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) { return dmidecode_get(self, "bios"); @@ -330,16 +387,6 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) //PyErr_Occurred(); } -/* -typedef struct { - PyObject_HEAD char *version; -} ivars; - -static PyMemberDef DMIDataMembers[] = { - { (char *)"fred", T_STRING, offsetof(ivars, version), 0, "2.10" }, - { NULL } -}; -*/ static PyMethodDef DMIDataMethods[] = { {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"}, @@ -365,19 +412,19 @@ static PyMethodDef DMIDataMethods[] = { PyMODINIT_FUNC initdmidecode(void) { - init(); - - PyObject *module = - Py_InitModule3((char *)"dmidecode", DMIDataMethods, - "Python extension module for dmidecode"); + char *dmiver = NULL; + PyObject *module = NULL; + PyObject *version = NULL; - PyObject *version = PyString_FromString("2.10"); + init(); + module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, + "Python extension module for dmidecode"); + version = PyString_FromString("2.10"); Py_INCREF(version); PyModule_AddObject(module, "version", version); - PyObject *dmi_version = NULL; - - dmidecode_set_version(&dmi_version); - PyModule_AddObject(module, "dmi", dmi_version ? dmi_version : Py_None); + opt.dmiversion_n = dmidecode_set_version(); + dmiver = dmixml_GetContent(opt.dmiversion_n); + PyModule_AddObject(module, "dmi", dmiver ? PyString_FromString(dmiver) : Py_None); } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 7583eb7..2ebc5d0 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -23,14 +23,14 @@ //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern void dmi_dump(xmlNode *node, struct dmi_header *h); -extern xmlNode *dmi_decode(struct dmi_header * h, u16 ver); +extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); extern int smbios_decode(u8 * buf, const char *devmem, xmlNode *node); extern int legacy_decode(u8 * buf, const char *devmem, xmlNode *node); -extern int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); -extern int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +extern xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem); +extern xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem); extern void *mem_chunk(size_t base, size_t len, const char *devmem); extern u8 *parse_opt_type(u8 * p, const char *arg); diff --git a/src/dmihelper.h b/src/dmihelper.h index 6c0b854..50cb185 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -9,6 +9,8 @@ #include #include +#include + #include "types.h" #define MAXVAL 1024 @@ -110,6 +112,8 @@ typedef struct _options { unsigned int flags; u8 *type; const struct string_keyword *string; + xmlDoc *mappingxml; + xmlNode *dmiversion_n; PyObject *dumpfile; } options; extern options opt; -- cgit From 268687f5b525ce4bdb1becd5a5207bfc2ced8340 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 28 Apr 2009 00:55:28 +1000 Subject: Version number fix --- src/setup-dbg.py | 2 +- src/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 1a23240..65f7436 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -2,7 +2,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode-dbg", - version = "2.10.3", + version = "2.10.5", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", diff --git a/src/setup.py b/src/setup.py index ec66c3f..cf07c9b 100644 --- a/src/setup.py +++ b/src/setup.py @@ -2,7 +2,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode", - version = "2.10.3", + version = "2.10.5", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", -- cgit From 89d2c50a648e3affd81ceb24e332bbd60de2b75d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 30 Apr 2009 19:18:17 +0200 Subject: Fixed a bug causing segv When calling dmidecode_get_xml(...) several times could cause a crash due to the opt.dmiversion_n pointer being freed by a mistake when the generated dmixml_n got freed later on in the function. Also fixed an assertion typo --- src/dmidecodemodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 8c3a2b9..05689b0 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -158,11 +158,11 @@ xmlNode *dmidecode_get_xml(PyObject *self, const char *section) u8 *buf; xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); - assert( dmixml != NULL ); + assert( dmixml_n != NULL ); // Append DMI version info if( opt.dmiversion_n != NULL ) { - xmlAddChild(dmixml_n, opt.dmiversion_n); + xmlAddChild(dmixml_n, xmlCopyNode(opt.dmiversion_n, 1)); } const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; -- cgit From 1bf1da9fa4ad24148fe18c1c5baa9a4ec931402c Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 30 Apr 2009 19:38:25 +0200 Subject: Improved setting of pythonmap.xml The default file is now set to /usr/share/python-dmidecode/pythonmap.xml (defined in config.h) and can be overridden with the dmidecode.pythonmap() function in Python. --- src/config.h | 4 ++++ src/dmidecodemodule.c | 27 ++++++++++++++++++++++++++- src/dmihelper.h | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index 713ac5d..f4c0fc4 100644 --- a/src/config.h +++ b/src/config.h @@ -23,4 +23,8 @@ #define ALIGNMENT_WORKAROUND #endif +#ifndef PYTHON_XML_MAP +#define PYTHON_XML_MAP "/usr/share/python-dmidecode/pythonmap.xmp" +#endif + #endif diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 05689b0..fc3a7ed 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -21,6 +21,7 @@ static void init(void) opt.type = NULL; opt.mappingxml = NULL; opt.dmiversion_n = NULL; + opt.python_xml_map = strdup(PYTHON_XML_MAP); } u8 *parse_opt_type(u8 * p, const char *arg) @@ -250,7 +251,7 @@ static PyObject *dmidecode_get(PyObject *self, const char *section) // Convert the retrieved XML nodes to Python dicts if( opt.mappingxml == NULL ) { // Load mapping into memory - opt.mappingxml = xmlReadFile("pythonmap.xml", NULL, 0); + opt.mappingxml = xmlReadFile(opt.python_xml_map, NULL, 0); assert( opt.mappingxml != NULL ); } @@ -387,6 +388,27 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) //PyErr_Occurred(); } +static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) +{ + if(PyString_Check(arg)) { + struct stat fileinfo; + char *fname = PyString_AsString(arg); + + memset(&fileinfo, 0, sizeof(struct stat)); + + if( stat(fname, &fileinfo) != 0 ) { + PyErr_SetString(PyExc_IOError, "Could not access the given python map XML file"); + return NULL; + } + + free(opt.python_xml_map); + opt.python_xml_map = strdup(fname); + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + static PyMethodDef DMIDataMethods[] = { {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"}, @@ -407,6 +429,9 @@ static PyMethodDef DMIDataMethods[] = { {(char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type"}, + {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O, + (char *) "Use another python dict map definition. The default file is " PYTHON_XML_MAP}, + {NULL, NULL, 0, NULL} }; diff --git a/src/dmihelper.h b/src/dmihelper.h index 50cb185..33da699 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -115,6 +115,7 @@ typedef struct _options { xmlDoc *mappingxml; xmlNode *dmiversion_n; PyObject *dumpfile; + char *python_xml_map; } options; extern options opt; -- cgit From aad6b79d7363ea4fa1c1ce67a39848b13bdd19f4 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 4 May 2009 09:32:19 +0200 Subject: Fixed typo in config.h - error in pythonmap.xml filename --- src/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index f4c0fc4..a2e7e58 100644 --- a/src/config.h +++ b/src/config.h @@ -24,7 +24,7 @@ #endif #ifndef PYTHON_XML_MAP -#define PYTHON_XML_MAP "/usr/share/python-dmidecode/pythonmap.xmp" +#define PYTHON_XML_MAP "/usr/share/python-dmidecode/pythonmap.xml" #endif #endif -- cgit From 1ccdf74b1e537c4bd747c079530a5d9ea904e138 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 4 May 2009 10:39:02 +0200 Subject: Improved error handling when parsing mapping XML --- src/dmidecodemodule.c | 4 +++- src/xmlpythonizer.c | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index fc3a7ed..14ff148 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -256,7 +256,9 @@ static PyObject *dmidecode_get(PyObject *self, const char *section) } mapping = dmiMAP_ParseMappingXML(opt.mappingxml, section); - assert( mapping != NULL ); + if( mapping == NULL ) { + return NULL; + } // Generate Python dict out of XML node pydata = pythonizeXMLnode(mapping, dmixml_n); diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 6287ea2..3c00f6b 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -243,13 +243,13 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // Verify that the root node got the right name if( (node == NULL) || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { - fprintf(stderr, "Invalid XML-Python mapping file\n"); + PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); return NULL; } // Verify that it's of a version we support if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - fprintf(stderr, "Unsupported XML-Python mapping file format\n"); + PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); return NULL; } @@ -264,8 +264,10 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { } if( node == NULL ) { - fprintf(stderr, "No mapping for '%s' was found " - "in the XML-Python mapping file\n", mapname); + char msg[8194]; + snprintf(msg, 8193, "No mapping for '%s' was found " + "in the XML-Python mapping file%c", mapname, 0); + PyErr_SetString(PyExc_IOError, msg); return NULL; } -- cgit From baf01ef0ad9635e506171d66c0e7ffa8c8c45ae1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 11:22:47 +0200 Subject: Corrected minor errors in ProcessorInfo XML tags --- src/dmidecode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index bdb0758..bf7af1b 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1252,7 +1252,7 @@ void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) } else { dmixml_AddAttribute(cache_n, "provided", "1"); dmixml_AddAttribute(cache_n, "available", "1"); - dmixml_AddAttribute(cache_n, "Handle", "0x%04x", code); + dmixml_AddAttribute(cache_n, "handle", "0x%04x", code); } } @@ -3844,9 +3844,10 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) dmixml_AddTextChild(sub_n, "Vendor", dmi_string(h, data[0x07])); dmixml_AddTextChild(sub_n, "Version", dmi_string(h, data[0x10])); - dmi_processor_voltage(sub_n, data[0x11]); sub_n = NULL; + dmi_processor_voltage(sect_n, data[0x11]); + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Frequencies", NULL); assert( sub_n != NULL ); -- cgit From ff78802fb52fe6404d12cbde3037371b69d05c03 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 11:23:17 +0200 Subject: Fixed segfault when processing XPATH_NODESET type and the nodeset is NULL --- src/dmixml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 8228bf3..65f5e07 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -227,7 +227,7 @@ char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int break; case XPATH_NODESET: - if( xpo->nodesetval->nodeNr >= (idx+1) ) { + if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr >= (idx+1)) ) { strncpy(buf, dmixml_GetContent(xpo->nodesetval->nodeTab[idx]), buflen-1); } break; -- cgit From 03bdcc92ff93e58a9befa5c9439b0cd656e57ccc Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 11:44:15 +0200 Subject: Add all CPU flags, and mark them as available or not This is to preserve backwards compatibility --- src/dmidecode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index bf7af1b..4a14992 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1121,9 +1121,10 @@ xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *vers int i; for(i = 0; i <= 31; i++) { - // Only add those flags which are present - if( (flags[i].flag != NULL) && (edx & (1 << i)) ) { + if( flags[i].flag != NULL ) { xmlNode *flg_n = dmixml_AddTextChild(flags_n, "flag", "%s", flags[i].descr); + dmixml_AddAttribute(flg_n, "available", "%i", + (edx & (1 << i) ? 1 : 0)); dmixml_AddAttribute(flg_n, "flag", "%s", flags[i].flag); } } @@ -3870,6 +3871,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) dmi_processor_status(sect_n, data[0x18] & 0x07); } else { dmixml_AddAttribute(sect_n, "populated", "0"); + dmi_processor_status(sect_n, data[0x18] & 0x07); } dmi_processor_upgrade(sect_n, data[0x19]); -- cgit From 40cd1a7ac2f912eb8be659a0c9dbadf5a0b22f14 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 17:22:04 +0200 Subject: Mark CPU as Populated = 'No' when not present --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 4a14992..422287c 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3871,7 +3871,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) dmi_processor_status(sect_n, data[0x18] & 0x07); } else { dmixml_AddAttribute(sect_n, "populated", "0"); - dmi_processor_status(sect_n, data[0x18] & 0x07); + dmixml_AddTextChild(sect_n, "Populated", "No"); } dmi_processor_upgrade(sect_n, data[0x19]); -- cgit From 94e81cb43908f90ccdeca4d7d459172999d4ae90 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 17:39:33 +0200 Subject: Big rewrite of xmlpythonizer - Supports relative XPaths now by using the rootpath attribute in the Map tag. This path is then set for all elements inside this Map tag. - Rewrote the parser to recurse correctly. The former version did not recurse well on the very outer (first) Map level. --- src/xmlpythonizer.c | 231 +++++++++++++++++++++++++++++++++++----------------- src/xmlpythonizer.h | 2 + 2 files changed, 157 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 3c00f6b..0065633 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -37,7 +37,7 @@ #include "dmixml.h" #include "xmlpythonizer.h" -ptzMAP *ptzmap_Add(const ptzMAP *chain, +ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, ptzTYPES ktyp, const char *key, ptzTYPES vtyp, const char *value, ptzMAP *child) @@ -53,6 +53,10 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, assert( ret != NULL ); memset(ret, 0, sizeof(ptzMAP)+2); + if( rootp != NULL ) { + ret->rootpath = strdup(rootp); + } + ret->type_key = ktyp; ret->key = strdup(key); @@ -77,6 +81,11 @@ void ptzmap_Free_func(ptzMAP *ptr) return; } + if( ptr->rootpath != NULL ) { + free(ptr->rootpath); + ptr->rootpath = NULL; + } + free(ptr->key); ptr->key = NULL; @@ -199,6 +208,7 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { ptzTYPES type_key, type_value; char *key = NULL, *value = NULL; + char *rootpath = NULL; if( ptr_n->type != XML_ELEMENT_NODE ) { continue; @@ -211,6 +221,8 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); + rootpath = dmixml_GetAttrValue(ptr_n, "rootpath"); + if( type_value == ptzDICT ) { // When value type is ptzDICT, traverse the children nodes // - should contain another Map set instead of a value attribute @@ -218,12 +230,12 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { continue; } // Recursion - retmap = ptzmap_Add(retmap, type_key, key, type_value, NULL, + retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, NULL, _do_dmimap_parsing(ptr_n->children->next)); } else { // Append the value as a normal value when the // value type is not a Python Dict - retmap = ptzmap_Add(retmap, type_key, key, type_value, value, NULL); + retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, value, NULL); } value = NULL; key = NULL; @@ -243,13 +255,13 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // Verify that the root node got the right name if( (node == NULL) || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { - PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + // PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); return NULL; } // Verify that it's of a version we support if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + // PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); return NULL; } @@ -267,7 +279,7 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { char msg[8194]; snprintf(msg, 8193, "No mapping for '%s' was found " "in the XML-Python mapping file%c", mapname, 0); - PyErr_SetString(PyExc_IOError, msg); + // PyErr_SetString(PyExc_IOError, msg); return NULL; } @@ -281,7 +293,6 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // // Parser routines for converting XML data into Python structures // - inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { PyObject *value; @@ -317,7 +328,6 @@ inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { return value; } - // Retrieve a value from the XML doc (XPath Context) based on a XPath query xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { xmlChar *xp_xpr = NULL; @@ -365,10 +375,11 @@ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *x } // We consider to have a key, if the first byte is a readable // character (usually starting at 0x20/32d) - return key; + return ((key != NULL) && (strlen(key) > 0) ? key : NULL) ; } + #define PyADD_DICT_VALUE(p, k, v) { \ PyDict_SetItemString(p, k, v); \ Py_DECREF(v); \ @@ -389,10 +400,19 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m switch( value->type ) { case XPATH_NODESET: - for( i = 0; i < value->nodesetval->nodeNr; i++ ) { - if( _get_key_value(key, 256, map_p, xpctx, i) != NULL ) { - dmixml_GetXPathContent(val, 4097, value, i); - PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); + if( value->nodesetval == NULL ) { + break; + } + if( value->nodesetval->nodeNr == 0 ) { + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + PyADD_DICT_VALUE(pydat, key, Py_None); + } + } else { + for( i = 0; i < value->nodesetval->nodeNr; i++ ) { + if( _get_key_value(key, 256, map_p, xpctx, i) != NULL ) { + dmixml_GetXPathContent(val, 4097, value, i); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); + } } } break; @@ -407,28 +427,43 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m free(val); } + // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. -PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { +PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *in_map, xmlNode *data_n, int elmtid) { ptzMAP *map_p = NULL; - PyObject *retdata = NULL; - int i = 0; char *key = NULL; + xmlXPathContext *xpctx = NULL; + xmlDoc *xpdoc = NULL; + + xpdoc = xmlNewDoc((xmlChar *) "1.0"); + assert( xpdoc != NULL ); + xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1)); + + xpctx = xmlXPathNewContext(xpdoc); + assert( xpctx != NULL ); + xpctx->node = data_n; key = (char *) malloc(258); assert( key != NULL ); - retdata = PyDict_New(); - for( map_p = in_map; map_p != NULL; map_p = map_p->next ) { - xmlXPathObject *xpobj = NULL; + for( map_p = in_map; map_p != NULL; map_p = map_p->next) { + xmlXPathObject *xpo = NULL; PyObject *value = NULL; + int i; - // Get 'value' value + // Extract value switch( map_p->type_value ) { case ptzCONST: if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { value = PyString_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); + } else { + char msg[8094]; + snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", + map_p->rootpath, elmtid, map_p->key, 0); + PyErr_SetString(PyExc_LookupError, msg); + continue; } break; @@ -436,10 +471,10 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzINT: case ptzFLOAT: case ptzBOOL: - xpobj = _get_xpath_values(xpctx, map_p->value); - if( xpobj != NULL ) { - _add_xpath_result(retdata, xpctx, map_p, xpobj); - xmlXPathFreeObject(xpobj); + xpo = _get_xpath_values(xpctx, map_p->value); + if( xpo != NULL ) { + _add_xpath_result(retdata, xpctx, map_p, xpo); + xmlXPathFreeObject(xpo); } break; @@ -447,86 +482,128 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzLIST_INT: case ptzLIST_FLOAT: case ptzLIST_BOOL: - xpobj = _get_xpath_values(xpctx, map_p->value); - value = PyList_New(0); - if( xpobj != NULL ) { + xpo = _get_xpath_values(xpctx, map_p->value); + if( xpo != NULL ) { if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { - char *valstr = NULL; - valstr = (char *) malloc(4098); - dmixml_GetXPathContent(valstr, 4097, xpobj, i); - PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); - free(valstr); + if( xpo->nodesetval->nodeNr > 0 ) { + value = PyList_New(0); + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { + char *valstr = NULL; + valstr = (char *) malloc(4098); + dmixml_GetXPathContent(valstr, 4097, xpo, i); + PyList_Append(value, StringToPyObj(map_p->type_value, + valstr)); + free(valstr); + } + } else { + value = Py_None; } - xmlXPathFreeObject(xpobj); PyADD_DICT_VALUE(retdata, key, value); + xmlXPathFreeObject(xpo); + } else { + char msg[8094]; + snprintf(msg, 8092, "Could not get key value: " + "%s [%i] (Defining key: %s)%c", + map_p->rootpath, elmtid, map_p->key, 0); + PyErr_SetString(PyExc_LookupError, msg); + continue; } } break; case ptzDICT: - // Traverse the children to get the value of this element - if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); - Py_DECREF(value); - PyADD_DICT_VALUE(retdata, key, value); + // Traverse children nodes + if( map_p->child == NULL ) { + break; + } + if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { + char msg[8094]; + snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", + in_map->rootpath, elmtid, map_p->key, 0); + PyErr_SetString(PyExc_LookupError, msg); + continue; } + value = pythonizeXMLnode(map_p->child, data_n); + PyADD_DICT_VALUE(retdata, key, (value != NULL ? value : Py_None)); break; default: fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); - return Py_None; break; } } + free(key); - Py_INCREF(retdata); + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); return retdata; } -// Convert a xmlDoc to a Python object, based on the given map -PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc) -{ - xmlXPathContext *xp_ctx = NULL; +// Convert a xmlNode to a Python object, based on the given map +PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { + xmlXPathContext *xpctx = NULL; + xmlDoc *xpdoc = NULL; PyObject *retdata = NULL; - // Prepare a XPath context for XPath queries - xp_ctx = xmlXPathNewContext(xmldoc); - assert( xp_ctx != NULL ); + if( (in_map == NULL) || (data_n == NULL) ) { + PyErr_SetString(PyExc_LookupError, "XMLnode or map is NULL"); + return NULL; + } - // Parse the XML and create Python data - retdata = _do_pythonizeXML(map, xp_ctx, 0); + // Set the root node in the XPath context + retdata = PyDict_New(); + if( in_map->rootpath != NULL ) { + xmlXPathObject *xpo = NULL; + int i; + + xpdoc = xmlNewDoc((xmlChar *) "1.0"); + assert( xpdoc != NULL ); + xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1)); + + xpctx = xmlXPathNewContext(xpdoc); + assert( xpctx != NULL ); + xpctx->node = data_n; + + xpo = _get_xpath_values(xpctx, in_map->rootpath); + if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { + char msg[8094]; + snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", + in_map->rootpath, in_map->key, 0); + PyErr_SetString(PyExc_LookupError, msg); + + if( xpo != NULL ) { + xmlXPathFreeObject(xpo); + } + xmlFreeDoc(xpdoc); + xmlXPathFreeContext(xpctx); + return NULL; + } - // Clean up and return data - xmlXPathFreeContext(xp_ctx); + retdata = PyDict_New(); + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { + _deep_pythonize(retdata, in_map, xpo->nodesetval->nodeTab[i], i); + } + xmlXPathFreeObject(xpo); + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + } else { + _deep_pythonize(retdata, in_map, data_n, 0); + } return retdata; } -// Convert a xmlNode to a Python object, based on the given map -PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes) -{ - xmlDoc *xmldoc = NULL; - PyObject *retdata = NULL; - // Create our own internal XML doc and - // copy over the input nodes to our internal doc. - // This is needed as the XPath parser in libxml2 - // only works with xmlDoc. - xmldoc = xmlNewDoc((xmlChar *) "1.0"); - assert( xmldoc != NULL ); - xmlDocSetRootElement(xmldoc, xmlCopyNode(nodes, 1)); - - // Parse the internal xmlDoc - retdata = pythonizeXMLdoc(map, xmldoc); +// Convert a xmlDoc to a Python object, based on the given map +PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *doc) +{ + xmlNode *node = NULL; - // Clean up and return data - xmlFreeDoc(xmldoc); - return retdata; + node = xmlDocGetRootElement(doc); + return pythonizeXMLnode(map, node); } - #if 0 // Simple independent main function - only for debugging int main() { @@ -534,15 +611,17 @@ int main() { ptzMAP *map = NULL; PyObject *pydat = NULL; + Py_Initialize(); + doc = xmlReadFile("pythonmap.xml", NULL, 0); assert( doc != NULL ); - map = dmiMAP_ParseMappingXML(doc, "bios"); - ptzmap_Dump(map); + map = dmiMAP_ParseMappingXML(doc, "processor"); + // ptzmap_Dump(map); printf("----------------------\n"); - data = xmlReadFile("test.xml", NULL, 0); + data = xmlReadFile("cpu.xml", NULL, 0); assert( data != NULL ); pydat = pythonizeXMLdoc(map, data); @@ -574,7 +653,7 @@ PyObject* demo_xmlpy() assert( mapping != NULL ); // Read XML data from file - doc = xmlReadFile("test.xml", NULL, 0); + doc = xmlReadFile("cpu.xml", NULL, 0); assert( doc != NULL ); // Create a PyObject out of the XML indata @@ -588,7 +667,6 @@ PyObject* demo_xmlpy() return ret; } - static PyMethodDef DemoMethods[] = { {"xmlpy", demo_xmlpy, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} @@ -605,3 +683,4 @@ PyMODINIT_FUNC initxmlpythonizer(void) { } #endif // Python test module + diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 770fa66..6c61381 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -32,6 +32,8 @@ typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL, ptzDICT } ptzTYPES; typedef struct ptzMAP_s { + char *rootpath; // XML root path for the data - if NULL, XML document is the root document. + ptzTYPES type_key; // Valid types: ptzCONST, ptzSTR, ptzINT, ptzFLOAT char *key; // for ptzCONST key contains a static string, other types an XPath to XML data ptzTYPES type_value; -- cgit From f7ab4ee0a2d1bd0ba32f78dceb1c95b28e313fa6 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 17:42:11 +0200 Subject: Added mapping for ProcessorInfo --- src/pythonmap.xml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 6fbc602..7583971 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -1,5 +1,8 @@ + + + @@ -42,4 +45,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From ce4d3eac5a50d25e2821a8aedf09f266b16988fe Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 18:11:50 +0200 Subject: Added mapping for chassis information --- src/pythonmap.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 7583971..5b4a437 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -90,4 +90,23 @@ + + + + + + + + + + + + + + + + + + + -- cgit From c07eb6b33813e41d98d4210dbca18e5de8c8fad6 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 18:30:58 +0200 Subject: Avoid segfault if XPATH_NODESET do not contain any data --- src/dmixml.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 65f5e07..dbca0c3 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -228,7 +228,12 @@ char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int case XPATH_NODESET: if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr >= (idx+1)) ) { - strncpy(buf, dmixml_GetContent(xpo->nodesetval->nodeTab[idx]), buflen-1); + char *str = dmixml_GetContent(xpo->nodesetval->nodeTab[idx]); + if( str != NULL ) { + strncpy(buf, str, buflen-1); + } else { + memset(buf, 0, buflen); + } } break; -- cgit From eeb40ea2c5a47737f318a1631316416e6f1ab75a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 14 May 2009 14:57:12 +0200 Subject: Fixed another parser issue When using rootpath, it did not parse all elements as expected. Also restricted the rootpath to only work when valuetype="dict". --- src/xmlpythonizer.c | 233 +++++++++++++++++++++++++++------------------------- 1 file changed, 122 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 0065633..f033e6d 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -129,6 +129,9 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) return; } + if( ptr->rootpath != NULL ) { + indent(level); printf("root path: %s\n", ptr->rootpath); + } indent(level); printf("key type: (%i) %-13.13s - key: %s\n", ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); indent(level); printf("value type: (%i) %-13.13s - value: %s\n", @@ -430,11 +433,13 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. -PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *in_map, xmlNode *data_n, int elmtid) { - ptzMAP *map_p = NULL; +PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int elmtid) { char *key = NULL; xmlXPathContext *xpctx = NULL; xmlDoc *xpdoc = NULL; + xmlXPathObject *xpo = NULL; + PyObject *value = NULL; + int i; xpdoc = xmlNewDoc((xmlChar *) "1.0"); assert( xpdoc != NULL ); @@ -447,90 +452,83 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *in_map, xmlNode *data_n, in key = (char *) malloc(258); assert( key != NULL ); - for( map_p = in_map; map_p != NULL; map_p = map_p->next) { - xmlXPathObject *xpo = NULL; - PyObject *value = NULL; - int i; + // Extract value + switch( map_p->type_value ) { + case ptzCONST: + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + value = PyString_FromString(map_p->value); + PyADD_DICT_VALUE(retdata, key, value); + } else { + char msg[8094]; + snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", + map_p->rootpath, elmtid, map_p->key, 0); + PyErr_SetString(PyExc_LookupError, msg); + } + break; + + case ptzSTR: + case ptzINT: + case ptzFLOAT: + case ptzBOOL: + xpo = _get_xpath_values(xpctx, map_p->value); + if( xpo != NULL ) { + _add_xpath_result(retdata, xpctx, map_p, xpo); + xmlXPathFreeObject(xpo); + } + break; - // Extract value - switch( map_p->type_value ) { - case ptzCONST: + case ptzLIST_STR: + case ptzLIST_INT: + case ptzLIST_FLOAT: + case ptzLIST_BOOL: + xpo = _get_xpath_values(xpctx, map_p->value); + if( xpo != NULL ) { if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - value = PyString_FromString(map_p->value); + if( xpo->nodesetval->nodeNr > 0 ) { + value = PyList_New(0); + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { + char *valstr = NULL; + valstr = (char *) malloc(4098); + dmixml_GetXPathContent(valstr, 4097, xpo, i); + PyList_Append(value, StringToPyObj(map_p->type_value, + valstr)); + free(valstr); + } + } else { + value = Py_None; + } PyADD_DICT_VALUE(retdata, key, value); + xmlXPathFreeObject(xpo); } else { char msg[8094]; - snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", + snprintf(msg, 8092, "Could not get key value: " + "%s [%i] (Defining key: %s)%c", map_p->rootpath, elmtid, map_p->key, 0); PyErr_SetString(PyExc_LookupError, msg); - continue; - } - break; - - case ptzSTR: - case ptzINT: - case ptzFLOAT: - case ptzBOOL: - xpo = _get_xpath_values(xpctx, map_p->value); - if( xpo != NULL ) { - _add_xpath_result(retdata, xpctx, map_p, xpo); - xmlXPathFreeObject(xpo); } - break; - - case ptzLIST_STR: - case ptzLIST_INT: - case ptzLIST_FLOAT: - case ptzLIST_BOOL: - xpo = _get_xpath_values(xpctx, map_p->value); - if( xpo != NULL ) { - if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - if( xpo->nodesetval->nodeNr > 0 ) { - value = PyList_New(0); - for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { - char *valstr = NULL; - valstr = (char *) malloc(4098); - dmixml_GetXPathContent(valstr, 4097, xpo, i); - PyList_Append(value, StringToPyObj(map_p->type_value, - valstr)); - free(valstr); - } - } else { - value = Py_None; - } - PyADD_DICT_VALUE(retdata, key, value); - xmlXPathFreeObject(xpo); - } else { - char msg[8094]; - snprintf(msg, 8092, "Could not get key value: " - "%s [%i] (Defining key: %s)%c", - map_p->rootpath, elmtid, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); - continue; - } - } - break; + } + break; - case ptzDICT: - // Traverse children nodes - if( map_p->child == NULL ) { - break; - } - if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { - char msg[8094]; - snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", - in_map->rootpath, elmtid, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); - continue; - } - value = pythonizeXMLnode(map_p->child, data_n); - PyADD_DICT_VALUE(retdata, key, (value != NULL ? value : Py_None)); + case ptzDICT: + // Traverse children nodes + if( map_p->child == NULL ) { break; - - default: - fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); + } + if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { + char msg[8094]; + snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", + map_p->rootpath, elmtid, map_p->key, 0); + PyErr_SetString(PyExc_LookupError, msg); break; } + // Use recursion when procession child elements + value = pythonizeXMLnode(map_p->child, data_n); + PyADD_DICT_VALUE(retdata, key, (value != NULL ? value : Py_None)); + break; + + default: + fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); + break; } free(key); @@ -544,52 +542,65 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xmlXPathContext *xpctx = NULL; xmlDoc *xpdoc = NULL; PyObject *retdata = NULL; + ptzMAP *map_p = NULL; + char *key = NULL; if( (in_map == NULL) || (data_n == NULL) ) { PyErr_SetString(PyExc_LookupError, "XMLnode or map is NULL"); return NULL; } - // Set the root node in the XPath context - retdata = PyDict_New(); - if( in_map->rootpath != NULL ) { - xmlXPathObject *xpo = NULL; - int i; + key = (char *) malloc(258); + assert( key != NULL ); - xpdoc = xmlNewDoc((xmlChar *) "1.0"); - assert( xpdoc != NULL ); - xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1)); + // Loop through all configured elements + retdata = PyDict_New(); + for( map_p = in_map; map_p != NULL; map_p = map_p->next ) { + if( (map_p->type_value == ptzDICT) && (map_p->rootpath != NULL) ) { + xmlXPathObject *xpo = NULL; + int i; + + // Set the root node in the XPath context + xpdoc = xmlNewDoc((xmlChar *) "1.0"); + assert( xpdoc != NULL ); + xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1)); + + xpctx = xmlXPathNewContext(xpdoc); + assert( xpctx != NULL ); + xpctx->node = data_n; + + xpo = _get_xpath_values(xpctx, map_p->rootpath); + if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { + char msg[8094]; + snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", + map_p->rootpath, map_p->key, 0); + fprintf(stderr, msg); + PyErr_SetString(PyExc_LookupError, msg); - xpctx = xmlXPathNewContext(xpdoc); - assert( xpctx != NULL ); - xpctx->node = data_n; + if( xpo != NULL ) { + xmlXPathFreeObject(xpo); + } + xmlFreeDoc(xpdoc); + xmlXPathFreeContext(xpctx); + return NULL; + } - xpo = _get_xpath_values(xpctx, in_map->rootpath); - if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { - char msg[8094]; - snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", - in_map->rootpath, in_map->key, 0); - PyErr_SetString(PyExc_LookupError, msg); + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { + xpctx->node = xpo->nodesetval->nodeTab[i]; - if( xpo != NULL ) { - xmlXPathFreeObject(xpo); + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + _deep_pythonize(retdata, map_p, + xpo->nodesetval->nodeTab[i], i); + } } - xmlFreeDoc(xpdoc); + xmlXPathFreeObject(xpo); xmlXPathFreeContext(xpctx); - return NULL; - } - - retdata = PyDict_New(); - for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { - _deep_pythonize(retdata, in_map, xpo->nodesetval->nodeTab[i], i); + xmlFreeDoc(xpdoc); + } else { + _deep_pythonize(retdata, map_p, data_n, 0); } - xmlXPathFreeObject(xpo); - xmlXPathFreeContext(xpctx); - xmlFreeDoc(xpdoc); - } else { - _deep_pythonize(retdata, in_map, data_n, 0); } - + free(key); return retdata; } @@ -606,7 +617,7 @@ PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *doc) #if 0 // Simple independent main function - only for debugging -int main() { +int main(int argc, char **argv) { xmlDoc *doc = NULL, *data = NULL; ptzMAP *map = NULL; PyObject *pydat = NULL; @@ -616,19 +627,19 @@ int main() { doc = xmlReadFile("pythonmap.xml", NULL, 0); assert( doc != NULL ); - map = dmiMAP_ParseMappingXML(doc, "processor"); - // ptzmap_Dump(map); + map = dmiMAP_ParseMappingXML(doc, argv[1]); + ptzmap_Dump(map); printf("----------------------\n"); - data = xmlReadFile("cpu.xml", NULL, 0); + data = xmlReadFile(argv[2], NULL, 0); assert( data != NULL ); pydat = pythonizeXMLdoc(map, data); Py_INCREF(pydat); PyObject_Print(pydat, stdout, 0); Py_DECREF(pydat); - + printf("\n"); ptzmap_Free(map); xmlFreeDoc(data); xmlFreeDoc(doc); -- cgit From a92cc1236ca7c5abee27e4360284b67297e39c15 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 14 May 2009 16:31:34 +0200 Subject: Support fixed size lists When using one of the list types as valuetype, the Map tag now also supports fixedsize and index_attr attributes. - fixedsize : Defines a fixed size of the list - index_attr : Defines an attribute name of the input XML data which contains the list index for the value --- src/xmlpythonizer.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++--- src/xmlpythonizer.h | 2 ++ 2 files changed, 69 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index f033e6d..e9671b2 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -75,6 +75,23 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, return ret; }; +void ptzmap_SetFixedList(ptzMAP *map_p, const char *index, int size) { + assert( map_p != NULL ); + + switch( map_p->type_value ) { + case ptzLIST_STR: + case ptzLIST_INT: + case ptzLIST_FLOAT: + case ptzLIST_BOOL: + map_p->list_index = strdup(index); + map_p->fixed_list_size = size; + break; + + default: + break; + } +} + void ptzmap_Free_func(ptzMAP *ptr) { if( ptr == NULL ) { @@ -86,6 +103,11 @@ void ptzmap_Free_func(ptzMAP *ptr) ptr->rootpath = NULL; } + if( ptr->list_index != NULL ) { + free(ptr->list_index); + ptr->list_index = NULL; + } + free(ptr->key); ptr->key = NULL; @@ -136,6 +158,11 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); indent(level); printf("value type: (%i) %-13.13s - value: %s\n", ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value); + if( ptr->list_index != NULL ) { + indent(level); + printf("List index: %s - Fixed size: %i\n", + ptr->list_index, ptr->fixed_list_size); + } if( ptr->child != NULL ) { indent(level); printf(" ** CHILD\n"); ptzmap_Dump_func(ptr->child, level + 1); @@ -212,7 +239,8 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { ptzTYPES type_key, type_value; char *key = NULL, *value = NULL; char *rootpath = NULL; - + char *listidx = NULL; + int fixedsize = 0; if( ptr_n->type != XML_ELEMENT_NODE ) { continue; } @@ -226,6 +254,12 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { rootpath = dmixml_GetAttrValue(ptr_n, "rootpath"); + listidx = dmixml_GetAttrValue(ptr_n, "index_attr"); + if( listidx != NULL ) { + char *fsz = dmixml_GetAttrValue(ptr_n, "fixedsize"); + fixedsize = (fsz != NULL ? atoi(fsz) : 0); + } + if( type_value == ptzDICT ) { // When value type is ptzDICT, traverse the children nodes // - should contain another Map set instead of a value attribute @@ -240,6 +274,11 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { // value type is not a Python Dict retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, value, NULL); } + + if( (retmap != NULL) && (listidx != NULL) && (fixedsize > 0) ) { + ptzmap_SetFixedList(retmap, listidx, fixedsize); + } + value = NULL; key = NULL; } @@ -486,12 +525,37 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { if( xpo->nodesetval->nodeNr > 0 ) { value = PyList_New(0); + + // If we're working on a fixed list, create one which contains + // only Py_None objects. Otherwise the list will be filled with + // elements. + if( map_p->fixed_list_size > 0 ) { + for( i = 0; i < map_p->fixed_list_size; i++ ) { + PyList_Append(value, Py_None); + } + } + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { char *valstr = NULL; valstr = (char *) malloc(4098); dmixml_GetXPathContent(valstr, 4097, xpo, i); - PyList_Append(value, StringToPyObj(map_p->type_value, - valstr)); + + // If we have a fixed list and we have a index value for the list + if( (map_p->fixed_list_size > 0) && (map_p->list_index != NULL) ) { + char *idx = NULL; + + idx = dmixml_GetAttrValue(xpo->nodesetval->nodeTab[i], + map_p->list_index); + if( idx != NULL ) { + PyList_SetItem(value, atoi(idx)-1, + StringToPyObj(map_p->type_value, + valstr) + ); + } + } else { + PyList_Append(value, StringToPyObj(map_p->type_value, + valstr)); + } free(valstr); } } else { diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 6c61381..d6fa54c 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -39,6 +39,8 @@ typedef struct ptzMAP_s { ptzTYPES type_value; char *value; // for ptzCONST key contains a static string, // the rest of types, an XPath to XML data + int fixed_list_size; // Only to be used on lists + char *list_index ; // Only to be used on fixed lists struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From 9d47720a88ee77ac4c0ab5f138a8eaf601c492d0 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 14 May 2009 17:06:18 +0200 Subject: Added new Map attribute - emptyIsNone If the emptyIsNone attribute is set to "1", the Python result will be forced to Py_None if the referenced XML value is empty. When checking if the value is empty, the XML value is right trimmed to remove trailing spaces. Only spaces are are removed. --- src/xmlpythonizer.c | 71 ++++++++++++++++++++++++++++++++++++++++++----------- src/xmlpythonizer.h | 2 ++ 2 files changed, 59 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index e9671b2..b8964bf 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -156,8 +156,9 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) } indent(level); printf("key type: (%i) %-13.13s - key: %s\n", ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); - indent(level); printf("value type: (%i) %-13.13s - value: %s\n", - ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value); + indent(level); printf("value type: (%i) %-13.13s - value: %s %s\n", + ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value, + (ptr->num_emptyIsNone ? "(EmptyIsNone)": "")); if( ptr->list_index != NULL ) { indent(level); printf("List index: %s - Fixed size: %i\n", @@ -270,9 +271,29 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, NULL, _do_dmimap_parsing(ptr_n->children->next)); } else { + char *emptyIsNone = NULL; + // Append the value as a normal value when the // value type is not a Python Dict retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, value, NULL); + + // Set emptyIsNone flag + if( (emptyIsNone = dmixml_GetAttrValue(ptr_n, "emptyIsNone")) != NULL ) { + switch( retmap->type_value ) { + case ptzSTR: + case ptzINT: + case ptzFLOAT: + case ptzBOOL: + case ptzLIST_STR: + case ptzLIST_INT: + case ptzLIST_FLOAT: + case ptzLIST_BOOL: + retmap->emptyIsNone = (emptyIsNone[0] == '1' ? 1 : 0); + break; + default: + break; + } + } } if( (retmap != NULL) && (listidx != NULL) && (fixedsize > 0) ) { @@ -297,13 +318,13 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // Verify that the root node got the right name if( (node == NULL) || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { - // PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); return NULL; } // Verify that it's of a version we support if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - // PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); return NULL; } @@ -321,7 +342,7 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { char msg[8194]; snprintf(msg, 8193, "No mapping for '%s' was found " "in the XML-Python mapping file%c", mapname, 0); - // PyErr_SetString(PyExc_IOError, msg); + PyErr_SetString(PyExc_IOError, msg); return NULL; } @@ -335,14 +356,38 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // // Parser routines for converting XML data into Python structures // -inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { +inline PyObject *StringToPyObj(ptzMAP *val_m, const char *str) { PyObject *value; if( str == NULL ) { return Py_None; } - switch( type ) { + if( val_m->emptyIsNone == 1) { + char *cp = strdup(str); + char *cp_p = NULL; + assert( cp != NULL ); + + // Trim the string for trailing spaces + cp_p = cp + strlen(cp) - 1; + while( (cp_p >= cp) && (*cp_p == ' ') ) { + *cp_p = 0; + cp_p--; + } + + // If our copy pointer is the same + // or less than the starting point, + // there is no data here + if( cp_p <= cp ) { + free(cp); + return Py_None; + } + free(cp); + } + + + + switch( val_m->type_value ) { case ptzINT: case ptzLIST_INT: value = PyInt_FromLong(atoi(str)); @@ -364,7 +409,7 @@ inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { break; default: - fprintf(stderr, "Invalid type '%i' for value '%s'\n", type, str); + fprintf(stderr, "Invalid type '%i' for value '%s'\n", val_m->type_value, str); value = Py_None; } return value; @@ -453,7 +498,7 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m for( i = 0; i < value->nodesetval->nodeNr; i++ ) { if( _get_key_value(key, 256, map_p, xpctx, i) != NULL ) { dmixml_GetXPathContent(val, 4097, value, i); - PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p, val)); } } } @@ -461,7 +506,7 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m default: if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { dmixml_GetXPathContent(val, 4097, value, 0); - PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p->type_value, val)); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p, val)); } break; } @@ -548,13 +593,11 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int map_p->list_index); if( idx != NULL ) { PyList_SetItem(value, atoi(idx)-1, - StringToPyObj(map_p->type_value, - valstr) + StringToPyObj(map_p, valstr) ); } } else { - PyList_Append(value, StringToPyObj(map_p->type_value, - valstr)); + PyList_Append(value, StringToPyObj(map_p, valstr)); } free(valstr); } diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index d6fa54c..f0efaee 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -41,6 +41,8 @@ typedef struct ptzMAP_s { // the rest of types, an XPath to XML data int fixed_list_size; // Only to be used on lists char *list_index ; // Only to be used on fixed lists + int emptyIsNone; // Only for ptzINT/ptzFLOAT values + // - if set to 1, empty input strings sets the result to Py_None struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From fff6c8a1cd328ebce904b7fab4bdc642596a8ef5 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 14 May 2009 17:11:55 +0200 Subject: Remove 'ns' from the speed_ns attribute in memory section --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 422287c..da6b72b 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -2645,7 +2645,7 @@ void dmi_memory_device_speed(xmlNode *node, u16 code) if(code == 0) { dmixml_AddAttribute(data_n, "unkown", "1"); } else { - dmixml_AddAttribute(data_n, "speed_ns", "%.1f ns", (float) 1000 / code); + dmixml_AddAttribute(data_n, "speed_ns", "%.1f", (float) 1000 / code); dmixml_AddAttribute(data_n, "unit", "MHz"); dmixml_AddTextContent(data_n, "%i", code); } -- cgit From 72016cb607798e567ac2f2ce67cc50652b0daa32 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 15 May 2009 11:06:20 +0200 Subject: Added 'emptyValue' attribute in the Map tag This attribute defines a default value when XML source data is empty --- src/xmlpythonizer.c | 46 ++++++++++++++++++++++++++++++++-------------- src/xmlpythonizer.h | 4 ++-- 2 files changed, 34 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index b8964bf..4690981 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -108,6 +108,11 @@ void ptzmap_Free_func(ptzMAP *ptr) ptr->list_index = NULL; } + if( ptr->emptyValue != NULL ) { + free(ptr->emptyValue); + ptr->emptyValue = NULL; + } + free(ptr->key); ptr->key = NULL; @@ -271,14 +276,14 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, NULL, _do_dmimap_parsing(ptr_n->children->next)); } else { - char *emptyIsNone = NULL; + char *tmpstr = NULL; // Append the value as a normal value when the // value type is not a Python Dict retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, value, NULL); // Set emptyIsNone flag - if( (emptyIsNone = dmixml_GetAttrValue(ptr_n, "emptyIsNone")) != NULL ) { + if( (tmpstr = dmixml_GetAttrValue(ptr_n, "emptyIsNone")) != NULL ) { switch( retmap->type_value ) { case ptzSTR: case ptzINT: @@ -288,12 +293,15 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { case ptzLIST_INT: case ptzLIST_FLOAT: case ptzLIST_BOOL: - retmap->emptyIsNone = (emptyIsNone[0] == '1' ? 1 : 0); + retmap->emptyIsNone = (tmpstr[0] == '1' ? 1 : 0); break; default: break; } } + if( (tmpstr = dmixml_GetAttrValue(ptr_n, "emptyValue")) != NULL ) { + retmap->emptyValue = strdup(tmpstr); + } } if( (retmap != NULL) && (listidx != NULL) && (fixedsize > 0) ) { @@ -356,15 +364,16 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // // Parser routines for converting XML data into Python structures // -inline PyObject *StringToPyObj(ptzMAP *val_m, const char *str) { +inline PyObject *StringToPyObj(ptzMAP *val_m, const char *instr) { PyObject *value; + const char *workstr = NULL; - if( str == NULL ) { + if( instr == NULL ) { return Py_None; } - if( val_m->emptyIsNone == 1) { - char *cp = strdup(str); + if( (val_m->emptyIsNone == 1) || (val_m->emptyValue != NULL) ) { + char *cp = strdup(instr); char *cp_p = NULL; assert( cp != NULL ); @@ -380,36 +389,45 @@ inline PyObject *StringToPyObj(ptzMAP *val_m, const char *str) { // there is no data here if( cp_p <= cp ) { free(cp); - return Py_None; + if( val_m->emptyIsNone == 1 ) { + return Py_None; + } + if( val_m->emptyValue != NULL ) { + workstr = (const char *)val_m->emptyValue; + } + } else { + free(cp); } - free(cp); } + if( workstr == NULL ) { + workstr = instr; + } switch( val_m->type_value ) { case ptzINT: case ptzLIST_INT: - value = PyInt_FromLong(atoi(str)); + value = PyInt_FromLong(atoi(workstr)); break; case ptzFLOAT: case ptzLIST_FLOAT: - value = PyFloat_FromDouble(atof(str)); + value = PyFloat_FromDouble(atof(workstr)); break; case ptzBOOL: case ptzLIST_BOOL: - value = PyBool_FromLong((atoi(str) == 1 ? 1:0)); + value = PyBool_FromLong((atoi(workstr) == 1 ? 1:0)); break; case ptzSTR: case ptzLIST_STR: - value = PyString_FromString(str); + value = PyString_FromString(workstr); break; default: - fprintf(stderr, "Invalid type '%i' for value '%s'\n", val_m->type_value, str); + fprintf(stderr, "Invalid type '%i' for value '%s'\n", val_m->type_value, instr); value = Py_None; } return value; diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index f0efaee..62134b4 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -41,8 +41,8 @@ typedef struct ptzMAP_s { // the rest of types, an XPath to XML data int fixed_list_size; // Only to be used on lists char *list_index ; // Only to be used on fixed lists - int emptyIsNone; // Only for ptzINT/ptzFLOAT values - // - if set to 1, empty input strings sets the result to Py_None + int emptyIsNone; // If set to 1, empty input (right trimmed) strings sets the result to Py_None + char *emptyValue; // If set, this value will be used when input is empty struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From a8d6f0ee846d03d10c188080af69c10567887b56 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 15 May 2009 11:20:07 +0200 Subject: Fixed some errors in decoding "3.3.5.9 Processor Characteristics" Fixes regression in parsing introduced when rewriting dmidecode to use libxml2 --- src/dmidecode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index da6b72b..d0efb8e 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1261,8 +1261,7 @@ void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) void dmi_processor_characteristics(xmlNode *node, u16 code) { static const char *characteristics[] = { - NULL, - "Unknown" /* 1 */ + "Unknown", /* 1 */ "64-bit capable" /* 2 */ }; -- cgit From 88688ef91d816e4158fd388131c4060e22116c74 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 15 May 2009 11:28:56 +0200 Subject: Completed mapping the memory section --- src/pythonmap.xml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 5b4a437..e55e107 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -109,4 +109,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From b694abeb522f93aa842d16720a3aa1f98ad2aa84 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 15 May 2009 11:55:25 +0200 Subject: Reorganised attributes in SystemSlots tag This part of the XML result was not valid due to duplicated tag attributes. Moved some of this specifications from the SystemSlots tag to its own SlotID tag, with even more details. --- src/dmidecode.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index d0efb8e..bb145b8 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1941,15 +1941,51 @@ void dmi_slot_length(xmlNode *node, u8 code) } /* 3.3.10.5 */ +void inline set_slottype(xmlNode *node, u8 type) { + switch (type) { + case 0x04: /* MCA */ + dmixml_AddAttribute(node, "slottype", "MCA"); + break; + case 0x05: /* EISA */ + dmixml_AddAttribute(node, "slottype", "EISA"); + break; + case 0x06: /* PCI */ + case 0x0E: /* PCI */ + dmixml_AddAttribute(node, "slottype", "PCI"); + break; + case 0x0F: /* AGP */ + case 0x10: /* AGP */ + case 0x11: /* AGP */ + case 0x13: /* AGP */ + dmixml_AddAttribute(node, "slottype", ""); + break; + case 0x12: /* PCI-X */ + dmixml_AddAttribute(node, "slottype", "PCI-X"); + break; + case 0xA5: /* PCI Express */ + dmixml_AddAttribute(node, "slottype", "PCI Express"); + break; + case 0x07: /* PCMCIA */ + dmixml_AddAttribute(node, "slottype", "PCMCIA"); + break; + default: + break; + } +} + void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type) { - dmixml_AddAttribute(node, "dmispec", "3.3.10.5"); + xmlNode *slotid_n = xmlNewChild(node, NULL, (xmlChar *) "SlotID", NULL); + dmixml_AddAttribute(slotid_n, "dmispec", "3.3.10.5"); + dmixml_AddAttribute(slotid_n, "flags1", "0x%04x", code1); + dmixml_AddAttribute(slotid_n, "flags2", "0x%04x", code2); + dmixml_AddAttribute(slotid_n, "type", "0x%04x", type); switch (type) { case 0x04: /* MCA */ - dmixml_AddAttribute(node, "id", "%i", code1); + dmixml_AddAttribute(slotid_n, "id", "%i", code1); break; case 0x05: /* EISA */ - dmixml_AddAttribute(node, "id", "%i", code1); + dmixml_AddAttribute(slotid_n, "id", "%i", code1); break; case 0x06: /* PCI */ case 0x0E: /* PCI */ @@ -1959,15 +1995,16 @@ void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type) case 0x12: /* PCI-X */ case 0x13: /* AGP */ case 0xA5: /* PCI Express */ - dmixml_AddAttribute(node, "id", "%i", code1); + dmixml_AddAttribute(slotid_n, "id", "%i", code1); break; case 0x07: /* PCMCIA */ - dmixml_AddAttribute(node, "adapter", "%i", code1); - dmixml_AddAttribute(node, "id", "%i", code2); + dmixml_AddAttribute(slotid_n, "adapter", "%i", code1); + dmixml_AddAttribute(slotid_n, "id", "%i", code2); break; default: break; } + set_slottype(slotid_n, type); } void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) -- cgit From b20e017f0b09e6f8946db04b0acef69e62fcf114 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 20 May 2009 22:19:23 +1000 Subject: Fixed some ugly, unattractive and unhealthy code These hangover lines must have crept in at the early stages of the initial conversion of dmidecode to python-dmidecode. Fixed. --- src/dmidecode.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index bb145b8..37fb6a0 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3974,8 +3974,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) break; case 5: /* 3.3.6 Memory Controller Information */ - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0F) { break; } @@ -4019,8 +4017,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) break; case 6: /* 3.3.7 Memory Module Information */ - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0C) { break; } @@ -4036,8 +4032,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) break; case 7: /* 3.3.8 Cache Information */ - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0F) { break; } @@ -4070,8 +4064,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) break; case 8: /* 3.3.9 Port Connector Information */ - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x09) { break; } @@ -4093,8 +4085,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) break; case 9: /* 3.3.10 System Slots */ - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x0C) { break; } @@ -4119,8 +4109,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) break; case 11: /* 3.3.12 OEM Strings */ - dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); - if(h->length < 0x05) { break; } -- cgit From c5ad272970644cee25eefb2010061b751dd17519 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 15 May 2009 13:43:09 +0200 Subject: Added a few missing comments --- src/pythonmap.xml | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index e55e107..d8add41 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -90,6 +90,10 @@ + + + + @@ -109,6 +113,10 @@ + + + + -- cgit From 9f34b97089fe7fb14c6877cc426658c06f04cb9e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 11:56:41 +0200 Subject: Fixed some errors in the XML layout on CacheInfo --- src/dmidecode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 37fb6a0..e507689 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1566,7 +1566,7 @@ void dmi_cache_location(xmlNode *node, u8 code) void dmi_cache_size(xmlNode *node, const char *tagname, u16 code) { - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CacheLocation", NULL); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "3.3.8"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); @@ -1603,8 +1603,8 @@ void dmi_cache_types(xmlNode *node, const char *tagname, u16 code) int i; for(i = 0; i <= 6; i++) { if(code & (1 << i)) { - xmlNode *n = dmixml_AddTextContent(data_n, "%s", types[i]); - dmixml_AddAttribute(n, "index", "%i", i); + xmlNode *n = dmixml_AddTextChild(data_n, "CacheType", "%s", types[i]); + dmixml_AddAttribute(n, "index", "%i", i+1); } } } -- cgit From 52f936c82d9098b2a64986228ebc1e9109828ac9 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 12:53:34 +0200 Subject: Added field python dict mapping for CacheInfo --- src/pythonmap.xml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index d8add41..4dc2eb4 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -163,4 +163,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From 599642f7370cb3f2fbf5c079c20269318d5a775f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 15:29:56 +0200 Subject: Added support for value type 'list:dict' for field mapping This builds up a list of dicts. Syntax is: The parser will iterate all nodes defined in the @value attribute and the root path will of the nested mapping will be using the path in @value as the root path for further parsing. --- src/xmlpythonizer.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++------- src/xmlpythonizer.h | 4 +-- 2 files changed, 80 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 4690981..d9827bd 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -46,8 +46,6 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, assert( (ktyp == ptzCONST) || (ktyp == ptzSTR) || (ktyp == ptzINT) || (ktyp == ptzFLOAT) ); assert( key != NULL ); - // Make sure that value and child are not used together - assert( ((value == NULL) && child != NULL) || ((value != NULL) && (child == NULL)) ); ret = (ptzMAP *) malloc(sizeof(ptzMAP)+2); assert( ret != NULL ); @@ -63,9 +61,9 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, ret->type_value = vtyp; if( value != NULL ) { ret->value = strdup(value); - ret->child = NULL; - } else if( child != NULL ) { - ret->value = NULL; + } + + if( child != NULL ) { ret->child = child; } @@ -135,7 +133,7 @@ void ptzmap_Free_func(ptzMAP *ptr) // DEBUG FUNCTIONS static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL", "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL", - "ptzDICT", NULL }; + "ptzDICT", "ptzLIST_DICT", NULL }; void indent(int lvl) { @@ -163,7 +161,7 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); indent(level); printf("value type: (%i) %-13.13s - value: %s %s\n", ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value, - (ptr->num_emptyIsNone ? "(EmptyIsNone)": "")); + (ptr->emptyIsNone ? "(EmptyIsNone)": "")); if( ptr->list_index != NULL ) { indent(level); printf("List index: %s - Fixed size: %i\n", @@ -211,9 +209,11 @@ inline ptzTYPES _convert_maptype(const char *str) { return ptzLIST_BOOL; } else if( strcmp(str, "dict") == 0 ) { return ptzDICT; + } else if( strcmp(str, "list:dict") == 0 ) { + return ptzLIST_DICT; } else { - fprintf(stderr, "Unknown field type: %s - defaulting to 'string'\n", str); - return ptzSTR; + fprintf(stderr, "Unknown field type: %s - defaulting to 'constant'\n", str); + return ptzCONST; } } @@ -266,14 +266,15 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { fixedsize = (fsz != NULL ? atoi(fsz) : 0); } - if( type_value == ptzDICT ) { + if( (type_value == ptzDICT) || (type_value == ptzLIST_DICT) ) { // When value type is ptzDICT, traverse the children nodes // - should contain another Map set instead of a value attribute if( ptr_n->children == NULL ) { continue; } // Recursion - retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, NULL, + retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, + (type_value == ptzLIST_DICT ? value : NULL), _do_dmimap_parsing(ptr_n->children->next)); } else { char *tmpstr = NULL; @@ -615,6 +616,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int ); } } else { + // No list index - append the value PyList_Append(value, StringToPyObj(map_p, valstr)); } free(valstr); @@ -651,6 +653,69 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int PyADD_DICT_VALUE(retdata, key, (value != NULL ? value : Py_None)); break; + case ptzLIST_DICT: // List of dict arrays + if( map_p->child == NULL ) { + break; + } + if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { + char msg[8094]; + snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", + map_p->rootpath, elmtid, map_p->key, 0); + PyErr_SetString(PyExc_LookupError, msg); + break; + } + + // Iterate all nodes which is found in the 'value' XPath + xpo = _get_xpath_values(xpctx, map_p->value); + if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { + char msg[8094]; + snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", + map_p->value, map_p->key, 0); + fprintf(stderr, msg); + PyErr_SetString(PyExc_LookupError, msg); + + if( xpo != NULL ) { + xmlXPathFreeObject(xpo); + } + break; + } + + // Prepare a data list + value = PyList_New(0); + + // If we're working on a fixed list, create one which contains + // only Py_None objects. Otherwise the list will be filled with + // elements. + if( map_p->fixed_list_size > 0 ) { + for( i = 0; i < map_p->fixed_list_size; i++ ) { + PyList_Append(value, Py_None); + } + } + + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { + PyObject *dataset = NULL; + + dataset = pythonizeXMLnode(map_p->child, xpo->nodesetval->nodeTab[i]); + if( dataset != NULL ) { + // If we have a fixed list and we have a index value for the list + if( (map_p->fixed_list_size > 0) && (map_p->list_index != NULL) ) { + char *idx = NULL; + + idx = dmixml_GetAttrValue(xpo->nodesetval->nodeTab[i], + map_p->list_index); + if( idx != NULL ) { + PyList_SetItem(value, atoi(idx)-1, dataset); + } + } else { + // No list index - append the value + PyList_Append(value, dataset); + } + } + } + PyADD_DICT_VALUE(retdata, key, value); + xmlXPathFreeObject(xpo); + break; + default: fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); break; @@ -762,9 +827,10 @@ int main(int argc, char **argv) { pydat = pythonizeXMLdoc(map, data); Py_INCREF(pydat); + printf("\n\n"); PyObject_Print(pydat, stdout, 0); Py_DECREF(pydat); - printf("\n"); + printf("\n\n"); ptzmap_Free(map); xmlFreeDoc(data); xmlFreeDoc(doc); diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 62134b4..e659340 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -29,7 +29,7 @@ typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL, ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, ptzLIST_BOOL, - ptzDICT } ptzTYPES; + ptzDICT, ptzLIST_DICT } ptzTYPES; typedef struct ptzMAP_s { char *rootpath; // XML root path for the data - if NULL, XML document is the root document. @@ -43,7 +43,7 @@ typedef struct ptzMAP_s { char *list_index ; // Only to be used on fixed lists int emptyIsNone; // If set to 1, empty input (right trimmed) strings sets the result to Py_None char *emptyValue; // If set, this value will be used when input is empty - struct ptzMAP_s *child; // Only used for type_value == pyDICT + struct ptzMAP_s *child; // Only used for type_value == (ptzDICT || ptzLIST_DICT) struct ptzMAP_s *next; // Pointer chain } ptzMAP; -- cgit From 15fd846d16312aae19d48bac080498a44a7c469c Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 15:36:23 +0200 Subject: Added field mapping for the dmidecode.system() section --- src/pythonmap.xml | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 4dc2eb4..ebe53f9 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -173,9 +173,6 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From 2ab1ede583c1dc2e9a81c20c80dc882964dde9a1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 15:46:09 +0200 Subject: Added field mapping for dmidecode.baseboard() --- src/pythonmap.xml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index ebe53f9..36d31a7 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -248,4 +248,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From 5900424cc4a3ba70b79a6f2c31cf2d738b4e0217 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 16:39:10 +0200 Subject: Use correct index value for /dmidecode/SystemSlots/SlotCharacteristics/Characteristic/@index --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index e507689..6cee5cf 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -2051,7 +2051,7 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) if(code2 & (1 << i)) { xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s", characteristics2[i]); - dmixml_AddAttribute(c_n, "index", "%i", i); + dmixml_AddAttribute(c_n, "index", "%i", i+8); c_n = NULL; } } -- cgit From 6e66a28fb04934a58286df8d3b84caf904ae2da7 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 16:41:16 +0200 Subject: Added field mapping for dmidecode.slots() --- src/pythonmap.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 36d31a7..4ef2ee6 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -276,4 +276,26 @@ + + + + + + + + + + + + + + + + + + + + -- cgit From 457723c74c011c9a60b6f16c4f089225b5df30c3 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 16:54:42 +0200 Subject: Added field mapping for dmidecode.connectors() --- src/pythonmap.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 4ef2ee6..90b2d88 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -298,4 +298,26 @@ + + + + + + + + + + + + + + + + + + -- cgit From eff9145436de625fdf0be489be95118c69ec3a2e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 17:02:47 +0200 Subject: Fixed the bios field mapping to use relative XPaths --- src/pythonmap.xml | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index 90b2d88..b2d2d31 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -4,45 +4,45 @@ - + + valuetype="list:string" value="Installed/Language"/> + valuetype="integer" value="@installable_languages"/> - - - + + + - + - + - + - + - + + value="concat(RuntimeSize,' ',RuntimeSize/@unit)"/> - + valuetype="string" value="BIOSrevision"/> + - - + value="concat(ROMsize,' ',ROMsize/@unit)"/> + + - - - + + + -- cgit From ff36dbbc2804858ad7229e1b6bda51fc2250133d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 17:09:48 +0200 Subject: Changed the node content of /dmidecode/ProcessorInfo/CPUCore/cpu_flags/flag to maintain backwards compatibility The old python-dmidecode uses the format '{flag} ({description})'. This format is now used is well as contents for the cpu_flags/flag text nodes. --- src/dmidecode.c | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 6cee5cf..7abec47 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -960,38 +960,38 @@ xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *vers const char *descr; } flags[] = { /* *INDENT-OFF* */ - {"FPU", "Floating-point unit on-chip"}, /* 0 */ - {"VME", "Virtual mode extension"}, - {"DE", "Debugging extension"}, - {"PSE", "Page size extension"}, - {"TSC", "Time stamp counter"}, - {"MSR", "Model specific registers"}, - {"PAE", "Physical address extension"}, - {"MCE", "Machine check exception"}, - {"CX8", "CMPXCHG8 instruction supported"}, - {"APIC", "On-chip APIC hardware supported"}, + {"FPU", "FPU (Floating-point unit on-chip)"}, /* 0 */ + {"VME", "VME (Virtual mode extension)"}, + {"DE", "DE (Debugging extension)"}, + {"PSE", "PSE (Page size extension)"}, + {"TSC", "TSC (Time stamp counter)"}, + {"MSR", "MSR (Model specific registers)"}, + {"PAE", "PAE (Physical address extension)"}, + {"MCE", "MCE (Machine check exception)"}, + {"CX8", "CX8 (CMPXCHG8 instruction supported)"}, + {"APIC", "APIC (On-chip APIC hardware supported)"}, {NULL, NULL}, /* 10 */ - {"SEP", "Fast system call"}, - {"MTRR", "Memory type range registers"}, - {"PGE", "Page global enable"}, - {"MCA", "Machine check architecture"}, - {"CMOV", "Conditional move instruction supported"}, - {"PAT", "Page attribute table"}, - {"PSE-36", "36-bit page size extension"}, - {"PSN", "Processor serial number present and enabled"}, - {"CLFSH", "CLFLUSH instruction supported"}, + {"SEP", "SEP (Fast system call)"}, + {"MTRR", "MTRR (Memory type range registers)"}, + {"PGE", "PGE (Page global enable)"}, + {"MCA", "MCA (Machine check architecture)"}, + {"CMOV", "CMOV (Conditional move instruction supported)"}, + {"PAT", "PAT (Page attribute table)"}, + {"PSE-36", "PSE-36 (36-bit page size extension)"}, + {"PSN", "PSN (Processor serial number present and enabled)"}, + {"CLFSH", "CLFLUSH (CLFLUSH instruction supported)"}, {NULL, NULL }, /* 20 */ - {"DS", "Debug store"}, - {"ACPI", "ACPI supported"}, - {"MMX", "MMX technology supported"}, - {"FXSR", "Fast floating-point save and restore"}, - {"SSE", "Streaming SIMD extensions"}, - {"SSE2", "Streaming SIMD extensions 2"}, - {"SS", "Self-snoop"}, - {"HTT", "Hyper-threading technology"}, - {"TM", "Thermal monitor supported"}, - {"IA64", "IA64 capabilities"}, - {"PBE", "Pending break enabled"} /* 31 */ + {"DS", "DS (Debug store)"}, + {"ACPI", "ACPI (ACPI supported)"}, + {"MMX", "MMX (MMX technology supported)"}, + {"FXSR", "FXSR (Fast floating-point save and restore)"}, + {"SSE", "SSE (Streaming SIMD extensions)"}, + {"SSE2", "SSE2 (Streaming SIMD extensions 2)"}, + {"SS", "SS (Self-snoop)"}, + {"HTT", "HTT (Hyper-threading technology)"}, + {"TM", "TM (Thermal monitor supported)"}, + {"IA64", "IA64 (IA64 capabilities)"}, + {"PBE", "PBE (Pending break enabled)"} /* 31 */ /* *INDENT-ON* */ }; -- cgit From ceaf615744b2a1a9cd655abef25e0840de731d01 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 20 May 2009 23:18:28 +1000 Subject: Fixed a bug, and preparing to dupload to Debian --- src/setup-dbg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 65f7436..e4b3b37 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -2,7 +2,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode-dbg", - version = "2.10.5", + version = "2.10.6", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", -- cgit From df5ddd3f51a353d03f2bd6a27c5d9ce14f077f41 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 21 May 2009 00:05:58 +1000 Subject: Bringing setup files upto date --- src/setup-dbg.py | 15 +++++++++------ src/setup.py | 6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index e4b3b37..fe05898 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -4,9 +4,9 @@ setup( name = "python-dmidecode-dbg", version = "2.10.6", description = "Python extension module for dmidecode", - author = "Nima Talebi", - author_email = "nima@autonomy.net.au", - url = "http://projects.autonomy.net.au/dmidecode/", + author = "Nima Talebi & David Sommerseth", + author_email = "nima@it.net.au, davids@redhat.com", + url = "http://projects.autonomy.net.au/python-dmidecode/", ext_modules = [ Extension( "dmidecode", @@ -15,10 +15,13 @@ setup( "src/dmihelper.c", "src/util.c", "src/dmioem.c", - "src/dmidecode.c" + "src/dmidecode.c", + "src/dmixml.c", + "src/xmlpythonizer.c" ], - library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], - libraries = [ "util" ], + include_dirs = [ "/usr/include/libxml2" ], + #library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], + libraries = [ "util", "xml2" ], #libraries = [ "util", "efence" ], ) ] diff --git a/src/setup.py b/src/setup.py index cf07c9b..c53dc17 100644 --- a/src/setup.py +++ b/src/setup.py @@ -4,9 +4,9 @@ setup( name = "python-dmidecode", version = "2.10.5", description = "Python extension module for dmidecode", - author = "Nima Talebi", - author_email = "nima@autonomy.net.au", - url = "http://projects.autonomy.net.au/dmidecode/", + author = "Nima Talebi & David Sommerseth", + author_email = "nima@it.net.au, davids@redhat.com", + url = "http://projects.autonomy.net.au/python-dmidecode/", ext_modules = [ Extension( "dmidecode", -- cgit From cd387fa3d1929505299d1df733fae890aacc75bc Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 21 May 2009 08:20:29 +1000 Subject: Update copyright notice --- src/dmidecode.c | 9 +++------ src/dmidecodemodule.c | 11 +++++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 7abec47..48f5df0 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -52,18 +52,15 @@ * http://www.intel.com/design/archives/wfm/downloads/bisspec.htm * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DMI Decode Python Module (Extension) + * DMI Decode Python module & libxml2 (Extension) * - * Copyright: 2007-2008 Nima Talebi + * Copyright: 2007-2009 Nima Talebi + * Copyright: 2009 David Sommerseth * License: GPLv3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* -#undef NDEBUG -*/ - #include #include #include diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 14ff148..33b0609 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -1,3 +1,14 @@ +/* + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DMI Decode Python module & libxml2 (Extension) + * + * Copyright: 2007-2009 Nima Talebi + * Copyright: 2009 David Sommerseth + * License: GPLv3 + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + #include #include -- cgit From d06d776adb0fef9504bd7662760e4cd0971fb748 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Fri, 22 May 2009 23:49:55 +1000 Subject: Reversioned, relicensed, and rejigged The version is of now, v3.10.6. The version major field has been upped due to the newly added XML functionality. The version has been reverted to GPLv2. Some headers have been cleaned up, copyright notices added etc. Credits given where due. --- src/dmidecode.c | 76 ++++++++++++++++++++++++++++----------------------- src/dmidecodemodule.c | 50 ++++++++++++++++++++++++++------- src/setup-dbg.py | 2 +- src/setup.py | 2 +- src/xmlpythonizer.c | 1 + 5 files changed, 85 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 48f5df0..1f4dbd9 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1,32 +1,48 @@ +/*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* + *. vim: fileencoding=utf-8 syntax=c sw=2 ts=2 et + *. + *. © 2007-2009 Nima Talebi + *. © 2009 David Sommerseth + *. © 2002-2008 Jean Delvare + *. © 2000-2002 Alan Cox + *. + *. This file is part of Python DMI-Decode. + *. + *. Python DMI-Decode is free software: you can redistribute it and/or modify + *. it under the terms of the GNU General Public License as published by + *. the Free Software Foundation, either version 2 of the License, or + *. (at your option) any later version. + *. + *. Python DMI-Decode 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 General Public License + *. along with Python DMI-Decode. If not, see . + *. + *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *. + *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY + *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE. + *. + *. $AutoHeaderSerial::20090522 $ + *. ******* AUTOHEADER END v1.1 ******* */ + /* - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DMI Decode * - * Copyright 2000-2002 Alan Cox - * Copyright 2002-2008 Jean Delvare - * Copyright 2009 David Sommerseth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * For the avoidance of doubt the "preferred form" of this code is one which - * is in an open unpatent encumbered format. Where cryptographic key signing - * forms part of the process of creating an executable the information - * including keys needed to generate an equivalently functional executable - * are deemed to be part of the source code. - * * Unless specified otherwise, all references are aimed at the "System * Management BIOS Reference Specification, Version 2.6" document, * available from http://www.dmtf.org/standards/smbios/. @@ -51,14 +67,7 @@ * - BIOS Integrity Services Application Programming Interface version 1.0 * http://www.intel.com/design/archives/wfm/downloads/bisspec.htm * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DMI Decode Python module & libxml2 (Extension) - * - * Copyright: 2007-2009 Nima Talebi - * Copyright: 2009 David Sommerseth - * License: GPLv3 - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include @@ -81,7 +90,6 @@ #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) - /******************************************************************************* ** Type-independant Stuff */ diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 33b0609..20739a1 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -1,13 +1,43 @@ -/* - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DMI Decode Python module & libxml2 (Extension) - * - * Copyright: 2007-2009 Nima Talebi - * Copyright: 2009 David Sommerseth - * License: GPLv3 - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - */ + +/*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* + *. vim: fileencoding=utf-8 syntax=c sw=2 ts=2 et + *. + *. © 2007-2009 Nima Talebi + *. © 2009 David Sommerseth + *. © 2002-2008 Jean Delvare + *. © 2000-2002 Alan Cox + *. + *. This file is part of Python DMI-Decode. + *. + *. Python DMI-Decode is free software: you can redistribute it and/or modify + *. it under the terms of the GNU General Public License as published by + *. the Free Software Foundation, either version 2 of the License, or + *. (at your option) any later version. + *. + *. Python DMI-Decode 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 General Public License + *. along with Python DMI-Decode. If not, see . + *. + *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *. + *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY + *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE. + *. + *. $AutoHeaderSerial::20090522 $ + *. ******* AUTOHEADER END v1.1 ******* */ #include diff --git a/src/setup-dbg.py b/src/setup-dbg.py index fe05898..1caac4d 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -2,7 +2,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode-dbg", - version = "2.10.6", + version = "3.10.6", description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", diff --git a/src/setup.py b/src/setup.py index c53dc17..7596cba 100644 --- a/src/setup.py +++ b/src/setup.py @@ -2,7 +2,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode", - version = "2.10.5", + version = "3.10.5", description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index d9827bd..d987802 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -1,3 +1,4 @@ + /* Converts XML docs and nodes to Python dicts and lists by * using an XML file which describes the Python dict layout * -- cgit From 1bd60ee4c38615f2f1aac873d95cde0e6fae7b1e Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 13:14:42 +1000 Subject: Fixed minor bug which prevented debug builds --- src/dmidecode.c | 4 ++-- src/dmidecodemodule.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 1f4dbd9..9a0baa8 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3960,7 +3960,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cores", NULL); - assert( cores_n != NULL ); + assert( sub_n != NULL ); if(data[0x23] != 0) { dmixml_AddTextChild(sub_n, "CoreCount", "%i", data[0x23]); @@ -3984,7 +3984,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ErrorCorrection", NULL); - assert( errc_n != NULL ); + assert( sub_n != NULL ); dmi_memory_controller_ed_method(sub_n, data[0x04]); dmi_memory_controller_ec_capabilities(sub_n, "Capabilities", data[0x05]); diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 2ebc5d0..34a2bad 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -21,6 +21,8 @@ #include "dmihelper.h" +xmlNode *dmidecode_set_version(void); + //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern void dmi_dump(xmlNode *node, struct dmi_header *h); extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); -- cgit From 3acedf5a988eab36f238979548cc79545bd7dced Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 13:24:02 +1000 Subject: Final cleanup --- src/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/setup.py b/src/setup.py index 7596cba..8c6fb03 100644 --- a/src/setup.py +++ b/src/setup.py @@ -2,7 +2,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode", - version = "3.10.5", + version = "3.10.6", description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", -- cgit From 90c5bac90b3366b897d7c34a4bba2a31e608b62c Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 13:53:28 +1000 Subject: Updating Debian-specifics --- src/setup-dbg.py | 5 +++-- src/setup.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 1caac4d..8b66f21 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -3,6 +3,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode-dbg", version = "3.10.6", + license='GPL-2', description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", @@ -20,9 +21,9 @@ setup( "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], - #library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], libraries = [ "util", "xml2" ], - #libraries = [ "util", "efence" ], + #libraries = [ "util", "xml2", "efence" ], + data_files = [ ('share/python-dmidecode', ['src/pythonmap.xml']) ] ) ] ) diff --git a/src/setup.py b/src/setup.py index 8c6fb03..ded7db4 100644 --- a/src/setup.py +++ b/src/setup.py @@ -3,6 +3,7 @@ from distutils.core import setup, Extension setup( name = "python-dmidecode", version = "3.10.6", + license='GPL-2', description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", @@ -22,7 +23,7 @@ setup( include_dirs = [ "/usr/include/libxml2" ], library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], libraries = [ "util", "xml2" ], - #libraries = [ "util", "efence" ], + data_files = [ ('share/python-dmidecode', ['src/pythonmap.xml']) ] ) ] ) -- cgit From a18a72fab2a622077d5257003b09be30ab283339 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 14:37:01 +1000 Subject: More cleanup Don't write to stdout unless in debug mode (with respect to writing to memory devices. Added the xml datafile to setup (distutils). Updated test case (incorporating color and cleaning up tests). --- src/dmidecode.c | 6 ++++++ src/dmidecodemodule.c | 2 +- src/setup-dbg.py | 5 ++--- src/setup.py | 4 ++-- src/xmlpythonizer.c | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 9a0baa8..de6fb2a 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4931,7 +4931,9 @@ int dumpling(u8 * buf, const char *dumpfile, u8 mode) if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { //. Part 1. +#ifdef NDEBUG printf("# Writing %d bytes to %s.\n", len, dumpfile); +#endif write_dump(32, len, buff, dumpfile, 0); free(buff); @@ -4941,14 +4943,18 @@ int dumpling(u8 * buf, const char *dumpfile, u8 mode) memcpy(crafted, buf, 32); overwrite_dmi_address(crafted + 0x10); +#ifdef NDEBUG printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); +#endif write_dump(0, crafted[0x05], crafted, dumpfile, 1); } else { u8 crafted[16]; memcpy(crafted, buf, 16); overwrite_dmi_address(crafted); +#ifdef NDEBUG printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); +#endif write_dump(0, 0x0F, crafted, dumpfile, 1); } } else { diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 20739a1..1b56837 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -488,7 +488,7 @@ PyMODINIT_FUNC initdmidecode(void) module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, "Python extension module for dmidecode"); - version = PyString_FromString("2.10"); + version = PyString_FromString("3.10.6"); Py_INCREF(version); PyModule_AddObject(module, "version", version); diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 8b66f21..0b7a2ed 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -8,6 +8,7 @@ setup( author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", url = "http://projects.autonomy.net.au/python-dmidecode/", + data_files = [ ('share/python-dmidecode-dbg', ['src/pythonmap.xml']) ], ext_modules = [ Extension( "dmidecode", @@ -21,9 +22,7 @@ setup( "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], - libraries = [ "util", "xml2" ], - #libraries = [ "util", "xml2", "efence" ], - data_files = [ ('share/python-dmidecode', ['src/pythonmap.xml']) ] + libraries = [ "util", "xml2" ], #[ "util", "xml2", "efence" ], ) ] ) diff --git a/src/setup.py b/src/setup.py index ded7db4..f9904af 100644 --- a/src/setup.py +++ b/src/setup.py @@ -8,6 +8,7 @@ setup( author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", url = "http://projects.autonomy.net.au/python-dmidecode/", + data_files = [ ('share/python-dmidecode', ['src/pythonmap.xml']) ], ext_modules = [ Extension( "dmidecode", @@ -22,8 +23,7 @@ setup( ], include_dirs = [ "/usr/include/libxml2" ], library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], - libraries = [ "util", "xml2" ], - data_files = [ ('share/python-dmidecode', ['src/pythonmap.xml']) ] + libraries = [ "util", "xml2" ] ) ] ) diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index d987802..dceeaa2 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -880,7 +880,7 @@ PyMODINIT_FUNC initxmlpythonizer(void) { Py_InitModule3((char *)"xmlpythonizer", DemoMethods, "XML to Python Proof-of-Concept Python Module"); - PyObject *version = PyString_FromString("2.10"); + PyObject *version = PyString_FromString("3.10.6"); Py_INCREF(version); PyModule_AddObject(module, "version", version); } -- cgit From f17fca75b0766caeba992bd62ab9c87cc6a79acc Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 15:21:42 +1000 Subject: Completed test case Removed trailing spaces from xml data file. Commented out fprintf()s for now (Perhapse should add them to the debug build at least). --- src/pythonmap.xml | 2 +- src/xmlpythonizer.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index b2d2d31..f4f8336 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -288,7 +288,7 @@ - diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index dceeaa2..f1d755e 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -672,7 +672,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int char msg[8094]; snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", map_p->value, map_p->key, 0); - fprintf(stderr, msg); + //fprintf(stderr, msg); PyErr_SetString(PyExc_LookupError, msg); if( xpo != NULL ) { @@ -765,7 +765,7 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { char msg[8094]; snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", map_p->rootpath, map_p->key, 0); - fprintf(stderr, msg); + //fprintf(stderr, msg); PyErr_SetString(PyExc_LookupError, msg); if( xpo != NULL ) { -- cgit From 076bcc59efb4cb0cd0dd274d58f3706b2fd3aa13 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 23:01:56 +1000 Subject: Reimplementing support for the type() method - WIP --- src/typemap.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/typemap.xml (limited to 'src') diff --git a/src/typemap.xml b/src/typemap.xml new file mode 100644 index 0000000..9e45931 --- /dev/null +++ b/src/typemap.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + -- cgit From 6b1598c8b98699b115525155b43d19365e79dd08 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 23 May 2009 23:02:46 +1000 Subject: Reimplementing the type() function - WIP --- src/config.h | 4 ++++ src/util.c | 9 +++++++++ src/util.h | 1 + src/xmlpythonizer.c | 21 +++++++++++++++------ 4 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index a2e7e58..8eb38ad 100644 --- a/src/config.h +++ b/src/config.h @@ -27,4 +27,8 @@ #define PYTHON_XML_MAP "/usr/share/python-dmidecode/pythonmap.xml" #endif +#ifndef PYTHON_XML_TYPEMAP +#define PYTHON_XML_TYPEMAP "/usr/share/python-dmidecode/typemap.xml" +#endif + #endif diff --git a/src/util.c b/src/util.c index d9ac510..58fd5ec 100644 --- a/src/util.c +++ b/src/util.c @@ -189,3 +189,12 @@ int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, fclose(f); return -1; } + +int is_int(const char *s) +{ + char _s[3]; + snprintf(_s, 3, "%ld", strtol(s, (char **)NULL, 10)); + return !strcmp(s, _s); +} + + diff --git a/src/util.h b/src/util.h index 3effd0c..e216566 100644 --- a/src/util.h +++ b/src/util.h @@ -28,3 +28,4 @@ int checksum(const u8 * buf, size_t len); void *mem_chunk(size_t base, size_t len, const char *devmem); int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add); +int is_int(const char *s); diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index f1d755e..ea78b94 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -35,6 +35,7 @@ #include #include +#include "util.h" #include "dmixml.h" #include "xmlpythonizer.h" @@ -338,14 +339,22 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { return NULL; } - // Find the section matching our request (mapname) - for( node = node->children->next; node != NULL; node = node->next ) { - if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { - char *name = dmixml_GetAttrValue(node, "name"); - if( (name != NULL) && (strcmp(name, mapname) == 0) ) { - break; + if(!is_int(mapname)) { + // Find the section matching our request (mapname) + for( node = node->children->next; node != NULL; node = node->next ) { + if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { + char *name = dmixml_GetAttrValue(node, "name"); + if( (name != NULL) && (strcmp(name, mapname) == 0) ) { + break; + } } } + } else { + //. FIXME + char msg[8194]; + snprintf(msg, 8193, "Not (yet) implemented%c", 0); + PyErr_SetString(PyExc_SystemError, msg); + return NULL; } if( node == NULL ) { -- cgit From af27ba4dd2ffdef8e4ee3abf187475c1b3303f71 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 00:26:23 +1000 Subject: Completed preliminary reimplementation of type() Updated test unit to match. Throw an exception instead of returning None/False in some functions. --- src/dmidecodemodule.c | 14 ++++++++++++-- src/dmixml.c | 30 ++++++++++++++++++++++++++++++ src/dmixml.h | 1 + src/util.c | 7 ++++--- src/util.h | 2 +- src/xmlpythonizer.c | 35 +++++++++++++++++++++-------------- 6 files changed, 69 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 1b56837..82f2de7 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -360,6 +360,8 @@ static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { long unsigned int lu; + char msg[8194]; + int e = 0; if(PyArg_ParseTuple(args, (char *)"i", &lu)) { if(lu < 256) { @@ -368,9 +370,17 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) sprintf(s, "%lu", lu); return dmidecode_get(self, s); } - return Py_False; + e = 1; + //return Py_False; } - return Py_None; + e = 2; + //return Py_None; + + if(e == 1) snprintf(msg, 8193, "Types are bound between 0 and 255 (inclusive)%c", 0); + else snprintf(msg, 8193, "Invalid type identifier%c", 0); + + PyErr_SetString(PyExc_SystemError, msg); + return NULL; } static PyObject *dmidecode_dump(PyObject * self, PyObject * null) diff --git a/src/dmixml.c b/src/dmixml.c index dbca0c3..f98c338 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -179,6 +179,36 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key) { return NULL; } +xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *key, const char *val) { + xmlNode *ptr_n = NULL; + xmlChar *key_s = NULL; + xmlChar *val_s = NULL; + xmlChar *_val_s = NULL; + + if( node->children == NULL ) { + return NULL; + } + + key_s = xmlCharStrdup(key); + assert( key_s != NULL ); + val_s = xmlCharStrdup(val); + assert( val_s != NULL ); + + for( ptr_n = node->children; ptr_n != NULL; ptr_n = ptr_n->next ) { + _val_s = xmlCharStrdup(dmixml_GetAttrValue(ptr_n, (const char *)key_s)); + if( (ptr_n->type == XML_ELEMENT_NODE) + && (xmlStrcmp(val_s, _val_s) == 0) ) { + free(val_s); val_s = NULL; + free(key_s); key_s = NULL; + return ptr_n; + } + free(_val_s); + } + free(key_s); key_s = NULL; + free(val_s); val_s = NULL; + return NULL; +} + xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { xmlNode *ptr_n = NULL; xmlChar *key_s = NULL; diff --git a/src/dmixml.h b/src/dmixml.h index b1d86c6..b1ca6d9 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -35,6 +35,7 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); char *dmixml_GetAttrValue(xmlNode *node, const char *key); +xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *key, const char *val); xmlNode *dmixml_FindNode(xmlNode *, const char *key); inline char *dmixml_GetContent(xmlNode *node); inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); diff --git a/src/util.c b/src/util.c index 58fd5ec..45bbd98 100644 --- a/src/util.c +++ b/src/util.c @@ -190,11 +190,12 @@ int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, return -1; } -int is_int(const char *s) +long is_int(const char *s) { + long i = strtol(s, (char **)NULL, 10); char _s[3]; - snprintf(_s, 3, "%ld", strtol(s, (char **)NULL, 10)); - return !strcmp(s, _s); + snprintf(_s, 3, "%ld", i); + return strcmp(s, _s)==0 ? i : -1; } diff --git a/src/util.h b/src/util.h index e216566..b95bbeb 100644 --- a/src/util.h +++ b/src/util.h @@ -28,4 +28,4 @@ int checksum(const u8 * buf, size_t len); void *mem_chunk(size_t base, size_t len, const char *devmem); int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add); -int is_int(const char *s); +long is_int(const char *s); diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index ea78b94..836e4da 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -339,22 +339,29 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { return NULL; } - if(!is_int(mapname)) { - // Find the section matching our request (mapname) - for( node = node->children->next; node != NULL; node = node->next ) { - if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { - char *name = dmixml_GetAttrValue(node, "name"); - if( (name != NULL) && (strcmp(name, mapname) == 0) ) { - break; - } + int type_id = is_int(mapname); + if(type_id > -1) { + //FIXME + char *python_xml_typemap = strdup(PYTHON_XML_TYPEMAP); + xmlDoc *typemappingxml = xmlReadFile(python_xml_typemap, NULL, 0); + xmlNode *node = xmlDocGetRootElement(typemappingxml); + xmlNode *wally; + char type_id_hex[5]; + snprintf(type_id_hex, 5, "0x%02x", type_id); + wally = dmixml_FindNodeByAttr(node, "id", type_id_hex); + if(wally) { + mapname = dmixml_GetAttrValue(wally, "value"); + } + } + + // Find the section matching our request (mapname) + for( node = node->children->next; node != NULL; node = node->next ) { + if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { + char *name = dmixml_GetAttrValue(node, "name"); + if( (name != NULL) && (strcmp(name, mapname) == 0) ) { + break; } } - } else { - //. FIXME - char msg[8194]; - snprintf(msg, 8193, "Not (yet) implemented%c", 0); - PyErr_SetString(PyExc_SystemError, msg); - return NULL; } if( node == NULL ) { -- cgit From 6b21c755269a80f3988259157d47430f491448be Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 02:17:21 +1000 Subject: Broken commit - change in XML mapping design Rather than hardcoding the data by function name (e.g. system, bios, connector, slot, etc), create each `type' as an individual XML tree, then group them under user-friendly names (as per the function names). Here the `pythonmap.xml' groups (but does not define) the various types (0..255), the types themselves are however defined in `typemap.xml'. This commit is broken, and a WIP. --- src/pythonmap.xml | 303 +++------------------------------------------- src/typemap.xml | 342 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/xmlpythonizer.c | 25 ++-- 3 files changed, 358 insertions(+), 312 deletions(-) (limited to 'src') diff --git a/src/pythonmap.xml b/src/pythonmap.xml index f4f8336..fce89fc 100644 --- a/src/pythonmap.xml +++ b/src/pythonmap.xml @@ -1,323 +1,54 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + + diff --git a/src/typemap.xml b/src/typemap.xml index 9e45931..20866da 100644 --- a/src/typemap.xml +++ b/src/typemap.xml @@ -1,21 +1,327 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 836e4da..11766b0 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -256,6 +256,7 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { // Get the attributes defining key, keytype, value and valuetype key = dmixml_GetAttrValue(ptr_n, "key"); type_key = _convert_maptype(dmixml_GetAttrValue(ptr_n, "keytype")); +fprintf(stderr, "%s\n", key); value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); @@ -352,14 +353,22 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { if(wally) { mapname = dmixml_GetAttrValue(wally, "value"); } - } - - // Find the section matching our request (mapname) - for( node = node->children->next; node != NULL; node = node->next ) { - if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { - char *name = dmixml_GetAttrValue(node, "name"); - if( (name != NULL) && (strcmp(name, mapname) == 0) ) { - break; + for( node = node->children->next; node != NULL; node = node->next ) { + if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { + char *name = dmixml_GetAttrValue(node, "name"); + if( (name != NULL) && (strcmp(name, mapname) == 0) ) { + break; + } + } + } + } else { + // Find the section matching our request (mapname) + for( node = node->children->next; node != NULL; node = node->next ) { + if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { + char *name = dmixml_GetAttrValue(node, "name"); + if( (name != NULL) && (strcmp(name, mapname) == 0) ) { + break; + } } } } -- cgit From cf468c3ceaf268da0ba17286bef85e4bdafcbc7e Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 03:45:10 +1000 Subject: Loading in the new the new `type' XML file --- src/dmidecodemodule.c | 11 ++++++++++- src/dmihelper.h | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 82f2de7..db780f3 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -61,8 +61,10 @@ static void init(void) opt.flags = 0; opt.type = NULL; opt.mappingxml = NULL; + opt.typemappingxml = NULL; opt.dmiversion_n = NULL; opt.python_xml_map = strdup(PYTHON_XML_MAP); + opt.python_xml_typemap = strdup(PYTHON_XML_TYPEMAP); } u8 *parse_opt_type(u8 * p, const char *arg) @@ -296,7 +298,14 @@ static PyObject *dmidecode_get(PyObject *self, const char *section) assert( opt.mappingxml != NULL ); } - mapping = dmiMAP_ParseMappingXML(opt.mappingxml, section); + if( opt.typemappingxml == NULL ) { + // Load mapping into memory + opt.typemappingxml = xmlReadFile(opt.python_xml_typemap, NULL, 0); + assert( opt.typemappingxml != NULL ); + } + + + mapping = dmiMAP_ParseMappingXML(opt.mappingxml, opt.typemappingxml, section); if( mapping == NULL ) { return NULL; } diff --git a/src/dmihelper.h b/src/dmihelper.h index 33da699..57ad7ab 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -113,9 +113,11 @@ typedef struct _options { u8 *type; const struct string_keyword *string; xmlDoc *mappingxml; + xmlDoc *typemappingxml; + char *python_xml_map; + char *python_xml_typemap; xmlNode *dmiversion_n; PyObject *dumpfile; - char *python_xml_map; } options; extern options opt; -- cgit From 1319dc584c7bc5f95b657a3c5171bdd582a3d940 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 03:45:54 +1000 Subject: Return earlier when possible --- src/dmixml.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index f98c338..27e5f3f 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -180,15 +180,15 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key) { } xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *key, const char *val) { + if( node->children == NULL ) { + return NULL; + } + xmlNode *ptr_n = NULL; xmlChar *key_s = NULL; xmlChar *val_s = NULL; xmlChar *_val_s = NULL; - if( node->children == NULL ) { - return NULL; - } - key_s = xmlCharStrdup(key); assert( key_s != NULL ); val_s = xmlCharStrdup(val); -- cgit From e5a38d8131071d302a1cce0cace50f14f7f643b5 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 03:47:49 +1000 Subject: Autoheadered --- src/xmlpythonizer.c | 155 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 113 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 11766b0..3099e5d 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -1,9 +1,44 @@ +/*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* + *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et + *. + *. © 2009 David Sommerseth + *. © 2007-2009 Nima Talebi + *. + *. This file is part of Python DMI-Decode. + *. + *. Python DMI-Decode is free software: you can redistribute it and/or modify + *. it under the terms of the GNU General Public License as published by + *. the Free Software Foundation, either version 2 of the License, or + *. (at your option) any later version. + *. + *. Python DMI-Decode 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 General Public License + *. along with Python DMI-Decode. If not, see . + *. + *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *. + *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY + *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE. + *. + *. $AutoHeaderSerial::20090522 $ + *. ******* AUTOHEADER END v1.1 ******* */ /* Converts XML docs and nodes to Python dicts and lists by * using an XML file which describes the Python dict layout * - * Copyright 2009 David Sommerseth - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -219,8 +254,8 @@ inline ptzTYPES _convert_maptype(const char *str) { } } -// Internal parser -ptzMAP *_do_dmimap_parsing(xmlNode *node) { +// Internal parser - SubMapper (Individual Types of a Group) +ptzMAP *_do_dmitypemap_parsing(xmlNode *node) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL;; @@ -256,7 +291,6 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { // Get the attributes defining key, keytype, value and valuetype key = dmixml_GetAttrValue(ptr_n, "key"); type_key = _convert_maptype(dmixml_GetAttrValue(ptr_n, "keytype")); -fprintf(stderr, "%s\n", key); value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); @@ -278,7 +312,7 @@ fprintf(stderr, "%s\n", key); // Recursion retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, (type_value == ptzLIST_DICT ? value : NULL), - _do_dmimap_parsing(ptr_n->children->next)); + _do_dmitypemap_parsing(ptr_n->children->next)); } else { char *tmpstr = NULL; @@ -318,50 +352,89 @@ fprintf(stderr, "%s\n", key); return retmap; } -// Main parser function for the mapping XML -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { - ptzMAP *map = NULL; - xmlNode *node = NULL; - - // Find the root tag and locate our mapping - node = xmlDocGetRootElement(xmlmap); - assert( node != NULL ); +// Internal parser - Mapper (Groups of Types) +ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap, xmlDoc *xmltypemap) { + ptzMAP *retmap = NULL; + xmlNode *ptr_n = NULL, *map_n = NULL;; - // Verify that the root node got the right name - if( (node == NULL) - || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { - PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + // Go to the next XML_ELEMENT_NODE + for( map_n = node; map_n != NULL; map_n = map_n->next ) { + if( map_n->type == XML_ELEMENT_NODE ) { + break; + } + } + if( map_n == NULL ) { return NULL; } - // Verify that it's of a version we support - if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); - return NULL; + // Go to the first node + if( xmlStrcmp(node->name, (xmlChar *) "TypeMap") != 0 ) { + map_n = dmixml_FindNode(node, "TypeMap"); + if( map_n == NULL ) { + return NULL; + } } + // Loop through it's children + xmlNode *typemap = xmlDocGetRootElement(xmltypemap); + assert( typemap != NULL ); + for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { + char *type_id = NULL; + type_id = dmixml_GetAttrValue(ptr_n, "id"); + map_n = dmixml_FindNodeByAttr(typemap, "id", type_id); + retmap = _do_dmitypemap_parsing(map_n); + break; + } + return retmap; +} + + + +// Main parser function for the mapping XML +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *mapname) { + ptzMAP *map = NULL; + xmlNode *node = NULL; + int type_id = is_int(mapname); if(type_id > -1) { - //FIXME - char *python_xml_typemap = strdup(PYTHON_XML_TYPEMAP); - xmlDoc *typemappingxml = xmlReadFile(python_xml_typemap, NULL, 0); - xmlNode *node = xmlDocGetRootElement(typemappingxml); - xmlNode *wally; + // Find the root tag and locate our mapping + node = xmlDocGetRootElement(xmltypemap); + assert( node != NULL ); + + // Verify that the root node got the right name + if( (node == NULL) + || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_typemap") != 0 )) { + PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + return NULL; + } + + // Verify that it's of a version we support + if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { + PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + return NULL; + } + char type_id_hex[5]; snprintf(type_id_hex, 5, "0x%02x", type_id); - wally = dmixml_FindNodeByAttr(node, "id", type_id_hex); - if(wally) { - mapname = dmixml_GetAttrValue(wally, "value"); + node = dmixml_FindNodeByAttr(node, "id", type_id_hex); + } else { + // Find the root tag and locate our mapping + node = xmlDocGetRootElement(xmlmap); + assert( node != NULL ); + + // Verify that the root node got the right name + if( (node == NULL) + || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { + PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + return NULL; } - for( node = node->children->next; node != NULL; node = node->next ) { - if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { - char *name = dmixml_GetAttrValue(node, "name"); - if( (name != NULL) && (strcmp(name, mapname) == 0) ) { - break; - } - } + + // Verify that it's of a version we support + if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { + PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + return NULL; } - } else { + // Find the section matching our request (mapname) for( node = node->children->next; node != NULL; node = node->next ) { if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { @@ -382,7 +455,7 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { } // Start creating an internal map structure based on the mapping XML. - map = _do_dmimap_parsing(node); + map = (type_id == -1) ? _do_dmimap_parsing(node, xmlmap, xmltypemap) : _do_dmitypemap_parsing(node); return map; } @@ -697,7 +770,6 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int char msg[8094]; snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", map_p->value, map_p->key, 0); - //fprintf(stderr, msg); PyErr_SetString(PyExc_LookupError, msg); if( xpo != NULL ) { @@ -787,10 +859,9 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xpo = _get_xpath_values(xpctx, map_p->rootpath); if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { - char msg[8094]; + char msg[8094]; //XXX snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", map_p->rootpath, map_p->key, 0); - //fprintf(stderr, msg); PyErr_SetString(PyExc_LookupError, msg); if( xpo != NULL ) { -- cgit From 6836d6806f56d83535cf4708907d30b4e56a6974 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 03:48:08 +1000 Subject: Update header file for new function declaration --- src/xmlpythonizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index e659340..2f71dc8 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,7 +48,7 @@ typedef struct ptzMAP_s { } ptzMAP; -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From a9426516a87d0eca3451e348dde22287935d9d5a Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 04:09:06 +1000 Subject: Renamed XML config files to better match code --- src/py-map.xml | 54 +++++++++ src/py-typemap.xml | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pythonmap.xml | 54 --------- src/typemap.xml | 327 ----------------------------------------------------- 4 files changed, 381 insertions(+), 381 deletions(-) create mode 100644 src/py-map.xml create mode 100644 src/py-typemap.xml delete mode 100644 src/pythonmap.xml delete mode 100644 src/typemap.xml (limited to 'src') diff --git a/src/py-map.xml b/src/py-map.xml new file mode 100644 index 0000000..fce89fc --- /dev/null +++ b/src/py-map.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/py-typemap.xml b/src/py-typemap.xml new file mode 100644 index 0000000..20866da --- /dev/null +++ b/src/py-typemap.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/pythonmap.xml b/src/pythonmap.xml deleted file mode 100644 index fce89fc..0000000 --- a/src/pythonmap.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/typemap.xml b/src/typemap.xml deleted file mode 100644 index 20866da..0000000 --- a/src/typemap.xml +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit From 64d2c31c902439eb0e62471fe97086bf217e7926 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 04:09:58 +1000 Subject: Follow-up on recent XML config file rename --- src/config.h | 4 ++-- src/setup-dbg.py | 2 +- src/setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index 8eb38ad..4fd5f41 100644 --- a/src/config.h +++ b/src/config.h @@ -24,11 +24,11 @@ #endif #ifndef PYTHON_XML_MAP -#define PYTHON_XML_MAP "/usr/share/python-dmidecode/pythonmap.xml" +#define PYTHON_XML_MAP "/usr/share/python-dmidecode/py-map.xml" #endif #ifndef PYTHON_XML_TYPEMAP -#define PYTHON_XML_TYPEMAP "/usr/share/python-dmidecode/typemap.xml" +#define PYTHON_XML_TYPEMAP "/usr/share/python-dmidecode/py-typemap.xml" #endif #endif diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 0b7a2ed..988c3f3 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -8,7 +8,7 @@ setup( author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", url = "http://projects.autonomy.net.au/python-dmidecode/", - data_files = [ ('share/python-dmidecode-dbg', ['src/pythonmap.xml']) ], + data_files = [ ('share/python-dmidecode-dbg', ['src/py-map.xml', 'src/py-typemap.xml']) ], ext_modules = [ Extension( "dmidecode", diff --git a/src/setup.py b/src/setup.py index f9904af..dde35eb 100644 --- a/src/setup.py +++ b/src/setup.py @@ -8,7 +8,7 @@ setup( author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", url = "http://projects.autonomy.net.au/python-dmidecode/", - data_files = [ ('share/python-dmidecode', ['src/pythonmap.xml']) ], + data_files = [ ('share/python-dmidecode', ['src/py-map.xml', 'src/py-typemap.xml']) ], ext_modules = [ Extension( "dmidecode", -- cgit From eaac9f1ef88c8c479829cdbec56b2a491b3e2da9 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 13:08:11 +1000 Subject: Added placeholder for most `type's In doing so, found and fixed a few mistakes in my previous commit. --- src/py-typemap.xml | 405 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 258 insertions(+), 147 deletions(-) (limited to 'src') diff --git a/src/py-typemap.xml b/src/py-typemap.xml index 20866da..0e08ee3 100644 --- a/src/py-typemap.xml +++ b/src/py-typemap.xml @@ -1,7 +1,14 @@ - + + + @@ -34,22 +41,62 @@ - - - + + + + + + - - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -92,80 +139,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + - + @@ -196,27 +178,91 @@ - - - + + + - - - - - - - - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -241,87 +287,152 @@ - - - + + + - + + + + + + - - - + + + + + + + + + + + + - - - + + + + + + - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From 3e7b0632d6522ff8e57dd685176d138eb16265e1 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 13:17:52 +1000 Subject: Small update, added FIXME tags and comments --- src/py-typemap.xml | 59 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/py-typemap.xml b/src/py-typemap.xml index 0e08ee3..b695948 100644 --- a/src/py-typemap.xml +++ b/src/py-typemap.xml @@ -2,10 +2,13 @@ @@ -139,11 +142,11 @@ - + - + @@ -234,11 +237,11 @@ - + - + @@ -257,7 +260,7 @@ - + @@ -339,59 +342,59 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -407,31 +410,31 @@ - + - + - + - + - + - + - + -- cgit From 13ff9d7e48ab1574b36473f75701cc7f7c1e461a Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 27 May 2009 00:11:54 +1000 Subject: WIP commit Merged the two XML files into one, and amended relevant code. I still want to modify the XML tag names, but not yet. The calls to dmidecode.type() not function as expected, but the others are broken - this is next. --- src/config.h | 6 +- src/dmidecodemodule.c | 69 +++---- src/dmihelper.h | 2 - src/py-map.xml | 54 ------ src/py-typemap.xml | 441 -------------------------------------------- src/pymap.xml | 495 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/setup-dbg.py | 2 +- src/setup.py | 2 +- src/xmlpythonizer.c | 70 ++++--- src/xmlpythonizer.h | 2 +- 10 files changed, 563 insertions(+), 580 deletions(-) delete mode 100644 src/py-map.xml delete mode 100644 src/py-typemap.xml create mode 100644 src/pymap.xml (limited to 'src') diff --git a/src/config.h b/src/config.h index 4fd5f41..add77cc 100644 --- a/src/config.h +++ b/src/config.h @@ -24,11 +24,7 @@ #endif #ifndef PYTHON_XML_MAP -#define PYTHON_XML_MAP "/usr/share/python-dmidecode/py-map.xml" -#endif - -#ifndef PYTHON_XML_TYPEMAP -#define PYTHON_XML_TYPEMAP "/usr/share/python-dmidecode/py-typemap.xml" +#define PYTHON_XML_MAP "/usr/share/python-dmidecode/pymap.xml" #endif #endif diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index db780f3..1b18f47 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -1,6 +1,6 @@ /*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* - *. vim: fileencoding=utf-8 syntax=c sw=2 ts=2 et + *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et *. *. © 2007-2009 Nima Talebi *. © 2009 David Sommerseth @@ -60,11 +60,9 @@ static void init(void) opt.dumpfile = NULL; opt.flags = 0; opt.type = NULL; - opt.mappingxml = NULL; - opt.typemappingxml = NULL; opt.dmiversion_n = NULL; + opt.mappingxml = NULL; opt.python_xml_map = strdup(PYTHON_XML_MAP); - opt.python_xml_typemap = strdup(PYTHON_XML_TYPEMAP); } u8 *parse_opt_type(u8 * p, const char *arg) @@ -191,8 +189,12 @@ xmlNode *dmidecode_set_version() return ver_n; } -xmlNode *dmidecode_get_xml(PyObject *self, const char *section) +int dmidecode_get_xml(xmlNode* dmixml_n) { + assert(dmixml_n != NULL); + if(dmixml_n == NULL) { + return 0; + } //mtrace(); int ret = 0; @@ -201,16 +203,7 @@ xmlNode *dmidecode_get_xml(PyObject *self, const char *section) int efi; u8 *buf; - xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); - assert( dmixml_n != NULL ); - - // Append DMI version info - if( opt.dmiversion_n != NULL ) { - xmlAddChild(dmixml_n, xmlCopyNode(opt.dmiversion_n, 1)); - } - const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; - if(access(f, R_OK) < 0) PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); @@ -263,16 +256,16 @@ xmlNode *dmidecode_get_xml(PyObject *self, const char *section) free(opt.type); if(ret == 0) { free(buf); - } else { + } /* else { TODO: Review this and if correctly commented out, then just delete it... xmlFreeNode(dmixml_n); dmixml_n = NULL; - } + }*/ //muntrace(); - return dmixml_n; + return ret; } -static PyObject *dmidecode_get(PyObject *self, const char *section) +static PyObject *dmidecode_get(const char *section) { PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; @@ -287,8 +280,14 @@ static PyObject *dmidecode_get(PyObject *self, const char *section) return NULL; } - dmixml_n = dmidecode_get_xml(self, section); - if( dmixml_n != NULL ) { + dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); + assert( dmixml_n != NULL ); + // Append DMI version info + if( opt.dmiversion_n != NULL ) { + xmlAddChild(dmixml_n, xmlCopyNode(opt.dmiversion_n, 1)); + } + + if(dmidecode_get_xml(dmixml_n) == 0) { ptzMAP *mapping = NULL; // Convert the retrieved XML nodes to Python dicts @@ -298,14 +297,7 @@ static PyObject *dmidecode_get(PyObject *self, const char *section) assert( opt.mappingxml != NULL ); } - if( opt.typemappingxml == NULL ) { - // Load mapping into memory - opt.typemappingxml = xmlReadFile(opt.python_xml_typemap, NULL, 0); - assert( opt.typemappingxml != NULL ); - } - - - mapping = dmiMAP_ParseMappingXML(opt.mappingxml, opt.typemappingxml, section); + mapping = dmiMAP_ParseMappingXML(opt.mappingxml, section); if( mapping == NULL ) { return NULL; } @@ -332,39 +324,39 @@ static PyObject *dmidecode_get(PyObject *self, const char *section) static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) { - return dmidecode_get(self, "bios"); + return dmidecode_get("bios"); } static PyObject *dmidecode_get_system(PyObject * self, PyObject * args) { - return dmidecode_get(self, "system"); + return dmidecode_get("system"); } static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args) { - return dmidecode_get(self, "baseboard"); + return dmidecode_get("baseboard"); } static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args) { - return dmidecode_get(self, "chassis"); + return dmidecode_get("chassis"); } static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args) { - return dmidecode_get(self, "processor"); + return dmidecode_get("processor"); } static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args) { - return dmidecode_get(self, "memory"); + return dmidecode_get("memory"); } static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args) { - return dmidecode_get(self, "cache"); + return dmidecode_get("cache"); } static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args) { - return dmidecode_get(self, "connector"); + return dmidecode_get("connector"); } static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) { - return dmidecode_get(self, "slot"); + return dmidecode_get("slot"); } static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { @@ -375,9 +367,8 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) if(PyArg_ParseTuple(args, (char *)"i", &lu)) { if(lu < 256) { char s[8]; - sprintf(s, "%lu", lu); - return dmidecode_get(self, s); + return dmidecode_get(s); } e = 1; //return Py_False; diff --git a/src/dmihelper.h b/src/dmihelper.h index 57ad7ab..82a936d 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -113,9 +113,7 @@ typedef struct _options { u8 *type; const struct string_keyword *string; xmlDoc *mappingxml; - xmlDoc *typemappingxml; char *python_xml_map; - char *python_xml_typemap; xmlNode *dmiversion_n; PyObject *dumpfile; } options; diff --git a/src/py-map.xml b/src/py-map.xml deleted file mode 100644 index fce89fc..0000000 --- a/src/py-map.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/py-typemap.xml b/src/py-typemap.xml deleted file mode 100644 index b695948..0000000 --- a/src/py-typemap.xml +++ /dev/null @@ -1,441 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/pymap.xml b/src/pymap.xml new file mode 100644 index 0000000..8619211 --- /dev/null +++ b/src/pymap.xml @@ -0,0 +1,495 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 988c3f3..e0a2358 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -8,7 +8,7 @@ setup( author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", url = "http://projects.autonomy.net.au/python-dmidecode/", - data_files = [ ('share/python-dmidecode-dbg', ['src/py-map.xml', 'src/py-typemap.xml']) ], + data_files = [ ('share/python-dmidecode-dbg', ['src/pymap.xml']) ], ext_modules = [ Extension( "dmidecode", diff --git a/src/setup.py b/src/setup.py index dde35eb..bb79a14 100644 --- a/src/setup.py +++ b/src/setup.py @@ -8,7 +8,7 @@ setup( author = "Nima Talebi & David Sommerseth", author_email = "nima@it.net.au, davids@redhat.com", url = "http://projects.autonomy.net.au/python-dmidecode/", - data_files = [ ('share/python-dmidecode', ['src/py-map.xml', 'src/py-typemap.xml']) ], + data_files = [ ('share/python-dmidecode', ['src/pymap.xml']) ], ext_modules = [ Extension( "dmidecode", diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 3099e5d..86bbb69 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -353,8 +353,9 @@ ptzMAP *_do_dmitypemap_parsing(xmlNode *node) { } // Internal parser - Mapper (Groups of Types) -ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap, xmlDoc *xmltypemap) { +ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap) { ptzMAP *retmap = NULL; + ptzMAP *tmp = NULL; xmlNode *ptr_n = NULL, *map_n = NULL;; // Go to the next XML_ELEMENT_NODE @@ -376,14 +377,21 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap, xmlDoc *xmltypemap) { } // Loop through it's children - xmlNode *typemap = xmlDocGetRootElement(xmltypemap); + xmlNode *typemap = xmlDocGetRootElement(xmlmap); assert( typemap != NULL ); + for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { char *type_id = NULL; + type_id = dmixml_GetAttrValue(ptr_n, "id"); map_n = dmixml_FindNodeByAttr(typemap, "id", type_id); - retmap = _do_dmitypemap_parsing(map_n); - break; + if( tmp != NULL) { + tmp->next = _do_dmitypemap_parsing(map_n); + tmp = tmp->next; + } else { + tmp = _do_dmitypemap_parsing(map_n); + retmap = tmp; + } } return retmap; } @@ -391,50 +399,40 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap, xmlDoc *xmltypemap) { // Main parser function for the mapping XML -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *mapname) { +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { ptzMAP *map = NULL; xmlNode *node = NULL; int type_id = is_int(mapname); - if(type_id > -1) { - // Find the root tag and locate our mapping - node = xmlDocGetRootElement(xmltypemap); - assert( node != NULL ); - // Verify that the root node got the right name - if( (node == NULL) - || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_typemap") != 0 )) { - PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); - return NULL; - } + // Find the root tag and locate our mapping + node = xmlDocGetRootElement(xmlmap); + assert( node != NULL ); - // Verify that it's of a version we support - if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); - return NULL; - } + // Verify that the root node got the right name + if( (node == NULL) + || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_mapping") != 0 )) { + PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + return NULL; + } + + // Verify that it's of a version we support + if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { + PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + return NULL; + } + + if(type_id > -1) { + node = dmixml_FindNode(node, "TypeMapping"); + assert( node != NULL ); char type_id_hex[5]; snprintf(type_id_hex, 5, "0x%02x", type_id); node = dmixml_FindNodeByAttr(node, "id", type_id_hex); } else { - // Find the root tag and locate our mapping - node = xmlDocGetRootElement(xmlmap); + node = dmixml_FindNode(node, "GroupMapping"); assert( node != NULL ); - // Verify that the root node got the right name - if( (node == NULL) - || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_fieldmap") != 0 )) { - PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); - return NULL; - } - - // Verify that it's of a version we support - if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); - return NULL; - } - // Find the section matching our request (mapname) for( node = node->children->next; node != NULL; node = node->next ) { if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { @@ -455,7 +453,7 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *m } // Start creating an internal map structure based on the mapping XML. - map = (type_id == -1) ? _do_dmimap_parsing(node, xmlmap, xmltypemap) : _do_dmitypemap_parsing(node); + map = (type_id == -1) ? _do_dmimap_parsing(node, xmlmap) : _do_dmitypemap_parsing(node); return map; } diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 2f71dc8..e659340 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,7 +48,7 @@ typedef struct ptzMAP_s { } ptzMAP; -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From 81f781c18d59fa5ec822136f9469fd5b6881ca2a Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 27 May 2009 12:33:51 +1000 Subject: Fixed WIP from last night (with notes) Note that this will not work as expected for `group mappings' that have unimplemented `type maps', and this is because the linked-list chain will ne broken at the first unimplemented `type map' There is no reason to code a workaround for this as the type do have to be implemented eventually, and hence added code will merely be noise. --- src/xmlpythonizer.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 86bbb69..34f6947 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -349,6 +349,7 @@ ptzMAP *_do_dmitypemap_parsing(xmlNode *node) { value = NULL; key = NULL; } + return retmap; } @@ -377,20 +378,23 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap) { } // Loop through it's children - xmlNode *typemap = xmlDocGetRootElement(xmlmap); + xmlNode *typemap = dmixml_FindNode(xmlDocGetRootElement(xmlmap), "TypeMapping"); assert( typemap != NULL ); + char *type_id; for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { - char *type_id = NULL; - + //. TODO: Dazo: I had to add this (if() statement), but not sure why I should need to + //. TODO: Needs investigation... type_id = dmixml_GetAttrValue(ptr_n, "id"); - map_n = dmixml_FindNodeByAttr(typemap, "id", type_id); - if( tmp != NULL) { - tmp->next = _do_dmitypemap_parsing(map_n); - tmp = tmp->next; - } else { - tmp = _do_dmitypemap_parsing(map_n); - retmap = tmp; + if(type_id) { + map_n = dmixml_FindNodeByAttr(typemap, "id", type_id); + if( tmp != NULL) { + tmp->next = _do_dmitypemap_parsing(map_n); + tmp = tmp->next; + } else { + retmap = _do_dmitypemap_parsing(map_n); + tmp = retmap; + } } } return retmap; @@ -766,7 +770,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int xpo = _get_xpath_values(xpctx, map_p->value); if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { char msg[8094]; - snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", + snprintf(msg, 8092, "Could not locate XML path node (e1): %s (Defining key: %s)%c", map_p->value, map_p->key, 0); PyErr_SetString(PyExc_LookupError, msg); @@ -858,7 +862,7 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xpo = _get_xpath_values(xpctx, map_p->rootpath); if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { char msg[8094]; //XXX - snprintf(msg, 8092, "Could not locate XML path node: %s (Defining key: %s)%c", + snprintf(msg, 8092, "Could not locate XML path node (e2): %s (Defining key: %s)%c", map_p->rootpath, map_p->key, 0); PyErr_SetString(PyExc_LookupError, msg); -- cgit From 9c5a1096acfbca059542c905b45860f17c08a619 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 27 May 2009 10:06:09 +0200 Subject: Removed unneeded section (already commented out) --- src/dmidecodemodule.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 1b18f47..6ed7fc5 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -256,11 +256,7 @@ int dmidecode_get_xml(xmlNode* dmixml_n) free(opt.type); if(ret == 0) { free(buf); - } /* else { TODO: Review this and if correctly commented out, then just delete it... - xmlFreeNode(dmixml_n); - dmixml_n = NULL; - }*/ - + } //muntrace(); return ret; } -- cgit From 033bd9e5008120546f8d6c973376e848f7a67f00 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 29 May 2009 18:00:13 +0200 Subject: Added a simple helper macro to simplify xmlNode traversing --- src/dmixml.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/dmixml.h b/src/dmixml.h index b1ca6d9..f394137 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -30,6 +30,8 @@ #include #include +#define foreach_xmlnode(n, itn) for( itn = n; itn != NULL; itn = itn->next ) + xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); -- cgit From 7e1ef7e718976c6a0ab92c01990a130203860ff5 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Jun 2009 15:46:37 +0200 Subject: Rewrote dmixml_FindNodeByAttr(...) function to also use TagName The previous version did not consider the tag name when searching for nodes. --- src/dmixml.c | 38 ++++++++++++++++++-------------------- src/dmixml.h | 2 +- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 27e5f3f..de79d99 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -31,6 +31,8 @@ #include #include +#include "dmixml.h" + // Internal function for dmixml_* functions ... builds up a variable xmlChar* string xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) { xmlChar *ret = NULL, *xmlfmt = NULL; @@ -179,34 +181,30 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key) { return NULL; } -xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *key, const char *val) { +xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey, const char *val) { + xmlNode *ptr_n = NULL; + xmlChar *tag_s = NULL; + + assert( node != NULL ); if( node->children == NULL ) { return NULL; } - xmlNode *ptr_n = NULL; - xmlChar *key_s = NULL; - xmlChar *val_s = NULL; - xmlChar *_val_s = NULL; - - key_s = xmlCharStrdup(key); - assert( key_s != NULL ); - val_s = xmlCharStrdup(val); - assert( val_s != NULL ); + tag_s = xmlCharStrdup(tagkey); + assert( tag_s != NULL ); - for( ptr_n = node->children; ptr_n != NULL; ptr_n = ptr_n->next ) { - _val_s = xmlCharStrdup(dmixml_GetAttrValue(ptr_n, (const char *)key_s)); + foreach_xmlnode(node->children, ptr_n) { + // To return the correct node, we need to check node type, + // tag name and the attribute value of the given attribute. if( (ptr_n->type == XML_ELEMENT_NODE) - && (xmlStrcmp(val_s, _val_s) == 0) ) { - free(val_s); val_s = NULL; - free(key_s); key_s = NULL; - return ptr_n; + && (xmlStrcmp(ptr_n->name, tag_s) == 0) + && (strcmp(dmixml_GetAttrValue(ptr_n, attrkey), val) == 0 ) ) { + goto exit; } - free(_val_s); } - free(key_s); key_s = NULL; - free(val_s); val_s = NULL; - return NULL; + exit: + free(tag_s); tag_s = NULL; + return ptr_n; } xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { diff --git a/src/dmixml.h b/src/dmixml.h index f394137..c78d8b0 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -37,7 +37,7 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); char *dmixml_GetAttrValue(xmlNode *node, const char *key); -xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *key, const char *val); +xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey, const char *val); xmlNode *dmixml_FindNode(xmlNode *, const char *key); inline char *dmixml_GetContent(xmlNode *node); inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); -- cgit From 3149fdcec94191102fd801c7967a5e3cb5b330a7 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Jun 2009 15:40:57 +0200 Subject: Rewrote the dmiMAP_ParseMappingXML(...) function and split it up Removed the automagic in the dmiMAP_ParseMappingXML(...) function from automatically decide what to parse (TypeMapping or GroupMapping). Introduced two new functions instead: - dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *name) Parses the XML mapping document, using the GroupMapping tags and building up a proper ptzMAP structure for all TypeMap defined in that group. - dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *typeid) Parses the XML mapping document, using only the TypeMapping section in th mapping document. Rewrote a lot of internal parts to reuse as much of the existing code as possible. --- src/xmlpythonizer.c | 199 ++++++++++++++++++++++++++++++++-------------------- src/xmlpythonizer.h | 3 +- 2 files changed, 124 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 34f6947..f1ecee7 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -74,6 +74,14 @@ #include "dmixml.h" #include "xmlpythonizer.h" + +ptzMAP *ptzmap_AppendMap(const ptzMAP *chain, ptzMAP *newmap) { + if( chain != NULL ) { + newmap->next = (ptzMAP *) chain; + } + return newmap; +} + ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, ptzTYPES ktyp, const char *key, ptzTYPES vtyp, const char *value, @@ -104,10 +112,7 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, ret->child = child; } - if( chain != NULL ) { - ret->next = (ptzMAP *) chain; - } - return ret; + return ptzmap_AppendMap(chain, ret); }; void ptzmap_SetFixedList(ptzMAP *map_p, const char *index, int size) { @@ -166,7 +171,7 @@ void ptzmap_Free_func(ptzMAP *ptr) } -#if 0 +#if 1 // DEBUG FUNCTIONS static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL", "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL", @@ -255,7 +260,7 @@ inline ptzTYPES _convert_maptype(const char *str) { } // Internal parser - SubMapper (Individual Types of a Group) -ptzMAP *_do_dmitypemap_parsing(xmlNode *node) { +ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL;; @@ -312,7 +317,7 @@ ptzMAP *_do_dmitypemap_parsing(xmlNode *node) { // Recursion retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, (type_value == ptzLIST_DICT ? value : NULL), - _do_dmitypemap_parsing(ptr_n->children->next)); + _do_dmimap_parsing_typeid(ptr_n->children->next)); } else { char *tmpstr = NULL; @@ -353,11 +358,70 @@ ptzMAP *_do_dmitypemap_parsing(xmlNode *node) { return retmap; } + +xmlNode *_dmiMAP_GetRootElement(xmlDoc *mapdoc) { + xmlNode *rootnode = NULL; + + // Find the root tag and locate our mapping + rootnode = xmlDocGetRootElement(mapdoc); + assert( rootnode != NULL ); + + // Verify that the root node got the right name + if( (rootnode == NULL) + || (xmlStrcmp(rootnode->name, (xmlChar *) "dmidecode_mapping") != 0 )) { + PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); + return NULL; + } + + // Verify that it's of a version we support + if( strcmp(dmixml_GetAttrValue(rootnode, "version"), "1") != 0 ) { + PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + return NULL; + } + return rootnode; +} + + +ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) { + xmlNode *node = NULL; + + assert( mapnode != NULL); + + // Find the tag with our type ID + node = dmixml_FindNodeByAttr(mapnode, "TypeMap", "id", typeid); + if( node == NULL ) { + char msg[8194]; + snprintf(msg, 8193, "No mapping for type ID '%s' was found " + "in the XML-Python mapping file%c", typeid, 0); + PyErr_SetString(PyExc_IOError, msg); + return NULL; + } + // Create an internal map structure and return this structure + return _do_dmimap_parsing_typeid(node); +} + + +// Main parser function for the mapping XML +ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname) { + xmlNode *node = NULL; + + node = _dmiMAP_GetRootElement(xmlmap); + if( node == NULL ) { + return NULL; + } + + // Find the section + node = dmixml_FindNode(node, "TypeMapping"); + assert( node != NULL ); + return _dmimap_parse_mapping_node_typeid(node, mapname); +} + + // Internal parser - Mapper (Groups of Types) -ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap) { +ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { ptzMAP *retmap = NULL; - ptzMAP *tmp = NULL; - xmlNode *ptr_n = NULL, *map_n = NULL;; + xmlNode *ptr_n = NULL, *map_n = NULL, *typemap = NULL; + char *type_id; // Go to the next XML_ELEMENT_NODE for( map_n = node; map_n != NULL; map_n = map_n->next ) { @@ -366,34 +430,43 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap) { } } if( map_n == NULL ) { + PyErr_SetString(PyExc_IOError, "Could not find any valid XML nodes"); return NULL; } - // Go to the first node - if( xmlStrcmp(node->name, (xmlChar *) "TypeMap") != 0 ) { - map_n = dmixml_FindNode(node, "TypeMap"); - if( map_n == NULL ) { - return NULL; - } + // Check that our "root" node is as expected + if( xmlStrcmp(node->name, (xmlChar *) "Mapping") != 0 ) { + PyErr_SetString(PyExc_IOError, "Could not find any valid XML nodes"); + return NULL; } - // Loop through it's children - xmlNode *typemap = dmixml_FindNode(xmlDocGetRootElement(xmlmap), "TypeMapping"); + // Go to the first node + map_n = dmixml_FindNode(node, "TypeMap"); + if( map_n == NULL ) { + return NULL; + } + + // Get the root element of the tag, needed for further parsing + typemap = dmixml_FindNode(xmlDocGetRootElement(xmlmap), "TypeMapping"); assert( typemap != NULL ); - char *type_id; + // Loop through it's children for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { //. TODO: Dazo: I had to add this (if() statement), but not sure why I should need to //. TODO: Needs investigation... - type_id = dmixml_GetAttrValue(ptr_n, "id"); - if(type_id) { - map_n = dmixml_FindNodeByAttr(typemap, "id", type_id); - if( tmp != NULL) { - tmp->next = _do_dmitypemap_parsing(map_n); - tmp = tmp->next; - } else { - retmap = _do_dmitypemap_parsing(map_n); - tmp = retmap; + + // Validate if we have the right node name + if( xmlStrcmp(ptr_n->name, (xmlChar *) "TypeMap") != 0 ) { + continue; // Skip unexpected tag names + } + + // Make sure that we have an id attribute before trying to locate that in th + if( (type_id = dmixml_GetAttrValue(ptr_n, "id")) != NULL) { + ptzMAP *map = NULL; + + map = _dmimap_parse_mapping_node_typeid(typemap, type_id); + if( map ) { + retmap = ptzmap_AppendMap(retmap, map); } } } @@ -401,68 +474,37 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node, xmlDoc *xmlmap) { } - // Main parser function for the mapping XML -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { - ptzMAP *map = NULL; +ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; - int type_id = is_int(mapname); - - // Find the root tag and locate our mapping - node = xmlDocGetRootElement(xmlmap); - assert( node != NULL ); - - // Verify that the root node got the right name - if( (node == NULL) - || (xmlStrcmp(node->name, (xmlChar *) "dmidecode_mapping") != 0 )) { - PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); - return NULL; - } - - // Verify that it's of a version we support - if( strcmp(dmixml_GetAttrValue(node, "version"), "1") != 0 ) { - PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); + // Validate the XML mapping document and get the root element + node = _dmiMAP_GetRootElement(xmlmap); + if( node == NULL ) { + PyErr_SetString(PyExc_IOError, "No valid mapping XML recieved"); return NULL; } - if(type_id > -1) { - node = dmixml_FindNode(node, "TypeMapping"); - assert( node != NULL ); - - char type_id_hex[5]; - snprintf(type_id_hex, 5, "0x%02x", type_id); - node = dmixml_FindNodeByAttr(node, "id", type_id_hex); - } else { - node = dmixml_FindNode(node, "GroupMapping"); - assert( node != NULL ); - - // Find the section matching our request (mapname) - for( node = node->children->next; node != NULL; node = node->next ) { - if( xmlStrcmp(node->name, (xmlChar *) "Mapping") == 0) { - char *name = dmixml_GetAttrValue(node, "name"); - if( (name != NULL) && (strcmp(name, mapname) == 0) ) { - break; - } - } - } - } + // Find the section + node = dmixml_FindNode(node, "GroupMapping"); + assert( node != NULL ); + // Find the section matching our request (mapname) + node = dmixml_FindNodeByAttr(node, "Mapping", "name", mapname); if( node == NULL ) { char msg[8194]; - snprintf(msg, 8193, "No mapping for '%s' was found " + snprintf(msg, 8193, "No group mapping for '%s' was found " "in the XML-Python mapping file%c", mapname, 0); PyErr_SetString(PyExc_IOError, msg); return NULL; } - // Start creating an internal map structure based on the mapping XML. - map = (type_id == -1) ? _do_dmimap_parsing(node, xmlmap) : _do_dmitypemap_parsing(node); - - return map; + // Create an internal map structure and return this structure + return _do_dmimap_parsing_group(node, xmlmap); } + // // Parser routines for converting XML data into Python structures // @@ -904,7 +946,7 @@ PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *doc) } -#if 0 +#if 1 // Simple independent main function - only for debugging int main(int argc, char **argv) { xmlDoc *doc = NULL, *data = NULL; @@ -913,18 +955,21 @@ int main(int argc, char **argv) { Py_Initialize(); - doc = xmlReadFile("pythonmap.xml", NULL, 0); + doc = xmlReadFile("pymap.xml", NULL, 0); assert( doc != NULL ); - map = dmiMAP_ParseMappingXML(doc, argv[1]); + // map = dmiMAP_ParseMappingXML_GroupName(doc, argv[1]); + map = dmiMAP_ParseMappingXML_TypeID(doc, argv[1]); ptzmap_Dump(map); printf("----------------------\n"); - + assert(map != NULL); data = xmlReadFile(argv[2], NULL, 0); assert( data != NULL ); pydat = pythonizeXMLdoc(map, data); + assert( pydat != NULL ); + Py_INCREF(pydat); printf("\n\n"); PyObject_Print(pydat, stdout, 0); diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index e659340..bda077e 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,7 +48,8 @@ typedef struct ptzMAP_s { } ptzMAP; -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From e99e3408206624facbb040d9006278848e1f0ead Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Jun 2009 15:49:30 +0200 Subject: Removed no longer needed function - is_int() This function did not work as expected and due to the rewrite of xmlpythonizer, this function is not longer needed. --- src/util.c | 9 --------- src/util.h | 1 - 2 files changed, 10 deletions(-) (limited to 'src') diff --git a/src/util.c b/src/util.c index 45bbd98..014b75d 100644 --- a/src/util.c +++ b/src/util.c @@ -190,12 +190,3 @@ int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, return -1; } -long is_int(const char *s) -{ - long i = strtol(s, (char **)NULL, 10); - char _s[3]; - snprintf(_s, 3, "%ld", i); - return strcmp(s, _s)==0 ? i : -1; -} - - diff --git a/src/util.h b/src/util.h index b95bbeb..3effd0c 100644 --- a/src/util.h +++ b/src/util.h @@ -28,4 +28,3 @@ int checksum(const u8 * buf, size_t len); void *mem_chunk(size_t base, size_t len, const char *devmem); int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add); -long is_int(const char *s); -- cgit From 4e39cec61e7434f4826533220bbe5870a4300baa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Jun 2009 16:17:52 +0200 Subject: Replaced all 'for' iterations on xmlNodes with 'foreach_xmlnode' --- src/xmlpythonizer.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index f1ecee7..3ba3e80 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -171,7 +171,7 @@ void ptzmap_Free_func(ptzMAP *ptr) } -#if 1 +#if 0 // DEBUG FUNCTIONS static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL", "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL", @@ -265,7 +265,7 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { xmlNode *ptr_n = NULL, *map_n = NULL;; // Go to the next XML_ELEMENT_NODE - for( map_n = node; map_n != NULL; map_n = map_n->next ) { + foreach_xmlnode(node, map_n) { if( map_n->type == XML_ELEMENT_NODE ) { break; } @@ -283,7 +283,7 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { } // Loop through it's children - for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { + foreach_xmlnode(map_n, ptr_n) { ptzTYPES type_key, type_value; char *key = NULL, *value = NULL; char *rootpath = NULL; @@ -424,7 +424,7 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { char *type_id; // Go to the next XML_ELEMENT_NODE - for( map_n = node; map_n != NULL; map_n = map_n->next ) { + foreach_xmlnode(node, map_n) { if( map_n->type == XML_ELEMENT_NODE ) { break; } @@ -451,7 +451,7 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { assert( typemap != NULL ); // Loop through it's children - for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { + foreach_xmlnode(map_n, ptr_n) { //. TODO: Dazo: I had to add this (if() statement), but not sure why I should need to //. TODO: Needs investigation... @@ -887,7 +887,7 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { // Loop through all configured elements retdata = PyDict_New(); - for( map_p = in_map; map_p != NULL; map_p = map_p->next ) { + foreach_xmlnode(in_map, map_p) { if( (map_p->type_value == ptzDICT) && (map_p->rootpath != NULL) ) { xmlXPathObject *xpo = NULL; int i; @@ -946,7 +946,7 @@ PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *doc) } -#if 1 +#if 0 // Simple independent main function - only for debugging int main(int argc, char **argv) { xmlDoc *doc = NULL, *data = NULL; @@ -958,8 +958,8 @@ int main(int argc, char **argv) { doc = xmlReadFile("pymap.xml", NULL, 0); assert( doc != NULL ); - // map = dmiMAP_ParseMappingXML_GroupName(doc, argv[1]); - map = dmiMAP_ParseMappingXML_TypeID(doc, argv[1]); + map = dmiMAP_ParseMappingXML_GroupName(doc, argv[1]); + // map = dmiMAP_ParseMappingXML_TypeID(doc, argv[1]); ptzmap_Dump(map); printf("----------------------\n"); assert(map != NULL); -- cgit From eb33e79cb5eae7da473347a4f79dc07d4e91ceff Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Jun 2009 19:47:44 +0200 Subject: Updated comments for all functions in xmlpythonizer.c in Doxygen format --- src/xmlpythonizer.c | 198 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 171 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 3ba3e80..74b7db3 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -60,6 +60,15 @@ * are deemed to be part of the source code. */ +/** + * @file xmlpythonizer.c + * @brief Generic parser for converting XML documents or XML nodes + * into Python Dictionaries + * @author David Sommerseth + * @author Nima Talebi + */ + + #include #include @@ -75,13 +84,37 @@ #include "xmlpythonizer.h" -ptzMAP *ptzmap_AppendMap(const ptzMAP *chain, ptzMAP *newmap) { +/** + * This functions appends a new ptzMAP structure to an already existing chain + * @author David Sommerseth + * @param ptzMAP* Pointer to the chain the new ptzMAP is to be appended + * @param ptzMAP* Pointer to the new ptzMAP to be appended to the already existing ptzMAP + * @return ptzMAP* Pointer to the ptzMAP which includes the newly added ptzMAP + */ +ptzMAP *ptzmap_AppendMap(const ptzMAP *chain, ptzMAP *newmap) +{ if( chain != NULL ) { newmap->next = (ptzMAP *) chain; } return newmap; } + +/** + * This function creates a new ptzMAP mapping record. This defines the key/value relationship in + * the resulting Python Dictionaries. + * @author David Sommerseth + * @param ptzMAP* Pointer to the chain the new mapping will be appended + * @param char* XPath root of the given key and value XPath expressions. + * If NULL, the key and value XPath expressions must be absolute. + * @param ptzTYPES Type of the 'key' value + * @param const char* XPath expression or constant string for the 'key' value + * @param ptzTYPES Type of the 'value' value + * @param const char* XPath expression or constant string for the 'value' value + * @param ptzMAP* Used if the value type is of one of the ptzDICT types, contains a new + * mapping level for the children + * @return ptzMAP* Pointer to the ptzMAP which includes the newly added ptzMAP + */ ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, ptzTYPES ktyp, const char *key, ptzTYPES vtyp, const char *value, @@ -115,7 +148,16 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp, return ptzmap_AppendMap(chain, ret); }; -void ptzmap_SetFixedList(ptzMAP *map_p, const char *index, int size) { + +/** + * This functions sets an ptzLIST typed map entry as a fixed list + * @author David Sommerseth + * @param ptzMAP* Pointer to the ptzMAP elemnt to be updated + * @param const char* Attribute name of the XML node of the 'key' to use as the list index + * @param int Defines the size of the list + */ +void ptzmap_SetFixedList(ptzMAP *map_p, const char *index, int size) +{ assert( map_p != NULL ); switch( map_p->type_value ) { @@ -132,6 +174,12 @@ void ptzmap_SetFixedList(ptzMAP *map_p, const char *index, int size) { } } + +/** + * This functions frees up a complete pointer chain. This is normally called via #define ptzmap_Free() + * @author David Sommerseth + * @param ptzMAP* Pointer to the ptzMAP to free + */ void ptzmap_Free_func(ptzMAP *ptr) { if( ptr == NULL ) { @@ -189,6 +237,7 @@ void indent(int lvl) } } + #define ptzmap_Dump(ptr) { ptzmap_Dump_func(ptr, 0); } void ptzmap_Dump_func(const ptzMAP *ptr, int level) { @@ -221,15 +270,13 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) } #endif // END OF DEBUG FUNCTIONS -// -// Parser for the XML -> Python mapping XML file -// -// This mappipng XML file describes how the Python result -// should look like and where it should pick the data from -// when later on parsing the dmidecode XML data. -// -// Valid key and value types for the mapping file +/** + * This functions converts a string to valid ptzTYPES values. This is used when parsing the XML mapping nodes + * @author David Sommerseth + * @param const char* String value containing the key/value type + * @return ptzTYPES The type value + */ inline ptzTYPES _convert_maptype(const char *str) { if( strcmp(str, "string") == 0 ) { return ptzSTR; @@ -259,7 +306,13 @@ inline ptzTYPES _convert_maptype(const char *str) { } } -// Internal parser - SubMapper (Individual Types of a Group) + +/** + * This functions is the internal parser - SubMapper (Individual Types of a Group) + * @author David Sommerseth + * @param xmlNode* Node of the starting point for the parsing + * @return ptzMAP* The ptzMAP version of the XML definition + */ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL;; @@ -358,7 +411,12 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { return retmap; } - +/** + * This functions validates and retrieves the root node of the dmidecode_mapping XML node from an XML document + * @author David Sommerseth + * @param xmlDoc* XML mapping document pointer + * @return xmlNode* The root xmlNode of a valid XML mapping document. On invalid document NULL is returned. + */ xmlNode *_dmiMAP_GetRootElement(xmlDoc *mapdoc) { xmlNode *rootnode = NULL; @@ -382,6 +440,14 @@ xmlNode *_dmiMAP_GetRootElement(xmlDoc *mapdoc) { } +/** + * Internal function which looks up the given Type ID among TypeMap nodes and and parses + * the found XML nodes into a ptzMAP + * @author David Sommerseth + * @param xmlNode* The node where the TypeMapping tags are found + * @param const char* The typeid to parse to a ptzMAP + * @return ptzMAP* The parsed result of the XML nodes + */ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) { xmlNode *node = NULL; @@ -401,7 +467,13 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) } -// Main parser function for the mapping XML +/** + * Exported function for parsing a XML mapping document for a given Type ID to a ptzMAP + * @author David Sommerseth + * @param xmlDoc* Pointer to the XML mapping document + * @param const char* The Type ID to create the map for + * @return ptzMAP* The parsed XML containing as a ptzMAP + */ ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; @@ -417,7 +489,15 @@ ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname) { } -// Internal parser - Mapper (Groups of Types) +/** + * Internal parser for GroupMapping (group of types). Converts a given GroupMapping to a ptzMAP + * from a XML node set + * @author Nima Talebi + * @author David Sommerseth + * @param xmlNode* The source XML nodes of what to parse to a ptzMAP + * @param xmlDoc* A pointer to the source map, used for further parsing of each type defined in the GroupMapping + * @return ptzMAP* The resulting ptzMAP of the parsed xmlNode group mapping + */ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL, *typemap = NULL; @@ -452,9 +532,6 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { // Loop through it's children foreach_xmlnode(map_n, ptr_n) { - //. TODO: Dazo: I had to add this (if() statement), but not sure why I should need to - //. TODO: Needs investigation... - // Validate if we have the right node name if( xmlStrcmp(ptr_n->name, (xmlChar *) "TypeMap") != 0 ) { continue; // Skip unexpected tag names @@ -474,7 +551,14 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { } -// Main parser function for the mapping XML +/** + * Exported function which parses a given GroupMapping (consisting of + * one or more TypeMaps) into a ptzMAP + * @author David Sommerseth + * @param xmlDoc* Pointer to the XML document holding the mapping + * @param const char* Defines which group mapping to parse to a ptzMAP + * @return ptzMAP* The parsed XML mapping in a ptzMAP + */ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; @@ -504,10 +588,13 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { } - -// -// Parser routines for converting XML data into Python structures -// +/** + * Internal function for converting a given mapped value to the appropriate Python data type + * @author David Sommerseth + * @param ptzMAP* Pointer to the current mapping entry being parsed + * @param const char * String which contains the value to be converted to a Python value + * @return PyObject * The converted value as a Python object + */ inline PyObject *StringToPyObj(ptzMAP *val_m, const char *instr) { PyObject *value; const char *workstr = NULL; @@ -577,7 +664,15 @@ inline PyObject *StringToPyObj(ptzMAP *val_m, const char *instr) { return value; } -// Retrieve a value from the XML doc (XPath Context) based on a XPath query + +/** + * Retrieves a value from the data XML doc (via XPath Context) based on a XPath query + * @author David Sommerseth + * @param xmlXPathContext* Pointer to the XPath context holding the source data + * @param const char* The XPath expression where to find the data + * @return xmlXPathObject* If data is found, it is returned in an XPath object for further processing + */ + xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { xmlChar *xp_xpr = NULL; xmlXPathObject *xp_obj = NULL; @@ -594,6 +689,18 @@ xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { return xp_obj; } + +/** + * Retrieves the value which is to be used as the key value in a Python dictionary. + * @author David Sommerseth + * @param char* Pointer to the return buffer for the value + * @param size_t Size of the return buffer + * @param ptzMAP* Pointer to the current mapping entry which is being parsed + * @param xmlXPathContext* Pointer to the XPath context containing the source data + * @param int Defines which of the XPath results to use, if more is found + * @returns char* Returns a pointer to the return buffer (parameter 1) if key value + * is found, or NULL if not found + */ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { xmlXPathObject *xpobj = NULL; @@ -628,12 +735,29 @@ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *x } +/** + * Simple define to properly add a key/value pair to a Python dictionary + * @author David Sommerseth + * @param PyObject* Pointer to the Python dictionary to be updated + * @param const char* String containing the key value + * @param PyObject* Pointer to the Python value + */ #define PyADD_DICT_VALUE(p, k, v) { \ PyDict_SetItemString(p, k, v); \ Py_DECREF(v); \ } + +/** + * Internal function for adding a XPath result to the resulting Python dictionary + * @author David Sommerseth + * @param PyObject* Pointer to the resulting Python dictionary + * @param xmlXPathContext* Pointer to the XPath context containing the source data + * (used for retrieving the key value) + * @param ptzMAP* Pointer to the current mapping entry being parsed + * @param xmlXPathObject* Pointer to XPath object containing the data value(s) for the dictionary + */ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) { int i = 0; char *key = NULL; @@ -677,8 +801,17 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m } -// Internal XML parser routine, which traverses the given mapping table, -// returning a Python structure accordingly to the map. +/** + * Internal XML parser routine, which traverses the given mapping table, + * returning a Python structure accordingly to the map. Data for the Python dictionary is + * take from the input XML node. + * @author David Sommerseth + * @param PyObject* Pointer to the Python dictionary of the result + * @param ptzMAP* Pointer to the starting point for the further parsing + * @param xmlNode* Pointer to the XML node containing the source data + * @param int For debug purpose only, to keep track of which element being parsed + * @return PyObject* Pointer to the input Python dictionary + */ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int elmtid) { char *key = NULL; xmlXPathContext *xpctx = NULL; @@ -869,7 +1002,13 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int return retdata; } -// Convert a xmlNode to a Python object, based on the given map + +/** + * Exported function, for parsing a XML node to a Python dictionary based on the given ptzMAP + * @author David Sommerseth + * @param ptzMAP* The map descriping the resulting Python dictionary + * @param xmlNode* XML node pointer to the source data to be used for populating the Python dictionary + */ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xmlXPathContext *xpctx = NULL; xmlDoc *xpdoc = NULL; @@ -936,7 +1075,12 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { } -// Convert a xmlDoc to a Python object, based on the given map +/** + * Exported function, for parsing a XML document to a Python dictionary based on the given ptzMAP + * @author David Sommerseth + * @param ptzMAP* The map descriping the resulting Python dictionary + * @param xmlDoc* XML document pointer to the source data to be used for populating the Python dictionary + */ PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *doc) { xmlNode *node = NULL; -- cgit From 788272fc9a0c027ecfec16ed3e746558cf988c92 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 3 Jun 2009 11:56:23 +0200 Subject: Renamed *_set_version() functions to a more proper *_get_version() function names Also changed dmiMAP_ParseMappingXML(...) to dmiMAP_ParseMappingXML_GroupName(...). In the dmidecode_get(...) function. This is just a quick fix for making it compile. It's also needed to implement usage of dmiMAP_ParseMappingXML_TypeID(...) as well. --- src/dmidecode.c | 4 ++-- src/dmidecode.h | 4 ++-- src/dmidecodemodule.c | 16 ++++++++-------- src/dmidecodemodule.h | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index de6fb2a..11dbd50 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5129,7 +5129,7 @@ int _smbios_decode_check(u8 * buf) return check; } -xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem) +xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) { int check = _smbios_decode_check(buf); @@ -5207,7 +5207,7 @@ int _legacy_decode_check(u8 * buf) return check; } -xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem) +xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) { int check = _legacy_decode_check(buf); diff --git a/src/dmidecode.h b/src/dmidecode.h index 04d8f04..135c264 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -32,9 +32,9 @@ void dmi_dump(xmlNode *node, struct dmi_header * h); xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); -xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem); +xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); -xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem); +xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 6ed7fc5..2564236 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -115,7 +115,7 @@ u8 *parse_opt_type(u8 * p, const char *arg) } -xmlNode *dmidecode_set_version() +xmlNode *dmidecode_get_version() { int found = 0; size_t fp; @@ -133,12 +133,12 @@ xmlNode *dmidecode_set_version() //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - ver_n = smbios_decode_set_version(buf, dumpfile); + ver_n = smbios_decode_get_version(buf, dumpfile); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } } else if(memcmp(buf, "_DMI_", 5) == 0) { - ver_n = legacy_decode_set_version(buf, dumpfile); + ver_n = legacy_decode_get_version(buf, dumpfile); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } @@ -152,13 +152,13 @@ xmlNode *dmidecode_set_version() if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - ver_n = smbios_decode_set_version(buf + fp, opt.devmem); + ver_n = smbios_decode_get_version(buf + fp, opt.devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } fp += 16; } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - ver_n = legacy_decode_set_version (buf + fp, opt.devmem); + ver_n = legacy_decode_get_version (buf + fp, opt.devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } @@ -170,7 +170,7 @@ xmlNode *dmidecode_set_version() } else { // Process as EFI if((buf = mem_chunk(fp, 0x20, opt.devmem)) != NULL) { - ver_n = smbios_decode_set_version(buf, opt.devmem); + ver_n = smbios_decode_get_version(buf, opt.devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } @@ -293,7 +293,7 @@ static PyObject *dmidecode_get(const char *section) assert( opt.mappingxml != NULL ); } - mapping = dmiMAP_ParseMappingXML(opt.mappingxml, section); + mapping = dmiMAP_ParseMappingXML_GroupName(opt.mappingxml, section); if( mapping == NULL ) { return NULL; } @@ -498,7 +498,7 @@ PyMODINIT_FUNC initdmidecode(void) Py_INCREF(version); PyModule_AddObject(module, "version", version); - opt.dmiversion_n = dmidecode_set_version(); + opt.dmiversion_n = dmidecode_get_version(); dmiver = dmixml_GetContent(opt.dmiversion_n); PyModule_AddObject(module, "dmi", dmiver ? PyString_FromString(dmiver) : Py_None); } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 34a2bad..0f5c75d 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -21,7 +21,7 @@ #include "dmihelper.h" -xmlNode *dmidecode_set_version(void); +xmlNode *dmidecode_get_version(void); //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern void dmi_dump(xmlNode *node, struct dmi_header *h); @@ -31,8 +31,8 @@ extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); extern int smbios_decode(u8 * buf, const char *devmem, xmlNode *node); extern int legacy_decode(u8 * buf, const char *devmem, xmlNode *node); -extern xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem); -extern xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem); +extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); +extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); extern void *mem_chunk(size_t base, size_t len, const char *devmem); extern u8 *parse_opt_type(u8 * p, const char *arg); -- cgit From 62ae0e75016b31aa3062f296ed070e0610f0b98f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 3 Jun 2009 15:22:23 +0200 Subject: Removed some dead code --- src/dmidecode.c | 1 - src/dmihelper.c | 117 ------------------------------------------------------- src/dmihelper.h | 4 -- src/setup-dbg.py | 1 - src/setup.py | 1 - 5 files changed, 124 deletions(-) delete mode 100644 src/dmihelper.c (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 11dbd50..d2f340f 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5004,7 +5004,6 @@ int dump(const char *dumpfile) free(buf); //. TODO: Exception - //dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G."); if(!found) ret = -1; } diff --git a/src/dmihelper.c b/src/dmihelper.c deleted file mode 100644 index 4000a92..0000000 --- a/src/dmihelper.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include - -#include "dmihelper.h" - -/* -dmi_minor* dmiAppendObject(long code, char const *key, const char *format, ...) { - static dmi_minor* last = NULL; - - //. int minor = code&0x00FF; - //. int major = code>>8; - - va_list arg; - va_start(arg, format); - - dmi_minor *o = (dmi_minor *)malloc(sizeof(dmi_minor)); - o->next = last; - o->id = code; - o->major = (dmi_codes_major *)&dmiCodesMajor[map_maj[code>>8]]; - o->key = (char *)key; - - if((format != NULL)&&(vsnprintf(o->value, MAXVAL-1, format, arg) > MAXVAL)) { - free(o); - o = NULL; - //. TODO: Make this a python exception. - printf("dmidecode: Internal (python module) error; Value too long.\n"); - } - - last = o; - va_end(arg); // cleanup - - return o; -} -*/ - -int dmiSetItem(PyObject * dict, const char *key, const char *format, ...) -{ - va_list arg; - - va_start(arg, format); - char buffer[2048]; - - vsprintf(buffer, format, arg); - va_end(arg); - //printf("DEBUG: Setting k:%s, f:%s s:%s...", key, format, buffer); - PyDict_SetItem(dict, PyString_FromString(key), PyString_FromString(buffer)); - //printf("Done.\n"); - return 0; -} - -/* NOTE: Decomissioned helper function... -void dmiAppendData(PyObject *pydata, const int count) { - dmi_minor* last = dmiAppendObject(count, "JUNK", "NODATA"); - - const char *id = last->major->id; - PyObject *_key, *_val; - - PyObject *pymajor = PyDict_New(); - - _key = PyString_FromString("code"); - _val = PyInt_FromLong((long)last->major->code); - PyDict_SetItem(pymajor, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - - _key = PyString_FromString("id"); - _val = PyString_FromString(last->major->id); - PyDict_SetItem(pymajor, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - - _key = PyString_FromString("name"); - _val = PyString_FromString(last->major->desc); - PyDict_SetItem(pymajor, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - - PyObject *pyminor = PyDict_New(); - while((last = last->next)) { - //printf("%d:<%s, %s> | %ld:[%s => %s]\n", last->major->code, last->major->id, last->major->desc, last->id, last->key, last->value); - _key = PyString_FromString(last->key); - _val = PyString_FromString(last->value); - PyDict_SetItem(pyminor, _key, _val); - Py_DECREF(_key); - Py_DECREF(_val); - } - _key = PyString_FromString("data"); - PyDict_SetItem(pymajor, _key, pyminor); - Py_DECREF(_key); - Py_DECREF(pyminor); - - _key = PyString_FromString(id); - PyDict_SetItem(pydata, _key, pymajor); - Py_DECREF(_key); - Py_DECREF(pymajor); -} -*/ - -/* NOTE: Decomissioned helper function... -int catsprintf(char *buf, const char *format, ...) { - if(format == NULL) { - bzero(buf, strlen(buf)); - return 0; - } - - va_list arg; // will point to each unnamed argument in turn - va_start(arg, format); // point to first element after fmt - - char b[8192]; - int c = vsprintf (b, format, arg); - - strcat(buf, b); - va_end(arg); // cleanp - - return c; -} -*/ diff --git a/src/dmihelper.h b/src/dmihelper.h index 82a936d..6dccd94 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -94,10 +94,6 @@ typedef struct _dmi_minor { struct _dmi_minor *next; } dmi_minor; -void dmiAppendData(PyObject * pydata, const int count); -int dmiSetItem(PyObject * dict, const char *key, const char *format, ...); - -//dmi_minor* dmiAppendObject(long code, char const *key, const char *format, ...); /*** dmiopt.h ***/ struct string_keyword { diff --git a/src/setup-dbg.py b/src/setup-dbg.py index e0a2358..95292e4 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -14,7 +14,6 @@ setup( "dmidecode", sources = [ "src/dmidecodemodule.c", - "src/dmihelper.c", "src/util.c", "src/dmioem.c", "src/dmidecode.c", diff --git a/src/setup.py b/src/setup.py index bb79a14..dd78087 100644 --- a/src/setup.py +++ b/src/setup.py @@ -14,7 +14,6 @@ setup( "dmidecode", sources = [ "src/dmidecodemodule.c", - "src/dmihelper.c", "src/util.c", "src/dmioem.c", "src/dmidecode.c", -- cgit From dead6d09ab08ebff5b7520f17ab46fac688ad1d1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 3 Jun 2009 16:15:40 +0200 Subject: Added Doxygent comments, fixed missing copyright --- src/dmixml.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 91 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index de79d99..0c1c731 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -1,6 +1,7 @@ /* Simplified XML API for dmidecode * * Copyright 2009 David Sommerseth + * Copyright 2009 Nima Talebi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +34,15 @@ #include "dmixml.h" -// Internal function for dmixml_* functions ... builds up a variable xmlChar* string +/** + * Internal function for dmixml_* functions. The function will allocate a buffer and populate it + * according to the format string + * @author David Sommerseth + * @param size_t The requested size for the new buffer + * @param const char* The format of the string being built (uses vsnprintf()) + * @param ... The needed variables to build up the string + * @return xmlChar* Pointer to the buffer of the string + */ xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) { xmlChar *ret = NULL, *xmlfmt = NULL; xmlChar *ptr = NULL; @@ -58,13 +67,15 @@ xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) { } -// Adds an XML property/attribute to the given XML node -// -// xmldata_n = ""; -// dmixml_AddAttribute(xmldata_n, "value", "1234"); -// gives: xmldata_n = " + * @param xmlNode* A pointer to the xmlNode being updated + * @param const char* The name of the attribute + * @param const char* Value of the string (can make use of string formating options) + * @return xmlAttr* Pointer to the new attribute node. On errors an assert is + * triggered and return value should be NULL. + */ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...) { xmlChar *val_s = NULL, *atrname_s = NULL; @@ -93,12 +104,15 @@ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt } -// Adds a new XML tag to the current node with the given tag name and value. -// -// xmldata_n = ""; -// dmixml_AddTextChild(xmldata_n, "sublevel1", "value"); -// gives: xmldata_n = "value" -// +/** + * Adds a new XML tag to the given node with the given tag name and value. + * @author David Sommerseth + * @param xmlNode* Pointer to the parent node for this new node + * @param const char* Name of the new tag + * @param const char* Contents of the new tag (can make use of string formating options) + * @return xmlNode* Pointer to the new tag. On errors an assert is triggered and return + * value should be NULL. + */ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...) { xmlChar *val_s = NULL, *tagname_s = NULL; @@ -127,12 +141,13 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt return res; } -// Adds a text node child to the current XML node -// -// xmldata_n = "; -// dmixml_AddTextContent(xmldata_n, "some data value"); -// gives: xmldata_n = "some data value" -// +/** + * Adds a text node child to the given XML node. If input is NULL, the tag contents will be empty. + * @author David Sommerseth + * @param xmlNode* Pointer to the current node which will get the text child + * @param const char* Contents of the tag (can make use of string formating options) + * @return xmlNode* Pointer to the tags content node + */ xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...) { xmlChar *val_s = NULL; @@ -158,7 +173,14 @@ xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...) return res; } - +/** + * Retrieve the contents of a named attribute in a given XML node + * @author David Sommerseth + * @param xmlNode* Pointer to the XML node of which we want to extract the attribute value + * @param const char* The name of the attribute to be extracted + * @return char* Pointer to the attribute contents if found, otherwise NULL. This value + * must NOT be freed, as it points directly into the value in the XML document. + */ char *dmixml_GetAttrValue(xmlNode *node, const char *key) { xmlAttr *aptr = NULL; xmlChar *key_s = NULL; @@ -181,6 +203,18 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key) { return NULL; } +/** + * Retrieve a pointer to an XML node based on tag name and a specified attribute value. To get + * a hit, tag name and the attribute must be found and the value of the attribute must match as well. + * The function will traverse all children nodes of the given input node, but it will not go deeper. + * @author David Sommerseth + * @author Nima Talebi + * @param xmlNode* Pointer to the XML node of where to start searching + * @param const char* Tag name the function will search for + * @param const char* Attribute to check for in the tag + * @param const char* Value of the attribute which must match to have a hit + * @return xmlNode* Pointer to the found XML node, NULL if no tag was found. + */ xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey, const char *val) { xmlNode *ptr_n = NULL; xmlChar *tag_s = NULL; @@ -207,6 +241,15 @@ xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *at return ptr_n; } +/** + * Retrieve a poitner to an XML node with the given name. The function will traverse + * all children nodes of the given input node, but it will not go deeper. The function + * will only return the first hit. + * @author David Sommerseth + * @param xmlNode* Pointer to the XML node of where to start searching + * @param const char* Name of the tag name the function will look for. + * @return xmlNode* Pointer to the found XML node, NULL if no tag was found. + */ xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { xmlNode *ptr_n = NULL; xmlChar *key_s = NULL; @@ -229,15 +272,42 @@ xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { return NULL; } +/** + * Retrieve the text contents of the given XML node + * @author David Sommerseth + * @param xmlNode* Pointer to the XML node of which we want to extract the contents + * @return char* Pointer to the tag contents if found, otherwise NULL. This value + * must NOT be freed, as it points directly into the value in the XML document. + */ inline char *dmixml_GetContent(xmlNode *node) { // FIXME: Should find better way how to return UTF-8 data return (((node != NULL) && (node->children != NULL)) ? (char *) node->children->content : NULL); } +/** + * Retrieve the text content of a given tag. The function will traverse + * all children nodes of the given input node, but it will not go deeper. + * The function will only return the first hit. + * @author David Sommerseth + * @param xmlNode* Pointer to the XML node of where to start searching + * @param const char* Name of the tag the function will look for + * @return char* Pointer to the tag contents if found, otherwise NULL. This value + * must NOT be freed, as it points directly into the value in the XML document. + */ inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { return dmixml_GetContent(dmixml_FindNode(node, key)); } +/** + * Retrieve the contents from an XPath object. + * @author David Sommerseth + * @param char* Pointer to a buffer where to return the value + * @param size_t Size of the return buffer + * @param xmlXPathObject* Pointer to the XPath object containing the data + * @param int If the XPath object contains a node set, this defines + * which of the elements to be extracted. + * @return char* Points at the return buffer if a value is found, otherwise NULL is returned. + */ char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx) { memset(buf, 0, buflen); @@ -273,4 +343,3 @@ char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int } return buf; } - -- cgit From aea8d44d49a3b461194cc72b28cdbf2be51da8d8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 3 Jun 2009 16:19:05 +0200 Subject: Added missing file section for Doxygen parsing --- src/dmixml.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 0c1c731..1092872 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -24,6 +24,15 @@ * are deemed to be part of the source code. */ +/** + * @file dmixml.c + * @brief Helper functions for XML nodes and documents. + * @author David Sommerseth + * @author Nima Talebi + */ + + + #include #include #include @@ -276,7 +285,7 @@ xmlNode *dmixml_FindNode(xmlNode *node, const char *key) { * Retrieve the text contents of the given XML node * @author David Sommerseth * @param xmlNode* Pointer to the XML node of which we want to extract the contents - * @return char* Pointer to the tag contents if found, otherwise NULL. This value + * @return char* Pointer to the tag contents if found, otherwise NULL. This value * must NOT be freed, as it points directly into the value in the XML document. */ inline char *dmixml_GetContent(xmlNode *node) { @@ -291,7 +300,7 @@ inline char *dmixml_GetContent(xmlNode *node) { * @author David Sommerseth * @param xmlNode* Pointer to the XML node of where to start searching * @param const char* Name of the tag the function will look for - * @return char* Pointer to the tag contents if found, otherwise NULL. This value + * @return char* Pointer to the tag contents if found, otherwise NULL. This value * must NOT be freed, as it points directly into the value in the XML document. */ inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { @@ -304,7 +313,7 @@ inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { * @param char* Pointer to a buffer where to return the value * @param size_t Size of the return buffer * @param xmlXPathObject* Pointer to the XPath object containing the data - * @param int If the XPath object contains a node set, this defines + * @param int If the XPath object contains a node set, this defines * which of the elements to be extracted. * @return char* Points at the return buffer if a value is found, otherwise NULL is returned. */ -- cgit From a05daf8fde753404511e9f247ab4e9ac9a75bf1a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 3 Jun 2009 20:40:47 +0200 Subject: Rewrote bigger parts to avoid global variables as much as possible --- src/dmidecode.c | 46 +++++------ src/dmidecode.h | 9 ++- src/dmidecodemodule.c | 205 +++++++++++++++++++++++++++++--------------------- src/dmidecodemodule.h | 10 +-- src/dmihelper.h | 3 +- 5 files changed, 152 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index d2f340f..4a978a9 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -201,7 +201,7 @@ static int dmi_bcd_range(u8 value, u8 low, u8 high) return 1; } -void dmi_dump(xmlNode *node, struct dmi_header * h) +void dmi_dump(options *opt, xmlNode *node, struct dmi_header * h) { int row, i; const char *s; @@ -234,7 +234,7 @@ void dmi_dump(xmlNode *node, struct dmi_header * h) while((s = dmi_string(h, i++)) != NULL) { //. FIXME: DUMP /* - * if(opt.flags & FLAG_DUMP) { + * if(opt->flags & FLAG_DUMP) { * int j, l = strlen(s)+1; * for(row=0; row<((l-1)>>4)+1; row++) { * for(j=0; j<16 && jdata; xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; @@ -4816,7 +4816,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) dmixml_AddAttribute(sect_n, "Type", "%i", h->type); dmixml_AddAttribute(sect_n, "InfoType", "%s", h->type >= 128 ? "OEM-specific" : "Unknown"); - dmi_dump(sect_n, h); + dmi_dump(opt, sect_n, h); break; } return sect_n; @@ -4830,10 +4830,10 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -xmlNode *dmi_table_string(xmlNode *prnt_n, const struct dmi_header *h, const u8 *data, u16 ver) +xmlNode *dmi_table_string(options *opt, xmlNode *prnt_n, const struct dmi_header *h, const u8 *data, u16 ver) { int key; - u8 offset = opt.string->offset; + u8 offset = opt->string->offset; xmlNode *handle_n = NULL, *dmi_n = NULL; if(offset >= h->length) @@ -4843,7 +4843,7 @@ xmlNode *dmi_table_string(xmlNode *prnt_n, const struct dmi_header *h, const u8 assert( handle_n != NULL ); //. TODO: These should have more meaningful dictionary names - key = (opt.string->type << 8) | offset; + key = (opt->string->type << 8) | offset; switch (key) { case 0x108: @@ -4877,7 +4877,7 @@ xmlNode *dmi_table_string(xmlNode *prnt_n, const struct dmi_header *h, const u8 } /* -static void dmi_table_dump(u32 base, u16 len, const char *devmem) +static void dmi_table_dump(options *opt, u32 base, u16 len, const char *devmem) { u8 *buf; @@ -4887,8 +4887,8 @@ static void dmi_table_dump(u32 base, u16 len, const char *devmem) return; } - printf("# Writing %d bytes to %s.\n", len, PyString_AS_STRING(opt.dumpfile)); - write_dump(32, len, buf, PyString_AS_STRING(opt.dumpfile), 0); + printf("# Writing %d bytes to %s.\n", len, opt->dumpfile); + write_dump(32, len, buf, opt->dumpfile, 0); free(buf); } */ @@ -5011,13 +5011,13 @@ int dump(const char *dumpfile) return ret == 0 ? found : ret; } -static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(options *opt, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; int i = 0; - if(opt.type == NULL) { + if(opt->type == NULL) { xmlNode *info_n = NULL; info_n = dmixml_AddTextChild(xmlnode, "DMIinfo", "%i structures occupying %i bytes", num, len); @@ -5025,7 +5025,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x dmixml_AddAttribute(info_n, "dmi_size", "%i", len); /* TODO DUMP - * if (!(opt.flags & FLAG_FROM_DUMP)) + * if (!(opt->flags & FLAG_FROM_DUMP)) * dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base); */ @@ -5050,9 +5050,9 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x int display; to_dmi_header(&h, data); - display = ((opt.type == NULL || opt.type[h.type]) + display = ((opt->type == NULL || opt->type[h.type]) // && !(h.type>39 && h.type<=127) - && !opt.string); + && !opt->string); /* ** If a short entry is found (less than 4 bytes), not only it @@ -5086,7 +5086,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x if(display) { if(next - buf <= len) { /* TODO: ... - * if(opt.flags & FLAG_DUMP) { + * if(opt->flags & FLAG_DUMP) { * PyDict_SetItem(hDict, PyString_FromString("lookup"), dmi_dump(&h)); * } else { * //. TODO: //. Is the value of `i' important?... @@ -5095,11 +5095,11 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - handle_n = dmi_decode(xmlnode, &h, ver); + handle_n = dmi_decode(opt, xmlnode, &h, ver); } else fprintf(stderr, ""); - } else if(opt.string != NULL && opt.string->type == h.type) { - handle_n = dmi_table_string(xmlnode, &h, data, ver); + } else if(opt->string != NULL && opt->string->type == h.type) { + handle_n = dmi_table_string(opt, xmlnode, &h, data, ver); } if( handle_n != NULL ) { dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); @@ -5173,7 +5173,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(options *opt, u8 * buf, const char *devmem, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5189,7 +5189,7 @@ int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) break; } //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); - dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, + dmi_table(opt, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, xmlnode); } return check; @@ -5228,12 +5228,12 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(options *opt, u8 * buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) - dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), + dmi_table(opt, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index 135c264..c199b7a 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -20,6 +20,7 @@ */ #include +#include "dmihelper.h" struct dmi_header { u8 type; @@ -28,14 +29,14 @@ struct dmi_header { u8 *data; }; -void dmi_dump(xmlNode *node, struct dmi_header * h); -xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); +void dmi_dump(options *, xmlNode *node, struct dmi_header * h); +xmlNode *dmi_decode(options *, xmlNode *parent_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); -int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); +int smbios_decode(options *, u8 * buf, const char *devmem, xmlNode *xmlnode); xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); -int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); +int legacy_decode(options *, u8 * buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 2564236..e77384a 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -48,21 +48,21 @@ #include "dmixml.h" #include -options opt; +options *global_options = NULL; -static void init(void) +static void init(options *opt) { /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule"); - opt.devmem = DEFAULT_MEM_DEV; - opt.dumpfile = NULL; - opt.flags = 0; - opt.type = NULL; - opt.dmiversion_n = NULL; - opt.mappingxml = NULL; - opt.python_xml_map = strdup(PYTHON_XML_MAP); + opt->devmem = DEFAULT_MEM_DEV; + opt->dumpfile = NULL; + opt->flags = 0; + opt->type = NULL; + opt->dmiversion_n = NULL; + opt->mappingxml = NULL; + opt->python_xml_map = strdup(PYTHON_XML_MAP); } u8 *parse_opt_type(u8 * p, const char *arg) @@ -115,7 +115,7 @@ u8 *parse_opt_type(u8 * p, const char *arg) } -xmlNode *dmidecode_get_version() +xmlNode *dmidecode_get_version(options *opt) { int found = 0; size_t fp; @@ -124,21 +124,21 @@ xmlNode *dmidecode_get_version() xmlNode *ver_n = NULL; /* Set default option values */ - opt.devmem = DEFAULT_MEM_DEV; + if( opt->devmem == NULL ) { + opt->devmem = DEFAULT_MEM_DEV; + } /* Read from dump if so instructed */ - if(opt.dumpfile != NULL) { - const char *dumpfile = PyString_AS_STRING(opt.dumpfile); - + if(opt->dumpfile != NULL) { //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); - if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { + if((buf = mem_chunk(0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - ver_n = smbios_decode_get_version(buf, dumpfile); + ver_n = smbios_decode_get_version(buf, opt->dumpfile); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } } else if(memcmp(buf, "_DMI_", 5) == 0) { - ver_n = legacy_decode_get_version(buf, dumpfile); + ver_n = legacy_decode_get_version(buf, opt->dumpfile); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } @@ -149,16 +149,16 @@ xmlNode *dmidecode_get_version() efi = address_from_efi(&fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { + if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - ver_n = smbios_decode_get_version(buf + fp, opt.devmem); + ver_n = smbios_decode_get_version(buf + fp, opt->devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } fp += 16; } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - ver_n = legacy_decode_get_version (buf + fp, opt.devmem); + ver_n = legacy_decode_get_version (buf + fp, opt->devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } @@ -169,8 +169,8 @@ xmlNode *dmidecode_get_version() ver_n = NULL; } else { // Process as EFI - if((buf = mem_chunk(fp, 0x20, opt.devmem)) != NULL) { - ver_n = smbios_decode_get_version(buf, opt.devmem); + if((buf = mem_chunk(fp, 0x20, opt->devmem)) != NULL) { + ver_n = smbios_decode_get_version(buf, opt->devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } @@ -181,15 +181,16 @@ xmlNode *dmidecode_get_version() if( buf != NULL ) { free(buf); } - if( !found ) { fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry."); } - free(opt.type); + if( opt->type != NULL ) { + free(opt->type); + } return ver_n; } -int dmidecode_get_xml(xmlNode* dmixml_n) +int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) { assert(dmixml_n != NULL); if(dmixml_n == NULL) { @@ -201,23 +202,21 @@ int dmidecode_get_xml(xmlNode* dmixml_n) int found = 0; size_t fp; int efi; - u8 *buf; + u8 *buf = NULL; - const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; + const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; if(access(f, R_OK) < 0) PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); /* Read from dump if so instructed */ - if(opt.dumpfile != NULL) { - const char *dumpfile = PyString_AS_STRING(opt.dumpfile); - + if(opt->dumpfile != NULL) { // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); - if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { + if((buf = mem_chunk(0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(buf, dumpfile, dmixml_n)) + if(smbios_decode(opt, buf, opt->dumpfile, dmixml_n)) found++; } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode(buf, dumpfile, dmixml_n)) + if(legacy_decode(opt, buf, opt->dumpfile, dmixml_n)) found++; } } else { @@ -228,15 +227,15 @@ int dmidecode_get_xml(xmlNode* dmixml_n) efi = address_from_efi(&fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { + if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(smbios_decode(buf + fp, opt.devmem, dmixml_n)) { + if(smbios_decode(opt, buf + fp, opt->devmem, dmixml_n)) { found++; fp += 16; } } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode(buf + fp, opt.devmem, dmixml_n)) + if(legacy_decode(opt, buf + fp, opt->devmem, dmixml_n)) found++; } } @@ -245,15 +244,16 @@ int dmidecode_get_xml(xmlNode* dmixml_n) } else if(efi == EFI_NO_SMBIOS) { ret = 1; } else { - if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) + if((buf = mem_chunk(fp, 0x20, opt->devmem)) == NULL) ret = 1; - else if(smbios_decode(buf, opt.devmem, dmixml_n)) + else if(smbios_decode(opt, buf, opt->devmem, dmixml_n)) found++; // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } } - - free(opt.type); + if( opt->type != NULL ) { + free(opt->type); + } if(ret == 0) { free(buf); } @@ -261,39 +261,41 @@ int dmidecode_get_xml(xmlNode* dmixml_n) return ret; } -static PyObject *dmidecode_get(const char *section) +static PyObject *dmidecode_get(options *opt, const char *section) { PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; /* Set default option values */ - opt.devmem = DEFAULT_MEM_DEV; - opt.flags = 0; - opt.type = NULL; - opt.type = parse_opt_type(opt.type, section); + if( opt->devmem == NULL ) { + opt->devmem = DEFAULT_MEM_DEV; + } + opt->flags = 0; + opt->type = NULL; + opt->type = parse_opt_type(opt->type, section); - if(opt.type == NULL) { + if(opt->type == NULL) { return NULL; } dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); assert( dmixml_n != NULL ); // Append DMI version info - if( opt.dmiversion_n != NULL ) { - xmlAddChild(dmixml_n, xmlCopyNode(opt.dmiversion_n, 1)); + if( opt->dmiversion_n != NULL ) { + xmlAddChild(dmixml_n, xmlCopyNode(opt->dmiversion_n, 1)); } - if(dmidecode_get_xml(dmixml_n) == 0) { + if(dmidecode_get_xml(opt, dmixml_n) == 0) { ptzMAP *mapping = NULL; // Convert the retrieved XML nodes to Python dicts - if( opt.mappingxml == NULL ) { + if( opt->mappingxml == NULL ) { // Load mapping into memory - opt.mappingxml = xmlReadFile(opt.python_xml_map, NULL, 0); - assert( opt.mappingxml != NULL ); + opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0); + assert( opt->mappingxml != NULL ); } - mapping = dmiMAP_ParseMappingXML_GroupName(opt.mappingxml, section); + mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); if( mapping == NULL ) { return NULL; } @@ -317,42 +319,41 @@ static PyObject *dmidecode_get(const char *section) } - static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) { - return dmidecode_get("bios"); + return dmidecode_get(global_options, "bios"); } static PyObject *dmidecode_get_system(PyObject * self, PyObject * args) { - return dmidecode_get("system"); + return dmidecode_get(global_options, "system"); } static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args) { - return dmidecode_get("baseboard"); + return dmidecode_get(global_options, "baseboard"); } static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args) { - return dmidecode_get("chassis"); + return dmidecode_get(global_options, "chassis"); } static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args) { - return dmidecode_get("processor"); + return dmidecode_get(global_options, "processor"); } static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args) { - return dmidecode_get("memory"); + return dmidecode_get(global_options, "memory"); } static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args) { - return dmidecode_get("cache"); + return dmidecode_get(global_options, "cache"); } static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args) { - return dmidecode_get("connector"); + return dmidecode_get(global_options, "connector"); } static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) { - return dmidecode_get("slot"); + return dmidecode_get(global_options, "slot"); } static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { @@ -364,7 +365,7 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) if(lu < 256) { char s[8]; sprintf(s, "%lu", lu); - return dmidecode_get(s); + return dmidecode_get(global_options, s); } e = 1; //return Py_False; @@ -382,26 +383,22 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) static PyObject *dmidecode_dump(PyObject * self, PyObject * null) { const char *f; - - f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; struct stat _buf; + f = (global_options->dumpfile ? global_options->dumpfile : global_options->devmem); stat(f, &_buf); if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode))) - if(dump(PyString_AS_STRING(opt.dumpfile))) + if(dump(PyString_AS_STRING(global_options->dumpfile))) Py_RETURN_TRUE; Py_RETURN_FALSE; } static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) { - PyObject *dev; - - if(opt.dumpfile != NULL) - dev = opt.dumpfile; - else - dev = PyString_FromString(opt.devmem); + PyObject *dev = NULL; + dev = PyString_FromString((global_options->dumpfile != NULL + ? global_options->dumpfile : global_options->devmem)); Py_INCREF(dev); return dev; } @@ -409,27 +406,26 @@ static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) { if(PyString_Check(arg)) { - if(opt.dumpfile == arg) - Py_RETURN_TRUE; - struct stat buf; char *f = PyString_AsString(arg); - stat(f, &buf); - if(opt.dumpfile) { - Py_DECREF(opt.dumpfile); + if( (f != NULL) && (strcmp(global_options->dumpfile, f) == 0) ) { + Py_RETURN_TRUE; } + stat(f, &buf); if(S_ISCHR(buf.st_mode)) { if(memcmp(PyString_AsString(arg), "/dev/mem", 8) == 0) { - opt.dumpfile = NULL; + if( global_options->dumpfile != NULL ) { + free(global_options->dumpfile); + global_options->dumpfile = NULL; + } Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } else if(!S_ISDIR(buf.st_mode)) { - opt.dumpfile = arg; - Py_INCREF(opt.dumpfile); + global_options->dumpfile = strdup(f); Py_RETURN_TRUE; } } @@ -450,8 +446,8 @@ static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) return NULL; } - free(opt.python_xml_map); - opt.python_xml_map = strdup(fname); + free(global_options->python_xml_map); + global_options->python_xml_map = strdup(fname); Py_RETURN_TRUE; } else { Py_RETURN_FALSE; @@ -484,13 +480,43 @@ static PyMethodDef DMIDataMethods[] = { {NULL, NULL, 0, NULL} }; +void destruct_options(void *ptr) { + options *opt = (options *) ptr; + + if( opt->mappingxml != NULL ) { + xmlFreeDoc(opt->mappingxml); + opt->mappingxml = NULL; + } + + if( opt->python_xml_map != NULL ) { + free(opt->python_xml_map); + opt->python_xml_map = NULL; + } + + if( opt->dmiversion_n != NULL ) { + xmlFreeNode(opt->dmiversion_n); + opt->dmiversion_n = NULL; + } + + if( opt->dumpfile != NULL ) { + free(opt->dumpfile); + opt->dumpfile = NULL; + } + + free(ptr); +} + + PyMODINIT_FUNC initdmidecode(void) { char *dmiver = NULL; PyObject *module = NULL; PyObject *version = NULL; + options *opt; - init(); + opt = (options *) malloc(sizeof(options)+2); + memset(opt, 0, sizeof(options)+2); + init(opt); module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, "Python extension module for dmidecode"); @@ -498,7 +524,12 @@ PyMODINIT_FUNC initdmidecode(void) Py_INCREF(version); PyModule_AddObject(module, "version", version); - opt.dmiversion_n = dmidecode_get_version(); - dmiver = dmixml_GetContent(opt.dmiversion_n); + opt->dmiversion_n = dmidecode_get_version(opt); + dmiver = dmixml_GetContent(opt->dmiversion_n); PyModule_AddObject(module, "dmi", dmiver ? PyString_FromString(dmiver) : Py_None); + + // Assign this options struct to the module as well with a destructor, that way it will + // clean up the memory for us. + PyModule_AddObject(module, "options", PyCObject_FromVoidPtr(opt, destruct_options)); + global_options = opt; } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 0f5c75d..04d1203 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -21,16 +21,16 @@ #include "dmihelper.h" -xmlNode *dmidecode_get_version(void); +xmlNode *dmidecode_get_version(options *); //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); -extern void dmi_dump(xmlNode *node, struct dmi_header *h); -extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); +extern void dmi_dump(options *, xmlNode *node, struct dmi_header *h); +extern xmlNode *dmi_decode(options *, xmlNode *parent_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); -extern int smbios_decode(u8 * buf, const char *devmem, xmlNode *node); -extern int legacy_decode(u8 * buf, const char *devmem, xmlNode *node); +extern int smbios_decode(options *, u8 * buf, const char *devmem, xmlNode *node); +extern int legacy_decode(options *, u8 * buf, const char *devmem, xmlNode *node); extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); extern void *mem_chunk(size_t base, size_t len, const char *devmem); diff --git a/src/dmihelper.h b/src/dmihelper.h index 6dccd94..bd2b7c9 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -111,8 +111,7 @@ typedef struct _options { xmlDoc *mappingxml; char *python_xml_map; xmlNode *dmiversion_n; - PyObject *dumpfile; + char *dumpfile; } options; -extern options opt; #endif -- cgit From 63e6c57e448d9dcc795cb14e89de6eb51f1033f6 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 4 Jun 2009 09:49:56 +1000 Subject: Removal of more deprecated/unused code. --- src/dmidecode.c | 1 - src/dmihelper.h | 23 ----------------------- 2 files changed, 24 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 4a978a9..8f2c545 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3691,7 +3691,6 @@ xmlNode *dmi_decode(options *opt, xmlNode *prnt_n, struct dmi_header * h, u16 ve //. 0xF1 --> 0xF100 //int minor = h->type<<8; - //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; sect_n = xmlNewChild(prnt_n, NULL, (xmlChar *) dmiMajor->tagname, NULL); diff --git a/src/dmihelper.h b/src/dmihelper.h index bd2b7c9..70f35ad 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -15,29 +15,6 @@ #define MAXVAL 1024 -static const int map_maj[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -}; - -typedef struct _dmi_codes_major { - const unsigned short code; - const char *id; - const char *desc; - const char *tagname; -} dmi_codes_major; - static const dmi_codes_major dmiCodesMajor[] = { {0, "3.3.1", "BIOS Information", "BIOSinfo"}, {1, "3.3.2", "System Information", "SystemInfo"}, -- cgit From 97ba1cbc0842897f5459a75ef1cd2ecbb3cab136 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Jun 2009 10:09:39 +0200 Subject: Resurrected struct _dmi_codes_major This got removed in commit 63e6c57e448d9dcc795cb14e89de6eb51f1033f6, but is needed for the following struct in dmihelper.h, and in dmidecode.c::dmi_decode():3694 --- src/dmihelper.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/dmihelper.h b/src/dmihelper.h index 70f35ad..e888639 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -15,6 +15,13 @@ #define MAXVAL 1024 +typedef struct _dmi_codes_major { + const unsigned short code; + const char *id; + const char *desc; + const char *tagname; +} dmi_codes_major; + static const dmi_codes_major dmiCodesMajor[] = { {0, "3.3.1", "BIOS Information", "BIOSinfo"}, {1, "3.3.2", "System Information", "SystemInfo"}, -- cgit From 5cd0472e1bc6a74f5011976e4b9fe31a0b84d938 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Jun 2009 10:18:16 +0200 Subject: Moved options global_options to a more suitable place. Added a comment --- src/dmidecodemodule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index e77384a..f9b0eb1 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -48,8 +48,6 @@ #include "dmixml.h" #include -options *global_options = NULL; - static void init(options *opt) { /* sanity check */ @@ -319,6 +317,10 @@ static PyObject *dmidecode_get(options *opt, const char *section) } +// This global variable should only be available for the "first-entry" functions +// which is defined in PyMethodDef DMIDataMethods[]. +options *global_options = NULL; + static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) { return dmidecode_get(global_options, "bios"); -- cgit From adc4191973b177f557d9a851d558d09cde841efe Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Jun 2009 15:21:21 +0200 Subject: Avoid passing the option struct to dmidecode.c functions --- src/dmidecode.c | 42 ++++++++++++++++++++++++------------------ src/dmidecode.h | 8 ++++---- src/dmidecodemodule.c | 10 +++++----- src/dmidecodemodule.h | 10 +++++----- 4 files changed, 38 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 8f2c545..974d6e3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -201,7 +201,7 @@ static int dmi_bcd_range(u8 value, u8 low, u8 high) return 1; } -void dmi_dump(options *opt, xmlNode *node, struct dmi_header * h) +void dmi_dump(xmlNode *node, struct dmi_header * h) { int row, i; const char *s; @@ -234,6 +234,9 @@ void dmi_dump(options *opt, xmlNode *node, struct dmi_header * h) while((s = dmi_string(h, i++)) != NULL) { //. FIXME: DUMP /* + * opt->flags will need to be transported to the function somehow + * when this feature is implemented completely. + * * if(opt->flags & FLAG_DUMP) { * int j, l = strlen(s)+1; * for(row=0; row<((l-1)>>4)+1; row++) { @@ -3684,7 +3687,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) ** Main */ -xmlNode *dmi_decode(options *opt, xmlNode *prnt_n, struct dmi_header * h, u16 ver) +xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) { const u8 *data = h->data; xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; @@ -4815,7 +4818,7 @@ xmlNode *dmi_decode(options *opt, xmlNode *prnt_n, struct dmi_header * h, u16 ve dmixml_AddAttribute(sect_n, "Type", "%i", h->type); dmixml_AddAttribute(sect_n, "InfoType", "%s", h->type >= 128 ? "OEM-specific" : "Unknown"); - dmi_dump(opt, sect_n, h); + dmi_dump(sect_n, h); break; } return sect_n; @@ -4829,10 +4832,11 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -xmlNode *dmi_table_string(options *opt, xmlNode *prnt_n, const struct dmi_header *h, const u8 *data, u16 ver) +xmlNode *dmi_table_string(const struct string_keyword *opt_string, xmlNode *prnt_n, + const struct dmi_header *h, const u8 *data, u16 ver) { int key; - u8 offset = opt->string->offset; + u8 offset = opt_string->offset; xmlNode *handle_n = NULL, *dmi_n = NULL; if(offset >= h->length) @@ -4842,7 +4846,7 @@ xmlNode *dmi_table_string(options *opt, xmlNode *prnt_n, const struct dmi_header assert( handle_n != NULL ); //. TODO: These should have more meaningful dictionary names - key = (opt->string->type << 8) | offset; + key = (opt_string->type << 8) | offset; switch (key) { case 0x108: @@ -5010,13 +5014,14 @@ int dump(const char *dumpfile) return ret == 0 ? found : ret; } -static void dmi_table(options *opt, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(u8 *type, const struct string_keyword *opt_string, + u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; int i = 0; - if(opt->type == NULL) { + if(type == NULL) { xmlNode *info_n = NULL; info_n = dmixml_AddTextChild(xmlnode, "DMIinfo", "%i structures occupying %i bytes", num, len); @@ -5049,9 +5054,8 @@ static void dmi_table(options *opt, u32 base, u16 len, u16 num, u16 ver, const c int display; to_dmi_header(&h, data); - display = ((opt->type == NULL || opt->type[h.type]) - // && !(h.type>39 && h.type<=127) - && !opt->string); + display = ((type == NULL || type[h.type]) // FIXME: Is this check correct? + && !opt_string); /* ** If a short entry is found (less than 4 bytes), not only it @@ -5094,11 +5098,11 @@ static void dmi_table(options *opt, u32 base, u16 len, u16 num, u16 ver, const c * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - handle_n = dmi_decode(opt, xmlnode, &h, ver); + handle_n = dmi_decode(xmlnode, &h, ver); } else fprintf(stderr, ""); - } else if(opt->string != NULL && opt->string->type == h.type) { - handle_n = dmi_table_string(opt, xmlnode, &h, data, ver); + } else if(opt_string != NULL && opt_string->type == h.type) { + handle_n = dmi_table_string(opt_string, xmlnode, &h, data, ver); } if( handle_n != NULL ) { dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); @@ -5172,7 +5176,8 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(options *opt, u8 * buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(u8 *type, const struct string_keyword *opt_string, + u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5188,7 +5193,7 @@ int smbios_decode(options *opt, u8 * buf, const char *devmem, xmlNode *xmlnode) break; } //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); - dmi_table(opt, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, + dmi_table(type, opt_string, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, xmlnode); } return check; @@ -5227,12 +5232,13 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(options *opt, u8 * buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(u8 *type, const struct string_keyword *opt_string, + u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) - dmi_table(opt, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), + dmi_table(type, opt_string, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index c199b7a..571c381 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -29,14 +29,14 @@ struct dmi_header { u8 *data; }; -void dmi_dump(options *, xmlNode *node, struct dmi_header * h); -xmlNode *dmi_decode(options *, xmlNode *parent_n, struct dmi_header * h, u16 ver); +void dmi_dump(xmlNode *node, struct dmi_header * h); +xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); -int smbios_decode(options *, u8 * buf, const char *devmem, xmlNode *xmlnode); +int smbios_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *xmlnode); xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); -int legacy_decode(options *, u8 * buf, const char *devmem, xmlNode *xmlnode); +int legacy_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index f9b0eb1..ab4561b 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -211,10 +211,10 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(opt, buf, opt->dumpfile, dmixml_n)) + if(smbios_decode(opt->type, opt->string, buf, opt->dumpfile, dmixml_n)) found++; } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode(opt, buf, opt->dumpfile, dmixml_n)) + if(legacy_decode(opt->type, opt->string, buf, opt->dumpfile, dmixml_n)) found++; } } else { @@ -228,12 +228,12 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(smbios_decode(opt, buf + fp, opt->devmem, dmixml_n)) { + if(smbios_decode(opt->type, opt->string, buf + fp, opt->devmem, dmixml_n)) { found++; fp += 16; } } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode(opt, buf + fp, opt->devmem, dmixml_n)) + if(legacy_decode(opt->type, opt->string, buf + fp, opt->devmem, dmixml_n)) found++; } } @@ -244,7 +244,7 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) } else { if((buf = mem_chunk(fp, 0x20, opt->devmem)) == NULL) ret = 1; - else if(smbios_decode(opt, buf, opt->devmem, dmixml_n)) + else if(smbios_decode(opt->type, opt->string, buf, opt->devmem, dmixml_n)) found++; // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 04d1203..7d085b2 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -24,13 +24,13 @@ xmlNode *dmidecode_get_version(options *); //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); -extern void dmi_dump(options *, xmlNode *node, struct dmi_header *h); -extern xmlNode *dmi_decode(options *, xmlNode *parent_n, struct dmi_header * h, u16 ver); +extern void dmi_dump(xmlNode *node, struct dmi_header *h); +extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); -extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); -extern int smbios_decode(options *, u8 * buf, const char *devmem, xmlNode *node); -extern int legacy_decode(options *, u8 * buf, const char *devmem, xmlNode *node); +// extern void dmi_table(u8 *type, const struct string_keyword *opt_string, u32 base, u16 len, u16 num, u16 ver, const char *devmem); +extern int smbios_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *node); +extern int legacy_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *node); extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); extern void *mem_chunk(size_t base, size_t len, const char *devmem); -- cgit From 2cf4f28f6fc671478003b31c03b93e070eee9942 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Fri, 5 Jun 2009 01:42:07 +1000 Subject: Further removal of deprecated functions Removed the `dmi_table_string' function, and `const struct string_keyword *string' from the `options' struct. Also modified the function calls that are now free of this, namely, `legacy_decode' and `smbios_decode'. --- src/dmidecode.c | 65 +++++---------------------------------------------- src/dmidecode.h | 5 ++-- src/dmidecodemodule.c | 10 ++++---- src/dmihelper.h | 1 - 4 files changed, 14 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 974d6e3..fbc151a 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4832,53 +4832,6 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -xmlNode *dmi_table_string(const struct string_keyword *opt_string, xmlNode *prnt_n, - const struct dmi_header *h, const u8 *data, u16 ver) -{ - int key; - u8 offset = opt_string->offset; - xmlNode *handle_n = NULL, *dmi_n = NULL; - - if(offset >= h->length) - return NULL; - - handle_n = xmlNewChild(prnt_n, NULL, (xmlChar *) "DMItable", NULL); - assert( handle_n != NULL ); - - //. TODO: These should have more meaningful dictionary names - key = (opt_string->type << 8) | offset; - - switch (key) { - case 0x108: - dmi_system_uuid(handle_n, data + offset, ver); - dmixml_AddAttribute(handle_n, "DMItype", "0x108"); - break; - - case 0x305: - dmi_chassis_type(handle_n, data[offset]); - dmixml_AddAttribute(handle_n, "DMItype", "0x305"); - // FIXME: Missing break? - - case 0x406: - dmi_processor_family(handle_n, h); - dmixml_AddAttribute(handle_n, "DMItype", "0x406"); - break; - - case 0x416: - dmi_n = dmixml_AddTextChild(handle_n, "ProcessorFrequency", "%s", - dmi_processor_frequency((u8 *) data + offset)); - dmixml_AddAttribute(dmi_n, "DMItype", "0x416"); - dmi_n = NULL; - break; - - default: - dmi_n = dmixml_AddTextChild(handle_n, "Unknown", "%s", dmi_string(h, data[offset])); - dmixml_AddAttribute(dmi_n, "DMItype", "0x%03x", key); - } - - return handle_n; -} - /* static void dmi_table_dump(options *opt, u32 base, u16 len, const char *devmem) { @@ -5014,8 +4967,7 @@ int dump(const char *dumpfile) return ret == 0 ? found : ret; } -static void dmi_table(u8 *type, const struct string_keyword *opt_string, - u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; @@ -5054,8 +5006,7 @@ static void dmi_table(u8 *type, const struct string_keyword *opt_string, int display; to_dmi_header(&h, data); - display = ((type == NULL || type[h.type]) // FIXME: Is this check correct? - && !opt_string); + display = (type == NULL || type[h.type]) // FIXME: Is this check correct? /* ** If a short entry is found (less than 4 bytes), not only it @@ -5101,8 +5052,6 @@ static void dmi_table(u8 *type, const struct string_keyword *opt_string, handle_n = dmi_decode(xmlnode, &h, ver); } else fprintf(stderr, ""); - } else if(opt_string != NULL && opt_string->type == h.type) { - handle_n = dmi_table_string(opt_string, xmlnode, &h, data, ver); } if( handle_n != NULL ) { dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); @@ -5176,8 +5125,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(u8 *type, const struct string_keyword *opt_string, - u8 *buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5193,7 +5141,7 @@ int smbios_decode(u8 *type, const struct string_keyword *opt_string, break; } //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); - dmi_table(type, opt_string, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, + dmi_table(type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, xmlnode); } return check; @@ -5232,13 +5180,12 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(u8 *type, const struct string_keyword *opt_string, - u8 *buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) - dmi_table(type, opt_string, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), + dmi_table(type, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index 571c381..cd6b8a6 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -33,10 +33,11 @@ void dmi_dump(xmlNode *node, struct dmi_header * h); xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); + xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); -int smbios_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *xmlnode); xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); -int legacy_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *xmlnode); +int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode); +int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index ab4561b..e551d67 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -211,10 +211,10 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(opt->type, opt->string, buf, opt->dumpfile, dmixml_n)) + if(smbios_decode(opt->type, buf, opt->dumpfile, dmixml_n)) found++; } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode(opt->type, opt->string, buf, opt->dumpfile, dmixml_n)) + if(legacy_decode(opt->type, buf, opt->dumpfile, dmixml_n)) found++; } } else { @@ -228,12 +228,12 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(smbios_decode(opt->type, opt->string, buf + fp, opt->devmem, dmixml_n)) { + if(smbios_decode(opt->type, buf + fp, opt->devmem, dmixml_n)) { found++; fp += 16; } } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode(opt->type, opt->string, buf + fp, opt->devmem, dmixml_n)) + if(legacy_decode(opt->type, buf + fp, opt->devmem, dmixml_n)) found++; } } @@ -244,7 +244,7 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) } else { if((buf = mem_chunk(fp, 0x20, opt->devmem)) == NULL) ret = 1; - else if(smbios_decode(opt->type, opt->string, buf, opt->devmem, dmixml_n)) + else if(smbios_decode(opt->type, buf, opt->devmem, dmixml_n)) found++; // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } diff --git a/src/dmihelper.h b/src/dmihelper.h index e888639..ccf840d 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -91,7 +91,6 @@ typedef struct _options { const char *devmem; unsigned int flags; u8 *type; - const struct string_keyword *string; xmlDoc *mappingxml; char *python_xml_map; xmlNode *dmiversion_n; -- cgit From 842f44f4efff348367ff9be5972def06d899b77b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Jun 2009 17:40:01 +0200 Subject: Fixed compiling issues after commit 2cf4f28f6fc671478003b31c03b93e070eee9942 Also cleaned up a little bit more, removed more unneeded stuff. --- src/dmidecode.c | 4 +--- src/dmidecodemodule.h | 6 ++---- src/dmihelper.h | 8 -------- 3 files changed, 3 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index fbc151a..0f77e67 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5003,10 +5003,8 @@ static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char u8 *next; struct dmi_header h; - int display; to_dmi_header(&h, data); - display = (type == NULL || type[h.type]) // FIXME: Is this check correct? /* ** If a short entry is found (less than 4 bytes), not only it @@ -5037,7 +5035,7 @@ static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char next += 2; xmlNode *handle_n = NULL; - if(display) { + if( type == NULL || type[h.type] ) { // FIXME: Is this check correct? if(next - buf <= len) { /* TODO: ... * if(opt->flags & FLAG_DUMP) { diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 7d085b2..47b22b6 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -23,14 +23,12 @@ xmlNode *dmidecode_get_version(options *); -//extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern void dmi_dump(xmlNode *node, struct dmi_header *h); extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); -// extern void dmi_table(u8 *type, const struct string_keyword *opt_string, u32 base, u16 len, u16 num, u16 ver, const char *devmem); -extern int smbios_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *node); -extern int legacy_decode(u8 *type, const struct string_keyword *opt_string, u8 *buf, const char *devmem, xmlNode *node); +extern int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *node); +extern int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *node); extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); extern void *mem_chunk(size_t base, size_t len, const char *devmem); diff --git a/src/dmihelper.h b/src/dmihelper.h index ccf840d..b0816b7 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -78,14 +78,6 @@ typedef struct _dmi_minor { struct _dmi_minor *next; } dmi_minor; - -/*** dmiopt.h ***/ -struct string_keyword { - const char *keyword; - u8 type; - u8 offset; -}; - /*** dmiopt.h ***/ typedef struct _options { const char *devmem; -- cgit From 2dce918111e8ef477942cd5ecf8340ddf39c1b5b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Jun 2009 17:59:23 +0200 Subject: More cleanup --- src/dmidecode.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 0f77e67..d55a697 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4832,23 +4832,6 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -/* -static void dmi_table_dump(options *opt, u32 base, u16 len, const char *devmem) -{ - u8 *buf; - - if ((buf = mem_chunk(base, len, devmem)) == NULL) - { - fprintf(stderr, "Failed to read table, sorry.\n"); - return; - } - - printf("# Writing %d bytes to %s.\n", len, opt->dumpfile); - write_dump(32, len, buf, opt->dumpfile, 0); - free(buf); -} -*/ - /* * Build a crafted entry point with table address hard-coded to 32, * as this is where we will put it in the output file. We adjust the -- cgit From ead8b4135115ec4a74c7866249b9155ea941a892 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Jun 2009 12:25:05 +0200 Subject: Implemented fix making python-dmidecode work with Python v2.3 This resolves Ticket #7 (http://projects.autonomy.net.au/python-dmidecode/ticket/7) (cherry picked from commit 39cbdfb56e80cabbd67754d8d77f781e14eaa3da) --- src/compat.h | 43 +++++++++++++++++++++++++++++++++++++++++++ src/dmidecodemodule.h | 1 + 2 files changed, 44 insertions(+) create mode 100644 src/compat.h (limited to 'src') diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..80a08c6 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,43 @@ +/* Defines to make python-dmidecode work with more Python versions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + + +#ifndef _COMPAT_H +#define _COMPAT_H + +// Missing in Python 2.3 +#ifndef Py_RETURN_TRUE +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#endif + +// Missing in Python 2.3 +#ifndef Py_RETURN_FALSE +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#endif + +// Missing in Python 2.3 +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#endif diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 47b22b6..ea5e36e 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -9,6 +9,7 @@ #include #include +#include "compat.h" #include "version.h" #include "config.h" #include "types.h" -- cgit From 4b22254e56bfdbec884a7f1cf634e340eff813c5 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 16:09:22 +0200 Subject: Renamed _dmiMAP_GetRootElement(...) to dmiMAP_GetRootElement(...) and exported the function --- src/xmlpythonizer.c | 6 +++--- src/xmlpythonizer.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 74b7db3..6c4d4c0 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -417,7 +417,7 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { * @param xmlDoc* XML mapping document pointer * @return xmlNode* The root xmlNode of a valid XML mapping document. On invalid document NULL is returned. */ -xmlNode *_dmiMAP_GetRootElement(xmlDoc *mapdoc) { +xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc) { xmlNode *rootnode = NULL; // Find the root tag and locate our mapping @@ -477,7 +477,7 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; - node = _dmiMAP_GetRootElement(xmlmap); + node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { return NULL; } @@ -563,7 +563,7 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; // Validate the XML mapping document and get the root element - node = _dmiMAP_GetRootElement(xmlmap); + node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { PyErr_SetString(PyExc_IOError, "No valid mapping XML recieved"); return NULL; diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index bda077e..f37bfa5 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,6 +48,7 @@ typedef struct ptzMAP_s { } ptzMAP; +xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc); ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname); ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } -- cgit From bfbac44bd8c0fcddcdcfade6a15313560c9cc6eb Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 16:48:15 +0200 Subject: Big rewrite again, simplified the usage of opt->type Instead of building up an u8 array with 255 cells where we only use one cell at the time now, just pass the type id value as an int the whole way through. --- src/dmidecode.c | 11 +-- src/dmidecode.h | 4 +- src/dmidecodemodule.c | 198 +++++++++++++++++++++++++++++++------------------- src/dmidecodemodule.h | 31 +------- src/dmihelper.h | 2 +- 5 files changed, 135 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index d55a697..0fca9c9 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -90,6 +90,7 @@ #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) + /******************************************************************************* ** Type-independant Stuff */ @@ -4950,13 +4951,13 @@ int dump(const char *dumpfile) return ret == 0 ? found : ret; } -static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; int i = 0; - if(type == NULL) { + if( type == -1 ) { xmlNode *info_n = NULL; info_n = dmixml_AddTextChild(xmlnode, "DMIinfo", "%i structures occupying %i bytes", num, len); @@ -5018,7 +5019,7 @@ static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char next += 2; xmlNode *handle_n = NULL; - if( type == NULL || type[h.type] ) { // FIXME: Is this check correct? + if( h.type == type ) { if(next - buf <= len) { /* TODO: ... * if(opt->flags & FLAG_DUMP) { @@ -5106,7 +5107,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5161,7 +5162,7 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); diff --git a/src/dmidecode.h b/src/dmidecode.h index cd6b8a6..f0cb1ab 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -36,8 +36,8 @@ void to_dmi_header(struct dmi_header *h, u8 * data); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); -int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode); -int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode); +int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode); +int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index e551d67..161e1b7 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -57,59 +57,36 @@ static void init(options *opt) opt->devmem = DEFAULT_MEM_DEV; opt->dumpfile = NULL; opt->flags = 0; - opt->type = NULL; + opt->type = -1; opt->dmiversion_n = NULL; opt->mappingxml = NULL; opt->python_xml_map = strdup(PYTHON_XML_MAP); } -u8 *parse_opt_type(u8 * p, const char *arg) +int parse_opt_type(const char *arg) { - - /* Allocate memory on first call only */ - if(p == NULL) { - if(!(p = (u8 *) calloc(256, sizeof(u8)))) { - perror("calloc"); - return NULL; - } - } - - unsigned int i, j; - - /* First try as a keyword */ - for(i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) { - if(!strcasecmp(arg, opt_type_keyword[i].keyword)) { - j = 0; - while(opt_type_keyword[i].type[j] != 255) - p[opt_type_keyword[i].type[j++]] = 1; - return p; - } - } - - /* Else try as a number */ while(*arg != '\0') { - unsigned long val; + int val; char *next; val = strtoul(arg, &next, 0); if(next == arg) { fprintf(stderr, "Invalid type keyword: %s\n", arg); - free(p); - return NULL; + return -1; } if(val > 0xff) { - fprintf(stderr, "Invalid type number: %lu\n", val); - free(p); - return NULL; + fprintf(stderr, "Invalid type number: %i\n", val); + return -1; } - p[val] = 1; + if( val >= 0 ) { + return val; + } arg = next; while(*arg == ',' || *arg == ' ') arg++; } - - return p; + return -1; } @@ -182,9 +159,6 @@ xmlNode *dmidecode_get_version(options *opt) if( !found ) { fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry."); } - if( opt->type != NULL ) { - free(opt->type); - } return ver_n; } @@ -249,9 +223,6 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } } - if( opt->type != NULL ) { - free(opt->type); - } if(ret == 0) { free(buf); } @@ -259,22 +230,41 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) return ret; } -static PyObject *dmidecode_get(options *opt, const char *section) +xmlNode* load_mappingxml(options *opt) { + xmlNode *group_n = NULL; + + if( opt->mappingxml == NULL ) { + // Load mapping into memory + opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0); + if( opt->mappingxml == NULL ) { + PyErr_SetString(PyExc_SystemError, "Could not open XML mapping file\n"); + assert( opt->mappingxml != NULL ); + return 1; + } + } + + + if( (group_n = dmiMAP_GetRootElement(opt->mappingxml)) == NULL ) { + PyErr_SetString(PyExc_SystemError, "Invalid XML mapping file\n"); + assert( group_n != NULL ); + return NULL; + } + + return group_n; +} + +static PyObject *dmidecode_get_group(options *opt, const char *section) { PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; + xmlNode *group_n = NULL; + ptzMAP *mapping = NULL; /* Set default option values */ if( opt->devmem == NULL ) { opt->devmem = DEFAULT_MEM_DEV; } opt->flags = 0; - opt->type = NULL; - opt->type = parse_opt_type(opt->type, section); - - if(opt->type == NULL) { - return NULL; - } dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); assert( dmixml_n != NULL ); @@ -283,79 +273,136 @@ static PyObject *dmidecode_get(options *opt, const char *section) xmlAddChild(dmixml_n, xmlCopyNode(opt->dmiversion_n, 1)); } - if(dmidecode_get_xml(opt, dmixml_n) == 0) { - ptzMAP *mapping = NULL; + // Fetch the Mapping XML file + if( (group_n = load_mappingxml(opt)) == NULL) { + return NULL; + } - // Convert the retrieved XML nodes to Python dicts - if( opt->mappingxml == NULL ) { - // Load mapping into memory - opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0); - assert( opt->mappingxml != NULL ); + // Find the section in the XML containing the group mappings + if( (group_n = dmixml_FindNode(group_n, "GroupMapping")) == NULL ) { + PyErr_SetString(PyExc_SystemError, + "Could not find the GroupMapping section in the XML mapping\n"); + assert( group_n != NULL ); + return NULL; + } + + // Find the XML node containing the Mapping section requested to be decoded + if( (group_n = dmixml_FindNodeByAttr(group_n, "Mapping", "name", section)) == NULL ) { + PyErr_SetString(PyExc_SystemError, + "Could not find the given Mapping section in the XML mapping\n"); + assert( group_n != NULL ); + return NULL; + } + + if( group_n->children == NULL ) { + PyErr_SetString(PyExc_SystemError, + "Mapping is empty for the given section in the XML mapping\n"); + assert( group_n->children != NULL ); + return NULL; + } + + // Go through all TypeMap's belonging to this Mapping section + foreach_xmlnode(dmixml_FindNode(group_n, "TypeMap"), group_n) { + char *typeid = dmixml_GetAttrValue(group_n, "id"); + + if( group_n->type != XML_ELEMENT_NODE ) { + continue; } - mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); - if( mapping == NULL ) { + // The children of tags must only be and + // they must have an 'id' attribute + if( (typeid == NULL) || (xmlStrcmp(group_n->name, (xmlChar *) "TypeMap") != 0) ) { + PyErr_SetString(PyExc_SystemError, + "Invalid Mapping node in mapping XML\n"); return NULL; } - // Generate Python dict out of XML node - pydata = pythonizeXMLnode(mapping, dmixml_n); + // Parse the typeid string to a an integer + opt->type = parse_opt_type(typeid); + if(opt->type == -1) { + PyErr_SetString(PyExc_SystemError, "Unexpected: opt->type is -1"); + return NULL; + } + // Parse the DMI data and put the result into dmixml_n node chain. + if( dmidecode_get_xml(opt, dmixml_n) != 0 ) { + PyErr_SetString(PyExc_SystemError, + "Error decoding DMI data\n"); + return NULL; + } + } #if 0 // DEBUG - will dump generated XML to stdout - xmlDoc *doc = xmlNewDoc((xmlChar *) "1.0"); - xmlDocSetRootElement(doc, xmlCopyNode(dmixml_n, 1)); - xmlSaveFormatFileEnc("-", doc, "UTF-8", 1); - xmlFreeDoc(doc); + xmlDoc *doc = xmlNewDoc((xmlChar *) "1.0"); + xmlDocSetRootElement(doc, xmlCopyNode(dmixml_n, 1)); + xmlSaveFormatFileEnc("-", doc, "UTF-8", 1); + xmlFreeDoc(doc); #endif - ptzmap_Free(mapping); - xmlFreeNode(dmixml_n); - } else { + + // Convert the retrieved XML nodes to a Python dictionary + mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); + if( mapping == NULL ) { return NULL; } + // Generate Python dict out of XML node + pydata = pythonizeXMLnode(mapping, dmixml_n); + if( pydata == NULL ) { + PyErr_SetString(PyExc_SystemError, + "Error converting XML to Python data.\n"); + } + + // Clean up and return the resulting Python dictionary + ptzmap_Free(mapping); + xmlFreeNode(dmixml_n); + return pydata; } +static PyObject *dmidecode_get_typeid(options *opt, const char *section) { + return NULL; +} + + // This global variable should only be available for the "first-entry" functions // which is defined in PyMethodDef DMIDataMethods[]. options *global_options = NULL; static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "bios"); + return dmidecode_get_group(global_options, "bios"); } static PyObject *dmidecode_get_system(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "system"); + return dmidecode_get_group(global_options, "system"); } static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "baseboard"); + return dmidecode_get_group(global_options, "baseboard"); } static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "chassis"); + return dmidecode_get_group(global_options, "chassis"); } static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "processor"); + return dmidecode_get_group(global_options, "processor"); } static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "memory"); + return dmidecode_get_group(global_options, "memory"); } static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "cache"); + return dmidecode_get_group(global_options, "cache"); } static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "connector"); + return dmidecode_get_group(global_options, "connector"); } static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) { - return dmidecode_get(global_options, "slot"); + return dmidecode_get_group(global_options, "slot"); } static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { @@ -367,7 +414,7 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) if(lu < 256) { char s[8]; sprintf(s, "%lu", lu); - return dmidecode_get(global_options, s); + return dmidecode_get_typeid(global_options, s); } e = 1; //return Py_False; @@ -516,6 +563,9 @@ PyMODINIT_FUNC initdmidecode(void) PyObject *version = NULL; options *opt; + xmlInitParser(); + xmlXPathInit(); + opt = (options *) malloc(sizeof(options)+2); memset(opt, 0, sizeof(options)+2); init(opt); diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index ea5e36e..9699e82 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -28,37 +28,10 @@ extern void dmi_dump(xmlNode *node, struct dmi_header *h); extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); -extern int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *node); -extern int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *node); +extern int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *node); +extern int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *node); extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); extern void *mem_chunk(size_t base, size_t len, const char *devmem); -extern u8 *parse_opt_type(u8 * p, const char *arg); -static const u8 opt_type_bios[] = { 0, 13, 255 }; -static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 }; -static const u8 opt_type_baseboard[] = { 2, 10, 255 }; -static const u8 opt_type_chassis[] = { 3, 255 }; -static const u8 opt_type_processor[] = { 4, 255 }; -static const u8 opt_type_memory[] = { 5, 6, 16, 17, 255 }; -static const u8 opt_type_cache[] = { 7, 255 }; -static const u8 opt_type_connector[] = { 8, 255 }; -static const u8 opt_type_slot[] = { 9, 255 }; -struct type_keyword { - const char *keyword; - const u8 *type; -}; - -static const struct type_keyword opt_type_keyword[] = { - {"bios", opt_type_bios}, - {"system", opt_type_system}, - {"baseboard", opt_type_baseboard}, - {"chassis", opt_type_chassis}, - {"processor", opt_type_processor}, - {"memory", opt_type_memory}, - {"cache", opt_type_cache}, - {"connector", opt_type_connector}, - {"slot", opt_type_slot}, -}; - PyMODINIT_FUNC initdmidecode(void); diff --git a/src/dmihelper.h b/src/dmihelper.h index b0816b7..6607dc5 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -82,7 +82,7 @@ typedef struct _dmi_minor { typedef struct _options { const char *devmem; unsigned int flags; - u8 *type; + int type; xmlDoc *mappingxml; char *python_xml_map; xmlNode *dmiversion_n; -- cgit From f9589f45af460c82fac3712b0560de0e1dc6171d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 17:14:29 +0200 Subject: Pass typeid as int internally to the dmiMAP_ParseMappingXML_TypeID(...) This function will then convert the value to proper hex value for further processing. --- src/xmlpythonizer.c | 10 +++++++--- src/xmlpythonizer.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 6c4d4c0..f7fdb3c 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -474,18 +474,22 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) * @param const char* The Type ID to create the map for * @return ptzMAP* The parsed XML containing as a ptzMAP */ -ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname) { +ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid) { xmlNode *node = NULL; + char typeid_s[16]; node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { return NULL; } + memset(&typeid_s, 0, 16); + snprintf(typeid_s, 14, "0x%02x", typeid); + // Find the section node = dmixml_FindNode(node, "TypeMapping"); assert( node != NULL ); - return _dmimap_parse_mapping_node_typeid(node, mapname); + return _dmimap_parse_mapping_node_typeid(node, typeid_s); } @@ -1103,7 +1107,7 @@ int main(int argc, char **argv) { assert( doc != NULL ); map = dmiMAP_ParseMappingXML_GroupName(doc, argv[1]); - // map = dmiMAP_ParseMappingXML_TypeID(doc, argv[1]); + // map = dmiMAP_ParseMappingXML_TypeID(doc, atoi(rgv[1])); ptzmap_Dump(map); printf("----------------------\n"); assert(map != NULL); diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index f37bfa5..df60140 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -49,7 +49,7 @@ typedef struct ptzMAP_s { } ptzMAP; xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc); -ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid); ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From 0d99e20115f56a3f7a0b56ada60662c51a5e1314 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 17:20:21 +0200 Subject: Implemented dmidecode.type(int) function properly --- src/dmidecodemodule.c | 85 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 161e1b7..fdef4ad 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -239,7 +239,7 @@ xmlNode* load_mappingxml(options *opt) { if( opt->mappingxml == NULL ) { PyErr_SetString(PyExc_SystemError, "Could not open XML mapping file\n"); assert( opt->mappingxml != NULL ); - return 1; + return NULL; } } @@ -359,8 +359,56 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) } -static PyObject *dmidecode_get_typeid(options *opt, const char *section) { - return NULL; +static PyObject *dmidecode_get_typeid(options *opt, int typeid) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + ptzMAP *mapping = NULL; + + /* Set default option values */ + if( opt->devmem == NULL ) { + opt->devmem = DEFAULT_MEM_DEV; + } + opt->flags = 0; + + dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); + assert( dmixml_n != NULL ); + // Append DMI version info + if( opt->dmiversion_n != NULL ) { + xmlAddChild(dmixml_n, xmlCopyNode(opt->dmiversion_n, 1)); + } + + // Fetch the Mapping XML file + if( load_mappingxml(opt) == NULL) { + return NULL; + } + + // Parse the DMI data and put the result into dmixml_n node chain. + opt->type = typeid; + if( dmidecode_get_xml(opt, dmixml_n) != 0 ) { + PyErr_SetString(PyExc_SystemError, + "Error decoding DMI data\n"); + return NULL; + } + + // Convert the retrieved XML nodes to a Python dictionary + mapping = dmiMAP_ParseMappingXML_TypeID(opt->mappingxml, opt->type); + if( mapping == NULL ) { + return NULL; + } + + // Generate Python dict out of XML node + pydata = pythonizeXMLnode(mapping, dmixml_n); + if( pydata == NULL ) { + PyErr_SetString(PyExc_SystemError, + "Error converting XML to Python data.\n"); + } + + // Clean up and return the resulting Python dictionary + ptzmap_Free(mapping); + xmlFreeNode(dmixml_n); + + return pydata; } @@ -406,27 +454,26 @@ static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) } static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { - long unsigned int lu; + int typeid; char msg[8194]; - int e = 0; + PyObject *pydata = NULL; - if(PyArg_ParseTuple(args, (char *)"i", &lu)) { - if(lu < 256) { - char s[8]; - sprintf(s, "%lu", lu); - return dmidecode_get_typeid(global_options, s); + if(PyArg_ParseTuple(args, (char *)"i", &typeid)) { + if( (typeid >= 0) && (typeid < 256) ) { + pydata = dmidecode_get_typeid(global_options, typeid); + } else { + snprintf(msg, 8192, "Types are bound between 0 and 255 (inclusive)%c", 0); + pydata = NULL; } - e = 1; - //return Py_False; + } else { + snprintf(msg, 8192, "Invalid type identifier%c", 0); + pydata = NULL; } - e = 2; - //return Py_None; - - if(e == 1) snprintf(msg, 8193, "Types are bound between 0 and 255 (inclusive)%c", 0); - else snprintf(msg, 8193, "Invalid type identifier%c", 0); - PyErr_SetString(PyExc_SystemError, msg); - return NULL; + if( pydata == NULL ) { + PyErr_SetString(PyExc_SystemError, msg); + } + return pydata; } static PyObject *dmidecode_dump(PyObject * self, PyObject * null) -- cgit From 8e3054ace87b7b91f9c4f4cbfede331901caecaa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 17:38:10 +0200 Subject: Fixed SEGV when setting new devive file --- src/dmidecodemodule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index fdef4ad..0e2ff10 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -462,7 +462,8 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) if( (typeid >= 0) && (typeid < 256) ) { pydata = dmidecode_get_typeid(global_options, typeid); } else { - snprintf(msg, 8192, "Types are bound between 0 and 255 (inclusive)%c", 0); + snprintf(msg, 8192, "Types are bound between 0 and 255 (inclusive)." + "Type value used was '%i'%c", typeid, 0); pydata = NULL; } } else { @@ -505,7 +506,8 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) struct stat buf; char *f = PyString_AsString(arg); - if( (f != NULL) && (strcmp(global_options->dumpfile, f) == 0) ) { + if( (f != NULL) && (global_options->dumpfile != NULL ) + && (strcmp(global_options->dumpfile, f) == 0) ) { Py_RETURN_TRUE; } -- cgit From e5055e5de82f0da125eb688971ccb990adcdeba3 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 20:16:53 +0200 Subject: Added new error handling code, to simplify error handling --- src/dmierror.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dmierror.h | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/dmierror.c create mode 100644 src/dmierror.h (limited to 'src') diff --git a/src/dmierror.c b/src/dmierror.c new file mode 100644 index 0000000..03d260a --- /dev/null +++ b/src/dmierror.c @@ -0,0 +1,79 @@ +/* Simpilfied and improved Python Error/Exception functions + * + * 2009 (C) David Sommerseth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +/** + * @file dmierror.h + * @brief Simpilfied and improved Python Error/Exception functions + * @author David Sommerseth + */ + +// #include +#include +#include +#include +#include + +#define PRINT_ERRORS 1 + +/** + * A more flexible function for setting error messages. This function + * is called via PyReturnError(...) macro which also returns NULL. + * @author David Sommerseth + * @param PyObject* A Python Exception object + * @param const char* Error message to follow the exception, may be string formated + * + */ +void _pyReturnError(void *exception, const char *fname, int line, const char *fmt, ...) +{ + va_list ap; + char *buf = NULL; + + va_start(ap, fmt); + buf = (char *) malloc(4098); + memset(buf, 0, 4098); + + if( buf == NULL ) { + // Backup routine if we can't get the needed memory + fprintf(stderr, "\n\n** ERROR ALLOCATING ERROR MESSAGE BUFFER\n\n"); + fprintf(stderr, "** ERROR: [%s:%i] ", fname, line); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + return; + } + + // Set the error state and message + snprintf(buf, 4096, "[%s:%i] %s", fname, line, fmt); + /// PyErr_Format(exception, buf, ap); + +#ifdef PRINT_ERRORS + fprintf(stderr, "\n**\n** ERROR: "); + vfprintf(stderr, buf, ap); + fprintf(stderr, "\n**\n\n"); +#endif + va_end(ap); + free(buf); buf = NULL; +} + diff --git a/src/dmierror.h b/src/dmierror.h new file mode 100644 index 0000000..0fa0858 --- /dev/null +++ b/src/dmierror.h @@ -0,0 +1,54 @@ +/* Simpilfied and improved Python Error/Exception functions + * + * 2009 (C) David Sommerseth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +/** + * @file dmierror.h + * @brief Simpilfied and improved Python Error/Exception functions + * @author David Sommerseth + */ + + +#ifndef DMIERROR_H +#define DMIERROR_H + +#include + +void _pyReturnError(PyObject *exception, const char *fname, int line, const char *msgfmt, ...); + +/** + * A more flexible function for setting error messages. + * This macro is the one which is supposed to be used in programs, as it will + * also exit the calling function with NULL. + * @author David Sommerseth + * @param PyObject* A Python Exception object + * @param const char* Error message to follow the exception, may be string formated + */ +#define PyReturnError(Exception, msg...) { \ + _pyReturnError(Exception, __FILE__, __LINE__,## msg); \ + return NULL; \ + } + + +#endif -- cgit From 80bf200604d80703f9ef02fe8a4a505b6cd96ab6 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 20:33:20 +0200 Subject: Moved xmlpythonizer.c over to new error functions --- src/xmlpythonizer.c | 107 +++++++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index f7fdb3c..fbf01fd 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -81,6 +81,7 @@ #include "util.h" #include "dmixml.h" +#include "dmierror.h" #include "xmlpythonizer.h" @@ -324,13 +325,15 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { } } if( map_n == NULL ) { - return NULL; + PyReturnError(PyExc_NameError, "No mapping nodes were found"); } // Go to the first node if( xmlStrcmp(node->name, (xmlChar *) "Map") != 0 ) { map_n = dmixml_FindNode(node, "Map"); if( map_n == NULL ) { + // If we don't find a node, we just exit now. + // Other checks will raise an exception if needed. return NULL; } } @@ -427,14 +430,14 @@ xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc) { // Verify that the root node got the right name if( (rootnode == NULL) || (xmlStrcmp(rootnode->name, (xmlChar *) "dmidecode_mapping") != 0 )) { - PyErr_SetString(PyExc_IOError, "Invalid XML-Python mapping file"); - return NULL; + PyReturnError(PyExc_IOError, "Invalid XML-Python mapping file. " + "Root node is not 'dmidecode_mapping'"); } // Verify that it's of a version we support if( strcmp(dmixml_GetAttrValue(rootnode, "version"), "1") != 0 ) { - PyErr_SetString(PyExc_IOError, "Unsupported XML-Python mapping file format"); - return NULL; + PyReturnError(PyExc_RuntimeError, "Unsupported XML-Python mapping file format. " + "Only version 1 is supported"); } return rootnode; } @@ -456,10 +459,9 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) // Find the tag with our type ID node = dmixml_FindNodeByAttr(mapnode, "TypeMap", "id", typeid); if( node == NULL ) { - char msg[8194]; - snprintf(msg, 8193, "No mapping for type ID '%s' was found " - "in the XML-Python mapping file%c", typeid, 0); - PyErr_SetString(PyExc_IOError, msg); + // No exception handling possible here, as we don't return PyObject + fprintf(stderr,"** WARNING: Could not find any XML->Python " + "mapping for type ID '%s'", typeid); return NULL; } // Create an internal map structure and return this structure @@ -480,7 +482,7 @@ ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid) { node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { - return NULL; + PyReturnError(PyExc_RuntimeError, "Could not locate root XML node for mapping file"); } memset(&typeid_s, 0, 16); @@ -514,25 +516,25 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { } } if( map_n == NULL ) { - PyErr_SetString(PyExc_IOError, "Could not find any valid XML nodes"); - return NULL; + PyReturnError(PyExc_RuntimeError, "Could not find any valid XML nodes"); } // Check that our "root" node is as expected if( xmlStrcmp(node->name, (xmlChar *) "Mapping") != 0 ) { - PyErr_SetString(PyExc_IOError, "Could not find any valid XML nodes"); - return NULL; + PyReturnError(PyExc_NameError, "Expected to find node"); } // Go to the first node map_n = dmixml_FindNode(node, "TypeMap"); if( map_n == NULL ) { - return NULL; + PyReturnError(PyExc_NameError, "Could not locate any nodes"); } // Get the root element of the tag, needed for further parsing typemap = dmixml_FindNode(xmlDocGetRootElement(xmlmap), "TypeMapping"); - assert( typemap != NULL ); + if( typemap == NULL ) { + PyReturnError(PyExc_NameError, "Could not locate the node"); + } // Loop through it's children foreach_xmlnode(map_n, ptr_n) { @@ -569,22 +571,20 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { // Validate the XML mapping document and get the root element node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { - PyErr_SetString(PyExc_IOError, "No valid mapping XML recieved"); - return NULL; + PyReturnError(PyExc_RuntimeError, "No valid mapping XML recieved"); } // Find the section node = dmixml_FindNode(node, "GroupMapping"); - assert( node != NULL ); + if( node == NULL ) { + PyReturnError(PyExc_NameError, "Could not find the node"); + } // Find the section matching our request (mapname) node = dmixml_FindNodeByAttr(node, "Mapping", "name", mapname); if( node == NULL ) { - char msg[8194]; - snprintf(msg, 8193, "No group mapping for '%s' was found " - "in the XML-Python mapping file%c", mapname, 0); - PyErr_SetString(PyExc_IOError, msg); - return NULL; + PyReturnError(PyExc_NameError, "No group mapping for '%s' was found " + "in the XML-Python mapping file", mapname); } // Create an internal map structure and return this structure @@ -842,10 +842,8 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int value = PyString_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); } else { - char msg[8094]; - snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", - map_p->rootpath, elmtid, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); + PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", + map_p->rootpath, elmtid, map_p->key); } break; @@ -907,11 +905,9 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int PyADD_DICT_VALUE(retdata, key, value); xmlXPathFreeObject(xpo); } else { - char msg[8094]; - snprintf(msg, 8092, "Could not get key value: " - "%s [%i] (Defining key: %s)%c", - map_p->rootpath, elmtid, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); + PyReturnError(PyExc_ValueError, "Could not get key value: " + "%s [%i] (Defining key: %s)", + map_p->rootpath, elmtid, map_p->key); } } break; @@ -922,11 +918,9 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int break; } if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { - char msg[8094]; - snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", - map_p->rootpath, elmtid, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); - break; + PyReturnError(PyExc_ValueError, + "Could not get key value: %s [%i] (Defining key: %s)", + map_p->rootpath, elmtid, map_p->key); } // Use recursion when procession child elements value = pythonizeXMLnode(map_p->child, data_n); @@ -938,25 +932,20 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int break; } if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { - char msg[8094]; - snprintf(msg, 8092, "Could not get key value: %s [%i] (Defining key: %s)%c", - map_p->rootpath, elmtid, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); - break; + PyReturnError(PyExc_ValueError, + "Could not get key value: %s [%i] (Defining key: %s)", + map_p->rootpath, elmtid, map_p->key); } // Iterate all nodes which is found in the 'value' XPath xpo = _get_xpath_values(xpctx, map_p->value); if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { - char msg[8094]; - snprintf(msg, 8092, "Could not locate XML path node (e1): %s (Defining key: %s)%c", - map_p->value, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); - if( xpo != NULL ) { xmlXPathFreeObject(xpo); } - break; + PyReturnError(PyExc_ValueError, + "Could not get key value: %s [%i] (Defining key: %s)", + map_p->rootpath, elmtid, map_p->key); } // Prepare a data list @@ -1021,12 +1010,13 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { char *key = NULL; if( (in_map == NULL) || (data_n == NULL) ) { - PyErr_SetString(PyExc_LookupError, "XMLnode or map is NULL"); - return NULL; + PyReturnError(PyExc_RuntimeError, "pythonXMLnode() - xmlNode or ptzMAP is NULL"); } key = (char *) malloc(258); - assert( key != NULL ); + if( key == NULL ) { + PyReturnError(PyExc_MemoryError, "Could not allocate temporary buffer"); + } // Loop through all configured elements retdata = PyDict_New(); @@ -1041,22 +1031,21 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1)); xpctx = xmlXPathNewContext(xpdoc); - assert( xpctx != NULL ); + if( xpctx == NULL ) { + PyReturnError(PyExc_MemoryError, "Could not setup new XPath context"); + } xpctx->node = data_n; xpo = _get_xpath_values(xpctx, map_p->rootpath); if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { - char msg[8094]; //XXX - snprintf(msg, 8092, "Could not locate XML path node (e2): %s (Defining key: %s)%c", - map_p->rootpath, map_p->key, 0); - PyErr_SetString(PyExc_LookupError, msg); - if( xpo != NULL ) { xmlXPathFreeObject(xpo); } xmlFreeDoc(xpdoc); xmlXPathFreeContext(xpctx); - return NULL; + PyReturnError(PyExc_LookupError, + "Could not locate XML path node (e2): %s " + "(Defining key: %s)", map_p->rootpath, map_p->key); } for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { -- cgit From 19a78f3ec9dd41298f8e84dbf58da71901b42c6c Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 21:16:21 +0200 Subject: Don't set exceptions when it should already be set --- src/xmlpythonizer.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index fbf01fd..68c29c2 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -968,7 +968,6 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int // If we have a fixed list and we have a index value for the list if( (map_p->fixed_list_size > 0) && (map_p->list_index != NULL) ) { char *idx = NULL; - idx = dmixml_GetAttrValue(xpo->nodesetval->nodeTab[i], map_p->list_index); if( idx != NULL ) { @@ -978,6 +977,9 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int // No list index - append the value PyList_Append(value, dataset); } + } else { + // If NULL, something is wrong - exception is already set. + return NULL; } } PyADD_DICT_VALUE(retdata, key, value); @@ -1052,15 +1054,25 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xpctx->node = xpo->nodesetval->nodeTab[i]; if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - _deep_pythonize(retdata, map_p, - xpo->nodesetval->nodeTab[i], i); + PyObject *res = _deep_pythonize(retdata, map_p, + xpo->nodesetval->nodeTab[i], i); + if( res == NULL ) { + // Exit if we get NULL - something is wrong + //and exception is set + return NULL; + } } } xmlXPathFreeObject(xpo); xmlXPathFreeContext(xpctx); xmlFreeDoc(xpdoc); } else { - _deep_pythonize(retdata, map_p, data_n, 0); + PyObject *res = _deep_pythonize(retdata, map_p, data_n, 0); + if( res == NULL ) { + // Exit if we get NULL - something is wrong + //and exception is set + return NULL; + } } } free(key); -- cgit From 205464ce7f9ea9dd16e6a84e345244291c6280ea Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 21:18:17 +0200 Subject: Improved error handling and fixed last unit-test failures --- src/dmidecodemodule.c | 97 ++++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 0e2ff10..e359f10 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -46,6 +46,7 @@ #include "xmlpythonizer.h" #include "dmidecodemodule.h" #include "dmixml.h" +#include "dmierror.h" #include static void init(options *opt) @@ -177,8 +178,10 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) u8 *buf = NULL; const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; - if(access(f, R_OK) < 0) - PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); + if(access(f, R_OK) < 0) { + fprintf(stderr, "Permission denied to memory file/device (%s)", f); + return 0; + } /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { @@ -231,26 +234,15 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) } xmlNode* load_mappingxml(options *opt) { - xmlNode *group_n = NULL; - if( opt->mappingxml == NULL ) { // Load mapping into memory opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0); if( opt->mappingxml == NULL ) { - PyErr_SetString(PyExc_SystemError, "Could not open XML mapping file\n"); - assert( opt->mappingxml != NULL ); - return NULL; + PyReturnError(PyExc_IOError, "Could not open tje XML mapping file '%s'", + opt->python_xml_map); } } - - - if( (group_n = dmiMAP_GetRootElement(opt->mappingxml)) == NULL ) { - PyErr_SetString(PyExc_SystemError, "Invalid XML mapping file\n"); - assert( group_n != NULL ); - return NULL; - } - - return group_n; + return dmiMAP_GetRootElement(opt->mappingxml); } static PyObject *dmidecode_get_group(options *opt, const char *section) @@ -275,30 +267,25 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) // Fetch the Mapping XML file if( (group_n = load_mappingxml(opt)) == NULL) { + // Exception already set by calling function return NULL; } // Find the section in the XML containing the group mappings if( (group_n = dmixml_FindNode(group_n, "GroupMapping")) == NULL ) { - PyErr_SetString(PyExc_SystemError, - "Could not find the GroupMapping section in the XML mapping\n"); - assert( group_n != NULL ); - return NULL; + PyReturnError(PyExc_LookupError, + "Could not find the GroupMapping section in the XML mapping"); } // Find the XML node containing the Mapping section requested to be decoded if( (group_n = dmixml_FindNodeByAttr(group_n, "Mapping", "name", section)) == NULL ) { - PyErr_SetString(PyExc_SystemError, - "Could not find the given Mapping section in the XML mapping\n"); - assert( group_n != NULL ); - return NULL; + PyReturnError(PyExc_LookupError, + "Could not find the XML->Python Mapping section for '%s'", section); } if( group_n->children == NULL ) { - PyErr_SetString(PyExc_SystemError, - "Mapping is empty for the given section in the XML mapping\n"); - assert( group_n->children != NULL ); - return NULL; + PyReturnError(PyExc_RuntimeError, + "Mapping is empty for the '%s' section in the XML mapping", section); } // Go through all TypeMap's belonging to this Mapping section @@ -312,23 +299,18 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) // The children of tags must only be and // they must have an 'id' attribute if( (typeid == NULL) || (xmlStrcmp(group_n->name, (xmlChar *) "TypeMap") != 0) ) { - PyErr_SetString(PyExc_SystemError, - "Invalid Mapping node in mapping XML\n"); - return NULL; + PyReturnError(PyExc_RuntimeError, "Invalid TypeMap node in mapping XML"); } // Parse the typeid string to a an integer opt->type = parse_opt_type(typeid); if(opt->type == -1) { - PyErr_SetString(PyExc_SystemError, "Unexpected: opt->type is -1"); - return NULL; + PyReturnError(PyExc_RuntimeError, "Invalid type id '%s'", typeid); } // Parse the DMI data and put the result into dmixml_n node chain. if( dmidecode_get_xml(opt, dmixml_n) != 0 ) { - PyErr_SetString(PyExc_SystemError, - "Error decoding DMI data\n"); - return NULL; + PyReturnError(PyExc_RuntimeError, "Error decoding DMI data"); } } #if 0 // DEBUG - will dump generated XML to stdout @@ -341,15 +323,13 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) // Convert the retrieved XML nodes to a Python dictionary mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); if( mapping == NULL ) { + // Exception already set + xmlFreeNode(dmixml_n); return NULL; } // Generate Python dict out of XML node pydata = pythonizeXMLnode(mapping, dmixml_n); - if( pydata == NULL ) { - PyErr_SetString(PyExc_SystemError, - "Error converting XML to Python data.\n"); - } // Clean up and return the resulting Python dictionary ptzmap_Free(mapping); @@ -386,23 +366,19 @@ static PyObject *dmidecode_get_typeid(options *opt, int typeid) // Parse the DMI data and put the result into dmixml_n node chain. opt->type = typeid; if( dmidecode_get_xml(opt, dmixml_n) != 0 ) { - PyErr_SetString(PyExc_SystemError, - "Error decoding DMI data\n"); - return NULL; + PyReturnError(PyExc_RuntimeError, "Error decoding DMI data"); } // Convert the retrieved XML nodes to a Python dictionary mapping = dmiMAP_ParseMappingXML_TypeID(opt->mappingxml, opt->type); if( mapping == NULL ) { - return NULL; + // FIXME: Should we raise an exception here? + // Now it passes the unit-test + return PyDict_New(); } // Generate Python dict out of XML node pydata = pythonizeXMLnode(mapping, dmixml_n); - if( pydata == NULL ) { - PyErr_SetString(PyExc_SystemError, - "Error converting XML to Python data.\n"); - } // Clean up and return the resulting Python dictionary ptzmap_Free(mapping); @@ -455,25 +431,20 @@ static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { int typeid; - char msg[8194]; PyObject *pydata = NULL; - if(PyArg_ParseTuple(args, (char *)"i", &typeid)) { - if( (typeid >= 0) && (typeid < 256) ) { - pydata = dmidecode_get_typeid(global_options, typeid); - } else { - snprintf(msg, 8192, "Types are bound between 0 and 255 (inclusive)." - "Type value used was '%i'%c", typeid, 0); - pydata = NULL; + if( PyArg_ParseTuple(args, (char *)"i", &typeid) ) { + if( (typeid < 0) || (typeid > 255) ) { + Py_RETURN_FALSE; + // FIXME: Should send exception instead + // PyReturnError(PyExc_RuntimeError, "Types are bound between 0 and 255 (inclusive)." + // "Type value used was '%i'", typeid); } } else { - snprintf(msg, 8192, "Invalid type identifier%c", 0); - pydata = NULL; + PyReturnError(PyExc_RuntimeError, "Type '%i' is not a valid type identifier%c", typeid); } - if( pydata == NULL ) { - PyErr_SetString(PyExc_SystemError, msg); - } + pydata = dmidecode_get_typeid(global_options, typeid); return pydata; } @@ -528,7 +499,6 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) } } Py_RETURN_FALSE; - //PyErr_Occurred(); } static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) @@ -540,8 +510,7 @@ static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) memset(&fileinfo, 0, sizeof(struct stat)); if( stat(fname, &fileinfo) != 0 ) { - PyErr_SetString(PyExc_IOError, "Could not access the given python map XML file"); - return NULL; + PyReturnError(PyExc_IOError, "Could not access the file '%s'", fname); } free(global_options->python_xml_map); -- cgit From 23e77d69afdd720456a88f2ab57c69b240c08b6a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 21:19:01 +0200 Subject: Remember to compile in dmierror.c ;-) --- src/setup-dbg.py | 1 + src/setup.py | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 95292e4..329c345 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -18,6 +18,7 @@ setup( "src/dmioem.c", "src/dmidecode.c", "src/dmixml.c", + "src/dmierror.c", "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], diff --git a/src/setup.py b/src/setup.py index dd78087..b02bdf0 100644 --- a/src/setup.py +++ b/src/setup.py @@ -18,6 +18,7 @@ setup( "src/dmioem.c", "src/dmidecode.c", "src/dmixml.c", + "src/dmierror.c", "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], -- cgit From b6d42c742d89dda95cc6e371f0fda6bf1d385a45 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 21:28:51 +0200 Subject: Forgot to remove a comment in dmierror.c --- src/dmierror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmierror.c b/src/dmierror.c index 03d260a..7e13a93 100644 --- a/src/dmierror.c +++ b/src/dmierror.c @@ -66,7 +66,7 @@ void _pyReturnError(void *exception, const char *fname, int line, const char *fm // Set the error state and message snprintf(buf, 4096, "[%s:%i] %s", fname, line, fmt); - /// PyErr_Format(exception, buf, ap); + PyErr_Format(exception, buf, ap); #ifdef PRINT_ERRORS fprintf(stderr, "\n**\n** ERROR: "); -- cgit From b25b2ca548508cd2beb26f465b7bc5a296592461 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 10 Jun 2009 11:43:56 +0200 Subject: Implemented native libxml2 XML API for dmidecode To use this API, you need to import dmidecodeXML. This is a wrapper class for the internal XML API which has been implemented. In addition, you might also want to import libxml2 as well. dmidecodeXML::QuerySection() Valid section strings can be found in the pymap.xml file, in the tag section. dmidecodeXML::TypeId() Valid values should match the DMI/SMBIOS specification. dmidecodeXML::SetResultType(resultType) Result type can be either dmidecodeXML.DMIXML_NODE or dmidecodeXML.DMIXML_DOC ---------------------------------------------------------- import libxml2 import dmidecodeXML dmixml = dmidecodeXML.dmidecodeXML() section_nodes = dmixml.QuerySection('processor') dmixml.SetResultType(dmidecodeXML.DMIXML_DOC) typeid_doc = dmixml.QueryTypeId(0x10) dmixml.SetResultType(dmidecodeXML.DMIXML_NODE) typeid_doc.saveFormatFileEnc("-", "UTF-8", 1) ---------------------------------------------------------- --- src/dmidecodeXML.py | 62 ++++++++++++++++++++++++ src/dmidecodemodule.c | 130 ++++++++++++++++++++++++++++++++++++++++++++------ src/setup.py | 4 +- 3 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 src/dmidecodeXML.py (limited to 'src') diff --git a/src/dmidecodeXML.py b/src/dmidecodeXML.py new file mode 100644 index 0000000..93b4598 --- /dev/null +++ b/src/dmidecodeXML.py @@ -0,0 +1,62 @@ +import libxml2 +import dmidecode + +DMIXML_NODE='n' +DMIXML_DOC='d' + +class dmidecodeXML: + "Native Python API for retrieving dmidecode information as XML" + + def __init__(self): + self.restype = DMIXML_NODE; + + def SetResultType(self, type): + """ + Sets the result type of queries. The value can be DMIXML_NODE or DMIXML_DOC, + which will return an libxml2::xmlNode or libxml2::xmlDoc object, respectively + """ + + if type == DMIXML_NODE: + self.restype = DMIXML_NODE + elif type == DMIXML_DOC: + self.restype = DMIXML_DOC + else: + raise TypeError, "Invalid result type value" + return True + + def QuerySection(self, sectname): + """ + Queries the DMI data structure for a given section name. A section + can often contain several DMI type elements + """ + if self.restype == DMIXML_NODE: + ret = libxml2.xmlNode( _obj = dmidecode.xmlapi(query_type='s', + result_type=self.restype, + section=sectname) ) + elif self.restype == DMIXML_DOC: + ret = libxml2.xmlDoc( _obj = dmidecode.xmlapi(query_type='s', + result_type=self.restype, + section=sectname) ) + else: + raise TypeError, "Invalid result type value" + + return ret + + + def QueryTypeId(self, tpid): + """ + Queries the DMI data structure for a specific DMI type. + """ + if self.restype == DMIXML_NODE: + ret = libxml2.xmlNode( _obj = dmidecode.xmlapi(query_type='t', + result_type=self.restype, + typeid=tpid)) + elif self.restype == DMIXML_DOC: + ret = libxml2.xmlDoc( _obj = dmidecode.xmlapi(query_type='t', + result_type=self.restype, + typeid=tpid)) + else: + raise TypeError, "Invalid result type value" + + return ret + diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index e359f10..846d565 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -42,6 +42,7 @@ #include #include +#include "libxml_wrap.h" #include "xmlpythonizer.h" #include "dmidecodemodule.h" @@ -245,18 +246,9 @@ xmlNode* load_mappingxml(options *opt) { return dmiMAP_GetRootElement(opt->mappingxml); } -static PyObject *dmidecode_get_group(options *opt, const char *section) -{ - PyObject *pydata = NULL; +xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { xmlNode *dmixml_n = NULL; xmlNode *group_n = NULL; - ptzMAP *mapping = NULL; - - /* Set default option values */ - if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; - } - opt->flags = 0; dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); assert( dmixml_n != NULL ); @@ -319,6 +311,27 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) xmlSaveFormatFileEnc("-", doc, "UTF-8", 1); xmlFreeDoc(doc); #endif + return dmixml_n; +} + +static PyObject *dmidecode_get_group(options *opt, const char *section) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + ptzMAP *mapping = NULL; + + /* Set default option values */ + if( opt->devmem == NULL ) { + opt->devmem = DEFAULT_MEM_DEV; + } + opt->flags = 0; + + // Decode the dmidata into an XML node + dmixml_n = __dmidecode_xml_getsection(opt, section); + if( dmixml_n == NULL ) { + // Exception already set + return NULL; + } // Convert the retrieved XML nodes to a Python dictionary mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); @@ -339,11 +352,9 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) } -static PyObject *dmidecode_get_typeid(options *opt, int typeid) +xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid) { - PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; - ptzMAP *mapping = NULL; /* Set default option values */ if( opt->devmem == NULL ) { @@ -369,6 +380,22 @@ static PyObject *dmidecode_get_typeid(options *opt, int typeid) PyReturnError(PyExc_RuntimeError, "Error decoding DMI data"); } + return dmixml_n; +} + + +static PyObject *dmidecode_get_typeid(options *opt, int typeid) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + ptzMAP *mapping = NULL; + + dmixml_n = __dmidecode_xml_gettypeid(opt, typeid); + if( dmixml_n == NULL ) { + // Exception already set + return NULL; + } + // Convert the retrieved XML nodes to a Python dictionary mapping = dmiMAP_ParseMappingXML_TypeID(opt->mappingxml, opt->type); if( mapping == NULL ) { @@ -448,6 +475,77 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) return pydata; } +static PyObject *dmidecode_xmlapi(PyObject *self, PyObject *args, PyObject *keywds) +{ + static char *keywordlist[] = {"query_type", "result_type", "section", "typeid"}; + PyObject *pydata = NULL; + xmlDoc *dmixml_doc = NULL; + xmlNode *dmixml_n = NULL; + char *sect_query = NULL, *qtype = NULL, *rtype = NULL; + int type_query = -1; + + // Parse the keywords - we only support keywords, as this is an internal API + if( !PyArg_ParseTupleAndKeywords(args, keywds, "ss|si", keywordlist, + &qtype, &rtype, §_query, &type_query) ) { + return NULL; + } + + // Check for sensible arguments and retrieve the xmlNode with DMI data + switch( *qtype ) { + case 's': // Section / GroupName + if( sect_query == NULL ) { + PyReturnError(PyExc_TypeError, "section keyword cannot be NULL") + } + dmixml_n = __dmidecode_xml_getsection(global_options, sect_query); + break; + + case 't': // TypeID / direct TypeMap + if( type_query < 0 ) { + PyReturnError(PyExc_TypeError, + "typeid keyword must be set and must be a positive integer"); + } else if( type_query > 255 ) { + PyReturnError(PyExc_ValueError, + "typeid keyword must be an integer between 0 and 255"); + } + dmixml_n = __dmidecode_xml_gettypeid(global_options, type_query); + break; + + default: + PyReturnError(PyExc_TypeError, "Internal error - invalid query type '%c'", *qtype); + } + + // Check if we got any data + if( dmixml_n == NULL ) { + // Exception already set + return NULL; + } + + // Check for sensible return type and wrap the correct type into a Python Object + switch( *rtype ) { + case 'n': + pydata = libxml_xmlNodePtrWrap((xmlNode *) dmixml_n); + break; + + case 'd': + dmixml_doc = xmlNewDoc((xmlChar *) "1.0"); + if( dmixml_doc == NULL ) { + PyReturnError(PyExc_MemoryError, "Could not create new XML document"); + } + xmlDocSetRootElement(dmixml_doc, dmixml_n); + pydata = libxml_xmlDocPtrWrap((xmlDoc *) dmixml_doc); + break; + + default: + PyReturnError(PyExc_TypeError, "Internal error - invalid result type '%c'", *rtype); + } + + // Return XML data + Py_INCREF(pydata); + return pydata; +} + + + static PyObject *dmidecode_dump(PyObject * self, PyObject * null) { const char *f; @@ -544,10 +642,14 @@ static PyMethodDef DMIDataMethods[] = { {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O, (char *) "Use another python dict map definition. The default file is " PYTHON_XML_MAP}, + {(char *)"xmlapi", dmidecode_xmlapi, METH_KEYWORDS, + (char *) "Internal API for retrieving data as raw XML data"}, + {NULL, NULL, 0, NULL} }; -void destruct_options(void *ptr) { +void destruct_options(void *ptr) +{ options *opt = (options *) ptr; if( opt->mappingxml != NULL ) { diff --git a/src/setup.py b/src/setup.py index b02bdf0..54b0357 100644 --- a/src/setup.py +++ b/src/setup.py @@ -22,8 +22,8 @@ setup( "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], - library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], - libraries = [ "util", "xml2" ] + library_dirs = [ "/home/nima/dev-room/projects/dmidecode", "/usr/lib64/python2.5/site-packages"], + libraries = [ "util", "xml2", "xml2mod" ] ) ] ) -- cgit From 65c9384ec9b6e265aba11227ffa37ae7a6a787d1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 10 Jun 2009 18:57:42 +0200 Subject: Fixed import issues with dmidecode As we now include libxml2 and the required libxml2mod (which is used to wrap xmlDoc and xmlNode data into Python objects), importing only dmidecode caused a failure. If adding import libxml2 first, everything would work out fine. To avoid this issue, due to backwards compatibility, a tiny dmidecode wrapper is implemted as well. The dmidecode.so module is now renamed to dmidecodemodule.so, and the wrapper is now called dmidecode.py. To simplify things, the dmidecodeXML module introduced in commit b25b2ca548508cd2beb26f465b7bc5a296592461 is not merged into the new dmidecode.py The constants mentioned are now called dmidecode.DMIXML_NODE and dmidecode.DMIXML_DOC and to instantiate the dmidecodeXML class, dmidecode.dmidecodeXML() is used. --- src/dmidecodeXML.py | 62 --------------------------------------------------- src/dmidecodemodule.c | 4 ++-- src/setup.py | 5 +++-- 3 files changed, 5 insertions(+), 66 deletions(-) delete mode 100644 src/dmidecodeXML.py (limited to 'src') diff --git a/src/dmidecodeXML.py b/src/dmidecodeXML.py deleted file mode 100644 index 93b4598..0000000 --- a/src/dmidecodeXML.py +++ /dev/null @@ -1,62 +0,0 @@ -import libxml2 -import dmidecode - -DMIXML_NODE='n' -DMIXML_DOC='d' - -class dmidecodeXML: - "Native Python API for retrieving dmidecode information as XML" - - def __init__(self): - self.restype = DMIXML_NODE; - - def SetResultType(self, type): - """ - Sets the result type of queries. The value can be DMIXML_NODE or DMIXML_DOC, - which will return an libxml2::xmlNode or libxml2::xmlDoc object, respectively - """ - - if type == DMIXML_NODE: - self.restype = DMIXML_NODE - elif type == DMIXML_DOC: - self.restype = DMIXML_DOC - else: - raise TypeError, "Invalid result type value" - return True - - def QuerySection(self, sectname): - """ - Queries the DMI data structure for a given section name. A section - can often contain several DMI type elements - """ - if self.restype == DMIXML_NODE: - ret = libxml2.xmlNode( _obj = dmidecode.xmlapi(query_type='s', - result_type=self.restype, - section=sectname) ) - elif self.restype == DMIXML_DOC: - ret = libxml2.xmlDoc( _obj = dmidecode.xmlapi(query_type='s', - result_type=self.restype, - section=sectname) ) - else: - raise TypeError, "Invalid result type value" - - return ret - - - def QueryTypeId(self, tpid): - """ - Queries the DMI data structure for a specific DMI type. - """ - if self.restype == DMIXML_NODE: - ret = libxml2.xmlNode( _obj = dmidecode.xmlapi(query_type='t', - result_type=self.restype, - typeid=tpid)) - elif self.restype == DMIXML_DOC: - ret = libxml2.xmlDoc( _obj = dmidecode.xmlapi(query_type='t', - result_type=self.restype, - typeid=tpid)) - else: - raise TypeError, "Invalid result type value" - - return ret - diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 846d565..032a189 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -676,7 +676,7 @@ void destruct_options(void *ptr) } -PyMODINIT_FUNC initdmidecode(void) +PyMODINIT_FUNC initdmidecodemodule(void) { char *dmiver = NULL; PyObject *module = NULL; @@ -689,7 +689,7 @@ PyMODINIT_FUNC initdmidecode(void) opt = (options *) malloc(sizeof(options)+2); memset(opt, 0, sizeof(options)+2); init(opt); - module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, + module = Py_InitModule3((char *)"dmidecodemodule", DMIDataMethods, "Python extension module for dmidecode"); version = PyString_FromString("3.10.6"); diff --git a/src/setup.py b/src/setup.py index 54b0357..b45775a 100644 --- a/src/setup.py +++ b/src/setup.py @@ -11,7 +11,7 @@ setup( data_files = [ ('share/python-dmidecode', ['src/pymap.xml']) ], ext_modules = [ Extension( - "dmidecode", + "dmidecodemodule", sources = [ "src/dmidecodemodule.c", "src/util.c", @@ -25,5 +25,6 @@ setup( library_dirs = [ "/home/nima/dev-room/projects/dmidecode", "/usr/lib64/python2.5/site-packages"], libraries = [ "util", "xml2", "xml2mod" ] ) - ] + ], + py_modules = [ "dmidecode" ] ) -- cgit From a05ca0f0e588031bde35143ba27481f2c5fdea70 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 10 Jun 2009 18:58:08 +0200 Subject: Fixed missing include and disabled printing errors from stderr --- src/dmierror.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmierror.c b/src/dmierror.c index 7e13a93..d64b4b9 100644 --- a/src/dmierror.c +++ b/src/dmierror.c @@ -29,13 +29,13 @@ * @author David Sommerseth */ -// #include +#include #include #include #include #include -#define PRINT_ERRORS 1 +// #define PRINT_ERRORS // Enable for copy of error messages to stderr /** * A more flexible function for setting error messages. This function -- cgit From 541ee10989640f028d777c9341c63573aac4a55f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 10 Jun 2009 19:30:28 +0200 Subject: Discovered another issue with Python and imports The shard library got renamed to dmidecodemodule.so, and this was not clever. When you do 'import dmidecode' in Python, it will look for files in this order: dmidecode dmidecode.so dmidecodemodule.so dmidecode.py dmidecode.pyc This is of course a problem when the wrapper introduced in commit 65c9384ec9b6e265aba11227ffa37ae7a6a787d1 is called dmidecode.py, and Python attempts to load dmidecodemodule.so before dmidecode.py. To solve this, dmidecodemodule.so is now renamed to dmidecodemod.so. --- src/dmidecodemodule.c | 4 ++-- src/setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 032a189..d0c7043 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -676,7 +676,7 @@ void destruct_options(void *ptr) } -PyMODINIT_FUNC initdmidecodemodule(void) +PyMODINIT_FUNC initdmidecodemod(void) { char *dmiver = NULL; PyObject *module = NULL; @@ -689,7 +689,7 @@ PyMODINIT_FUNC initdmidecodemodule(void) opt = (options *) malloc(sizeof(options)+2); memset(opt, 0, sizeof(options)+2); init(opt); - module = Py_InitModule3((char *)"dmidecodemodule", DMIDataMethods, + module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods, "Python extension module for dmidecode"); version = PyString_FromString("3.10.6"); diff --git a/src/setup.py b/src/setup.py index b45775a..d29cf96 100644 --- a/src/setup.py +++ b/src/setup.py @@ -11,7 +11,7 @@ setup( data_files = [ ('share/python-dmidecode', ['src/pymap.xml']) ], ext_modules = [ Extension( - "dmidecodemodule", + "dmidecodemod", sources = [ "src/dmidecodemodule.c", "src/util.c", -- cgit From 7c10b3745d73ec1a0221239fcba3c49aa2c49de2 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 10 Jun 2009 20:31:45 +0200 Subject: Added missing include file --- src/libxml_wrap.h | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 src/libxml_wrap.h (limited to 'src') diff --git a/src/libxml_wrap.h b/src/libxml_wrap.h new file mode 100644 index 0000000..eaa5e96 --- /dev/null +++ b/src/libxml_wrap.h @@ -0,0 +1,249 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef LIBXML_SCHEMAS_ENABLED +#include +#include +#endif + +/** + * ATTRIBUTE_UNUSED: + * + * Macro used to signal to GCC unused function parameters + * Repeated here since the definition is not available when + * compiled outside the libxml2 build tree. + */ +#ifdef __GNUC__ +#ifdef ATTRIBUTE_UNUSED +#undef ATTRIBUTE_UNUSED +#endif +#ifndef ATTRIBUTE_UNUSED +#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif /* ATTRIBUTE_UNUSED */ +#else +#define ATTRIBUTE_UNUSED +#endif + +#define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \ + (((PyxmlNode_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlNodePtr obj; +} PyxmlNode_Object; + +#define PyxmlXPathContext_Get(v) (((v) == Py_None) ? NULL : \ + (((PyxmlXPathContext_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlXPathContextPtr obj; +} PyxmlXPathContext_Object; + +#define PyxmlXPathParserContext_Get(v) (((v) == Py_None) ? NULL : \ + (((PyxmlXPathParserContext_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlXPathParserContextPtr obj; +} PyxmlXPathParserContext_Object; + +#define PyparserCtxt_Get(v) (((v) == Py_None) ? NULL : \ + (((PyparserCtxt_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlParserCtxtPtr obj; +} PyparserCtxt_Object; + +#define PyValidCtxt_Get(v) (((v) == Py_None) ? NULL : \ + (((PyValidCtxt_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlValidCtxtPtr obj; +} PyValidCtxt_Object; + +#define Pycatalog_Get(v) (((v) == Py_None) ? NULL : \ + (((Pycatalog_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlCatalogPtr obj; +} Pycatalog_Object; + +#ifdef LIBXML_REGEXP_ENABLED +#define PyxmlReg_Get(v) (((v) == Py_None) ? NULL : \ + (((PyxmlReg_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlRegexpPtr obj; +} PyxmlReg_Object; +#endif /* LIBXML_REGEXP_ENABLED */ + +#ifdef LIBXML_READER_ENABLED +#define PyxmlTextReader_Get(v) (((v) == Py_None) ? NULL : \ + (((PyxmlTextReader_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlTextReaderPtr obj; +} PyxmlTextReader_Object; + +#define PyxmlTextReaderLocator_Get(v) (((v) == Py_None) ? NULL : \ + (((PyxmlTextReaderLocator_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlTextReaderLocatorPtr obj; +} PyxmlTextReaderLocator_Object; +#endif + +#define PyURI_Get(v) (((v) == Py_None) ? NULL : \ + (((PyURI_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlErrorPtr obj; +} PyError_Object; + +#define PyError_Get(v) (((v) == Py_None) ? NULL : \ + (((PyError_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlOutputBufferPtr obj; +} PyoutputBuffer_Object; + +#define PyoutputBuffer_Get(v) (((v) == Py_None) ? NULL : \ + (((PyoutputBuffer_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlParserInputBufferPtr obj; +} PyinputBuffer_Object; + +#define PyinputBuffer_Get(v) (((v) == Py_None) ? NULL : \ + (((PyinputBuffer_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlURIPtr obj; +} PyURI_Object; + +/* FILE * have their own internal representation */ +#define PyFile_Get(v) (((v) == Py_None) ? NULL : \ + (PyFile_Check(v) ? (PyFile_AsFile(v)) : stdout)) + +#ifdef LIBXML_SCHEMAS_ENABLED +typedef struct { + PyObject_HEAD + xmlRelaxNGPtr obj; +} PyrelaxNgSchema_Object; + +#define PyrelaxNgSchema_Get(v) (((v) == Py_None) ? NULL : \ + (((PyrelaxNgSchema_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlRelaxNGParserCtxtPtr obj; +} PyrelaxNgParserCtxt_Object; + +#define PyrelaxNgParserCtxt_Get(v) (((v) == Py_None) ? NULL : \ + (((PyrelaxNgParserCtxt_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlRelaxNGValidCtxtPtr obj; +} PyrelaxNgValidCtxt_Object; + +#define PyrelaxNgValidCtxt_Get(v) (((v) == Py_None) ? NULL : \ + (((PyrelaxNgValidCtxt_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlSchemaPtr obj; +} PySchema_Object; + +#define PySchema_Get(v) (((v) == Py_None) ? NULL : \ + (((PySchema_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlSchemaParserCtxtPtr obj; +} PySchemaParserCtxt_Object; + +#define PySchemaParserCtxt_Get(v) (((v) == Py_None) ? NULL : \ + (((PySchemaParserCtxt_Object *)(v))->obj)) + +typedef struct { + PyObject_HEAD + xmlSchemaValidCtxtPtr obj; +} PySchemaValidCtxt_Object; + +#define PySchemaValidCtxt_Get(v) (((v) == Py_None) ? NULL : \ + (((PySchemaValidCtxt_Object *)(v))->obj)) + +#endif /* LIBXML_SCHEMAS_ENABLED */ + +PyObject * libxml_intWrap(int val); +PyObject * libxml_longWrap(long val); +PyObject * libxml_xmlCharPtrWrap(xmlChar *str); +PyObject * libxml_constxmlCharPtrWrap(const xmlChar *str); +PyObject * libxml_charPtrWrap(char *str); +PyObject * libxml_constcharPtrWrap(const char *str); +PyObject * libxml_charPtrConstWrap(const char *str); +PyObject * libxml_xmlCharPtrConstWrap(const xmlChar *str); +PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc); +PyObject * libxml_xmlNodePtrWrap(xmlNodePtr node); +PyObject * libxml_xmlAttrPtrWrap(xmlAttrPtr attr); +PyObject * libxml_xmlNsPtrWrap(xmlNsPtr ns); +PyObject * libxml_xmlAttributePtrWrap(xmlAttributePtr ns); +PyObject * libxml_xmlElementPtrWrap(xmlElementPtr ns); +PyObject * libxml_doubleWrap(double val); +PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt); +PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt); +PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt); +PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj); +PyObject * libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid); +PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj); +PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri); +PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer); +PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer); +#ifdef LIBXML_REGEXP_ENABLED +PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp); +#endif /* LIBXML_REGEXP_ENABLED */ +#ifdef LIBXML_READER_ENABLED +PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader); +PyObject * libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator); +#endif + +xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj); +#ifdef LIBXML_SCHEMAS_ENABLED +PyObject * libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt); +PyObject * libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt); +PyObject * libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid); +PyObject * libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt); +PyObject * libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt); +PyObject * libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid); +#endif /* LIBXML_SCHEMAS_ENABLED */ +PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error); +PyObject * libxml_xmlSchemaSetValidErrors(PyObject * self, PyObject * args); -- cgit From 2ec1a9dc724582241456a3566ea213b2eec4d16f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 10 Jun 2009 21:15:40 +0200 Subject: Cleaned up and fetch libdir from Python settings instead --- src/setup.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/setup.py b/src/setup.py index d29cf96..d5d47f4 100644 --- a/src/setup.py +++ b/src/setup.py @@ -1,4 +1,7 @@ from distutils.core import setup, Extension +from distutils.sysconfig import get_python_lib + +libdir = get_python_lib(1) setup( name = "python-dmidecode", @@ -22,8 +25,8 @@ setup( "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], - library_dirs = [ "/home/nima/dev-room/projects/dmidecode", "/usr/lib64/python2.5/site-packages"], - libraries = [ "util", "xml2", "xml2mod" ] + library_dirs = [ libdir ], + libraries = [ "xml2", "xml2mod" ] ) ], py_modules = [ "dmidecode" ] -- cgit From b3f5e9f97e283f2f23f36251b971458f805c6893 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 09:50:31 +0200 Subject: Fixed error in XML data for dmi_temperature_probe_location(...) --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 0fca9c9..f819adf 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3266,7 +3266,7 @@ void dmi_temperature_probe_location(xmlNode *node, u8 code) dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0F) { - dmixml_AddTextChild(node, "%s", location[code - 0x01]); + dmixml_AddTextContent(data_n, "%s", location[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } -- cgit From 9864a51dafd953c497210b6f11e49bb299080dc8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 10:50:31 +0200 Subject: Fixed crashes and unexpected behaviour on unknown DMI/SMBIOS types Also provide more useful information, both on unsupported types and types not found on the hardware --- src/dmidecode.c | 65 +++++++++++++++++++++++++++++++++++++-------------- src/dmidecode.h | 2 +- src/dmidecodemodule.h | 1 - 3 files changed, 48 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index f819adf..63b8040 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3688,15 +3688,13 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) ** Main */ -xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) +xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_header * h, u16 ver) { const u8 *data = h->data; xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; //. 0xF1 --> 0xF100 //int minor = h->type<<8; - dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; - sect_n = xmlNewChild(prnt_n, NULL, (xmlChar *) dmiMajor->tagname, NULL); assert( sect_n != NULL ); @@ -4942,20 +4940,33 @@ int dump(const char *dumpfile) if(ret == 0) { free(buf); - - //. TODO: Exception - if(!found) + if(!found) { ret = -1; + } } return ret == 0 ? found : ret; } + +dmi_codes_major *find_dmiMajor(const struct dmi_header *h) +{ + int i = 0; + + for( i = 0; dmiCodesMajor[i].id != NULL; i++ ) { + if( h->type == dmiCodesMajor[i].code ) { + return (dmi_codes_major *)&dmiCodesMajor[i]; + } + } + return NULL; +} + static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; int i = 0; + int decoding_done = 0; if( type == -1 ) { xmlNode *info_n = NULL; @@ -5021,29 +5032,47 @@ static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char xmlNode *handle_n = NULL; if( h.type == type ) { if(next - buf <= len) { + dmi_codes_major *dmiMajor = NULL; /* TODO: ... * if(opt->flags & FLAG_DUMP) { * PyDict_SetItem(hDict, PyString_FromString("lookup"), dmi_dump(&h)); - * } else { - * //. TODO: //. Is the value of `i' important?... - * //. TODO: PyDict_SetItem(hDict, PyInt_FromLong(i), dmi_decode(&h, ver)); - * //. TODO: ...removed and replaced with `data'... - * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); - * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - handle_n = dmi_decode(xmlnode, &h, ver); - } else - fprintf(stderr, ""); - } - if( handle_n != NULL ) { + + dmiMajor = find_dmiMajor(&h); + if( dmiMajor != NULL ) { + handle_n = dmi_decode(xmlnode, dmiMajor, &h, ver); + } else { + handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMImessage", NULL); + assert( handle_n != NULL ); + dmixml_AddTextContent(handle_n, "DMI/SMBIOS type 0x%02X is not supported " + "by dmidecode", h.type); + dmixml_AddAttribute(handle_n, "type", "%i", h.type); + dmixml_AddAttribute(handle_n, "unsupported", "1"); + } + } else { + handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMIerror", NULL); + assert( handle_n != NULL ); + dmixml_AddTextContent(handle_n, "Data is truncated"); + dmixml_AddAttribute(handle_n, "type", "%i", h.type); + dmixml_AddAttribute(handle_n, "truncated", "1"); + } dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); dmixml_AddAttribute(handle_n, "size", "%d", h.length); + decoding_done = 1; } - data = next; i++; } + if( decoding_done == 0 ) { + xmlNode *handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMImessage", NULL); + assert( handle_n != NULL ); + dmixml_AddTextContent(handle_n, "DMI/SMBIOS type 0x%02X is not found on this hardware", + type); + dmixml_AddAttribute(handle_n, "type", "%i", type); + dmixml_AddAttribute(handle_n, "notfound", "1"); + } + if(i != num) fprintf(stderr, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i); diff --git a/src/dmidecode.h b/src/dmidecode.h index f0cb1ab..81cd249 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -30,7 +30,7 @@ struct dmi_header { }; void dmi_dump(xmlNode *node, struct dmi_header * h); -xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); +xmlNode *dmi_decode(xmlNode *parent_n, dmi_codes_major *dmiMajor, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 9699e82..378ad2a 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -25,7 +25,6 @@ xmlNode *dmidecode_get_version(options *); extern void dmi_dump(xmlNode *node, struct dmi_header *h); -extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); extern int address_from_efi(size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); extern int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *node); -- cgit From bd2860211df08c041033c1403707c13d899ae786 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 10:59:56 +0200 Subject: Added mapping to retrieve all DMI/SMBIOS types dmidecode can decode --- src/pymap.xml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 8619211..0b16def 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -490,6 +490,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit From ad581a625904993404878b06804106fe5d8caf67 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 11:01:55 +0200 Subject: Renamed to to avoid confusion with the tag --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 63b8040..3900770 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3700,7 +3700,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddAttribute(sect_n, "dmispec", "%s", dmiMajor->id); dmixml_AddAttribute(sect_n, "type", "%i", h->type); - dmixml_AddTextChild(sect_n, "description", "%s", dmiMajor->desc); + dmixml_AddTextChild(sect_n, "DMIdescription", "%s", dmiMajor->desc); switch (h->type) { case 0: /* 3.3.1 BIOS Information */ -- cgit From 42a61ee1bf81334fffb02d75cb04196862746cef Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 11:26:07 +0200 Subject: Implemented new dmidecode function - QuerySection(...) This is a more dynamic function than the static functions like dmidecode.bios(). The equivalent will be dmidecode.QuerySection('bios') This is to unify the dmidecode API and the dmidecodeXML API --- src/dmidecodemodule.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index d0c7043..3bc54d0 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -455,6 +455,17 @@ static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "slot"); } + +static PyObject *dmidecode_get_section(PyObject *self, PyObject *args) +{ + char *section = PyString_AsString(args); + + if( section != NULL ) { + return dmidecode_get_group(global_options, section); + } + PyReturnError(PyExc_RuntimeError, "No section name was given"); +} + static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) { int typeid; @@ -637,6 +648,11 @@ static PyMethodDef DMIDataMethods[] = { {(char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data"}, {(char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data"}, + {(char *)"QuerySection", dmidecode_get_section, METH_O, + (char *) "Queries the DMI data structure for a given section name. A section" + "can often contain several DMI type elements" + }, + {(char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type"}, {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O, -- cgit From 5df4623af673405691c7f778b42bfcbc4e974082 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 11:29:54 +0200 Subject: Implemented new dmidecode function - QueryTypeId(...) This function shadows the dmidecode.type() function. This is to clarify more what the function does and to unify the API against the dmidecodeXML API. --- src/dmidecodemodule.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 3bc54d0..7cdbd26 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -655,6 +655,10 @@ static PyMethodDef DMIDataMethods[] = { {(char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type"}, + {(char *)"QueryTypeId", dmidecode_get_type, METH_VARARGS, + (char *) "Queries the DMI data structure for a specific DMI type." + }, + {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O, (char *) "Use another python dict map definition. The default file is " PYTHON_XML_MAP}, -- cgit From a8257055f3d5f474d601cb3a5cbcbdb44e2b707d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 13:34:26 +0200 Subject: Made sure copyright is in place and right people get their deserved credit --- src/config.h | 34 ++++++++++++++++++++++++++++++++++ src/dmidecodemodule.h | 41 +++++++++++++++++++++++++++++++++++++++++ src/dmihelper.h | 41 +++++++++++++++++++++++++++++++++++++++++ src/libxml_wrap.h | 31 +++++++++++++++++++++++++++++++ src/pymap.xml | 41 ++++++++++++++++++++++++++++++++++++----- src/setup-dbg.py | 28 ++++++++++++++++++++++++++++ src/setup.py | 28 ++++++++++++++++++++++++++++ src/types.h | 26 ++++++++++++++++++++++++++ 8 files changed, 265 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/config.h b/src/config.h index add77cc..2876788 100644 --- a/src/config.h +++ b/src/config.h @@ -1,3 +1,37 @@ +/* + * © 2007-2009 Nima Talebi + * © 2009 David Sommerseth + * + * This file is part of Python DMI-Decode. + * + * Python DMI-Decode is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Python DMI-Decode 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 General Public License + * along with Python DMI-Decode. If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY + * AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE. + * + */ /* * Configuration diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 378ad2a..c0be3a1 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -1,3 +1,44 @@ +/*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* + *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et + *. + *. © 2007-2009 Nima Talebi + *. © 2009 David Sommerseth + *. © 2002-2008 Jean Delvare + *. © 2000-2002 Alan Cox + *. + *. This file is part of Python DMI-Decode. + *. + *. Python DMI-Decode is free software: you can redistribute it and/or modify + *. it under the terms of the GNU General Public License as published by + *. the Free Software Foundation, either version 2 of the License, or + *. (at your option) any later version. + *. + *. Python DMI-Decode 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 General Public License + *. along with Python DMI-Decode. If not, see . + *. + *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *. + *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY + *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE. + *. + *. $AutoHeaderSerial::20090522 $ + *. ******* AUTOHEADER END v1.1 ******* */ + + #include #include diff --git a/src/dmihelper.h b/src/dmihelper.h index 6607dc5..d89c024 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -1,3 +1,44 @@ +/*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* + *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et + *. + *. © 2007-2009 Nima Talebi + *. © 2009 David Sommerseth + *. © 2002-2008 Jean Delvare + *. © 2000-2002 Alan Cox + *. + *. This file is part of Python DMI-Decode. + *. + *. Python DMI-Decode is free software: you can redistribute it and/or modify + *. it under the terms of the GNU General Public License as published by + *. the Free Software Foundation, either version 2 of the License, or + *. (at your option) any later version. + *. + *. Python DMI-Decode 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 General Public License + *. along with Python DMI-Decode. If not, see . + *. + *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *. + *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY + *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE. + *. + *. $AutoHeaderSerial::20090522 $ + *. ******* AUTOHEADER END v1.1 ******* */ + + #ifndef HELPER #define HELPER 1 diff --git a/src/libxml_wrap.h b/src/libxml_wrap.h index eaa5e96..e4f56dd 100644 --- a/src/libxml_wrap.h +++ b/src/libxml_wrap.h @@ -1,3 +1,34 @@ +/* + * Copyright (C) 1998-2003 Daniel Veillard. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is fur- + * nished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Daniel Veillard shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + * ings in this Software without prior written authorization from him. + * + * + * This include file is taken from the libxml2 source tree, to provide the needed + * declarations to implement usage of libxml2xml.so + * (David Sommerseth , 2009) + * + */ + #include #include #include diff --git a/src/pymap.xml b/src/pymap.xml index 0b16def..e59fdf1 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -1,14 +1,45 @@ + + diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 329c345..8067cad 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -1,3 +1,31 @@ +# +# setup-dbg.py +# Python distutil package setup, with debug features enabled +# +# Copyright 2009 David Sommerseth +# Copyright 2007-2009 Nima Talebi +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# For the avoidance of doubt the "preferred form" of this code is one which +# is in an open unpatent encumbered format. Where cryptographic key signing +# forms part of the process of creating an executable the information +# including keys needed to generate an equivalently functional executable +# are deemed to be part of the source code. +# + from distutils.core import setup, Extension setup( diff --git a/src/setup.py b/src/setup.py index d5d47f4..8453e3b 100644 --- a/src/setup.py +++ b/src/setup.py @@ -1,3 +1,31 @@ +# +# setup.py +# Python distutil package setup +# +# Copyright 2009 David Sommerseth +# Copyright 2007-2009 Nima Talebi +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# For the avoidance of doubt the "preferred form" of this code is one which +# is in an open unpatent encumbered format. Where cryptographic key signing +# forms part of the process of creating an executable the information +# including keys needed to generate an equivalently functional executable +# are deemed to be part of the source code. +# + from distutils.core import setup, Extension from distutils.sysconfig import get_python_lib diff --git a/src/types.h b/src/types.h index 39d3d8f..5f3dcd4 100644 --- a/src/types.h +++ b/src/types.h @@ -1,3 +1,29 @@ +/* + * This file is part of the dmidecode project. + * + * Copyright (C) 2002-2008 Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + #ifndef TYPES_H #define TYPES_H -- cgit From 15463a7100a1d22ff2692f39d3a66f1d42eee3f7 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 13:41:18 +0200 Subject: Updated setup-dbg.py to be in sync with setup.py Also undefined the NDEBUG when building this package --- src/setup-dbg.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 8067cad..9d297b0 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -27,6 +27,9 @@ # from distutils.core import setup, Extension +from distutils.sysconfig import get_python_lib + +libdir = get_python_lib(1) setup( name = "python-dmidecode-dbg", @@ -39,7 +42,7 @@ setup( data_files = [ ('share/python-dmidecode-dbg', ['src/pymap.xml']) ], ext_modules = [ Extension( - "dmidecode", + "dmidecodemod", sources = [ "src/dmidecodemodule.c", "src/util.c", @@ -50,7 +53,10 @@ setup( "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], - libraries = [ "util", "xml2" ], #[ "util", "xml2", "efence" ], + library_dirs = [ libdir ], + libraries = [ "xml2", "xml2mod" ], + undef_macros = [ "NDEBUG" ] ) - ] + ], + py_modules = [ "dmidecode" ] ) -- cgit From 1d8478a6437e9eb4cd12c679c8dbd26dc2c344e1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 15:07:47 +0200 Subject: Improved setup.py/setup-dbg.py even more Get libxml2 compile time info from xml2-config. Retrieve version number from src/version.h --- src/setup-dbg.py | 27 +++++++++++++---- src/setup.py | 27 +++++++++++++---- src/setup_common.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/version.h | 2 +- 4 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 src/setup_common.py (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 9d297b0..30e6754 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -28,12 +28,29 @@ from distutils.core import setup, Extension from distutils.sysconfig import get_python_lib +from setup_common import * -libdir = get_python_lib(1) +# +# Some default values +# +incdir = [] +libdir = [get_python_lib(1)] +libs = [] + +# Get libxml2 info +libxml2_include(incdir) +libxml2_lib(libdir, libs) + +# misc info +dmidec_version = get_version() + +# +# Python setup +# setup( name = "python-dmidecode-dbg", - version = "3.10.6", + version = dmidec_version, license='GPL-2', description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", @@ -52,9 +69,9 @@ setup( "src/dmierror.c", "src/xmlpythonizer.c" ], - include_dirs = [ "/usr/include/libxml2" ], - library_dirs = [ libdir ], - libraries = [ "xml2", "xml2mod" ], + include_dirs = incdir, + library_dirs = libdir, + libraries = libs, undef_macros = [ "NDEBUG" ] ) ], diff --git a/src/setup.py b/src/setup.py index 8453e3b..81f302a 100644 --- a/src/setup.py +++ b/src/setup.py @@ -28,12 +28,29 @@ from distutils.core import setup, Extension from distutils.sysconfig import get_python_lib +from setup_common import * -libdir = get_python_lib(1) +# +# Some default values +# +incdir = [] +libdir = [get_python_lib(1)] +libs = [] + +# Get libxml2 info +libxml2_include(incdir) +libxml2_lib(libdir, libs) + +# misc info +dmidec_version = get_version() + +# +# Python setup +# setup( name = "python-dmidecode", - version = "3.10.6", + version = dmidec_version, license='GPL-2', description = "Python extension module for dmidecode", author = "Nima Talebi & David Sommerseth", @@ -52,9 +69,9 @@ setup( "src/dmierror.c", "src/xmlpythonizer.c" ], - include_dirs = [ "/usr/include/libxml2" ], - library_dirs = [ libdir ], - libraries = [ "xml2", "xml2mod" ] + include_dirs = incdir, + library_dirs = libdir, + libraries = libs ) ], py_modules = [ "dmidecode" ] diff --git a/src/setup_common.py b/src/setup_common.py new file mode 100644 index 0000000..fda01a8 --- /dev/null +++ b/src/setup_common.py @@ -0,0 +1,83 @@ +# +# setup-common.py +# Helper functions for retrieving libxml2 arguments needed for compilation +# and other functions which is used in both setup.py and setup-dbg.py +# +# Copyright 2009 David Sommerseth +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# For the avoidance of doubt the "preferred form" of this code is one which +# is in an open unpatent encumbered format. Where cryptographic key signing +# forms part of the process of creating an executable the information +# including keys needed to generate an equivalently functional executable +# are deemed to be part of the source code. +# + +import commands, sys + +# libxml2 - C flags +def libxml2_include(incdir): + (res, libxml2_cflags) = commands.getstatusoutput("xml2-config --cflags") + if res != 0: + print "Could not build python-dmidecode." + print "Could not run xml2-config, is libxml2 installed?" + print "Also the development libraries?" + sys.exit(1) + + # Parse the xml2-config --cflags response + for l in libxml2_cflags.split(" "): + if l.find('-I') == 0: + incdir.append(l.replace("-I", "", 1)) + + + +# libxml2 - library flags +def libxml2_lib(libdir, libs): + (res, libxml2_libs) = commands.getstatusoutput("xml2-config --libs") + if res != 0: + print "Could not build python-dmidecode." + print "Could not run xml2-config, is libxml2 installed?" + print "Also the development libraries?" + sys.exit(1) + + # Parse the xml2-config --libs response + for l in libxml2_libs.split(" "): + if l.find('-L') == 0: + libdir.append(l.replace("-L", "", 1)) + elif l.find('-l') == 0: + libs.append(l.replace("-l", "", 1)) + + # this library is not reported and we need it anyway + libs.append('xml2mod') + + + +# Get version from src/version.h +def get_version(): + f = open("src/version.h") + version = "0.0.0" + try: + for line in f: + part = line.split(" ") + if part[0] == "#define": + if part[1] == "VERSION": + version = part[2].strip().strip('"') + break + finally: + f.close() + + return version + diff --git a/src/version.h b/src/version.h index 050cf7a..70ea80d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "2.9" +#define VERSION "3.10.6" -- cgit From 67a5695ed2b709cf934763ef34c1d239542fedf4 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 15:26:47 +0200 Subject: Make get_version() look for version.h one more place --- src/setup_common.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/setup_common.py b/src/setup_common.py index fda01a8..e55bf4f 100644 --- a/src/setup_common.py +++ b/src/setup_common.py @@ -67,8 +67,12 @@ def libxml2_lib(libdir, libs): # Get version from src/version.h def get_version(): - f = open("src/version.h") version = "0.0.0" + try: + f = open("src/version.h") + except: + f = open("version.h") + try: for line in f: part = line.split(" ") -- cgit From 0bad177cda15cf21ab5bb7f1ea9eaf736d0f1ba7 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 15:34:14 +0200 Subject: Pick the version info from version.h --- src/dmidecodemodule.c | 3 ++- src/xmlpythonizer.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 7cdbd26..0d92612 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -48,6 +48,7 @@ #include "dmidecodemodule.h" #include "dmixml.h" #include "dmierror.h" +#include "version.h" #include static void init(options *opt) @@ -712,7 +713,7 @@ PyMODINIT_FUNC initdmidecodemod(void) module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods, "Python extension module for dmidecode"); - version = PyString_FromString("3.10.6"); + version = PyString_FromString(VERSION); Py_INCREF(version); PyModule_AddObject(module, "version", version); diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 68c29c2..f6dfe15 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -83,6 +83,7 @@ #include "dmixml.h" #include "dmierror.h" #include "xmlpythonizer.h" +#include "version.h" /** @@ -1172,7 +1173,7 @@ PyMODINIT_FUNC initxmlpythonizer(void) { Py_InitModule3((char *)"xmlpythonizer", DemoMethods, "XML to Python Proof-of-Concept Python Module"); - PyObject *version = PyString_FromString("3.10.6"); + PyObject *version = PyString_FromString(VERSION); Py_INCREF(version); PyModule_AddObject(module, "version", version); } -- cgit From d3e1e163a21a55ca8f3daf1d4eb0549851b28361 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 11 Jun 2009 18:56:10 +0200 Subject: Fixed an XML formatting issue - dmispec attribute was duplicated in --- src/dmidecode.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 3900770..e5e4a4b 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -2140,7 +2140,6 @@ void dmi_oem_strings(xmlNode *node, struct dmi_header *h) u8 count = p[0x00]; int i; - dmixml_AddAttribute(node, "dmispec", "3.3.12"); dmixml_AddAttribute(node, "count", "%i", count); for(i = 1; i <= count; i++) { -- cgit From 27f81037d82585b29ed09db2f6d7ed1e30db7dd1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 12 Jun 2009 18:10:44 +0200 Subject: Fixed another XML formatting error in dmidecode.c --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index e5e4a4b..003e9ff 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4336,7 +4336,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_pointing_device_type(sect_n, data[0x04]); dmi_pointing_device_interface(sect_n, data[0x05]); - dmixml_AddTextContent(sect_n, "Buttons", "%i", data[0x06]); + dmixml_AddTextChild(sect_n, "Buttons", "%i", data[0x06]); break; case 22: /* 3.3.23 Portable Battery */ -- cgit From 4f46bece8a32378062857da9d740fcee17ffc246 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 12 Jun 2009 18:17:19 +0200 Subject: Fixed error in dumping DMI/SMBIOS data to disk --- src/dmidecodemodule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 0d92612..7e7d0a3 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -566,9 +566,11 @@ static PyObject *dmidecode_dump(PyObject * self, PyObject * null) f = (global_options->dumpfile ? global_options->dumpfile : global_options->devmem); stat(f, &_buf); - if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode))) - if(dump(PyString_AS_STRING(global_options->dumpfile))) + if( (access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode)) ) { + if( dump(f) ) { Py_RETURN_TRUE; + } + } Py_RETURN_FALSE; } -- cgit From 20030e42b4d3f7283f6143641cb009a8dbf1da24 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 15 Jun 2009 11:07:34 +0200 Subject: Fixed wrong int->hex string conversion Upper case hex string values is used in the pymap.xml file. This should be improved so that type id is case insensitive. --- src/xmlpythonizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index f6dfe15..bf3d323 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -487,7 +487,7 @@ ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid) { } memset(&typeid_s, 0, 16); - snprintf(typeid_s, 14, "0x%02x", typeid); + snprintf(typeid_s, 14, "0x%02X", typeid); // Find the section node = dmixml_FindNode(node, "TypeMapping"); -- cgit From e9a6b7f9ec31c1227be982fb8f2bb0ee8bf97710 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 15 Jun 2009 11:11:55 +0200 Subject: Fixed wrong behavivour in pythonizeXMLnode() when no key value is found If the XPath expression for the key value points on a non-existing XML node, it would earlier abort pythonizing the XML data. Even though this could look like the correct behaviour, it will not work out well in reality. For sections like 'bios', it might be that the DMI/SMBIOS data do not describe or provide the BIOSLanguage section (type id 0x0D). Which means calling dmidecode.bios() would fail completely instead of reporting what it could find. This patch fixes this issue and it will normally ignore not found key values and just continue pythonizing the XML data and return what it managed to translate into a Python dictionary. If DEBUG is defined when compiling python-dmidecode, a warning message will be printed directly to stderr when a key value is not found. A warning is printed if dmidecode is compiled with DEBUG defined. --- src/xmlpythonizer.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index bf3d323..a9282e2 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -1040,33 +1040,32 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { xpctx->node = data_n; xpo = _get_xpath_values(xpctx, map_p->rootpath); - if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) { - if( xpo != NULL ) { - xmlXPathFreeObject(xpo); + if( (xpo != NULL) && (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr > 0) ) { + for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { + xpctx->node = xpo->nodesetval->nodeTab[i]; + + if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + PyObject *res = _deep_pythonize(retdata, map_p, + xpo->nodesetval->nodeTab[i], i); + if( res == NULL ) { + // Exit if we get NULL - something is wrong + //and exception is set + return NULL; + } + } } - xmlFreeDoc(xpdoc); xmlXPathFreeContext(xpctx); - PyReturnError(PyExc_LookupError, - "Could not locate XML path node (e2): %s " - "(Defining key: %s)", map_p->rootpath, map_p->key); + xmlFreeDoc(xpdoc); } - - for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { - xpctx->node = xpo->nodesetval->nodeTab[i]; - - if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - PyObject *res = _deep_pythonize(retdata, map_p, - xpo->nodesetval->nodeTab[i], i); - if( res == NULL ) { - // Exit if we get NULL - something is wrong - //and exception is set - return NULL; - } - } +#ifdef DEBUG + else { + fprintf(stderr, "** pythonizeXMLnode :: Could not locate node for key value: " + "root path '%s', key '%s'\n", map_p->rootpath, map_p->key); + } +#endif + if( xpo != NULL ) { + xmlXPathFreeObject(xpo); xpo = NULL; } - xmlXPathFreeObject(xpo); - xmlXPathFreeContext(xpctx); - xmlFreeDoc(xpdoc); } else { PyObject *res = _deep_pythonize(retdata, map_p, data_n, 0); if( res == NULL ) { -- cgit From 655799b06376c503086e43a0225298d170e08dbf Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 15 Jun 2009 18:39:49 +0200 Subject: Added new function: dmixml_FindNodeByAttr_NoCase(...) This function will ignore the case of the string of the value to be found. This improves the behaviour mentioned in commit 20030e42b4d3f7283f6143641cb009a8dbf1da24. At the moment, the immediate advantage is that the pymap.xml is not strictly bound to if the type IDs in hex are in upper and/or lower case. Both cases and mixed cases will now work. --- src/dmixml.c | 16 +++++++++++----- src/dmixml.h | 35 ++++++++++++++++++++++++++++++++++- src/xmlpythonizer.c | 2 +- 3 files changed, 46 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/dmixml.c b/src/dmixml.c index 1092872..5d9f1a1 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -213,20 +213,24 @@ char *dmixml_GetAttrValue(xmlNode *node, const char *key) { } /** - * Retrieve a pointer to an XML node based on tag name and a specified attribute value. To get - * a hit, tag name and the attribute must be found and the value of the attribute must match as well. - * The function will traverse all children nodes of the given input node, but it will not go deeper. + * Internal function - Retrieve a pointer to an XML node based on tag name and a specified attribute + * value. To get a hit, tag name and the attribute must be found and the value of the attribute must + * match as well. The function will traverse all children nodes of the given input node, but it will + * not go deeper. * @author David Sommerseth * @author Nima Talebi * @param xmlNode* Pointer to the XML node of where to start searching * @param const char* Tag name the function will search for * @param const char* Attribute to check for in the tag * @param const char* Value of the attribute which must match to have a hit + * @param int Be case sensitive or not. 1 == case sensitive, 0 == case insensitive * @return xmlNode* Pointer to the found XML node, NULL if no tag was found. */ -xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey, const char *val) { +xmlNode *__dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey, + const char *val, int casesens) { xmlNode *ptr_n = NULL; xmlChar *tag_s = NULL; + int (*compare_func) (const char *, const char *); assert( node != NULL ); if( node->children == NULL ) { @@ -236,12 +240,14 @@ xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *at tag_s = xmlCharStrdup(tagkey); assert( tag_s != NULL ); + compare_func = (casesens == 1 ? strcmp : strcasecmp); + foreach_xmlnode(node->children, ptr_n) { // To return the correct node, we need to check node type, // tag name and the attribute value of the given attribute. if( (ptr_n->type == XML_ELEMENT_NODE) && (xmlStrcmp(ptr_n->name, tag_s) == 0) - && (strcmp(dmixml_GetAttrValue(ptr_n, attrkey), val) == 0 ) ) { + && (compare_func(dmixml_GetAttrValue(ptr_n, attrkey), val) == 0 ) ) { goto exit; } } diff --git a/src/dmixml.h b/src/dmixml.h index c78d8b0..3dc32e5 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -37,7 +37,40 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); char *dmixml_GetAttrValue(xmlNode *node, const char *key); -xmlNode *dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey, const char *val); + +xmlNode *__dmixml_FindNodeByAttr(xmlNode *, const char *, const char *, const char *, int); + +/** + * Retrieve a pointer to an XML node based on tag name and a specified attribute value. To get + * a hit, tag name and the attribute must be found and the value of the attribute must match as well. + * The function will traverse all children nodes of the given input node, but it will not go deeper. + * Matching is case sensitive. + * @author David Sommerseth + * @author Nima Talebi + * @param xmlNode* Pointer to the XML node of where to start searching + * @param const char* Tag name the function will search for + * @param const char* Attribute to check for in the tag + * @param const char* Value of the attribute which must match to have a hit + * @return xmlNode* Pointer to the found XML node, NULL if no tag was found. + */ +#define dmixml_FindNodeByAttr(n, t, a, v) __dmixml_FindNodeByAttr(n, t, a, v, 1) + +/** + * Retrieve a pointer to an XML node based on tag name and a specified attribute value. To get + * a hit, tag name and the attribute must be found and the value of the attribute must match as well. + * The function will traverse all children nodes of the given input node, but it will not go deeper. + * Matching is case INsensitive. + * @author David Sommerseth + * @author Nima Talebi + * @param xmlNode* Pointer to the XML node of where to start searching + * @param const char* Tag name the function will search for + * @param const char* Attribute to check for in the tag + * @param const char* Value of the attribute which must match to have a hit + * @return xmlNode* Pointer to the found XML node, NULL if no tag was found. + */ +#define dmixml_FindNodeByAttr_NoCase(n, t, a, v) __dmixml_FindNodeByAttr(n, t, a, v, 0) + + xmlNode *dmixml_FindNode(xmlNode *, const char *key); inline char *dmixml_GetContent(xmlNode *node); inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index a9282e2..47590dd 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -458,7 +458,7 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) assert( mapnode != NULL); // Find the tag with our type ID - node = dmixml_FindNodeByAttr(mapnode, "TypeMap", "id", typeid); + node = dmixml_FindNodeByAttr_NoCase(mapnode, "TypeMap", "id", typeid); if( node == NULL ) { // No exception handling possible here, as we don't return PyObject fprintf(stderr,"** WARNING: Could not find any XML->Python " -- cgit From cb94510ce84cea18a675f1984cc8a3c955e6a2a4 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 17 Jun 2009 22:51:25 +1000 Subject: Commented in the Debian workaround for `xml2mod' --- src/setup-dbg.py | 1 + src/setup.py | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 30e6754..38ba6df 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -34,6 +34,7 @@ from setup_common import * # Some default values # incdir = [] +#. XXX: Debian Workaound: libdir = [get_python_lib(1), "/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2]] libdir = [get_python_lib(1)] libs = [] diff --git a/src/setup.py b/src/setup.py index 81f302a..a8ab032 100644 --- a/src/setup.py +++ b/src/setup.py @@ -34,6 +34,7 @@ from setup_common import * # Some default values # incdir = [] +#. XXX: Debian Workaound: libdir = [get_python_lib(1), "/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2]] libdir = [get_python_lib(1)] libs = [] -- cgit From 3849ca0a4abf5eb661758e1341a6e595d3013c2c Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 18 Jun 2009 14:53:29 +0200 Subject: Splitted out SMBIOS/DMI dump functions from dmidecode.c to separate files --- src/dmidecode.c | 164 +------------------------------------------------- src/dmidecode.h | 4 -- src/dmidecodemodule.c | 3 +- src/dmidump.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++ src/dmidump.h | 37 ++++++++++++ src/efi.c | 83 +++++++++++++++++++++++++ src/efi.h | 35 +++++++++++ src/setup-dbg.py | 4 +- src/setup.py | 4 +- 9 files changed, 320 insertions(+), 169 deletions(-) create mode 100644 src/dmidump.c create mode 100644 src/dmidump.h create mode 100644 src/efi.c create mode 100644 src/efi.h (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 003e9ff..9a35ecb 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -84,13 +84,11 @@ #include "dmixml.h" #include "dmidecode.h" #include "dmioem.h" +#include "efi.h" +#include "dmidump.h" #include "dmihelper.h" -#define EFI_NOT_FOUND (-1) -#define EFI_NO_SMBIOS (-2) - - /******************************************************************************* ** Type-independant Stuff */ @@ -4830,123 +4828,6 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -/* - * Build a crafted entry point with table address hard-coded to 32, - * as this is where we will put it in the output file. We adjust the - * DMI checksum appropriately. The SMBIOS checksum needs no adjustment. - */ -static void overwrite_dmi_address(u8 * buf) -{ - buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32; - buf[0x08] = 32; - buf[0x09] = 0; - buf[0x0A] = 0; - buf[0x0B] = 0; -} - -#define NON_LEGACY 0 -#define LEGACY 1 -int dumpling(u8 * buf, const char *dumpfile, u8 mode) -{ - u32 base; - u16 len; - - if(mode == NON_LEGACY) { - if(!checksum(buf, buf[0x05]) || !memcmp(buf + 0x10, "_DMI_", 5) == 0 || - !checksum(buf + 0x10, 0x0F)) - return 0; - base = DWORD(buf + 0x18); - len = WORD(buf + 0x16); - } else { - if(!checksum(buf, 0x0F)) - return 0; - base = DWORD(buf + 0x08); - len = WORD(buf + 0x06); - } - - u8 *buff; - - if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { - //. Part 1. -#ifdef NDEBUG - printf("# Writing %d bytes to %s.\n", len, dumpfile); -#endif - write_dump(32, len, buff, dumpfile, 0); - free(buff); - - //. Part 2. - if(mode != LEGACY) { - u8 crafted[32]; - - memcpy(crafted, buf, 32); - overwrite_dmi_address(crafted + 0x10); -#ifdef NDEBUG - printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); -#endif - write_dump(0, crafted[0x05], crafted, dumpfile, 1); - } else { - u8 crafted[16]; - - memcpy(crafted, buf, 16); - overwrite_dmi_address(crafted); -#ifdef NDEBUG - printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); -#endif - write_dump(0, 0x0F, crafted, dumpfile, 1); - } - } else { - fprintf(stderr, "Failed to read table, sorry.\n"); - } - - //. TODO: Cleanup - return 1; -} - -int dump(const char *dumpfile) -{ - /* On success, return found, otherwise return -1 */ - int ret = 0; - int found = 0; - size_t fp; - int efi; - u8 *buf; - - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(0xF0000, 0x10000, DEFAULT_MEM_DEV)) != NULL) { - for(fp = 0; fp <= 0xFFF0; fp += 16) { - if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(dumpling(buf + fp, dumpfile, NON_LEGACY)) - found++; - fp += 16; - } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(dumpling(buf + fp, dumpfile, LEGACY)) - found++; - } - } - } else - ret = -1; - } else if(efi == EFI_NO_SMBIOS) { - ret = -1; - } else { - if((buf = mem_chunk(fp, 0x20, DEFAULT_MEM_DEV)) == NULL) - ret = -1; - else if(dumpling(buf, dumpfile, NON_LEGACY)) - found++; - } - - if(ret == 0) { - free(buf); - if(!found) { - ret = -1; - } - } - - return ret == 0 ? found : ret; -} - dmi_codes_major *find_dmiMajor(const struct dmi_header *h) { @@ -5200,44 +5081,3 @@ int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) return check; } -/******************************************************************************* -** Probe for EFI interface -*/ -int address_from_efi(size_t * address) -{ - FILE *efi_systab; - const char *filename; - char linebuf[64]; - int ret; - - *address = 0; /* Prevent compiler warning */ - - /* - ** Linux <= 2.6.6: /proc/efi/systab - ** Linux >= 2.6.7: /sys/firmware/efi/systab - */ - if((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL - && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) { - /* No EFI interface, fallback to memory scan */ - return EFI_NOT_FOUND; - } - ret = EFI_NO_SMBIOS; - while((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) { - char *addrp = strchr(linebuf, '='); - - *(addrp++) = '\0'; - if(strcmp(linebuf, "SMBIOS") == 0) { - *address = strtoul(addrp, NULL, 0); - printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address); - ret = 0; - break; - } - } - if(fclose(efi_systab) != 0) - perror(filename); - - if(ret == EFI_NO_SMBIOS) - fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); - - return ret; -} diff --git a/src/dmidecode.h b/src/dmidecode.h index 81cd249..10412c6 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -31,7 +31,6 @@ struct dmi_header { void dmi_dump(xmlNode *node, struct dmi_header * h); xmlNode *dmi_decode(xmlNode *parent_n, dmi_codes_major *dmiMajor, struct dmi_header * h, u16 ver); -int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); @@ -43,6 +42,3 @@ const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); void dmi_chassis_type(xmlNode *node, u8 code); int dmi_processor_frequency(const u8 * p); - -int dump(const char *dumpfile); -int dumpling(u8 * buf, const char *devmem, u8 mode); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 7e7d0a3..1f37dc3 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -49,6 +49,7 @@ #include "dmixml.h" #include "dmierror.h" #include "version.h" +#include "dmidump.h" #include static void init(options *opt) @@ -567,7 +568,7 @@ static PyObject *dmidecode_dump(PyObject * self, PyObject * null) stat(f, &_buf); if( (access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode)) ) { - if( dump(f) ) { + if( dump(DEFAULT_MEM_DEV, f) ) { Py_RETURN_TRUE; } } diff --git a/src/dmidump.c b/src/dmidump.c new file mode 100644 index 0000000..4ecbb4d --- /dev/null +++ b/src/dmidump.c @@ -0,0 +1,155 @@ +/* Simple program for dumping DMI/SMBIOS data + * Based on code from python-dmidecode/dmidecode.c + * + * Copyright 2009 David Sommerseth + * Copyright 2002-2008 Jean Delvare + * Copyright 2000-2002 Alan Cox + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + + +#include +#include +#include +#include "types.h" +#include "util.h" + +#include "dmidump.h" +#include "efi.h" + +/* + * Build a crafted entry point with table address hard-coded to 32, + * as this is where we will put it in the output file. We adjust the + * DMI checksum appropriately. The SMBIOS checksum needs no adjustment. + */ +static void overwrite_dmi_address(u8 * buf) +{ + buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32; + buf[0x08] = 32; + buf[0x09] = 0; + buf[0x0A] = 0; + buf[0x0B] = 0; +} + +int dumpling(u8 * buf, const char *dumpfile, u8 mode) +{ + u32 base; + u16 len; + + if(mode == NON_LEGACY) { + if(!checksum(buf, buf[0x05]) || !memcmp(buf + 0x10, "_DMI_", 5) == 0 || + !checksum(buf + 0x10, 0x0F)) + return 0; + base = DWORD(buf + 0x18); + len = WORD(buf + 0x16); + } else { + if(!checksum(buf, 0x0F)) + return 0; + base = DWORD(buf + 0x08); + len = WORD(buf + 0x06); + } + + u8 *buff; + + if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { + //. Part 1. +#ifdef NDEBUG + printf("# Writing %d bytes to %s.\n", len, dumpfile); +#endif + write_dump(32, len, buff, dumpfile, 0); + free(buff); + + //. Part 2. + if(mode != LEGACY) { + u8 crafted[32]; + + memcpy(crafted, buf, 32); + overwrite_dmi_address(crafted + 0x10); +#ifdef NDEBUG + printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); +#endif + write_dump(0, crafted[0x05], crafted, dumpfile, 1); + } else { + u8 crafted[16]; + + memcpy(crafted, buf, 16); + overwrite_dmi_address(crafted); +#ifdef NDEBUG + printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); +#endif + write_dump(0, 0x0F, crafted, dumpfile, 1); + } + } else { + fprintf(stderr, "Failed to read table, sorry.\n"); + } + + //. TODO: Cleanup + return 1; +} + + +int dump(const char *memdev, const char *dumpfile) +{ + /* On success, return found, otherwise return -1 */ + int ret = 0; + int found = 0; + size_t fp; + int efi; + u8 *buf; + + /* First try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + if(efi == EFI_NOT_FOUND) { + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(0xF0000, 0x10000, memdev)) != NULL) { + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(dumpling(buf + fp, dumpfile, NON_LEGACY)) + found++; + fp += 16; + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(dumpling(buf + fp, dumpfile, LEGACY)) + found++; + } + } + } else + ret = -1; + } else if(efi == EFI_NO_SMBIOS) { + ret = -1; + } else { + if((buf = mem_chunk(fp, 0x20, memdev)) == NULL) + ret = -1; + else if(dumpling(buf, dumpfile, NON_LEGACY)) + found++; + } + + if(ret == 0) { + free(buf); + if(!found) { + ret = -1; + } + } + + return ret == 0 ? found : ret; +} +#endif diff --git a/src/dmidump.h b/src/dmidump.h new file mode 100644 index 0000000..3c12248 --- /dev/null +++ b/src/dmidump.h @@ -0,0 +1,37 @@ +/* Simple program for dumping DMI/SMBIOS data + * Based on code from python-dmidecode/dmidecode.c + * + * Copyright 2009 David Sommerseth + * Copyright 2002-2008 Jean Delvare + * Copyright 2000-2002 Alan Cox + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#ifndef _DMIDUMP_H + +#define NON_LEGACY 0 +#define LEGACY 1 + +int dump(const char *memdev, const char *dumpfile); + +#endif diff --git a/src/efi.c b/src/efi.c new file mode 100644 index 0000000..9802171 --- /dev/null +++ b/src/efi.c @@ -0,0 +1,83 @@ +/* + * Copyright 2009 David Sommerseth + * Copyright 2002-2008 Jean Delvare + * Copyright 2000-2002 Alan Cox + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#include +#include +#include +#include "efi.h" + +/** + * @file xmlpythonizer.c + * @brief Helper function for EFI support + * @author Jean Delvare + * @author Alan Cox + */ + +/** + * Probe for EFI interface + * @param size_t* + * @return returns EFI_NOT_FOUND or EFI_NO_SMBIOS + */ +int address_from_efi(size_t * address) +{ + FILE *efi_systab; + const char *filename; + char linebuf[64]; + int ret; + + *address = 0; /* Prevent compiler warning */ + + /* + ** Linux <= 2.6.6: /proc/efi/systab + ** Linux >= 2.6.7: /sys/firmware/efi/systab + */ + if((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL + && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) { + /* No EFI interface, fallback to memory scan */ + return EFI_NOT_FOUND; + } + ret = EFI_NO_SMBIOS; + while((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) { + char *addrp = strchr(linebuf, '='); + + *(addrp++) = '\0'; + if(strcmp(linebuf, "SMBIOS") == 0) { + *address = strtoul(addrp, NULL, 0); + printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address); + ret = 0; + break; + } + } + if(fclose(efi_systab) != 0) + perror(filename); + + if(ret == EFI_NO_SMBIOS) + fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); + + return ret; +} + diff --git a/src/efi.h b/src/efi.h new file mode 100644 index 0000000..240fb01 --- /dev/null +++ b/src/efi.h @@ -0,0 +1,35 @@ +/* + * Copyright 2009 David Sommerseth + * Copyright 2002-2008 Jean Delvare + * Copyright 2000-2002 Alan Cox + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#ifndef _EFI_H +#define _EFI_H +#define EFI_NOT_FOUND (-1) +#define EFI_NO_SMBIOS (-2) + +int address_from_efi(size_t * address); + +#endif diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 38ba6df..4077eaf 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -68,7 +68,9 @@ setup( "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", - "src/xmlpythonizer.c" + "src/xmlpythonizer.c", + "src/efi.c", + "src/dmidump.c" ], include_dirs = incdir, library_dirs = libdir, diff --git a/src/setup.py b/src/setup.py index a8ab032..75be21b 100644 --- a/src/setup.py +++ b/src/setup.py @@ -68,7 +68,9 @@ setup( "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", - "src/xmlpythonizer.c" + "src/xmlpythonizer.c", + "src/efi.c", + "src/dmidump.c" ], include_dirs = incdir, library_dirs = libdir, -- cgit From a95af5acd4f2591e2c0d42f0284897cd3de90230 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 18 Jun 2009 15:00:57 +0200 Subject: Added dmidump utility This is a simple utility which dumps DMI/SMBIOS data straight to a file, written i C and should not depend on anything extra. Useful to get DMI/SMBIOS data without installing python and/or python-dmidecode. The data dump can be parsed by python-dmidecode later on on a different box. --- src/dmidump.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/dmidump.c b/src/dmidump.c index 4ecbb4d..a07c975 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -152,4 +152,17 @@ int dump(const char *memdev, const char *dumpfile) return ret == 0 ? found : ret; } + + +#ifdef _DMIDUMP_MAIN_ +int main(int argc, char **argv) +{ + if( argc != 3 ) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + dump(argv[1], argv[2]); + + return 0; +} #endif -- cgit From 849627808ac2c20f5baec6431c4ee65547c11ecc Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 18 Jun 2009 18:58:28 +0200 Subject: Fixed issue with unterminated list in dmidecode_xmlapi() This caused an exception on Python2.3 --- src/dmidecodemodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 1f37dc3..5c74124 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -490,7 +490,7 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) static PyObject *dmidecode_xmlapi(PyObject *self, PyObject *args, PyObject *keywds) { - static char *keywordlist[] = {"query_type", "result_type", "section", "typeid"}; + static char *keywordlist[] = {"query_type", "result_type", "section", "typeid", NULL}; PyObject *pydata = NULL; xmlDoc *dmixml_doc = NULL; xmlNode *dmixml_n = NULL; -- cgit From d7376531310a92837dff47f9b0b130bb529c490b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 19 Jun 2009 11:14:47 +0200 Subject: Fixed missing check which caused SEGV on Python2.3 Could also be related to an older libxml2 version as well, as this behaviour was found on RHEL4u4 --- src/xmlpythonizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 47590dd..6704d1b 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -866,7 +866,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int xpo = _get_xpath_values(xpctx, map_p->value); if( xpo != NULL ) { if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { - if( xpo->nodesetval->nodeNr > 0 ) { + if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr > 0) ) { value = PyList_New(0); // If we're working on a fixed list, create one which contains -- cgit From 9c651823c9d4bb918c7b7bb618a3a6275ee22619 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 19 Jun 2009 11:16:08 +0200 Subject: Fixed incorrectly Py_DECREC() on Py_None values --- src/xmlpythonizer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 6704d1b..ba018eb 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -748,9 +748,11 @@ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *x * @param PyObject* Pointer to the Python value */ -#define PyADD_DICT_VALUE(p, k, v) { \ - PyDict_SetItemString(p, k, v); \ - Py_DECREF(v); \ +#define PyADD_DICT_VALUE(p, k, v) { \ + PyDict_SetItemString(p, k, v); \ + if( v != Py_None ) { \ + Py_DECREF(v); \ + } \ } -- cgit From ebb06f31e490f181b2e2267b0268421fda9b5d95 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 1 Jul 2009 15:04:00 +0200 Subject: Undefine NDEBUG in normal compiles as well. Arguments for doing so is that asserts are important to catch unhandled error situations and will help debugging if it fails in a production environment. --- src/setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/setup.py b/src/setup.py index 75be21b..96b6133 100644 --- a/src/setup.py +++ b/src/setup.py @@ -74,7 +74,8 @@ setup( ], include_dirs = incdir, library_dirs = libdir, - libraries = libs + libraries = libs, + undef_macros = [ "NDEBUG" ] ) ], py_modules = [ "dmidecode" ] -- cgit From 6bd9742784fb487463449e41330cdd102e0a5df1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 17:10:30 +0200 Subject: Completed python XML map for TypeMap 0x05 --- src/dmidecode.c | 15 ++++++++------- src/pymap.xml | 32 +++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 9a35ecb..41f882c 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1160,10 +1160,11 @@ void dmi_processor_voltage(xmlNode *node, u8 code) dmixml_AddAttribute(vltg_n, "unknown_value", "1"); } else { for(i = 0; i <= 2; i++) { - if( code & (1 << i) ) { - xmlNode *v_n = dmixml_AddTextChild(vltg_n, "Voltage", "%s", voltage[i]); - dmixml_AddAttribute(v_n, "unit", "V"); - } + xmlNode *v_n = dmixml_AddTextChild(vltg_n, "Voltage", "%s", voltage[i]); + dmixml_AddAttribute(v_n, "key_compound", "%s V", voltage[i]); + dmixml_AddAttribute(v_n, "available", "%i", (code & (1 << i) ? 1 : 0)); + dmixml_AddAttribute(v_n, "unit", "V"); + v_n = NULL; } } } @@ -1340,7 +1341,7 @@ void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u if(code & (1 << i)) { xmlNode *c_n = dmixml_AddTextChild(cap_n, "Capability", "%s", capabilities[i]); assert( c_n != NULL ); - dmixml_AddAttribute(c_n, "index", "%i", i); + dmixml_AddAttribute(c_n, "index", "%i", i+1); } } } @@ -1411,7 +1412,7 @@ void dmi_memory_controller_slots(xmlNode *node, u8 count, const u8 * p) assert( mslts_n != NULL ); for(i = 0; i < count; i++) { - xmlNode *sl_n = dmixml_AddTextChild(mslts_n, "Slot", "0x%04x:", WORD(p + sizeof(u16) * i)); + xmlNode *sl_n = dmixml_AddTextChild(mslts_n, "Slot", "0x%x:", WORD(p + sizeof(u16) * i)); dmixml_AddAttribute(sl_n, "index", "%i", i); } } @@ -1448,7 +1449,7 @@ void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code) if(code & (1 << i)) { xmlNode *mt_n = dmixml_AddTextChild(mmt_n, "ModuleType", types[i]); assert( mt_n != NULL ); - dmixml_AddAttribute(mt_n, "index", "%i", i); + dmixml_AddAttribute(mt_n, "index", "%i", i+1); } } } diff --git a/src/pymap.xml b/src/pymap.xml index e59fdf1..263f7db 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -174,8 +174,38 @@ - + + + + + + + + + + + + + + + + + + + + + -- cgit From fd0d07610740a4899461daa1a3ea2cf8dd5ef7bb Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 17:47:48 +0200 Subject: Completed python XML map for TypeMap 0x06 --- src/dmidecode.c | 4 ++-- src/pymap.xml | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 41f882c..33730c3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1464,10 +1464,10 @@ void dmi_memory_module_connections(xmlNode *node, u8 code) if(code != 0xFF) { if((code & 0xF0) != 0xF0) { - dmixml_AddTextContent(data_n, "%ld", (code >> 4)); + dmixml_AddTextChild(data_n, "Connection", "%ld", (code >> 4)); } if((code & 0x0F) != 0x0F) { - dmixml_AddTextContent(data_n, "%ld", (code & 0x0F)); + dmixml_AddTextChild(data_n, "Connection", "%ld", (code & 0x0F)); } } } diff --git a/src/pymap.xml b/src/pymap.xml index 263f7db..33e48a8 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -208,8 +208,33 @@ - + + + + + + + + + + + + + + + + + + + + + -- cgit From 14ed1dab72d3de65716acf71a4b2ad48bf19760f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 17:48:15 +0200 Subject: Completed python XML map for TypeMap 0x0B --- src/pymap.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 33e48a8..62860ca 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -324,8 +324,18 @@ - + + + + + + + + + + + -- cgit From e2c086d9aadeeeeb586af95b4fc1ecf65deecc8e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 17:52:31 +0200 Subject: Completed python XML map for TypeMap 0x0C --- src/pymap.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 62860ca..dc477ee 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -338,8 +338,18 @@ - + + + + + + + + + + + -- cgit From abdaa329af1f53c043a6293ac87c7a53d419545f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 18:03:36 +0200 Subject: Completed python XML map for TypeMap 0x12 --- src/pymap.xml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index dc477ee..ee49da2 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -449,8 +449,25 @@ - + + + + + + + + + + + + + + + -- cgit From 9cff9fae8afcaffcc2b06e982f2671aab0963009 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 18:13:42 +0200 Subject: Completed python XML map for TypeMap 0x13 --- src/pymap.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index ee49da2..e74dd7f 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -470,8 +470,21 @@ - + + + + + + + + + + + + + -- cgit From 2ae485557d176e79b7295813e732bbb38d33c379 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 18:25:01 +0200 Subject: Completed python XML map for TypeMap 0x14 --- src/pymap.xml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index e74dd7f..ece6e1d 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -487,8 +487,25 @@ - + + + + + + + + + + + + + + + -- cgit From 7081e1a71c3b420cb75a8bcb4a805cffd2dd804f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 18:57:58 +0200 Subject: Completed python XML map for TypeMap 0x15 --- src/pymap.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index ece6e1d..6b3c7ab 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -510,6 +510,16 @@ + + + + + + + + + + -- cgit From 7663721800f7428aafad5ee6072763f05c7c0fde Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:06:35 +0200 Subject: Completed python XML map for TypeMap 0x16 --- src/dmidecode.c | 2 +- src/pymap.xml | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index 33730c3..d4d8e9a 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4383,7 +4383,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddTextChild(sect_n, "SBDSchemistry", "%s", dmi_string(h, data[0x14])); } - dmixml_AddTextChild(sect_n, "OEMinformation", "%s", "0x%08x", DWORD(data + 0x16)); + dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x16)); break; case 23: /* 3.3.24 System Reset */ diff --git a/src/pymap.xml b/src/pymap.xml index 6b3c7ab..9323b59 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -522,8 +522,29 @@ - + + + + + + + + + + + + + + + + + + + -- cgit From 8bce361e874ccf31b444326aed4900e3adf218ca Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:12:07 +0200 Subject: Completed python XML map for TypeMap 0x17 --- src/pymap.xml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 9323b59..03e8ccd 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -547,8 +547,24 @@ - + + + + + + + + + + + + + + + + -- cgit From a35f7ab80bdae8140937916035b2dd6336f9bf69 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:16:56 +0200 Subject: Completed python XML map for TypeMap 0x18 --- src/pymap.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 03e8ccd..abbf334 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -567,8 +567,23 @@ - + + + + + + + + + + + + -- cgit From c16c803b41d8a7053180169930e34e3e4c1f0c87 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:21:08 +0200 Subject: Completed python XML map for TypeMap 0x19 Format has changed slightly. The original format in v2.10 was: {'Next Scheduled Power-on': [' *','-*',' 0',':0',':0']} The new format is: {'Next Scheduled Power-on': '*-* *:*:*'} The reason is that the formatting in the original list was rather half-done, containing separators in some of the elements. --- src/pymap.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index abbf334..2e7f5aa 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -586,8 +586,16 @@ - + + + + + + + + + -- cgit From 9a62dfed606a010b834fad5400ac93eeb7490e0d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:30:01 +0200 Subject: Completed python XML map for TypeMap 0x1A --- src/pymap.xml | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 2e7f5aa..d0de6fa 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -598,8 +598,31 @@ - + + + + + + + + + + + + + + + + + -- cgit From 886fecb84f270a78a92e051bad42407c28780e98 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:32:33 +0200 Subject: Completed python XML map for TypeMap 0x1B --- src/pymap.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index d0de6fa..5ddb0d8 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -625,8 +625,18 @@ - + + + + + + + + + + + -- cgit From 4331297215914119a225a8501300c200d700cd3f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:38:26 +0200 Subject: Completed python XML map for TypeMap 0x1C --- src/dmidecode.c | 2 +- src/pymap.xml | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dmidecode.c b/src/dmidecode.c index d4d8e9a..aa2332d 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3294,7 +3294,7 @@ void dmi_temperature_probe_resolution(xmlNode *node, u16 code) dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "unit", "C"); - dmixml_AddTextContent(data_n, "%.3f deg C", (float)code / 1000); + dmixml_AddTextContent(data_n, "%.3f", (float)code / 1000); } } diff --git a/src/pymap.xml b/src/pymap.xml index 5ddb0d8..74cab5d 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -639,8 +639,31 @@ - + + + + + + + + + + + + + + + + + -- cgit From 95ad9b1c534e3bcd8cd41cd616961c1a5e91331b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:43:59 +0200 Subject: Completed python XML map for TypeMap 0x1E --- src/pymap.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 74cab5d..34df4b1 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -670,8 +670,20 @@ - + + + + + + + + + + + -- cgit From 6503a07cdf8a7ddaaf858ee1e1a5af90258c14f2 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:48:28 +0200 Subject: Completed python XML map for TypeMap 0x21 --- src/pymap.xml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 34df4b1..4d258b4 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -702,8 +702,24 @@ - + + + + + + + + + + + + + + + -- cgit From 12254a81617b5984e2a696821e98487e9cbb1c69 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 2 Jul 2009 19:56:25 +0200 Subject: Completed python XML map for TypeMap 0x26 --- src/pymap.xml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pymap.xml b/src/pymap.xml index 4d258b4..a07512c 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -508,7 +508,7 @@ - + @@ -738,8 +738,24 @@ - + + + + + + + + + + + + + + + -- cgit From 392a9976b14d558d4b2f331b5a44ee97912fc5e3 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 3 Aug 2009 20:16:22 +1000 Subject: Moved a OS-specific library settings out to common The libxml2 path is now handled by `setup_common.py', so the actual setup files are clean from any OS-specific (Debian/RedHat) hacks. --- src/setup-dbg.py | 4 +--- src/setup.py | 4 +--- src/setup_common.py | 6 ++++++ 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 4077eaf..9602abc 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -27,15 +27,13 @@ # from distutils.core import setup, Extension -from distutils.sysconfig import get_python_lib from setup_common import * # # Some default values # incdir = [] -#. XXX: Debian Workaound: libdir = [get_python_lib(1), "/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2]] -libdir = [get_python_lib(1)] +libdir = [] libs = [] # Get libxml2 info diff --git a/src/setup.py b/src/setup.py index 96b6133..d33db64 100644 --- a/src/setup.py +++ b/src/setup.py @@ -27,15 +27,13 @@ # from distutils.core import setup, Extension -from distutils.sysconfig import get_python_lib from setup_common import * # # Some default values # incdir = [] -#. XXX: Debian Workaound: libdir = [get_python_lib(1), "/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2]] -libdir = [get_python_lib(1)] +libdir = [] libs = [] # Get libxml2 info diff --git a/src/setup_common.py b/src/setup_common.py index e55bf4f..fdf5c8c 100644 --- a/src/setup_common.py +++ b/src/setup_common.py @@ -27,6 +27,8 @@ # import commands, sys +from os import path as os_path +from distutils.sysconfig import get_python_lib # libxml2 - C flags def libxml2_include(incdir): @@ -46,6 +48,10 @@ def libxml2_include(incdir): # libxml2 - library flags def libxml2_lib(libdir, libs): + libdir.append(get_python_lib(1)) + if os_path.exists("/etc/debian_version"): #. XXX: Debian Workaround... + libdir.append("/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2]) + (res, libxml2_libs) = commands.getstatusoutput("xml2-config --libs") if res != 0: print "Could not build python-dmidecode." -- cgit